1 /* ELF object file format
2 Copyright (C) 1992, 1993 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
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.
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.
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. */
24 static int obj_elf_write_symbol_p
PARAMS ((symbolS
*sym
));
26 static void obj_elf_line
PARAMS ((int));
27 void obj_elf_version
PARAMS ((int));
28 static void obj_elf_size
PARAMS ((int));
29 static void obj_elf_type
PARAMS ((int));
30 static void obj_elf_ident
PARAMS ((int));
31 static void obj_elf_weak
PARAMS ((int));
32 static void obj_elf_local
PARAMS ((int));
33 static void obj_elf_common
PARAMS ((int));
34 static void obj_elf_data
PARAMS ((int));
35 static void obj_elf_text
PARAMS ((int));
37 const pseudo_typeS obj_pseudo_table
[] =
39 {"comm", obj_elf_common
, 0},
40 {"ident", obj_elf_ident
, 0},
41 {"local", obj_elf_local
, 0},
42 {"previous", obj_elf_previous
, 0},
43 {"section", obj_elf_section
, 0},
44 {"size", obj_elf_size
, 0},
45 {"type", obj_elf_type
, 0},
46 {"version", obj_elf_version
, 0},
47 {"weak", obj_elf_weak
, 0},
49 /* These are used for stabs-in-elf configurations. */
50 {"line", obj_elf_line
, 0},
52 /* These are used for dwarf. */
57 /* We need to trap the section changing calls to handle .previous. */
58 {"data", obj_elf_data
, 0},
59 {"text", obj_elf_text
, 0},
61 {NULL
} /* end sentinel */
65 #include "aout/aout64.h"
73 sym
= symbol_new (s
, absolute_section
, (valueT
) 0, (struct frag
*) 0);
74 sym
->sy_frag
= &zero_address_frag
;
75 sym
->bsym
->flags
|= BSF_FILE
;
77 if (symbol_rootP
!= sym
)
79 symbol_remove (sym
, &symbol_rootP
, &symbol_lastP
);
80 symbol_insert (sym
, symbol_rootP
, &symbol_rootP
, &symbol_lastP
);
82 verify_symbol_chain (symbol_rootP
, symbol_lastP
);
88 obj_elf_common (ignore
)
97 name
= input_line_pointer
;
98 c
= get_symbol_end ();
99 /* just after name is now '\0' */
100 p
= input_line_pointer
;
103 if (*input_line_pointer
!= ',')
105 as_bad ("Expected comma after symbol-name");
106 ignore_rest_of_line ();
109 input_line_pointer
++; /* skip ',' */
110 if ((temp
= get_absolute_expression ()) < 0)
112 as_bad (".COMMon length (%d.) <0! Ignored.", temp
);
113 ignore_rest_of_line ();
118 symbolP
= symbol_find_or_make (name
);
120 if (S_IS_DEFINED (symbolP
))
122 as_bad ("Ignoring attempt to re-define symbol");
123 ignore_rest_of_line ();
126 if (S_GET_VALUE (symbolP
) != 0)
128 if (S_GET_VALUE (symbolP
) != size
)
130 as_warn ("Length of .comm \"%s\" is already %ld. Not changed to %d.",
131 S_GET_NAME (symbolP
), (long) S_GET_VALUE (symbolP
), size
);
134 know (symbolP
->sy_frag
== &zero_address_frag
);
135 if (*input_line_pointer
!= ',')
137 as_bad ("Expected comma after common length");
138 ignore_rest_of_line ();
141 input_line_pointer
++;
143 if (*input_line_pointer
!= '"')
145 temp
= get_absolute_expression ();
149 as_warn ("Common alignment negative; 0 assumed");
160 old_subsec
= now_subseg
;
162 record_alignment (bss_section
, align
);
163 subseg_set (bss_section
, 0);
165 frag_align (align
, 0);
166 if (S_GET_SEGMENT (symbolP
) == bss_section
)
167 symbolP
->sy_frag
->fr_symbol
= 0;
168 symbolP
->sy_frag
= frag_now
;
169 pfrag
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
, size
,
172 S_SET_SEGMENT (symbolP
, bss_section
);
173 S_CLEAR_EXTERNAL (symbolP
);
174 subseg_set (old_sec
, old_subsec
);
179 S_SET_VALUE (symbolP
, (valueT
) size
);
180 S_SET_EXTERNAL (symbolP
);
181 /* should be common, but this is how gas does it for now */
182 S_SET_SEGMENT (symbolP
, &bfd_und_section
);
187 input_line_pointer
++;
188 /* @@ Some use the dot, some don't. Can we get some consistency?? */
189 if (*input_line_pointer
== '.')
190 input_line_pointer
++;
191 /* @@ Some say data, some say bss. */
192 if (strncmp (input_line_pointer
, "bss\"", 4)
193 && strncmp (input_line_pointer
, "data\"", 5))
195 while (*--input_line_pointer
!= '"')
197 input_line_pointer
--;
198 goto bad_common_segment
;
200 while (*input_line_pointer
++ != '"')
202 goto allocate_common
;
204 demand_empty_rest_of_line ();
209 p
= input_line_pointer
;
210 while (*p
&& *p
!= '\n')
214 as_bad ("bad .common segment %s", input_line_pointer
+ 1);
216 input_line_pointer
= p
;
217 ignore_rest_of_line ();
223 obj_elf_local (ignore
)
232 name
= input_line_pointer
;
233 c
= get_symbol_end ();
234 symbolP
= symbol_find_or_make (name
);
235 *input_line_pointer
= c
;
237 S_CLEAR_EXTERNAL (symbolP
);
241 input_line_pointer
++;
243 if (*input_line_pointer
== '\n')
248 demand_empty_rest_of_line ();
252 obj_elf_weak (ignore
)
261 name
= input_line_pointer
;
262 c
= get_symbol_end ();
263 symbolP
= symbol_find_or_make (name
);
264 *input_line_pointer
= c
;
266 S_SET_WEAK (symbolP
);
270 input_line_pointer
++;
272 if (*input_line_pointer
== '\n')
277 demand_empty_rest_of_line ();
280 static segT previous_section
;
281 static int previous_subsection
;
284 obj_elf_section (xxx
)
291 /* Initialize this with inclusive-or of all flags that can be cleared
292 by attributes, but not set by them. Also include flags that won't
293 get set properly in the assembler, but which the user/compiler
294 shouldn't be expected to set. */
295 flagword flags
= SEC_READONLY
| SEC_ALLOC
| SEC_RELOC
| SEC_LOAD
;
296 /* Initialize this with the default flags to be used if none are
298 flagword default_flags
= 0;
301 /* Get name of section. */
302 if (*input_line_pointer
== '"')
303 string
= demand_copy_C_string (&xxx
);
306 char *p
= input_line_pointer
;
308 while (0 == strchr ("\n\t,; ", *p
))
312 string
= xmalloc ((unsigned long) (p
- input_line_pointer
+ 1));
313 strcpy (string
, input_line_pointer
);
315 input_line_pointer
= p
;
317 if (!strcmp (string
, ".rodata")
318 || !strcmp (string
, ".rodata1"))
319 default_flags
= SEC_ALLOC
| SEC_READONLY
| SEC_RELOC
| SEC_LOAD
;
320 else if (!strcmp (string
, ".init")
321 || !strcmp (string
, ".fini"))
322 default_flags
= SEC_ALLOC
| SEC_READONLY
| SEC_RELOC
| SEC_CODE
| SEC_LOAD
;
325 if (*input_line_pointer
!= ',')
326 flags
= default_flags
;
327 while (*input_line_pointer
== ',')
334 input_line_pointer
++;
336 /* Under i386-svr4, gcc emits a string here. I don't know what this
337 string is supposed to signify or how to handle it. Ignore it for
338 now, unless it becomes a problem. */
339 if (*input_line_pointer
== '"')
341 demand_copy_C_string (&xxx
);
346 if (*input_line_pointer
!= '#' && *input_line_pointer
!= '@')
348 as_bad ("unrecognized syntax in .section command");
349 ignore_rest_of_line ();
352 input_line_pointer
++;
354 #define CHECK(X,BIT,NEG) \
355 if (!strncmp(X,input_line_pointer,len = sizeof(X) - 1)) { \
356 bit = BIT; inv = NEG; goto match; }
358 CHECK ("write", SEC_READONLY
, 1);
359 CHECK ("alloc", SEC_ALLOC
| SEC_LOAD
, 0);
360 CHECK ("execinstr", SEC_CODE
, 1);
361 CHECK ("progbits", SEC_LOAD
, 1);
364 p
= input_line_pointer
;
365 while (!is_end_of_line
[(unsigned char) *p
] && *p
!= 0 && *p
!= ',')
369 as_bad ("unrecognized section attribute `%s' ignored",
379 input_line_pointer
+= len
;
381 demand_empty_rest_of_line ();
383 /* If the C string wasn't valid, `string' could be null. */
387 previous_section
= now_seg
;
388 previous_subsection
= now_subseg
;
390 new_sec
= bfd_get_section_by_name (stdoutput
, string
) == NULL
;
391 sec
= subseg_new (string
, 0);
393 bfd_set_section_flags (stdoutput
, sec
, flags
);
396 /* Change to the .data section. */
402 previous_section
= now_seg
;
403 previous_subsection
= now_subseg
;
407 /* Change to the .text section. */
413 previous_section
= now_seg
;
414 previous_subsection
= now_subseg
;
419 obj_elf_previous (ignore
)
422 if (previous_section
== 0)
424 as_bad (".previous without corresponding .section; ignored");
427 subseg_set (previous_section
, previous_subsection
);
428 previous_section
= 0;
432 obj_elf_write_symbol_p (sym
)
435 /* If this is a local symbol, are there any relocations for which
438 /* To find this out, we examine all relocations in all bfd sections
439 that have relocations. If there is one that references this
440 symbol, we need to keep this symbol. In this case, we return a
441 true status. In all other cases, we return a false status. */
443 if (S_IS_LOCAL (sym
))
445 asymbol
*bsym
= sym
->bsym
;
446 bfd
*abfd
= bsym
->the_bfd
;
449 for (bsec
= abfd
->sections
; bsec
; bsec
= bsec
->next
)
451 struct reloc_cache_entry
**rlocs
= bsec
->orelocation
;
452 int rcnt
= bsec
->reloc_count
;
458 for (i
= 0; i
< rcnt
; i
++)
459 if (rlocs
[i
]->sym_ptr_ptr
460 && rlocs
[i
]->sym_ptr_ptr
[0] == bsym
)
465 /* No relocations for this section. Check the seg_info
466 structure to see if there are any fixups for this
468 segment_info_type
*seginfo
= seg_info (bsec
);
471 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= fixp
->fx_next
)
472 if ((fixp
->fx_addsy
&& fixp
->fx_addsy
->bsym
== bsym
)
473 || (fixp
->fx_subsy
&& fixp
->fx_subsy
->bsym
== bsym
))
482 obj_elf_write_symbol (sym
)
485 return /* obj_elf_write_symbol_p (sym) || */ !S_IS_LOCAL (sym
);
489 obj_elf_frob_symbol (sym
, punt
)
493 #if 0 /* ?? The return value is ignored. Only the value of *punt is
495 return obj_elf_write_symbol_p (sym
);
497 /* FIXME: Just return 0 until is fixed. */
502 obj_elf_line (ignore
)
505 /* Assume delimiter is part of expression. BSD4.2 as fails with
506 delightful bug, so we are not being incompatible here. */
507 new_logical_line ((char *) NULL
, (int) (get_absolute_expression ()));
508 demand_empty_rest_of_line ();
512 obj_read_begin_hook ()
517 obj_symbol_new_hook (symbolP
)
520 #if 0 /* BFD already takes care of this */
521 elf32_symbol_type
*esym
= (elf32_symbol_type
*) symbolP
;
523 /* There is an Elf_Internal_Sym and an Elf_External_Sym. For now,
524 just zero them out. */
526 bzero ((char *) &esym
->internal_elf_sym
, sizeof (esym
->internal_elf_sym
));
527 bzero ((char *) &esym
->native_elf_sym
, sizeof (esym
->native_elf_sym
));
528 bzero ((char *) &esym
->tc_data
, sizeof (esym
->tc_data
));
533 obj_elf_version (ignore
)
540 asection
*seg
= now_seg
;
541 subsegT subseg
= now_subseg
;
542 Elf_Internal_Note i_note
;
543 Elf_External_Note e_note
;
544 asection
*note_secp
= (asection
*) NULL
;
548 if (*input_line_pointer
== '\"')
550 ++input_line_pointer
; /* -> 1st char of string. */
551 name
= input_line_pointer
;
553 while (is_a_char (c
= next_char_of_string ()))
555 c
= *input_line_pointer
;
556 *input_line_pointer
= '\0';
557 *(input_line_pointer
- 1) = '\0';
558 *input_line_pointer
= c
;
560 /* create the .note section */
562 note_secp
= subseg_new (".note", 0);
563 bfd_set_section_flags (stdoutput
,
565 SEC_HAS_CONTENTS
| SEC_READONLY
);
567 /* process the version string */
571 i_note
.namesz
= ((len
+ 1) + 3) & ~3; /* round this to word boundary */
572 i_note
.descsz
= 0; /* no description */
573 i_note
.type
= NT_VERSION
;
574 p
= frag_more (sizeof (e_note
.namesz
));
575 md_number_to_chars (p
, (valueT
) i_note
.namesz
, 4);
576 p
= frag_more (sizeof (e_note
.descsz
));
577 md_number_to_chars (p
, (valueT
) i_note
.descsz
, 4);
578 p
= frag_more (sizeof (e_note
.type
));
579 md_number_to_chars (p
, (valueT
) i_note
.type
, 4);
581 for (i
= 0; i
< len
; i
++)
585 FRAG_APPEND_1_CHAR (ch
);
590 subseg_set (seg
, subseg
);
594 as_bad ("Expected quoted string");
596 demand_empty_rest_of_line ();
600 obj_elf_size (ignore
)
603 char *name
= input_line_pointer
;
604 char c
= get_symbol_end ();
609 p
= input_line_pointer
;
612 if (*input_line_pointer
!= ',')
615 as_bad ("expected comma after name `%s' in .size directive", name
);
617 ignore_rest_of_line ();
620 input_line_pointer
++;
622 if (exp
.X_op
== O_absent
)
624 as_bad ("missing expression in .size directive");
625 exp
.X_op
= O_constant
;
626 exp
.X_add_number
= 0;
629 sym
= symbol_find_or_make (name
);
631 if (exp
.X_op
== O_constant
)
632 S_SET_SIZE (sym
, exp
.X_add_number
);
639 as_tsktsk (".size expressions not yet supported, ignored");
644 demand_empty_rest_of_line ();
648 obj_elf_type (ignore
)
651 char *name
= input_line_pointer
;
652 char c
= get_symbol_end ();
657 p
= input_line_pointer
;
660 if (*input_line_pointer
!= ',')
662 as_bad ("expected comma after name in .type directive");
664 ignore_rest_of_line ();
667 input_line_pointer
++;
669 if (*input_line_pointer
!= '#' && *input_line_pointer
!= '@')
671 as_bad ("expected `#' or `@' after comma in .type directive");
674 input_line_pointer
++;
675 if (!strncmp ("function", input_line_pointer
, sizeof ("function") - 1))
678 input_line_pointer
+= sizeof ("function") - 1;
680 else if (!strncmp ("object", input_line_pointer
, sizeof ("object") - 1))
682 input_line_pointer
+= sizeof ("object") - 1;
686 as_bad ("unrecognized symbol type, ignored");
689 demand_empty_rest_of_line ();
691 sym
= symbol_find_or_make (name
);
692 sym
->bsym
->flags
|= type
;
696 obj_elf_ident (ignore
)
699 static segT comment_section
;
700 segT old_section
= now_seg
;
701 int old_subsection
= now_subseg
;
703 if (!comment_section
)
706 comment_section
= subseg_new (".comment", 0);
707 bfd_set_section_flags (stdoutput
, comment_section
, SEC_HAS_CONTENTS
);
712 subseg_set (comment_section
, 0);
714 subseg_set (old_section
, old_subsection
);
718 adjust_stab_sections (abfd
, sec
, xxx
)
728 if (strncmp (".stab", sec
->name
, 5))
730 if (!strcmp ("str", sec
->name
+ strlen (sec
->name
) - 3))
733 name
= (char *) alloca (strlen (sec
->name
) + 4);
734 strcpy (name
, sec
->name
);
735 strcat (name
, "str");
736 strsec
= bfd_get_section_by_name (abfd
, name
);
738 strsz
= bfd_section_size (abfd
, strsec
);
741 nsyms
= bfd_section_size (abfd
, sec
) / 12 - 1;
743 p
= seg_info (sec
)->stabu
.p
;
746 bfd_h_put_16 (abfd
, (bfd_vma
) nsyms
, p
+ 6);
747 bfd_h_put_32 (abfd
, (bfd_vma
) strsz
, p
+ 8);
753 bfd_map_over_sections (stdoutput
, adjust_stab_sections
, (PTR
) 0);
759 for (i
= 0; i
< stdoutput
->symcount
; i
++)
760 elf_tc_symbol (stdoutput
, (PTR
) (stdoutput
->outsymbols
[i
]),
765 #ifdef elf_tc_final_processing
766 elf_tc_final_processing ();
769 /* Finally, we must make any target-specific sections. */
771 #ifdef elf_tc_make_sections
772 elf_tc_make_sections (stdoutput
);