95ea6df85089a6c619d7efcee7b1b00f545ae585
[deliverable/binutils-gdb.git] / gas / config / obj-elf.c
1 /* ELF object file format
2 Copyright (C) 1992, 1993 Free Software Foundation, Inc.
3
4 This file is part of GAS, the GNU Assembler.
5
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as
8 published by the Free Software Foundation; either version 2,
9 or (at your option) any later version.
10
11 GAS is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
14 the GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public
17 License along with GAS; see the file COPYING. If not, write
18 to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 #include "as.h"
21 #include "subsegs.h"
22 #include "aout/stab_gnu.h"
23 #include "obstack.h"
24
25 static void obj_elf_stab PARAMS ((int what));
26 static void obj_elf_xstab PARAMS ((int what));
27 static void obj_elf_line PARAMS ((void));
28 void obj_elf_desc PARAMS ((void));
29 void obj_elf_version PARAMS ((void));
30 static void obj_elf_section PARAMS ((int));
31 static void obj_elf_size PARAMS ((void));
32 static void obj_elf_type PARAMS ((void));
33 static void obj_elf_ident PARAMS ((void));
34
35 const pseudo_typeS obj_pseudo_table[] =
36 {
37 {"ident", obj_elf_ident, 0},
38 {"section", obj_elf_section, 0},
39 {"size", obj_elf_size, 0},
40 {"type", obj_elf_type, 0},
41 {"version", obj_elf_version, 0},
42
43 /* These are used for stabs-in-elf configurations. */
44 {"desc", obj_elf_desc, 0},
45 {"line", obj_elf_line, 0},
46 {"stabd", obj_elf_stab, 'd'},
47 {"stabn", obj_elf_stab, 'n'},
48 {"stabs", obj_elf_stab, 's'},
49 /* This is used on Solaris 2.x on SPARC, but not supported yet. */
50 {"xstabs", obj_elf_xstab, 's'},
51
52 {NULL} /* end sentinel */
53 };
54
55 #include "aout/aout64.h"
56
57 void
58 elf_file_symbol (s)
59 char *s;
60 {
61 symbolS *sym;
62
63 sym = symbol_new (s, absolute_section, (valueT) 0, (struct frag *) 0);
64 sym->sy_frag = &zero_address_frag;
65 sym->bsym->flags |= BSF_FILE;
66
67 if (symbol_rootP != sym)
68 {
69 symbol_remove (sym, &symbol_rootP, &symbol_lastP);
70 symbol_insert (sym, symbol_rootP, &symbol_rootP, &symbol_lastP);
71 #ifdef DEBUG
72 verify_symbol_chain (symbol_rootP, symbol_lastP);
73 #endif
74 }
75 }
76
77 static void
78 obj_elf_section (xxx)
79 int xxx;
80 {
81 char *string;
82 asection *sec;
83
84 /* Initialize this with inclusive-or of all flags that can be cleared
85 by attributes, but not set by them. Also include flags that won't
86 get set properly in the assembler, but which the user/compiler
87 shouldn't be expected to set. */
88 flagword flags = SEC_READONLY | SEC_ALLOC | SEC_RELOC;
89 /* Initialize this with the default flags to be used if none are
90 specified. */
91 flagword default_flags = SEC_ALLOC | SEC_RELOC;
92
93 string = demand_copy_C_string (&xxx);
94 SKIP_WHITESPACE ();
95 if (*input_line_pointer != ',')
96 flags = default_flags;
97 while (*input_line_pointer == ',')
98 {
99 flagword bit;
100 int len, inv;
101 char *p, oldp;
102
103 input_line_pointer++;
104 if (*input_line_pointer != '#' && *input_line_pointer != '@')
105 {
106 as_bad ("unrecognized syntax in .section command");
107 ignore_rest_of_line ();
108 break;
109 }
110 input_line_pointer++;
111
112 #define CHECK(X,BIT,NEG) \
113 if (!strncmp(X,input_line_pointer,len = sizeof(X) - 1)) { \
114 bit = BIT; inv = NEG; goto match; }
115
116 CHECK ("write", SEC_READONLY, 1);
117 CHECK ("alloc", SEC_ALLOC, 0);
118 CHECK ("execinstr", SEC_CODE, 1);
119 #undef CHECK
120
121 p = input_line_pointer;
122 while (!is_end_of_line[*p] && *p != 0 && *p != ',')
123 p++;
124 *p = 0;
125 oldp = *p;
126 as_bad ("unrecognized section attribute `%s' ignored",
127 input_line_pointer);
128 *p = oldp;
129 continue;
130
131 match:
132 if (inv)
133 flags &= ~bit;
134 else
135 flags |= bit;
136 input_line_pointer += len;
137 }
138 demand_empty_rest_of_line ();
139
140 sec = bfd_get_section_by_name (stdoutput, string);
141 if (sec == 0)
142 {
143 sec = subseg_new (string, 0);
144 bfd_set_section_flags (stdoutput, sec, flags);
145 sec->output_section = sec;
146 }
147 subseg_set (sec, 0);
148 }
149
150 int
151 obj_elf_write_symbol_p (sym)
152 symbolS *sym;
153 {
154 /* If this is a local symbol, are there any relocations for which
155 need this symbol? */
156
157 /* To find this out, we examine all relocations in all bfd sections
158 that have relocations. If there is one that references this
159 symbol, we need to keep this symbol. In this case, we return a
160 true status. In all other cases, we return a false status. */
161
162 if (S_IS_LOCAL (sym))
163 {
164 asymbol *bsym = sym->bsym;
165 bfd *abfd = bsym->the_bfd;
166 asection *bsec;
167
168 for (bsec = abfd->sections; bsec; bsec = bsec->next)
169 {
170 struct reloc_cache_entry **rlocs = bsec->orelocation;
171 int rcnt = bsec->reloc_count;
172
173 if (rlocs)
174 {
175 int i;
176
177 for (i = 0; i < rcnt; i++)
178 if (rlocs[i]->sym_ptr_ptr
179 && rlocs[i]->sym_ptr_ptr[0] == bsym)
180 return 1;
181 }
182 else
183 {
184 /* No relocations for this section. Check the seg_info
185 structure to see if there are any fixups for this
186 section. */
187 segment_info_type *seginfo = seg_info (bsec);
188 fixS *fixp;
189
190 for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next)
191 if ((fixp->fx_addsy && fixp->fx_addsy->bsym == bsym)
192 || (fixp->fx_subsy && fixp->fx_subsy->bsym == bsym))
193 return 1;
194 }
195 }
196 }
197 return 0;
198 }
199
200 int
201 obj_elf_write_symbol (sym)
202 symbolS *sym;
203 {
204 return /* obj_elf_write_symbol_p (sym) || */ !S_IS_LOCAL (sym);
205 }
206
207 int
208 obj_elf_frob_symbol (sym, punt)
209 symbolS *sym;
210 int *punt;
211 {
212 return obj_elf_write_symbol_p (sym);
213 }
214
215 static void
216 obj_elf_line ()
217 {
218 /* Assume delimiter is part of expression. BSD4.2 as fails with
219 delightful bug, so we are not being incompatible here. */
220 new_logical_line ((char *) NULL, (int) (get_absolute_expression ()));
221 demand_empty_rest_of_line ();
222 }
223
224 /*
225 * stab()
226 *
227 * Handle .stabX directives, which used to be open-coded.
228 * So much creeping featurism overloaded the semantics that we decided
229 * to put all .stabX thinking in one place. Here.
230 *
231 * We try to make any .stabX directive legal. Other people's AS will often
232 * do assembly-time consistency checks: eg assigning meaning to n_type bits
233 * and "protecting" you from setting them to certain values. (They also zero
234 * certain bits before emitting symbols. Tut tut.)
235 *
236 * If an expression is not absolute we either gripe or use the relocation
237 * information. Other people's assemblers silently forget information they
238 * don't need and invent information they need that you didn't supply.
239 *
240 * .stabX directives always make a symbol table entry. It may be junk if
241 * the rest of your .stabX directive is malformed.
242 */
243
244 /*
245 * elf_stab_symbol_string()
246 *
247 * Build a string dictionary entry for a .stabX symbol.
248 * The symbol is added to the .stabstr section.
249 *
250 */
251
252 static unsigned int
253 elf_stab_symbol_string (string, secname)
254 char *string, *secname;
255 {
256 asection *save_seg;
257 asection *seg;
258 subsegT save_subseg;
259 unsigned int length;
260 unsigned int old_gdb_string_index;
261 char *clengthP;
262 int i;
263 char c;
264 /* @@FIXME -- there should be no static data here!
265 This also has the effect of making all stab string tables large enough
266 to contain all the contents written to any of them. This only matters
267 with the Solaris native compiler for the moment, but it should be fixed
268 anyways. */
269 static unsigned int gdb_string_index = 0;
270
271 old_gdb_string_index = 0;
272 length = strlen (string);
273 clengthP = (char *) &length;
274 if (length > 0)
275 { /* Ordinary case. */
276 save_seg = now_seg;
277 save_subseg = now_subseg;
278
279 /* Create the stab sections, if they are not already created. */
280 {
281 char *newsecname = xmalloc (strlen (secname) + 4);
282 strcpy (newsecname, secname);
283 strcat (newsecname, "str");
284 seg = bfd_get_section_by_name (stdoutput, newsecname);
285 if (seg == 0)
286 {
287 seg = bfd_make_section_old_way (stdoutput, newsecname);
288 bfd_set_section_flags (stdoutput, seg, SEC_READONLY | SEC_ALLOC);
289 }
290 /* free (newsecname);*/
291 }
292 subseg_new ((char *) seg->name, save_subseg);
293 old_gdb_string_index = gdb_string_index;
294 i = 0;
295 while ((c = *string++))
296 {
297 i++;
298 gdb_string_index++;
299 FRAG_APPEND_1_CHAR (c);
300 }
301 {
302 FRAG_APPEND_1_CHAR ((char) 0);
303 i++;
304 gdb_string_index++;
305 }
306 while (i % 4 != 0)
307 {
308 FRAG_APPEND_1_CHAR ((char) 0);
309 i++;
310 gdb_string_index++;
311 }
312 subseg_new ((char *) save_seg->name, save_subseg);
313 }
314
315 return old_gdb_string_index;
316 }
317
318 static void
319 DEFUN (elf_stab_symbol, (symbolP, stab_type),
320 symbolS *symbolP AND
321 int stab_type)
322 {
323 char *toP;
324
325 toP = frag_more (8);
326 /* the string index portion of the stab */
327 md_number_to_chars (toP, (valueT) symbolP->sy_name_offset, 4);
328 md_number_to_chars (toP + 4, (valueT) S_GET_TYPE (symbolP), 1);
329 md_number_to_chars (toP + 5, (valueT) S_GET_OTHER (symbolP), 1);
330 md_number_to_chars (toP + 6, (valueT) S_GET_DESC (symbolP), 2);
331 /* The n_value field doesn't get written here, it gets done below. It
332 may be an expression needing relocating. */
333 }
334
335 static void
336 obj_elf_stab_generic (what, secname)
337 int what;
338 char *secname;
339 {
340 extern int listing;
341
342 symbolS *symbolP = 0;
343 char *string;
344 int saved_type = 0;
345 int length;
346 int goof = 0;
347 long longint;
348 asection *saved_seg = now_seg;
349 asection *seg;
350 subsegT subseg = now_subseg;
351
352 #if 1
353 /* This function doesn't work yet.
354
355 Actually, this function is okay, but some finalizations are needed
356 before writing the object file; that's not done yet, and the Solaris
357 linker chokes without it.
358
359 In any case, this should effectively disable it for now. */
360 if (what == 's')
361 demand_copy_C_string (&length);
362 s_ignore (69);
363 return;
364 #endif
365
366 seg = bfd_get_section_by_name (stdoutput, secname);
367 if (seg == 0)
368 {
369 seg = subseg_new (secname, 0);
370 bfd_set_section_flags (stdoutput, seg,
371 SEC_READONLY | SEC_ALLOC | SEC_RELOC);
372 subseg_set (saved_seg, subseg);
373 }
374
375 /*
376 * Enter with input_line_pointer pointing past .stabX and any following
377 * whitespace.
378 */
379 if (what == 's')
380 {
381 string = demand_copy_C_string (&length);
382 SKIP_WHITESPACE ();
383 if (*input_line_pointer == ',')
384 input_line_pointer++;
385 else
386 {
387 as_bad ("I need a comma after symbol's name");
388 goof = 1;
389 }
390 }
391 else
392 string = "";
393
394 /*
395 * Input_line_pointer->after ','. String->symbol name.
396 */
397 if (!goof)
398 {
399 symbolP = symbol_new (string, &bfd_und_section, (valueT) 0, (struct frag *) 0);
400
401 /* enter the string in the .stab string table (section .stabstr) */
402 symbolP->sy_name_offset = elf_stab_symbol_string (string, secname);
403
404 switch (what)
405 {
406 case 'd':
407 S_SET_NAME (symbolP, NULL); /* .stabd feature. */
408 S_SET_VALUE (symbolP,
409 (valueT) ((char*) obstack_next_free (&frags) - frag_now->fr_literal));
410 S_SET_SEGMENT (symbolP, now_seg);
411 symbolP->sy_frag = frag_now;
412 break;
413
414 case 'n':
415 symbolP->sy_frag = &zero_address_frag;
416 break;
417
418 case 's':
419 symbolP->sy_frag = &zero_address_frag;
420 break;
421
422 default:
423 BAD_CASE (what);
424 break;
425 }
426
427 if (get_absolute_expression_and_terminator (&longint) == ',')
428 {
429 saved_type = longint;
430 S_SET_TYPE (symbolP, saved_type);
431 }
432 else
433 {
434 as_bad ("I want a comma after the n_type expression");
435 goof = 1;
436 input_line_pointer--; /* Backup over a non-',' char. */
437 }
438 }
439
440 if (!goof)
441 {
442 if (get_absolute_expression_and_terminator (&longint) == ',')
443 S_SET_OTHER (symbolP, longint);
444 else
445 {
446 as_bad ("I want a comma after the n_other expression");
447 goof = 1;
448 input_line_pointer--; /* Backup over a non-',' char. */
449 }
450 }
451
452 if (!goof)
453 {
454 S_SET_DESC (symbolP, get_absolute_expression ());
455 if (what == 's' || what == 'n')
456 {
457 if (*input_line_pointer != ',')
458 {
459 as_bad ("I want a comma after the n_desc expression");
460 goof = 1;
461 }
462 else
463 {
464 input_line_pointer++;
465 }
466 }
467 }
468
469 if (!goof)
470 {
471 subseg_new ((char *) seg->name, subseg);
472
473 /* Emit the stab symbol. */
474 elf_stab_symbol (symbolP, what);
475
476 if (what == 's' || what == 'n')
477 {
478 cons (4);
479 input_line_pointer--;
480 }
481 else
482 {
483 char *p = frag_more (4);
484 md_number_to_chars (p, 0, 0);
485 }
486 subseg_new ((char *) saved_seg->name, subseg);
487
488 if ((what == 's' || what == 'n')
489 && symbolP->sy_forward == NULL)
490 {
491 /* symbol is not needed in the regular symbol table */
492 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
493 }
494
495 }
496
497 #ifndef NO_LISTING
498 if (listing && !goof)
499 switch (S_GET_TYPE (symbolP))
500 {
501 case N_SLINE:
502 listing_source_line (S_GET_DESC (symbolP));
503 break;
504 case N_SO:
505 case N_SOL:
506 listing_source_file (string);
507 break;
508 }
509 #endif
510
511 if (goof)
512 ignore_rest_of_line ();
513 else
514 demand_empty_rest_of_line ();
515 }
516
517 static void
518 obj_elf_stab (what)
519 int what;
520 {
521 obj_elf_stab_generic (what, ".stab");
522 }
523
524 static void
525 obj_elf_xstab (what)
526 int what;
527 {
528 int length;
529 char *secname;
530
531 secname = demand_copy_C_string (&length);
532 SKIP_WHITESPACE ();
533 if (*input_line_pointer == ',')
534 input_line_pointer++;
535 else
536 {
537 as_bad ("comma missing in .xstabs");
538 ignore_rest_of_line ();
539 return;
540 }
541 obj_elf_stab_generic (what, secname);
542 }
543
544 void
545 obj_elf_desc ()
546 {
547 char *name;
548 char c;
549 char *p;
550 symbolS *symbolP;
551 int temp;
552
553 /* Frob invented at RMS' request. Set the n_desc of a symbol. */
554 name = input_line_pointer;
555 c = get_symbol_end ();
556 p = input_line_pointer;
557 *p = c;
558 SKIP_WHITESPACE ();
559 if (*input_line_pointer != ',')
560 {
561 *p = 0;
562 as_bad ("Expected comma after name \"%s\"", name);
563 *p = c;
564 ignore_rest_of_line ();
565 }
566 else
567 {
568 input_line_pointer++;
569 temp = get_absolute_expression ();
570 *p = 0;
571 symbolP = symbol_find_or_make (name);
572 *p = c;
573 S_SET_DESC (symbolP, temp);
574 }
575 demand_empty_rest_of_line ();
576 } /* obj_elf_desc() */
577
578 void
579 obj_read_begin_hook ()
580 {
581 }
582
583 void
584 obj_symbol_new_hook (symbolP)
585 symbolS *symbolP;
586 {
587 #if 0 /* BFD already takes care of this */
588 elf32_symbol_type *esym = (elf32_symbol_type *) symbolP;
589
590 /* There is an Elf_Internal_Sym and an Elf_External_Sym. For now,
591 just zero them out. */
592
593 bzero ((char *) &esym->internal_elf_sym, sizeof (esym->internal_elf_sym));
594 bzero ((char *) &esym->native_elf_sym, sizeof (esym->native_elf_sym));
595 bzero ((char *) &esym->tc_data, sizeof (esym->tc_data));
596 #endif
597 }
598
599 void
600 obj_elf_version ()
601 {
602 char *name;
603 unsigned int c;
604 char ch;
605 char *p;
606 asection *seg = now_seg;
607 subsegT subseg = now_subseg;
608 Elf_Internal_Note i_note;
609 Elf_External_Note e_note;
610 asection *note_secp = (asection *) NULL;
611 int i, len;
612
613 SKIP_WHITESPACE ();
614 if (*input_line_pointer == '\"')
615 {
616 ++input_line_pointer; /* -> 1st char of string. */
617 name = input_line_pointer;
618
619 while (is_a_char (c = next_char_of_string ()))
620 ;
621 c = *input_line_pointer;
622 *input_line_pointer = '\0';
623 *(input_line_pointer - 1) = '\0';
624 *input_line_pointer = c;
625
626 /* create the .note section if this is the first version string */
627
628 note_secp = bfd_get_section_by_name (stdoutput, ".note");
629 if (note_secp == (asection *) NULL)
630 {
631 note_secp = bfd_make_section_old_way (stdoutput, ".note");
632 bfd_set_section_flags (stdoutput,
633 note_secp,
634 SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS);
635 }
636
637 /* process the version string */
638
639 subseg_new ((char *) note_secp->name, 0);
640 len = strlen (name);
641
642 i_note.namesz = ((len + 1) + 3) & ~3; /* round this to word boundary */
643 i_note.descsz = 0; /* no description */
644 i_note.type = NT_VERSION;
645 p = frag_more (sizeof (e_note.namesz));
646 md_number_to_chars (p, (valueT) i_note.namesz, 4);
647 p = frag_more (sizeof (e_note.descsz));
648 md_number_to_chars (p, (valueT) i_note.descsz, 4);
649 p = frag_more (sizeof (e_note.type));
650 md_number_to_chars (p, (valueT) i_note.type, 4);
651
652 for (i = 0; i < len; i++)
653 {
654 ch = *(name + i);
655 {
656 FRAG_APPEND_1_CHAR (ch);
657 }
658 }
659 frag_align (2, 0);
660
661 subseg_new ((char *) seg->name, subseg);
662 }
663 else
664 {
665 as_bad ("Expected \"-ed string");
666 }
667 demand_empty_rest_of_line ();
668 }
669
670 static void
671 obj_elf_size ()
672 {
673 char *name = input_line_pointer;
674 char c = get_symbol_end ();
675 char *p;
676 expressionS exp;
677 segT sec;
678 symbolS *sym;
679
680 p = input_line_pointer;
681 *p = c;
682 SKIP_WHITESPACE ();
683 if (*input_line_pointer != ',')
684 {
685 *p = 0;
686 as_bad ("expected comma after name `%s' in .size directive", name);
687 *p = c;
688 ignore_rest_of_line ();
689 return;
690 }
691 input_line_pointer++;
692 sec = expression (&exp);
693 if (sec == absent_section)
694 {
695 as_bad ("missing expression in .size directive");
696 exp.X_seg = absolute_section;
697 exp.X_add_number = 0;
698 }
699 *p = 0;
700 sym = symbol_find_or_make (name);
701 *p = c;
702 if (sec == absolute_section)
703 S_SET_SIZE (sym, exp.X_add_number);
704 else
705 {
706 #if 0
707 static int warned;
708 if (!warned)
709 {
710 as_tsktsk (".size expressions not yet supported, ignored");
711 warned++;
712 }
713 #endif
714 }
715 demand_empty_rest_of_line ();
716 }
717
718 static void
719 obj_elf_type ()
720 {
721 char *name = input_line_pointer;
722 char c = get_symbol_end ();
723 char *p;
724 int type = 0;
725 symbolS *sym;
726
727 p = input_line_pointer;
728 *p = c;
729 SKIP_WHITESPACE ();
730 if (*input_line_pointer != ',')
731 {
732 as_bad ("expected comma after name in .type directive");
733 egress:
734 ignore_rest_of_line ();
735 return;
736 }
737 input_line_pointer++;
738 SKIP_WHITESPACE ();
739 if (*input_line_pointer != '#')
740 {
741 as_bad ("expected `#' after comma in .type directive");
742 goto egress;
743 }
744 input_line_pointer++;
745 if (!strncmp ("function", input_line_pointer, sizeof ("function") - 1))
746 {
747 type = BSF_FUNCTION;
748 input_line_pointer += sizeof ("function") - 1;
749 }
750 else if (!strncmp ("object", input_line_pointer, sizeof ("object") - 1))
751 {
752 input_line_pointer += sizeof ("object") - 1;
753 }
754 else
755 {
756 as_bad ("unrecognized symbol type, ignored");
757 goto egress;
758 }
759 demand_empty_rest_of_line ();
760 *p = 0;
761 sym = symbol_find_or_make (name);
762 sym->bsym->flags |= type;
763 }
764
765 static void
766 obj_elf_ident ()
767 {
768 static segT comment_section;
769 segT old_section = now_seg;
770 int old_subsection = now_subseg;
771
772 if (!comment_section)
773 {
774 char *p;
775 comment_section = subseg_new (".comment", 0);
776 bfd_set_section_flags (stdoutput, comment_section, SEC_HAS_CONTENTS);
777 p = frag_more (1);
778 *p = 0;
779 }
780 else
781 subseg_set (comment_section, 0);
782 stringer (1);
783 subseg_set (old_section, old_subsection);
784 }
785
786 void
787 elf_frob_file ()
788 {
789 #ifdef elf_tc_symbol
790 int i;
791
792 for (i = 0; i < stdoutput->symcount; i++)
793 elf_tc_symbol (stdoutput, (elf_symbol_type *) (stdoutput->outsymbols[i]), i + 1);
794 #endif
795 #ifdef elf_tc_final_processing
796 elf_tc_final_processing_hook ();
797 #endif
798
799 /* Finally, we must make any target-specific sections. */
800
801 #ifdef elf_tc_make_sections
802 elf_tc_make_sections (stdoutput, NULL);
803 #endif
804 }
This page took 0.046059 seconds and 4 git commands to generate.