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));
35 const pseudo_typeS obj_pseudo_table
[] =
37 {"comm", obj_elf_common
, 0},
38 {"ident", obj_elf_ident
, 0},
39 {"local", obj_elf_local
, 0},
40 {"previous", obj_elf_previous
, 0},
41 {"section", obj_elf_section
, 0},
42 {"size", obj_elf_size
, 0},
43 {"type", obj_elf_type
, 0},
44 {"version", obj_elf_version
, 0},
45 {"weak", obj_elf_weak
, 0},
47 /* These are used for stabs-in-elf configurations. */
48 {"line", obj_elf_line
, 0},
50 /* These are used for dwarf. */
55 {NULL
} /* end sentinel */
59 #include "aout/aout64.h"
67 sym
= symbol_new (s
, absolute_section
, (valueT
) 0, (struct frag
*) 0);
68 sym
->sy_frag
= &zero_address_frag
;
69 sym
->bsym
->flags
|= BSF_FILE
;
71 if (symbol_rootP
!= sym
)
73 symbol_remove (sym
, &symbol_rootP
, &symbol_lastP
);
74 symbol_insert (sym
, symbol_rootP
, &symbol_rootP
, &symbol_lastP
);
76 verify_symbol_chain (symbol_rootP
, symbol_lastP
);
82 obj_elf_common (ignore
)
91 name
= input_line_pointer
;
92 c
= get_symbol_end ();
93 /* just after name is now '\0' */
94 p
= input_line_pointer
;
97 if (*input_line_pointer
!= ',')
99 as_bad ("Expected comma after symbol-name");
100 ignore_rest_of_line ();
103 input_line_pointer
++; /* skip ',' */
104 if ((temp
= get_absolute_expression ()) < 0)
106 as_bad (".COMMon length (%d.) <0! Ignored.", temp
);
107 ignore_rest_of_line ();
112 symbolP
= symbol_find_or_make (name
);
114 if (S_IS_DEFINED (symbolP
))
116 as_bad ("Ignoring attempt to re-define symbol");
117 ignore_rest_of_line ();
120 if (S_GET_VALUE (symbolP
) != 0)
122 if (S_GET_VALUE (symbolP
) != size
)
124 as_warn ("Length of .comm \"%s\" is already %ld. Not changed to %d.",
125 S_GET_NAME (symbolP
), (long) S_GET_VALUE (symbolP
), size
);
128 know (symbolP
->sy_frag
== &zero_address_frag
);
129 if (*input_line_pointer
!= ',')
131 as_bad ("Expected comma after common length");
132 ignore_rest_of_line ();
135 input_line_pointer
++;
137 if (*input_line_pointer
!= '"')
139 temp
= get_absolute_expression ();
143 as_warn ("Common alignment negative; 0 assumed");
154 old_subsec
= now_subseg
;
156 record_alignment (bss_section
, align
);
157 subseg_set (bss_section
, 0);
159 frag_align (align
, 0);
160 if (S_GET_SEGMENT (symbolP
) == bss_section
)
161 symbolP
->sy_frag
->fr_symbol
= 0;
162 symbolP
->sy_frag
= frag_now
;
163 pfrag
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
, size
,
166 S_SET_SEGMENT (symbolP
, bss_section
);
167 S_CLEAR_EXTERNAL (symbolP
);
168 subseg_set (old_sec
, old_subsec
);
173 S_SET_VALUE (symbolP
, (valueT
) size
);
174 S_SET_EXTERNAL (symbolP
);
175 /* should be common, but this is how gas does it for now */
176 S_SET_SEGMENT (symbolP
, &bfd_und_section
);
181 input_line_pointer
++;
182 /* @@ Some use the dot, some don't. Can we get some consistency?? */
183 if (*input_line_pointer
== '.')
184 input_line_pointer
++;
185 /* @@ Some say data, some say bss. */
186 if (strncmp (input_line_pointer
, "bss\"", 4)
187 && strncmp (input_line_pointer
, "data\"", 5))
189 while (*--input_line_pointer
!= '"')
191 input_line_pointer
--;
192 goto bad_common_segment
;
194 while (*input_line_pointer
++ != '"')
196 goto allocate_common
;
198 demand_empty_rest_of_line ();
203 p
= input_line_pointer
;
204 while (*p
&& *p
!= '\n')
208 as_bad ("bad .common segment %s", input_line_pointer
+ 1);
210 input_line_pointer
= p
;
211 ignore_rest_of_line ();
217 obj_elf_local (ignore
)
226 name
= input_line_pointer
;
227 c
= get_symbol_end ();
228 symbolP
= symbol_find_or_make (name
);
229 *input_line_pointer
= c
;
231 S_CLEAR_EXTERNAL (symbolP
);
235 input_line_pointer
++;
237 if (*input_line_pointer
== '\n')
242 demand_empty_rest_of_line ();
246 obj_elf_weak (ignore
)
255 name
= input_line_pointer
;
256 c
= get_symbol_end ();
257 symbolP
= symbol_find_or_make (name
);
258 *input_line_pointer
= c
;
260 S_SET_WEAK (symbolP
);
264 input_line_pointer
++;
266 if (*input_line_pointer
== '\n')
271 demand_empty_rest_of_line ();
274 static segT previous_section
;
275 static int previous_subsection
;
278 obj_elf_section (xxx
)
284 /* Initialize this with inclusive-or of all flags that can be cleared
285 by attributes, but not set by them. Also include flags that won't
286 get set properly in the assembler, but which the user/compiler
287 shouldn't be expected to set. */
288 flagword flags
= SEC_READONLY
| SEC_ALLOC
| SEC_RELOC
;
289 /* Initialize this with the default flags to be used if none are
291 flagword default_flags
= 0;
294 /* Get name of section. */
295 if (*input_line_pointer
== '"')
296 string
= demand_copy_C_string (&xxx
);
299 char *p
= input_line_pointer
;
301 while (0 == strchr ("\n\t,; ", *p
))
305 string
= xmalloc ((unsigned long) (p
- input_line_pointer
+ 1));
306 strcpy (string
, input_line_pointer
);
308 input_line_pointer
= p
;
310 if (!strcmp (string
, ".rodata"))
311 default_flags
= SEC_ALLOC
| SEC_READONLY
| SEC_RELOC
| SEC_LOAD
;
312 else if (!strcmp (string
, ".init")
313 || !strcmp (string
, ".fini"))
314 default_flags
= SEC_ALLOC
| SEC_READONLY
| SEC_RELOC
| SEC_CODE
| SEC_LOAD
;
317 if (*input_line_pointer
!= ',')
318 flags
= default_flags
;
319 while (*input_line_pointer
== ',')
326 input_line_pointer
++;
328 /* Under i386-svr4, gcc emits a string here. I don't know what this
329 string is supposed to signify or how to handle it. Ignore it for
330 now, unless it becomes a problem. */
331 if (*input_line_pointer
== '"')
333 demand_copy_C_string (&xxx
);
338 if (*input_line_pointer
!= '#' && *input_line_pointer
!= '@')
340 as_bad ("unrecognized syntax in .section command");
341 ignore_rest_of_line ();
344 input_line_pointer
++;
346 #define CHECK(X,BIT,NEG) \
347 if (!strncmp(X,input_line_pointer,len = sizeof(X) - 1)) { \
348 bit = BIT; inv = NEG; goto match; }
350 CHECK ("write", SEC_READONLY
, 1);
351 CHECK ("alloc", SEC_ALLOC
, 0);
352 CHECK ("execinstr", SEC_CODE
, 1);
353 CHECK ("progbits", SEC_LOAD
, 1);
356 p
= input_line_pointer
;
357 while (!is_end_of_line
[(unsigned char) *p
] && *p
!= 0 && *p
!= ',')
361 as_bad ("unrecognized section attribute `%s' ignored",
371 input_line_pointer
+= len
;
373 demand_empty_rest_of_line ();
375 /* If the C string wasn't valid, `string' could be null. */
379 sec
= bfd_get_section_by_name (stdoutput
, string
);
382 sec
= subseg_new (string
, 0);
383 bfd_set_section_flags (stdoutput
, sec
, flags
);
384 sec
->output_section
= sec
;
386 previous_section
= now_seg
;
387 previous_subsection
= now_subseg
;
392 obj_elf_previous (ignore
)
395 if (previous_section
== 0)
397 as_bad (".previous without corresponding .section; ignored");
400 subseg_set (previous_section
, previous_subsection
);
401 previous_section
= 0;
405 obj_elf_write_symbol_p (sym
)
408 /* If this is a local symbol, are there any relocations for which
411 /* To find this out, we examine all relocations in all bfd sections
412 that have relocations. If there is one that references this
413 symbol, we need to keep this symbol. In this case, we return a
414 true status. In all other cases, we return a false status. */
416 if (S_IS_LOCAL (sym
))
418 asymbol
*bsym
= sym
->bsym
;
419 bfd
*abfd
= bsym
->the_bfd
;
422 for (bsec
= abfd
->sections
; bsec
; bsec
= bsec
->next
)
424 struct reloc_cache_entry
**rlocs
= bsec
->orelocation
;
425 int rcnt
= bsec
->reloc_count
;
431 for (i
= 0; i
< rcnt
; i
++)
432 if (rlocs
[i
]->sym_ptr_ptr
433 && rlocs
[i
]->sym_ptr_ptr
[0] == bsym
)
438 /* No relocations for this section. Check the seg_info
439 structure to see if there are any fixups for this
441 segment_info_type
*seginfo
= seg_info (bsec
);
444 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= fixp
->fx_next
)
445 if ((fixp
->fx_addsy
&& fixp
->fx_addsy
->bsym
== bsym
)
446 || (fixp
->fx_subsy
&& fixp
->fx_subsy
->bsym
== bsym
))
455 obj_elf_write_symbol (sym
)
458 return /* obj_elf_write_symbol_p (sym) || */ !S_IS_LOCAL (sym
);
462 obj_elf_frob_symbol (sym
, punt
)
466 #if 0 /* ?? The return value is ignored. Only the value of *punt is
468 return obj_elf_write_symbol_p (sym
);
470 /* FIXME: Just return 0 until is fixed. */
475 obj_elf_line (ignore
)
478 /* Assume delimiter is part of expression. BSD4.2 as fails with
479 delightful bug, so we are not being incompatible here. */
480 new_logical_line ((char *) NULL
, (int) (get_absolute_expression ()));
481 demand_empty_rest_of_line ();
485 obj_read_begin_hook ()
490 obj_symbol_new_hook (symbolP
)
493 #if 0 /* BFD already takes care of this */
494 elf32_symbol_type
*esym
= (elf32_symbol_type
*) symbolP
;
496 /* There is an Elf_Internal_Sym and an Elf_External_Sym. For now,
497 just zero them out. */
499 bzero ((char *) &esym
->internal_elf_sym
, sizeof (esym
->internal_elf_sym
));
500 bzero ((char *) &esym
->native_elf_sym
, sizeof (esym
->native_elf_sym
));
501 bzero ((char *) &esym
->tc_data
, sizeof (esym
->tc_data
));
506 obj_elf_version (ignore
)
513 asection
*seg
= now_seg
;
514 subsegT subseg
= now_subseg
;
515 Elf_Internal_Note i_note
;
516 Elf_External_Note e_note
;
517 asection
*note_secp
= (asection
*) NULL
;
521 if (*input_line_pointer
== '\"')
523 ++input_line_pointer
; /* -> 1st char of string. */
524 name
= input_line_pointer
;
526 while (is_a_char (c
= next_char_of_string ()))
528 c
= *input_line_pointer
;
529 *input_line_pointer
= '\0';
530 *(input_line_pointer
- 1) = '\0';
531 *input_line_pointer
= c
;
533 /* create the .note section */
535 note_secp
= subseg_new (".note", 0);
536 bfd_set_section_flags (stdoutput
,
538 SEC_HAS_CONTENTS
| SEC_READONLY
);
540 /* process the version string */
544 i_note
.namesz
= ((len
+ 1) + 3) & ~3; /* round this to word boundary */
545 i_note
.descsz
= 0; /* no description */
546 i_note
.type
= NT_VERSION
;
547 p
= frag_more (sizeof (e_note
.namesz
));
548 md_number_to_chars (p
, (valueT
) i_note
.namesz
, 4);
549 p
= frag_more (sizeof (e_note
.descsz
));
550 md_number_to_chars (p
, (valueT
) i_note
.descsz
, 4);
551 p
= frag_more (sizeof (e_note
.type
));
552 md_number_to_chars (p
, (valueT
) i_note
.type
, 4);
554 for (i
= 0; i
< len
; i
++)
558 FRAG_APPEND_1_CHAR (ch
);
563 subseg_set (seg
, subseg
);
567 as_bad ("Expected quoted string");
569 demand_empty_rest_of_line ();
573 obj_elf_size (ignore
)
576 char *name
= input_line_pointer
;
577 char c
= get_symbol_end ();
582 p
= input_line_pointer
;
585 if (*input_line_pointer
!= ',')
588 as_bad ("expected comma after name `%s' in .size directive", name
);
590 ignore_rest_of_line ();
593 input_line_pointer
++;
595 if (exp
.X_op
== O_absent
)
597 as_bad ("missing expression in .size directive");
598 exp
.X_op
= O_constant
;
599 exp
.X_add_number
= 0;
602 sym
= symbol_find_or_make (name
);
604 if (exp
.X_op
== O_constant
)
605 S_SET_SIZE (sym
, exp
.X_add_number
);
612 as_tsktsk (".size expressions not yet supported, ignored");
617 demand_empty_rest_of_line ();
621 obj_elf_type (ignore
)
624 char *name
= input_line_pointer
;
625 char c
= get_symbol_end ();
630 p
= input_line_pointer
;
633 if (*input_line_pointer
!= ',')
635 as_bad ("expected comma after name in .type directive");
637 ignore_rest_of_line ();
640 input_line_pointer
++;
642 if (*input_line_pointer
!= '#' && *input_line_pointer
!= '@')
644 as_bad ("expected `#' or `@' after comma in .type directive");
647 input_line_pointer
++;
648 if (!strncmp ("function", input_line_pointer
, sizeof ("function") - 1))
651 input_line_pointer
+= sizeof ("function") - 1;
653 else if (!strncmp ("object", input_line_pointer
, sizeof ("object") - 1))
655 input_line_pointer
+= sizeof ("object") - 1;
659 as_bad ("unrecognized symbol type, ignored");
662 demand_empty_rest_of_line ();
664 sym
= symbol_find_or_make (name
);
665 sym
->bsym
->flags
|= type
;
669 obj_elf_ident (ignore
)
672 static segT comment_section
;
673 segT old_section
= now_seg
;
674 int old_subsection
= now_subseg
;
676 if (!comment_section
)
679 comment_section
= subseg_new (".comment", 0);
680 bfd_set_section_flags (stdoutput
, comment_section
, SEC_HAS_CONTENTS
);
685 subseg_set (comment_section
, 0);
687 subseg_set (old_section
, old_subsection
);
691 adjust_stab_sections (abfd
, sec
, xxx
)
701 if (strncmp (".stab", sec
->name
, 5))
703 if (!strcmp ("str", sec
->name
+ strlen (sec
->name
) - 3))
706 name
= (char *) alloca (strlen (sec
->name
) + 4);
707 strcpy (name
, sec
->name
);
708 strcat (name
, "str");
709 strsec
= bfd_get_section_by_name (abfd
, name
);
711 strsz
= bfd_section_size (abfd
, strsec
);
714 nsyms
= bfd_section_size (abfd
, sec
) / 12 - 1;
716 p
= seg_info (sec
)->stabu
.p
;
719 bfd_h_put_16 (abfd
, (bfd_vma
) nsyms
, p
+ 6);
720 bfd_h_put_32 (abfd
, (bfd_vma
) strsz
, p
+ 8);
726 bfd_map_over_sections (stdoutput
, adjust_stab_sections
, (PTR
) 0);
732 for (i
= 0; i
< stdoutput
->symcount
; i
++)
733 elf_tc_symbol (stdoutput
, (PTR
) (stdoutput
->outsymbols
[i
]),
738 #ifdef elf_tc_final_processing
739 elf_tc_final_processing ();
742 /* Finally, we must make any target-specific sections. */
744 #ifdef elf_tc_make_sections
745 elf_tc_make_sections (stdoutput
);