obj-aout.c revision 33965
133965Sjdp/* a.out object file format 233965Sjdp Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 1996 333965Sjdp Free Software Foundation, Inc. 433965Sjdp 533965SjdpThis file is part of GAS, the GNU Assembler. 633965Sjdp 733965SjdpGAS is free software; you can redistribute it and/or modify 833965Sjdpit under the terms of the GNU General Public License as 933965Sjdppublished by the Free Software Foundation; either version 2, 1033965Sjdpor (at your option) any later version. 1133965Sjdp 1233965SjdpGAS is distributed in the hope that it will be useful, but 1333965SjdpWITHOUT ANY WARRANTY; without even the implied warranty of 1433965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 1533965Sjdpthe GNU General Public License for more details. 1633965Sjdp 1733965SjdpYou should have received a copy of the GNU General Public 1833965SjdpLicense along with GAS; see the file COPYING. If not, write 1933965Sjdpto the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 2033965Sjdp 2133965Sjdp#include "as.h" 2233965Sjdp#ifdef BFD_ASSEMBLER 2333965Sjdp#undef NO_RELOC 2433965Sjdp#include "aout/aout64.h" 2533965Sjdp#endif 2633965Sjdp#include "obstack.h" 2733965Sjdp 2833965Sjdp#ifndef BFD_ASSEMBLER 2933965Sjdp/* in: segT out: N_TYPE bits */ 3033965Sjdpconst short seg_N_TYPE[] = 3133965Sjdp{ 3233965Sjdp N_ABS, 3333965Sjdp N_TEXT, 3433965Sjdp N_DATA, 3533965Sjdp N_BSS, 3633965Sjdp N_UNDF, /* unknown */ 3733965Sjdp N_UNDF, /* error */ 3833965Sjdp N_UNDF, /* expression */ 3933965Sjdp N_UNDF, /* debug */ 4033965Sjdp N_UNDF, /* ntv */ 4133965Sjdp N_UNDF, /* ptv */ 4233965Sjdp N_REGISTER, /* register */ 4333965Sjdp}; 4433965Sjdp 4533965Sjdpconst segT N_TYPE_seg[N_TYPE + 2] = 4633965Sjdp{ /* N_TYPE == 0x1E = 32-2 */ 4733965Sjdp SEG_UNKNOWN, /* N_UNDF == 0 */ 4833965Sjdp SEG_GOOF, 4933965Sjdp SEG_ABSOLUTE, /* N_ABS == 2 */ 5033965Sjdp SEG_GOOF, 5133965Sjdp SEG_TEXT, /* N_TEXT == 4 */ 5233965Sjdp SEG_GOOF, 5333965Sjdp SEG_DATA, /* N_DATA == 6 */ 5433965Sjdp SEG_GOOF, 5533965Sjdp SEG_BSS, /* N_BSS == 8 */ 5633965Sjdp SEG_GOOF, 5733965Sjdp SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, 5833965Sjdp SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, 5933965Sjdp SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, 6033965Sjdp SEG_REGISTER, /* dummy N_REGISTER for regs = 30 */ 6133965Sjdp SEG_GOOF, 6233965Sjdp}; 6333965Sjdp#endif 6433965Sjdp 6533965Sjdpstatic void obj_aout_line PARAMS ((int)); 6633965Sjdpstatic void obj_aout_weak PARAMS ((int)); 6733965Sjdpstatic void obj_aout_type PARAMS ((int)); 6833965Sjdp 6933965Sjdpconst pseudo_typeS obj_pseudo_table[] = 7033965Sjdp{ 7133965Sjdp {"line", obj_aout_line, 0}, /* source code line number */ 7233965Sjdp {"ln", obj_aout_line, 0}, /* coff line number that we use anyway */ 7333965Sjdp 7433965Sjdp {"weak", obj_aout_weak, 0}, /* mark symbol as weak. */ 7533965Sjdp 7633965Sjdp {"type", obj_aout_type, 0}, 7733965Sjdp 7833965Sjdp /* coff debug pseudos (ignored) */ 7933965Sjdp {"def", s_ignore, 0}, 8033965Sjdp {"dim", s_ignore, 0}, 8133965Sjdp {"endef", s_ignore, 0}, 8233965Sjdp {"ident", s_ignore, 0}, 8333965Sjdp {"line", s_ignore, 0}, 8433965Sjdp {"ln", s_ignore, 0}, 8533965Sjdp {"scl", s_ignore, 0}, 8633965Sjdp {"size", s_ignore, 0}, 8733965Sjdp {"tag", s_ignore, 0}, 8833965Sjdp {"val", s_ignore, 0}, 8933965Sjdp {"version", s_ignore, 0}, 9033965Sjdp 9133965Sjdp {"optim", s_ignore, 0}, /* For sun386i cc (?) */ 9233965Sjdp 9333965Sjdp /* other stuff */ 9433965Sjdp {"ABORT", s_abort, 0}, 9533965Sjdp 9633965Sjdp {NULL} /* end sentinel */ 9733965Sjdp}; /* obj_pseudo_table */ 9833965Sjdp 9933965Sjdp 10033965Sjdp#ifdef BFD_ASSEMBLER 10133965Sjdp 10233965Sjdpvoid 10333965Sjdpobj_aout_frob_symbol (sym, punt) 10433965Sjdp symbolS *sym; 10533965Sjdp int *punt; 10633965Sjdp{ 10733965Sjdp flagword flags; 10833965Sjdp asection *sec; 10933965Sjdp int desc, type, other; 11033965Sjdp 11133965Sjdp flags = sym->bsym->flags; 11233965Sjdp desc = S_GET_DESC (sym); 11333965Sjdp type = S_GET_TYPE (sym); 11433965Sjdp other = S_GET_OTHER (sym); 11533965Sjdp sec = sym->bsym->section; 11633965Sjdp 11733965Sjdp /* Only frob simple symbols this way right now. */ 11833965Sjdp if (! (type & ~ (N_TYPE | N_EXT))) 11933965Sjdp { 12033965Sjdp if (type == (N_UNDF | N_EXT) 12133965Sjdp && sec == &bfd_abs_section) 12233965Sjdp sym->bsym->section = sec = bfd_und_section_ptr; 12333965Sjdp 12433965Sjdp if ((type & N_TYPE) != N_INDR 12533965Sjdp && (type & N_TYPE) != N_SETA 12633965Sjdp && (type & N_TYPE) != N_SETT 12733965Sjdp && (type & N_TYPE) != N_SETD 12833965Sjdp && (type & N_TYPE) != N_SETB 12933965Sjdp && type != N_WARNING 13033965Sjdp && (sec == &bfd_abs_section 13133965Sjdp || sec == &bfd_und_section)) 13233965Sjdp return; 13333965Sjdp if (flags & BSF_EXPORT) 13433965Sjdp type |= N_EXT; 13533965Sjdp 13633965Sjdp switch (type & N_TYPE) 13733965Sjdp { 13833965Sjdp case N_SETA: 13933965Sjdp case N_SETT: 14033965Sjdp case N_SETD: 14133965Sjdp case N_SETB: 14233965Sjdp /* Set the debugging flag for constructor symbols so that 14333965Sjdp BFD leaves them alone. */ 14433965Sjdp sym->bsym->flags |= BSF_DEBUGGING; 14533965Sjdp 14633965Sjdp /* You can't put a common symbol in a set. The way a set 14733965Sjdp element works is that the symbol has a definition and a 14833965Sjdp name, and the linker adds the definition to the set of 14933965Sjdp that name. That does not work for a common symbol, 15033965Sjdp because the linker can't tell which common symbol the 15133965Sjdp user means. FIXME: Using as_bad here may be 15233965Sjdp inappropriate, since the user may want to force a 15333965Sjdp particular type without regard to the semantics of sets; 15433965Sjdp on the other hand, we certainly don't want anybody to be 15533965Sjdp mislead into thinking that their code will work. */ 15633965Sjdp if (S_IS_COMMON (sym)) 15733965Sjdp as_bad ("Attempt to put a common symbol into set %s", 15833965Sjdp S_GET_NAME (sym)); 15933965Sjdp /* Similarly, you can't put an undefined symbol in a set. */ 16033965Sjdp else if (! S_IS_DEFINED (sym)) 16133965Sjdp as_bad ("Attempt to put an undefined symbol into set %s", 16233965Sjdp S_GET_NAME (sym)); 16333965Sjdp 16433965Sjdp break; 16533965Sjdp case N_INDR: 16633965Sjdp /* Put indirect symbols in the indirect section. */ 16733965Sjdp sym->bsym->section = bfd_ind_section_ptr; 16833965Sjdp sym->bsym->flags |= BSF_INDIRECT; 16933965Sjdp if (type & N_EXT) 17033965Sjdp { 17133965Sjdp sym->bsym->flags |= BSF_EXPORT; 17233965Sjdp sym->bsym->flags &=~ BSF_LOCAL; 17333965Sjdp } 17433965Sjdp break; 17533965Sjdp case N_WARNING: 17633965Sjdp /* Mark warning symbols. */ 17733965Sjdp sym->bsym->flags |= BSF_WARNING; 17833965Sjdp break; 17933965Sjdp } 18033965Sjdp } 18133965Sjdp else 18233965Sjdp { 18333965Sjdp sym->bsym->flags |= BSF_DEBUGGING; 18433965Sjdp } 18533965Sjdp 18633965Sjdp S_SET_TYPE (sym, type); 18733965Sjdp 18833965Sjdp /* Double check weak symbols. */ 18933965Sjdp if (sym->bsym->flags & BSF_WEAK) 19033965Sjdp { 19133965Sjdp if (S_IS_COMMON (sym)) 19233965Sjdp as_bad ("Symbol `%s' can not be both weak and common", 19333965Sjdp S_GET_NAME (sym)); 19433965Sjdp } 19533965Sjdp} 19633965Sjdp 19733965Sjdpvoid 19833965Sjdpobj_aout_frob_file () 19933965Sjdp{ 20033965Sjdp /* Relocation processing may require knowing the VMAs of the sections. 20133965Sjdp Since writing to a section will cause the BFD back end to compute the 20233965Sjdp VMAs, fake it out here.... */ 20333965Sjdp bfd_byte b = 0; 20433965Sjdp boolean x = true; 20533965Sjdp if (bfd_section_size (stdoutput, text_section) != 0) 20633965Sjdp { 20733965Sjdp x = bfd_set_section_contents (stdoutput, text_section, &b, (file_ptr) 0, 20833965Sjdp (bfd_size_type) 1); 20933965Sjdp } 21033965Sjdp else if (bfd_section_size (stdoutput, data_section) != 0) 21133965Sjdp { 21233965Sjdp x = bfd_set_section_contents (stdoutput, data_section, &b, (file_ptr) 0, 21333965Sjdp (bfd_size_type) 1); 21433965Sjdp } 21533965Sjdp assert (x == true); 21633965Sjdp} 21733965Sjdp 21833965Sjdp#else 21933965Sjdp 22033965Sjdp/* Relocation. */ 22133965Sjdp 22233965Sjdp/* 22333965Sjdp * emit_relocations() 22433965Sjdp * 22533965Sjdp * Crawl along a fixS chain. Emit the segment's relocations. 22633965Sjdp */ 22733965Sjdpvoid 22833965Sjdpobj_emit_relocations (where, fixP, segment_address_in_file) 22933965Sjdp char **where; 23033965Sjdp fixS *fixP; /* Fixup chain for this segment. */ 23133965Sjdp relax_addressT segment_address_in_file; 23233965Sjdp{ 23333965Sjdp for (; fixP; fixP = fixP->fx_next) 23433965Sjdp if (fixP->fx_done == 0) 23533965Sjdp { 23633965Sjdp symbolS *sym; 23733965Sjdp 23833965Sjdp sym = fixP->fx_addsy; 23933965Sjdp while (sym->sy_value.X_op == O_symbol 24033965Sjdp && (! S_IS_DEFINED (sym) || S_IS_COMMON (sym))) 24133965Sjdp sym = sym->sy_value.X_add_symbol; 24233965Sjdp fixP->fx_addsy = sym; 24333965Sjdp 24433965Sjdp if (! sym->sy_resolved && ! S_IS_DEFINED (sym)) 24533965Sjdp { 24633965Sjdp char *file; 24733965Sjdp unsigned int line; 24833965Sjdp 24933965Sjdp if (expr_symbol_where (sym, &file, &line)) 25033965Sjdp as_bad_where (file, line, "unresolved relocation"); 25133965Sjdp else 25233965Sjdp as_bad ("bad relocation: symbol `%s' not in symbol table", 25333965Sjdp S_GET_NAME (sym)); 25433965Sjdp } 25533965Sjdp 25633965Sjdp tc_aout_fix_to_chars (*where, fixP, segment_address_in_file); 25733965Sjdp *where += md_reloc_size; 25833965Sjdp } 25933965Sjdp} 26033965Sjdp 26133965Sjdp#ifndef obj_header_append 26233965Sjdp/* Aout file generation & utilities */ 26333965Sjdpvoid 26433965Sjdpobj_header_append (where, headers) 26533965Sjdp char **where; 26633965Sjdp object_headers *headers; 26733965Sjdp{ 26833965Sjdp tc_headers_hook (headers); 26933965Sjdp 27033965Sjdp#ifdef CROSS_COMPILE 27133965Sjdp md_number_to_chars (*where, headers->header.a_info, sizeof (headers->header.a_info)); 27233965Sjdp *where += sizeof (headers->header.a_info); 27333965Sjdp md_number_to_chars (*where, headers->header.a_text, sizeof (headers->header.a_text)); 27433965Sjdp *where += sizeof (headers->header.a_text); 27533965Sjdp md_number_to_chars (*where, headers->header.a_data, sizeof (headers->header.a_data)); 27633965Sjdp *where += sizeof (headers->header.a_data); 27733965Sjdp md_number_to_chars (*where, headers->header.a_bss, sizeof (headers->header.a_bss)); 27833965Sjdp *where += sizeof (headers->header.a_bss); 27933965Sjdp md_number_to_chars (*where, headers->header.a_syms, sizeof (headers->header.a_syms)); 28033965Sjdp *where += sizeof (headers->header.a_syms); 28133965Sjdp md_number_to_chars (*where, headers->header.a_entry, sizeof (headers->header.a_entry)); 28233965Sjdp *where += sizeof (headers->header.a_entry); 28333965Sjdp md_number_to_chars (*where, headers->header.a_trsize, sizeof (headers->header.a_trsize)); 28433965Sjdp *where += sizeof (headers->header.a_trsize); 28533965Sjdp md_number_to_chars (*where, headers->header.a_drsize, sizeof (headers->header.a_drsize)); 28633965Sjdp *where += sizeof (headers->header.a_drsize); 28733965Sjdp 28833965Sjdp#else /* CROSS_COMPILE */ 28933965Sjdp 29033965Sjdp append (where, (char *) &headers->header, sizeof (headers->header)); 29133965Sjdp#endif /* CROSS_COMPILE */ 29233965Sjdp 29333965Sjdp} 29433965Sjdp#endif 29533965Sjdp 29633965Sjdpvoid 29733965Sjdpobj_symbol_to_chars (where, symbolP) 29833965Sjdp char **where; 29933965Sjdp symbolS *symbolP; 30033965Sjdp{ 30133965Sjdp md_number_to_chars ((char *) &(S_GET_OFFSET (symbolP)), S_GET_OFFSET (symbolP), sizeof (S_GET_OFFSET (symbolP))); 30233965Sjdp md_number_to_chars ((char *) &(S_GET_DESC (symbolP)), S_GET_DESC (symbolP), sizeof (S_GET_DESC (symbolP))); 30333965Sjdp md_number_to_chars ((char *) &(symbolP->sy_symbol.n_value), S_GET_VALUE (symbolP), sizeof (symbolP->sy_symbol.n_value)); 30433965Sjdp 30533965Sjdp append (where, (char *) &symbolP->sy_symbol, sizeof (obj_symbol_type)); 30633965Sjdp} 30733965Sjdp 30833965Sjdpvoid 30933965Sjdpobj_emit_symbols (where, symbol_rootP) 31033965Sjdp char **where; 31133965Sjdp symbolS *symbol_rootP; 31233965Sjdp{ 31333965Sjdp symbolS *symbolP; 31433965Sjdp 31533965Sjdp /* Emit all symbols left in the symbol chain. */ 31633965Sjdp for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP)) 31733965Sjdp { 31833965Sjdp /* Used to save the offset of the name. It is used to point 31933965Sjdp to the string in memory but must be a file offset. */ 32033965Sjdp register char *temp; 32133965Sjdp 32233965Sjdp temp = S_GET_NAME (symbolP); 32333965Sjdp S_SET_OFFSET (symbolP, symbolP->sy_name_offset); 32433965Sjdp 32533965Sjdp /* Any symbol still undefined and is not a dbg symbol is made N_EXT. */ 32633965Sjdp if (!S_IS_DEBUG (symbolP) && !S_IS_DEFINED (symbolP)) 32733965Sjdp S_SET_EXTERNAL (symbolP); 32833965Sjdp 32933965Sjdp /* Adjust the type of a weak symbol. */ 33033965Sjdp if (S_GET_WEAK (symbolP)) 33133965Sjdp { 33233965Sjdp switch (S_GET_TYPE (symbolP)) 33333965Sjdp { 33433965Sjdp case N_UNDF: S_SET_TYPE (symbolP, N_WEAKU); break; 33533965Sjdp case N_ABS: S_SET_TYPE (symbolP, N_WEAKA); break; 33633965Sjdp case N_TEXT: S_SET_TYPE (symbolP, N_WEAKT); break; 33733965Sjdp case N_DATA: S_SET_TYPE (symbolP, N_WEAKD); break; 33833965Sjdp case N_BSS: S_SET_TYPE (symbolP, N_WEAKB); break; 33933965Sjdp default: as_bad ("%s: bad type for weak symbol", temp); break; 34033965Sjdp } 34133965Sjdp } 34233965Sjdp 34333965Sjdp obj_symbol_to_chars (where, symbolP); 34433965Sjdp S_SET_NAME (symbolP, temp); 34533965Sjdp } 34633965Sjdp} 34733965Sjdp 34833965Sjdp#endif /* ! BFD_ASSEMBLER */ 34933965Sjdp 35033965Sjdpstatic void 35133965Sjdpobj_aout_line (ignore) 35233965Sjdp int ignore; 35333965Sjdp{ 35433965Sjdp /* Assume delimiter is part of expression. 35533965Sjdp BSD4.2 as fails with delightful bug, so we 35633965Sjdp are not being incompatible here. */ 35733965Sjdp new_logical_line ((char *) NULL, (int) (get_absolute_expression ())); 35833965Sjdp demand_empty_rest_of_line (); 35933965Sjdp} /* obj_aout_line() */ 36033965Sjdp 36133965Sjdp/* Handle .weak. This is a GNU extension. */ 36233965Sjdp 36333965Sjdpstatic void 36433965Sjdpobj_aout_weak (ignore) 36533965Sjdp int ignore; 36633965Sjdp{ 36733965Sjdp char *name; 36833965Sjdp int c; 36933965Sjdp symbolS *symbolP; 37033965Sjdp 37133965Sjdp do 37233965Sjdp { 37333965Sjdp name = input_line_pointer; 37433965Sjdp c = get_symbol_end (); 37533965Sjdp symbolP = symbol_find_or_make (name); 37633965Sjdp *input_line_pointer = c; 37733965Sjdp SKIP_WHITESPACE (); 37833965Sjdp S_SET_WEAK (symbolP); 37933965Sjdp if (c == ',') 38033965Sjdp { 38133965Sjdp input_line_pointer++; 38233965Sjdp SKIP_WHITESPACE (); 38333965Sjdp if (*input_line_pointer == '\n') 38433965Sjdp c = '\n'; 38533965Sjdp } 38633965Sjdp } 38733965Sjdp while (c == ','); 38833965Sjdp demand_empty_rest_of_line (); 38933965Sjdp} 39033965Sjdp 39133965Sjdp/* Handle .type. On {Net,Open}BSD, this is used to set the n_other field, 39233965Sjdp which is then apparently used when doing dynamic linking. Older 39333965Sjdp versions ogas ignored the .type pseudo-op, so we also ignore it if 39433965Sjdp we can't parse it. */ 39533965Sjdp 39633965Sjdpstatic void 39733965Sjdpobj_aout_type (ignore) 39833965Sjdp int ignore; 39933965Sjdp{ 40033965Sjdp char *name; 40133965Sjdp int c; 40233965Sjdp symbolS *sym; 40333965Sjdp 40433965Sjdp name = input_line_pointer; 40533965Sjdp c = get_symbol_end (); 40633965Sjdp sym = symbol_find (name); 40733965Sjdp *input_line_pointer = c; 40833965Sjdp if (sym != NULL) 40933965Sjdp { 41033965Sjdp SKIP_WHITESPACE (); 41133965Sjdp if (*input_line_pointer == ',') 41233965Sjdp { 41333965Sjdp ++input_line_pointer; 41433965Sjdp SKIP_WHITESPACE (); 41533965Sjdp if (*input_line_pointer == '@') 41633965Sjdp { 41733965Sjdp ++input_line_pointer; 41833965Sjdp if (strncmp (input_line_pointer, "object", 6) == 0) 41933965Sjdp S_SET_OTHER (sym, 1); 42033965Sjdp else if (strncmp (input_line_pointer, "function", 8) == 0) 42133965Sjdp S_SET_OTHER (sym, 2); 42233965Sjdp } 42333965Sjdp } 42433965Sjdp } 42533965Sjdp 42633965Sjdp /* Ignore everything else on the line. */ 42733965Sjdp s_ignore (0); 42833965Sjdp} 42933965Sjdp 43033965Sjdpvoid 43133965Sjdpobj_read_begin_hook () 43233965Sjdp{ 43333965Sjdp} 43433965Sjdp 43533965Sjdp#ifndef BFD_ASSEMBLER 43633965Sjdp 43733965Sjdpvoid 43833965Sjdpobj_crawl_symbol_chain (headers) 43933965Sjdp object_headers *headers; 44033965Sjdp{ 44133965Sjdp symbolS *symbolP; 44233965Sjdp symbolS **symbolPP; 44333965Sjdp int symbol_number = 0; 44433965Sjdp 44533965Sjdp tc_crawl_symbol_chain (headers); 44633965Sjdp 44733965Sjdp symbolPP = &symbol_rootP; /*->last symbol chain link. */ 44833965Sjdp while ((symbolP = *symbolPP) != NULL) 44933965Sjdp { 45033965Sjdp if (symbolP->sy_mri_common) 45133965Sjdp { 45233965Sjdp if (S_IS_EXTERNAL (symbolP)) 45333965Sjdp as_bad ("%s: global symbols not supported in common sections", 45433965Sjdp S_GET_NAME (symbolP)); 45533965Sjdp *symbolPP = symbol_next (symbolP); 45633965Sjdp continue; 45733965Sjdp } 45833965Sjdp 45933965Sjdp if (flag_readonly_data_in_text && (S_GET_SEGMENT (symbolP) == SEG_DATA)) 46033965Sjdp { 46133965Sjdp S_SET_SEGMENT (symbolP, SEG_TEXT); 46233965Sjdp } /* if pusing data into text */ 46333965Sjdp 46433965Sjdp resolve_symbol_value (symbolP); 46533965Sjdp 46633965Sjdp /* Skip symbols which were equated to undefined or common 46733965Sjdp symbols. */ 46833965Sjdp if (symbolP->sy_value.X_op == O_symbol 46933965Sjdp && (! S_IS_DEFINED (symbolP) || S_IS_COMMON (symbolP))) 47033965Sjdp { 47133965Sjdp *symbolPP = symbol_next (symbolP); 47233965Sjdp continue; 47333965Sjdp } 47433965Sjdp 47533965Sjdp /* OK, here is how we decide which symbols go out into the brave 47633965Sjdp new symtab. Symbols that do are: 47733965Sjdp 47833965Sjdp * symbols with no name (stabd's?) 47933965Sjdp * symbols with debug info in their N_TYPE 48033965Sjdp 48133965Sjdp Symbols that don't are: 48233965Sjdp * symbols that are registers 48333965Sjdp * symbols with \1 as their 3rd character (numeric labels) 48433965Sjdp * "local labels" as defined by S_LOCAL_NAME(name) if the -L 48533965Sjdp switch was passed to gas. 48633965Sjdp 48733965Sjdp All other symbols are output. We complain if a deleted 48833965Sjdp symbol was marked external. */ 48933965Sjdp 49033965Sjdp 49133965Sjdp if (!S_IS_REGISTER (symbolP) 49233965Sjdp && (!S_GET_NAME (symbolP) 49333965Sjdp || S_IS_DEBUG (symbolP) 49433965Sjdp || !S_IS_DEFINED (symbolP) 49533965Sjdp || S_IS_EXTERNAL (symbolP) 49633965Sjdp || (S_GET_NAME (symbolP)[0] != '\001' 49733965Sjdp && (flag_keep_locals || !S_LOCAL_NAME (symbolP))))) 49833965Sjdp { 49933965Sjdp symbolP->sy_number = symbol_number++; 50033965Sjdp 50133965Sjdp /* The + 1 after strlen account for the \0 at the 50233965Sjdp end of each string */ 50333965Sjdp if (!S_IS_STABD (symbolP)) 50433965Sjdp { 50533965Sjdp /* Ordinary case. */ 50633965Sjdp symbolP->sy_name_offset = string_byte_count; 50733965Sjdp string_byte_count += strlen (S_GET_NAME (symbolP)) + 1; 50833965Sjdp } 50933965Sjdp else /* .Stabd case. */ 51033965Sjdp symbolP->sy_name_offset = 0; 51133965Sjdp symbolPP = &(symbol_next (symbolP)); 51233965Sjdp } 51333965Sjdp else 51433965Sjdp { 51533965Sjdp if (S_IS_EXTERNAL (symbolP) || !S_IS_DEFINED (symbolP)) 51633965Sjdp /* This warning should never get triggered any more. 51733965Sjdp Well, maybe if you're doing twisted things with 51833965Sjdp register names... */ 51933965Sjdp { 52033965Sjdp as_bad ("Local symbol %s never defined.", decode_local_label_name (S_GET_NAME (symbolP))); 52133965Sjdp } /* oops. */ 52233965Sjdp 52333965Sjdp /* Unhook it from the chain */ 52433965Sjdp *symbolPP = symbol_next (symbolP); 52533965Sjdp } /* if this symbol should be in the output */ 52633965Sjdp } /* for each symbol */ 52733965Sjdp 52833965Sjdp H_SET_SYMBOL_TABLE_SIZE (headers, symbol_number); 52933965Sjdp} 53033965Sjdp 53133965Sjdp/* 53233965Sjdp * Find strings by crawling along symbol table chain. 53333965Sjdp */ 53433965Sjdp 53533965Sjdpvoid 53633965Sjdpobj_emit_strings (where) 53733965Sjdp char **where; 53833965Sjdp{ 53933965Sjdp symbolS *symbolP; 54033965Sjdp 54133965Sjdp#ifdef CROSS_COMPILE 54233965Sjdp /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */ 54333965Sjdp md_number_to_chars (*where, string_byte_count, sizeof (string_byte_count)); 54433965Sjdp *where += sizeof (string_byte_count); 54533965Sjdp#else /* CROSS_COMPILE */ 54633965Sjdp append (where, (char *) &string_byte_count, (unsigned long) sizeof (string_byte_count)); 54733965Sjdp#endif /* CROSS_COMPILE */ 54833965Sjdp 54933965Sjdp for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP)) 55033965Sjdp { 55133965Sjdp if (S_GET_NAME (symbolP)) 55233965Sjdp append (&next_object_file_charP, S_GET_NAME (symbolP), 55333965Sjdp (unsigned long) (strlen (S_GET_NAME (symbolP)) + 1)); 55433965Sjdp } /* walk symbol chain */ 55533965Sjdp} 55633965Sjdp 55733965Sjdp#ifndef AOUT_VERSION 55833965Sjdp#define AOUT_VERSION 0 55933965Sjdp#endif 56033965Sjdp 56133965Sjdpvoid 56233965Sjdpobj_pre_write_hook (headers) 56333965Sjdp object_headers *headers; 56433965Sjdp{ 56533965Sjdp H_SET_DYNAMIC (headers, 0); 56633965Sjdp H_SET_VERSION (headers, AOUT_VERSION); 56733965Sjdp H_SET_MACHTYPE (headers, AOUT_MACHTYPE); 56833965Sjdp tc_aout_pre_write_hook (headers); 56933965Sjdp} 57033965Sjdp 57133965Sjdpvoid 57233965SjdpDEFUN_VOID (s_sect) 57333965Sjdp{ 57433965Sjdp /* Strip out the section name */ 57533965Sjdp char *section_name; 57633965Sjdp char *section_name_end; 57733965Sjdp char c; 57833965Sjdp 57933965Sjdp unsigned int len; 58033965Sjdp unsigned int exp; 58133965Sjdp char *save; 58233965Sjdp 58333965Sjdp section_name = input_line_pointer; 58433965Sjdp c = get_symbol_end (); 58533965Sjdp section_name_end = input_line_pointer; 58633965Sjdp 58733965Sjdp len = section_name_end - section_name; 58833965Sjdp input_line_pointer++; 58933965Sjdp save = input_line_pointer; 59033965Sjdp 59133965Sjdp SKIP_WHITESPACE (); 59233965Sjdp if (c == ',') 59333965Sjdp { 59433965Sjdp exp = get_absolute_expression (); 59533965Sjdp } 59633965Sjdp else if (*input_line_pointer == ',') 59733965Sjdp { 59833965Sjdp input_line_pointer++; 59933965Sjdp exp = get_absolute_expression (); 60033965Sjdp } 60133965Sjdp else 60233965Sjdp { 60333965Sjdp input_line_pointer = save; 60433965Sjdp exp = 0; 60533965Sjdp } 60633965Sjdp if (exp >= 1000) 60733965Sjdp { 60833965Sjdp as_bad ("subsegment index too high"); 60933965Sjdp } 61033965Sjdp 61133965Sjdp if (strcmp (section_name, ".text") == 0) 61233965Sjdp { 61333965Sjdp subseg_set (SEG_TEXT, (subsegT) exp); 61433965Sjdp } 61533965Sjdp 61633965Sjdp if (strcmp (section_name, ".data") == 0) 61733965Sjdp { 61833965Sjdp if (flag_readonly_data_in_text) 61933965Sjdp subseg_set (SEG_TEXT, (subsegT) exp + 1000); 62033965Sjdp else 62133965Sjdp subseg_set (SEG_DATA, (subsegT) exp); 62233965Sjdp } 62333965Sjdp 62433965Sjdp *section_name_end = c; 62533965Sjdp} 62633965Sjdp 62733965Sjdp#endif /* ! BFD_ASSEMBLER */ 62833965Sjdp 62933965Sjdp/* end of obj-aout.c */ 630