1 /* a.out object file format
2 Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2000,
3 2001, 2002 Free Software Foundation, Inc.
5 This file is part of GAS, the GNU Assembler.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2,
10 or (at your option) any later version.
12 GAS is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15 the GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 #define OBJ_HEADER "obj-aout.h"
27 #include "aout/aout64.h"
32 /* in: segT out: N_TYPE bits */
33 const short seg_N_TYPE
[] =
41 N_UNDF
, /* expression */
45 N_REGISTER
, /* register */
48 const segT N_TYPE_seg
[N_TYPE
+ 2] =
49 { /* N_TYPE == 0x1E = 32-2 */
50 SEG_UNKNOWN
, /* N_UNDF == 0 */
52 SEG_ABSOLUTE
, /* N_ABS == 2 */
54 SEG_TEXT
, /* N_TEXT == 4 */
56 SEG_DATA
, /* N_DATA == 6 */
58 SEG_BSS
, /* N_BSS == 8 */
60 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
61 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
62 SEG_GOOF
, SEG_GOOF
, SEG_GOOF
, SEG_GOOF
,
63 SEG_REGISTER
, /* dummy N_REGISTER for regs = 30 */
68 static void obj_aout_line
PARAMS ((int));
69 static void obj_aout_weak
PARAMS ((int));
70 static void obj_aout_type
PARAMS ((int));
72 const pseudo_typeS aout_pseudo_table
[] =
74 {"line", obj_aout_line
, 0}, /* source code line number */
75 {"ln", obj_aout_line
, 0}, /* coff line number that we use anyway */
77 {"weak", obj_aout_weak
, 0}, /* mark symbol as weak. */
79 {"type", obj_aout_type
, 0},
81 /* coff debug pseudos (ignored) */
84 {"endef", s_ignore
, 0},
85 {"ident", s_ignore
, 0},
86 {"line", s_ignore
, 0},
89 {"size", s_ignore
, 0},
92 {"version", s_ignore
, 0},
94 {"optim", s_ignore
, 0}, /* For sun386i cc (?) */
97 {"ABORT", s_abort
, 0},
99 {NULL
, NULL
, 0} /* end sentinel */
100 }; /* aout_pseudo_table */
105 obj_aout_frob_symbol (sym
, punt
)
107 int *punt ATTRIBUTE_UNUSED
;
111 int desc
, type
, other
;
113 flags
= symbol_get_bfdsym (sym
)->flags
;
114 desc
= aout_symbol (symbol_get_bfdsym (sym
))->desc
;
115 type
= aout_symbol (symbol_get_bfdsym (sym
))->type
;
116 other
= aout_symbol (symbol_get_bfdsym (sym
))->other
;
117 sec
= S_GET_SEGMENT (sym
);
119 /* Only frob simple symbols this way right now. */
120 if (! (type
& ~ (N_TYPE
| N_EXT
)))
122 if (type
== (N_UNDF
| N_EXT
)
123 && sec
== &bfd_abs_section
)
125 sec
= bfd_und_section_ptr
;
126 S_SET_SEGMENT (sym
, sec
);
129 if ((type
& N_TYPE
) != N_INDR
130 && (type
& N_TYPE
) != N_SETA
131 && (type
& N_TYPE
) != N_SETT
132 && (type
& N_TYPE
) != N_SETD
133 && (type
& N_TYPE
) != N_SETB
135 && (sec
== &bfd_abs_section
136 || sec
== &bfd_und_section
))
138 if (flags
& BSF_EXPORT
)
141 switch (type
& N_TYPE
)
147 /* Set the debugging flag for constructor symbols so that
148 BFD leaves them alone. */
149 symbol_get_bfdsym (sym
)->flags
|= BSF_DEBUGGING
;
151 /* You can't put a common symbol in a set. The way a set
152 element works is that the symbol has a definition and a
153 name, and the linker adds the definition to the set of
154 that name. That does not work for a common symbol,
155 because the linker can't tell which common symbol the
156 user means. FIXME: Using as_bad here may be
157 inappropriate, since the user may want to force a
158 particular type without regard to the semantics of sets;
159 on the other hand, we certainly don't want anybody to be
160 mislead into thinking that their code will work. */
161 if (S_IS_COMMON (sym
))
162 as_bad (_("Attempt to put a common symbol into set %s"),
164 /* Similarly, you can't put an undefined symbol in a set. */
165 else if (! S_IS_DEFINED (sym
))
166 as_bad (_("Attempt to put an undefined symbol into set %s"),
171 /* Put indirect symbols in the indirect section. */
172 S_SET_SEGMENT (sym
, bfd_ind_section_ptr
);
173 symbol_get_bfdsym (sym
)->flags
|= BSF_INDIRECT
;
176 symbol_get_bfdsym (sym
)->flags
|= BSF_EXPORT
;
177 symbol_get_bfdsym (sym
)->flags
&=~ BSF_LOCAL
;
181 /* Mark warning symbols. */
182 symbol_get_bfdsym (sym
)->flags
|= BSF_WARNING
;
188 symbol_get_bfdsym (sym
)->flags
|= BSF_DEBUGGING
;
191 aout_symbol (symbol_get_bfdsym (sym
))->type
= type
;
193 /* Double check weak symbols. */
196 if (S_IS_COMMON (sym
))
197 as_bad (_("Symbol `%s' can not be both weak and common"),
203 obj_aout_frob_file_before_fix ()
205 /* Relocation processing may require knowing the VMAs of the sections.
206 Since writing to a section will cause the BFD back end to compute the
207 VMAs, fake it out here.... */
209 bfd_boolean x
= TRUE
;
210 if (bfd_section_size (stdoutput
, text_section
) != 0)
212 x
= bfd_set_section_contents (stdoutput
, text_section
, &b
, (file_ptr
) 0,
215 else if (bfd_section_size (stdoutput
, data_section
) != 0)
217 x
= bfd_set_section_contents (stdoutput
, data_section
, &b
, (file_ptr
) 0,
223 #else /* ! BFD_ASSEMBLER */
230 * Crawl along a fixS chain. Emit the segment's relocations.
233 obj_emit_relocations (where
, fixP
, segment_address_in_file
)
235 fixS
*fixP
; /* Fixup chain for this segment. */
236 relax_addressT segment_address_in_file
;
238 for (; fixP
; fixP
= fixP
->fx_next
)
239 if (fixP
->fx_done
== 0)
243 sym
= fixP
->fx_addsy
;
244 while (sym
->sy_value
.X_op
== O_symbol
245 && (! S_IS_DEFINED (sym
) || S_IS_COMMON (sym
)))
246 sym
= sym
->sy_value
.X_add_symbol
;
247 fixP
->fx_addsy
= sym
;
249 if (! sym
->sy_resolved
&& ! S_IS_DEFINED (sym
))
254 if (expr_symbol_where (sym
, &file
, &line
))
255 as_bad_where (file
, line
, _("unresolved relocation"));
257 as_bad (_("bad relocation: symbol `%s' not in symbol table"),
261 tc_aout_fix_to_chars (*where
, fixP
, segment_address_in_file
);
262 *where
+= md_reloc_size
;
266 #ifndef obj_header_append
267 /* Aout file generation & utilities */
269 obj_header_append (where
, headers
)
271 object_headers
*headers
;
273 tc_headers_hook (headers
);
276 md_number_to_chars (*where
, headers
->header
.a_info
, sizeof (headers
->header
.a_info
));
277 *where
+= sizeof (headers
->header
.a_info
);
278 md_number_to_chars (*where
, headers
->header
.a_text
, sizeof (headers
->header
.a_text
));
279 *where
+= sizeof (headers
->header
.a_text
);
280 md_number_to_chars (*where
, headers
->header
.a_data
, sizeof (headers
->header
.a_data
));
281 *where
+= sizeof (headers
->header
.a_data
);
282 md_number_to_chars (*where
, headers
->header
.a_bss
, sizeof (headers
->header
.a_bss
));
283 *where
+= sizeof (headers
->header
.a_bss
);
284 md_number_to_chars (*where
, headers
->header
.a_syms
, sizeof (headers
->header
.a_syms
));
285 *where
+= sizeof (headers
->header
.a_syms
);
286 md_number_to_chars (*where
, headers
->header
.a_entry
, sizeof (headers
->header
.a_entry
));
287 *where
+= sizeof (headers
->header
.a_entry
);
288 md_number_to_chars (*where
, headers
->header
.a_trsize
, sizeof (headers
->header
.a_trsize
));
289 *where
+= sizeof (headers
->header
.a_trsize
);
290 md_number_to_chars (*where
, headers
->header
.a_drsize
, sizeof (headers
->header
.a_drsize
));
291 *where
+= sizeof (headers
->header
.a_drsize
);
293 #else /* CROSS_COMPILE */
295 append (where
, (char *) &headers
->header
, sizeof (headers
->header
));
296 #endif /* CROSS_COMPILE */
299 #endif /* ! defined (obj_header_append) */
302 obj_symbol_to_chars (where
, symbolP
)
306 md_number_to_chars ((char *) &(S_GET_OFFSET (symbolP
)), S_GET_OFFSET (symbolP
), sizeof (S_GET_OFFSET (symbolP
)));
307 md_number_to_chars ((char *) &(S_GET_DESC (symbolP
)), S_GET_DESC (symbolP
), sizeof (S_GET_DESC (symbolP
)));
308 md_number_to_chars ((char *) &(symbolP
->sy_symbol
.n_value
), S_GET_VALUE (symbolP
), sizeof (symbolP
->sy_symbol
.n_value
));
310 append (where
, (char *) &symbolP
->sy_symbol
, sizeof (obj_symbol_type
));
314 obj_emit_symbols (where
, symbol_rootP
)
316 symbolS
*symbol_rootP
;
320 /* Emit all symbols left in the symbol chain. */
321 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
323 /* Used to save the offset of the name. It is used to point
324 to the string in memory but must be a file offset. */
327 temp
= S_GET_NAME (symbolP
);
328 S_SET_OFFSET (symbolP
, symbolP
->sy_name_offset
);
330 /* Any symbol still undefined and is not a dbg symbol is made N_EXT. */
331 if (!S_IS_DEBUG (symbolP
) && !S_IS_DEFINED (symbolP
))
332 S_SET_EXTERNAL (symbolP
);
334 /* Adjust the type of a weak symbol. */
335 if (S_GET_WEAK (symbolP
))
337 switch (S_GET_TYPE (symbolP
))
339 case N_UNDF
: S_SET_TYPE (symbolP
, N_WEAKU
); break;
340 case N_ABS
: S_SET_TYPE (symbolP
, N_WEAKA
); break;
341 case N_TEXT
: S_SET_TYPE (symbolP
, N_WEAKT
); break;
342 case N_DATA
: S_SET_TYPE (symbolP
, N_WEAKD
); break;
343 case N_BSS
: S_SET_TYPE (symbolP
, N_WEAKB
); break;
344 default: as_bad (_("%s: bad type for weak symbol"), temp
); break;
348 obj_symbol_to_chars (where
, symbolP
);
349 S_SET_NAME (symbolP
, temp
);
353 #endif /* ! BFD_ASSEMBLER */
356 obj_aout_line (ignore
)
357 int ignore ATTRIBUTE_UNUSED
;
359 /* Assume delimiter is part of expression.
360 BSD4.2 as fails with delightful bug, so we
361 are not being incompatible here. */
362 new_logical_line ((char *) NULL
, (int) (get_absolute_expression ()));
363 demand_empty_rest_of_line ();
364 } /* obj_aout_line() */
366 /* Handle .weak. This is a GNU extension. */
369 obj_aout_weak (ignore
)
370 int ignore ATTRIBUTE_UNUSED
;
378 name
= input_line_pointer
;
379 c
= get_symbol_end ();
380 symbolP
= symbol_find_or_make (name
);
381 *input_line_pointer
= c
;
383 S_SET_WEAK (symbolP
);
386 input_line_pointer
++;
388 if (*input_line_pointer
== '\n')
393 demand_empty_rest_of_line ();
396 /* Handle .type. On {Net,Open}BSD, this is used to set the n_other field,
397 which is then apparently used when doing dynamic linking. Older
398 versions of gas ignored the .type pseudo-op, so we also ignore it if
399 we can't parse it. */
402 obj_aout_type (ignore
)
403 int ignore ATTRIBUTE_UNUSED
;
409 name
= input_line_pointer
;
410 c
= get_symbol_end ();
411 sym
= symbol_find_or_make (name
);
412 *input_line_pointer
= c
;
414 if (*input_line_pointer
== ',')
416 ++input_line_pointer
;
418 if (*input_line_pointer
== '@')
420 ++input_line_pointer
;
421 if (strncmp (input_line_pointer
, "object", 6) == 0)
423 aout_symbol (symbol_get_bfdsym (sym
))->other
= 1;
425 S_SET_OTHER (sym
, 1);
427 else if (strncmp (input_line_pointer
, "function", 8) == 0)
429 aout_symbol (symbol_get_bfdsym (sym
))->other
= 2;
431 S_SET_OTHER (sym
, 2);
436 /* Ignore everything else on the line. */
440 #ifndef BFD_ASSEMBLER
443 obj_crawl_symbol_chain (headers
)
444 object_headers
*headers
;
448 int symbol_number
= 0;
450 tc_crawl_symbol_chain (headers
);
452 symbolPP
= &symbol_rootP
; /*->last symbol chain link. */
453 while ((symbolP
= *symbolPP
) != NULL
)
455 if (symbolP
->sy_mri_common
)
457 if (S_IS_EXTERNAL (symbolP
))
458 as_bad (_("%s: global symbols not supported in common sections"),
459 S_GET_NAME (symbolP
));
460 *symbolPP
= symbol_next (symbolP
);
464 if (flag_readonly_data_in_text
&& (S_GET_SEGMENT (symbolP
) == SEG_DATA
))
466 S_SET_SEGMENT (symbolP
, SEG_TEXT
);
467 } /* if pushing data into text */
469 resolve_symbol_value (symbolP
);
471 /* Skip symbols which were equated to undefined or common
472 symbols. Also skip defined uncommon symbols which can
473 be resolved since in this case they should have been
474 resolved to a non-symbolic constant. */
475 if (symbolP
->sy_value
.X_op
== O_symbol
476 && (! S_IS_DEFINED (symbolP
)
477 || S_IS_COMMON (symbolP
)
478 || symbol_resolved_p (symbolP
)))
480 *symbolPP
= symbol_next (symbolP
);
484 /* OK, here is how we decide which symbols go out into the brave
485 new symtab. Symbols that do are:
487 * symbols with no name (stabd's?)
488 * symbols with debug info in their N_TYPE
490 Symbols that don't are:
491 * symbols that are registers
492 * symbols with \1 as their 3rd character (numeric labels)
493 * "local labels" as defined by S_LOCAL_NAME(name) if the -L
494 switch was passed to gas.
496 All other symbols are output. We complain if a deleted
497 symbol was marked external. */
499 if (!S_IS_REGISTER (symbolP
)
500 && (!S_GET_NAME (symbolP
)
501 || S_IS_DEBUG (symbolP
)
502 || !S_IS_DEFINED (symbolP
)
503 || S_IS_EXTERNAL (symbolP
)
504 || (S_GET_NAME (symbolP
)[0] != '\001'
505 && (flag_keep_locals
|| !S_LOCAL_NAME (symbolP
)))))
507 symbolP
->sy_number
= symbol_number
++;
509 /* The + 1 after strlen account for the \0 at the
510 end of each string */
511 if (!S_IS_STABD (symbolP
))
514 symbolP
->sy_name_offset
= string_byte_count
;
515 string_byte_count
+= strlen (S_GET_NAME (symbolP
)) + 1;
517 else /* .Stabd case. */
518 symbolP
->sy_name_offset
= 0;
519 symbolPP
= &symbolP
->sy_next
;
523 if (S_IS_EXTERNAL (symbolP
) || !S_IS_DEFINED (symbolP
))
524 /* This warning should never get triggered any more.
525 Well, maybe if you're doing twisted things with
528 as_bad (_("Local symbol %s never defined."), decode_local_label_name (S_GET_NAME (symbolP
)));
531 /* Unhook it from the chain */
532 *symbolPP
= symbol_next (symbolP
);
533 } /* if this symbol should be in the output */
534 } /* for each symbol */
536 H_SET_SYMBOL_TABLE_SIZE (headers
, symbol_number
);
540 * Find strings by crawling along symbol table chain.
544 obj_emit_strings (where
)
550 /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
551 md_number_to_chars (*where
, string_byte_count
, sizeof (string_byte_count
));
552 *where
+= sizeof (string_byte_count
);
553 #else /* CROSS_COMPILE */
554 append (where
, (char *) &string_byte_count
, (unsigned long) sizeof (string_byte_count
));
555 #endif /* CROSS_COMPILE */
557 for (symbolP
= symbol_rootP
; symbolP
; symbolP
= symbol_next (symbolP
))
559 if (S_GET_NAME (symbolP
))
560 append (&next_object_file_charP
, S_GET_NAME (symbolP
),
561 (unsigned long) (strlen (S_GET_NAME (symbolP
)) + 1));
562 } /* walk symbol chain */
566 #define AOUT_VERSION 0
570 obj_pre_write_hook (headers
)
571 object_headers
*headers
;
573 H_SET_DYNAMIC (headers
, 0);
574 H_SET_VERSION (headers
, AOUT_VERSION
);
575 H_SET_MACHTYPE (headers
, AOUT_MACHTYPE
);
576 tc_aout_pre_write_hook (headers
);
579 #endif /* ! BFD_ASSEMBLER */
583 /* Support for an AOUT emulation. */
585 static void aout_pop_insert
PARAMS ((void));
586 static int obj_aout_s_get_other
PARAMS ((symbolS
*));
587 static void obj_aout_s_set_other
PARAMS ((symbolS
*, int));
588 static int obj_aout_s_get_desc
PARAMS ((symbolS
*));
589 static void obj_aout_s_set_desc
PARAMS ((symbolS
*, int));
590 static int obj_aout_s_get_type
PARAMS ((symbolS
*));
591 static void obj_aout_s_set_type
PARAMS ((symbolS
*, int));
592 static int obj_aout_separate_stab_sections
PARAMS ((void));
593 static int obj_aout_sec_sym_ok_for_reloc
PARAMS ((asection
*));
594 static void obj_aout_process_stab
PARAMS ((segT
, int, const char *, int, int, int));
599 pop_insert (aout_pseudo_table
);
603 obj_aout_s_get_other (sym
)
606 return aout_symbol (symbol_get_bfdsym (sym
))->other
;
610 obj_aout_s_set_other (sym
, o
)
614 aout_symbol (symbol_get_bfdsym (sym
))->other
= o
;
618 obj_aout_sec_sym_ok_for_reloc (sec
)
619 asection
*sec ATTRIBUTE_UNUSED
;
621 return obj_sec_sym_ok_for_reloc (sec
);
625 obj_aout_process_stab (seg
, w
, s
, t
, o
, d
)
626 segT seg ATTRIBUTE_UNUSED
;
633 aout_process_stab (w
, s
, t
, o
, d
);
637 obj_aout_s_get_desc (sym
)
640 return aout_symbol (symbol_get_bfdsym (sym
))->desc
;
644 obj_aout_s_set_desc (sym
, d
)
648 aout_symbol (symbol_get_bfdsym (sym
))->desc
= d
;
652 obj_aout_s_get_type (sym
)
655 return aout_symbol (symbol_get_bfdsym (sym
))->type
;
659 obj_aout_s_set_type (sym
, t
)
663 aout_symbol (symbol_get_bfdsym (sym
))->type
= t
;
667 obj_aout_separate_stab_sections ()
672 /* When changed, make sure these table entries match the single-format
673 definitions in obj-aout.h. */
674 const struct format_ops aout_format_ops
=
676 bfd_target_aout_flavour
,
677 1, /* dfl_leading_underscore */
678 0, /* emit_section_symbols */
681 obj_aout_frob_symbol
,
683 0, /* frob_file_before_adjust */
684 obj_aout_frob_file_before_fix
,
685 0, /* frob_file_after_relocs */
690 obj_aout_s_get_other
,
691 obj_aout_s_set_other
,
696 0, /* copy_symbol_attributes */
697 0, /* generate_asm_lineno */
698 obj_aout_process_stab
,
699 obj_aout_separate_stab_sections
,
700 0, /* init_stab_section */
701 obj_aout_sec_sym_ok_for_reloc
,
703 0, /* ecoff_set_ext */
704 0, /* read_begin_hook */
705 0 /* symbol_new_hook */
707 #endif /* BFD_ASSEMBLER */