obj-aout.c revision 38889
1193323Sed/* a.out object file format 2193323Sed Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 1996 3193323Sed Free Software Foundation, Inc. 4193323Sed 5193323SedThis file is part of GAS, the GNU Assembler. 6193323Sed 7193323SedGAS is free software; you can redistribute it and/or modify 8193323Sedit under the terms of the GNU General Public License as 9193323Sedpublished by the Free Software Foundation; either version 2, 10193323Sedor (at your option) any later version. 11193323Sed 12193323SedGAS is distributed in the hope that it will be useful, but 13193323SedWITHOUT ANY WARRANTY; without even the implied warranty of 14193323SedMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 15249423Sdimthe GNU General Public License for more details. 16249423Sdim 17193323SedYou should have received a copy of the GNU General Public 18251662SdimLicense along with GAS; see the file COPYING. If not, write 19193323Sedto the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 20203954Srdivacky 21198892Srdivacky#include "as.h" 22249423Sdim#ifdef BFD_ASSEMBLER 23234353Sdim#undef NO_RELOC 24249423Sdim#include "aout/aout64.h" 25198090Srdivacky#endif 26193323Sed#include "obstack.h" 27234353Sdim 28234353Sdim#ifndef BFD_ASSEMBLER 29234353Sdim/* in: segT out: N_TYPE bits */ 30249423Sdimconst short seg_N_TYPE[] = 31193323Sed{ 32193323Sed N_ABS, 33193323Sed N_TEXT, 34193323Sed N_DATA, 35193323Sed N_BSS, 36263508Sdim N_UNDF, /* unknown */ 37198090Srdivacky N_UNDF, /* error */ 38193323Sed N_UNDF, /* expression */ 39193323Sed N_UNDF, /* debug */ 40193323Sed N_UNDF, /* ntv */ 41195098Sed N_UNDF, /* ptv */ 42195098Sed N_REGISTER, /* register */ 43195098Sed}; 44193323Sed 45195098Sedconst segT N_TYPE_seg[N_TYPE + 2] = 46251662Sdim{ /* N_TYPE == 0x1E = 32-2 */ 47263508Sdim SEG_UNKNOWN, /* N_UNDF == 0 */ 48234353Sdim SEG_GOOF, 49193323Sed SEG_ABSOLUTE, /* N_ABS == 2 */ 50193323Sed SEG_GOOF, 51218893Sdim SEG_TEXT, /* N_TEXT == 4 */ 52218893Sdim SEG_GOOF, 53193323Sed SEG_DATA, /* N_DATA == 6 */ 54198090Srdivacky SEG_GOOF, 55198892Srdivacky SEG_BSS, /* N_BSS == 8 */ 56198892Srdivacky SEG_GOOF, 57198892Srdivacky SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, 58198892Srdivacky SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, 59198892Srdivacky SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, 60198892Srdivacky SEG_REGISTER, /* dummy N_REGISTER for regs = 30 */ 61198892Srdivacky SEG_GOOF, 62198090Srdivacky}; 63198892Srdivacky#endif 64198892Srdivacky 65198090Srdivackystatic void obj_aout_line PARAMS ((int)); 66193323Sedstatic void obj_aout_weak PARAMS ((int)); 67198090Srdivackystatic void obj_aout_type PARAMS ((int)); 68198090Srdivacky 69193323Sedconst pseudo_typeS obj_pseudo_table[] = 70193323Sed{ 71198892Srdivacky {"line", obj_aout_line, 0}, /* source code line number */ 72193323Sed {"ln", obj_aout_line, 0}, /* coff line number that we use anyway */ 73193323Sed 74193323Sed {"weak", obj_aout_weak, 0}, /* mark symbol as weak. */ 75193323Sed 76193323Sed {"type", obj_aout_type, 0}, 77198090Srdivacky 78193323Sed /* coff debug pseudos (ignored) */ 79193323Sed {"def", s_ignore, 0}, 80198892Srdivacky {"dim", s_ignore, 0}, 81198090Srdivacky {"endef", s_ignore, 0}, 82218893Sdim {"ident", s_ignore, 0}, 83193323Sed {"line", s_ignore, 0}, 84193323Sed {"ln", s_ignore, 0}, 85193323Sed {"scl", s_ignore, 0}, 86198090Srdivacky {"size", s_ignore, 0}, 87193323Sed {"tag", s_ignore, 0}, 88193323Sed {"val", s_ignore, 0}, 89193323Sed {"version", s_ignore, 0}, 90198090Srdivacky 91218893Sdim {"optim", s_ignore, 0}, /* For sun386i cc (?) */ 92218893Sdim 93243830Sdim /* other stuff */ 94198090Srdivacky {"ABORT", s_abort, 0}, 95193323Sed 96193323Sed {NULL} /* end sentinel */ 97218893Sdim}; /* obj_pseudo_table */ 98218893Sdim 99218893Sdim 100218893Sdim#ifdef BFD_ASSEMBLER 101218893Sdim 102218893Sdimvoid 103218893Sdimobj_aout_frob_symbol (sym, punt) 104218893Sdim symbolS *sym; 105218893Sdim int *punt; 106218893Sdim{ 107193323Sed flagword flags; 108218893Sdim asection *sec; 109243830Sdim int desc, type, other; 110218893Sdim 111218893Sdim flags = sym->bsym->flags; 112198892Srdivacky desc = S_GET_DESC (sym); 113218893Sdim type = S_GET_TYPE (sym); 114218893Sdim other = S_GET_OTHER (sym); 115193323Sed sec = sym->bsym->section; 116218893Sdim 117218893Sdim /* Only frob simple symbols this way right now. */ 118218893Sdim if (! (type & ~ (N_TYPE | N_EXT))) 119193323Sed { 120193323Sed if (type == (N_UNDF | N_EXT) 121198090Srdivacky && sec == &bfd_abs_section) 122198090Srdivacky sym->bsym->section = sec = bfd_und_section_ptr; 123193323Sed 124218893Sdim if ((type & N_TYPE) != N_INDR 125218893Sdim && (type & N_TYPE) != N_SETA 126203954Srdivacky && (type & N_TYPE) != N_SETT 127221345Sdim && (type & N_TYPE) != N_SETD 128243830Sdim && (type & N_TYPE) != N_SETB 129221345Sdim && type != N_WARNING 130193323Sed && (sec == &bfd_abs_section 131218893Sdim || sec == &bfd_und_section)) 132193323Sed return; 133193323Sed if (flags & BSF_EXPORT) 134218893Sdim type |= N_EXT; 135218893Sdim 136203954Srdivacky switch (type & N_TYPE) 137203954Srdivacky { 138203954Srdivacky case N_SETA: 139203954Srdivacky case N_SETT: 140203954Srdivacky case N_SETD: 141223017Sdim case N_SETB: 142218893Sdim /* Set the debugging flag for constructor symbols so that 143218893Sdim BFD leaves them alone. */ 144218893Sdim sym->bsym->flags |= BSF_DEBUGGING; 145263508Sdim 146218893Sdim /* You can't put a common symbol in a set. The way a set 147223017Sdim element works is that the symbol has a definition and a 148226633Sdim name, and the linker adds the definition to the set of 149193323Sed that name. That does not work for a common symbol, 150193323Sed because the linker can't tell which common symbol the 151218893Sdim user means. FIXME: Using as_bad here may be 152218893Sdim inappropriate, since the user may want to force a 153218893Sdim particular type without regard to the semantics of sets; 154221345Sdim on the other hand, we certainly don't want anybody to be 155193323Sed mislead into thinking that their code will work. */ 156263508Sdim if (S_IS_COMMON (sym)) 157193323Sed as_bad ("Attempt to put a common symbol into set %s", 158193323Sed S_GET_NAME (sym)); 159218893Sdim /* Similarly, you can't put an undefined symbol in a set. */ 160193323Sed else if (! S_IS_DEFINED (sym)) 161193323Sed as_bad ("Attempt to put an undefined symbol into set %s", 162193323Sed S_GET_NAME (sym)); 163193323Sed 164193323Sed break; 165193323Sed case N_INDR: 166193323Sed /* Put indirect symbols in the indirect section. */ 167193323Sed sym->bsym->section = bfd_ind_section_ptr; 168193323Sed sym->bsym->flags |= BSF_INDIRECT; 169203954Srdivacky if (type & N_EXT) 170218893Sdim { 171218893Sdim sym->bsym->flags |= BSF_EXPORT; 172218893Sdim sym->bsym->flags &=~ BSF_LOCAL; 173218893Sdim } 174221345Sdim break; 175218893Sdim case N_WARNING: 176218893Sdim /* Mark warning symbols. */ 177203954Srdivacky sym->bsym->flags |= BSF_WARNING; 178193323Sed break; 179193323Sed } 180193323Sed } 181226633Sdim else 182198090Srdivacky { 183198090Srdivacky sym->bsym->flags |= BSF_DEBUGGING; 184193323Sed } 185193323Sed 186203954Srdivacky S_SET_TYPE (sym, type); 187198090Srdivacky 188198090Srdivacky /* Double check weak symbols. */ 189198090Srdivacky if (sym->bsym->flags & BSF_WEAK) 190203954Srdivacky { 191193323Sed if (S_IS_COMMON (sym)) 192193323Sed as_bad ("Symbol `%s' can not be both weak and common", 193193323Sed S_GET_NAME (sym)); 194226633Sdim } 195199481Srdivacky} 196226633Sdim 197210299Sedvoid 198226633Sdimobj_aout_frob_file () 199193323Sed{ 200203954Srdivacky /* Relocation processing may require knowing the VMAs of the sections. 201203954Srdivacky Since writing to a section will cause the BFD back end to compute the 202203954Srdivacky VMAs, fake it out here.... */ 203203954Srdivacky bfd_byte b = 0; 204203954Srdivacky boolean x = true; 205193323Sed if (bfd_section_size (stdoutput, text_section) != 0) 206221345Sdim { 207218893Sdim x = bfd_set_section_contents (stdoutput, text_section, &b, (file_ptr) 0, 208193323Sed (bfd_size_type) 1); 209243830Sdim } 210193323Sed else if (bfd_section_size (stdoutput, data_section) != 0) 211203954Srdivacky { 212203954Srdivacky x = bfd_set_section_contents (stdoutput, data_section, &b, (file_ptr) 0, 213203954Srdivacky (bfd_size_type) 1); 214193323Sed } 215193323Sed assert (x == true); 216193323Sed} 217193323Sed 218263508Sdim#else 219221345Sdim 220193323Sed/* Relocation. */ 221193323Sed 222193323Sed/* 223193323Sed * emit_relocations() 224193323Sed * 225234353Sdim * Crawl along a fixS chain. Emit the segment's relocations. 226234353Sdim */ 227234353Sdimvoid 228234353Sdimobj_emit_relocations (where, fixP, segment_address_in_file) 229234353Sdim char **where; 230234353Sdim fixS *fixP; /* Fixup chain for this segment. */ 231234353Sdim relax_addressT segment_address_in_file; 232234353Sdim{ 233263508Sdim for (; fixP; fixP = fixP->fx_next) 234263508Sdim if (fixP->fx_done == 0) 235263508Sdim { 236263508Sdim symbolS *sym; 237263508Sdim 238234353Sdim sym = fixP->fx_addsy; 239234353Sdim while (sym->sy_value.X_op == O_symbol 240234353Sdim && (! S_IS_DEFINED (sym) || S_IS_COMMON (sym))) 241234353Sdim sym = sym->sy_value.X_add_symbol; 242234353Sdim fixP->fx_addsy = sym; 243234353Sdim 244234353Sdim if (! sym->sy_resolved && ! S_IS_DEFINED (sym)) 245243830Sdim { 246234353Sdim char *file; 247234353Sdim unsigned int line; 248234353Sdim 249234353Sdim if (expr_symbol_where (sym, &file, &line)) 250263508Sdim as_bad_where (file, line, "unresolved relocation"); 251263508Sdim else 252263508Sdim as_bad ("bad relocation: symbol `%s' not in symbol table", 253263508Sdim S_GET_NAME (sym)); 254263508Sdim } 255263508Sdim 256263508Sdim tc_aout_fix_to_chars (*where, fixP, segment_address_in_file); 257263508Sdim *where += md_reloc_size; 258263508Sdim } 259263508Sdim} 260263508Sdim 261263508Sdim#ifndef obj_header_append 262263508Sdim/* Aout file generation & utilities */ 263263508Sdimvoid 264263508Sdimobj_header_append (where, headers) 265263508Sdim char **where; 266263508Sdim object_headers *headers; 267263508Sdim{ 268263508Sdim tc_headers_hook (headers); 269263508Sdim 270263508Sdim#ifdef CROSS_COMPILE 271263508Sdim md_number_to_chars (*where, headers->header.a_info, sizeof (headers->header.a_info)); 272263508Sdim *where += sizeof (headers->header.a_info); 273263508Sdim md_number_to_chars (*where, headers->header.a_text, sizeof (headers->header.a_text)); 274263508Sdim *where += sizeof (headers->header.a_text); 275243830Sdim md_number_to_chars (*where, headers->header.a_data, sizeof (headers->header.a_data)); 276243830Sdim *where += sizeof (headers->header.a_data); 277193323Sed md_number_to_chars (*where, headers->header.a_bss, sizeof (headers->header.a_bss)); 278218893Sdim *where += sizeof (headers->header.a_bss); 279218893Sdim md_number_to_chars (*where, headers->header.a_syms, sizeof (headers->header.a_syms)); 280218893Sdim *where += sizeof (headers->header.a_syms); 281263508Sdim md_number_to_chars (*where, headers->header.a_entry, sizeof (headers->header.a_entry)); 282218893Sdim *where += sizeof (headers->header.a_entry); 283193323Sed md_number_to_chars (*where, headers->header.a_trsize, sizeof (headers->header.a_trsize)); 284218893Sdim *where += sizeof (headers->header.a_trsize); 285218893Sdim md_number_to_chars (*where, headers->header.a_drsize, sizeof (headers->header.a_drsize)); 286218893Sdim *where += sizeof (headers->header.a_drsize); 287193323Sed 288221345Sdim#else /* CROSS_COMPILE */ 289221345Sdim 290193323Sed append (where, (char *) &headers->header, sizeof (headers->header)); 291193323Sed#endif /* CROSS_COMPILE */ 292193323Sed 293193323Sed} 294193323Sed#endif 295193323Sed 296193323Sedvoid 297193323Sedobj_symbol_to_chars (where, symbolP) 298193323Sed char **where; 299193323Sed symbolS *symbolP; 300193323Sed{ 301198090Srdivacky md_number_to_chars ((char *) &(S_GET_OFFSET (symbolP)), S_GET_OFFSET (symbolP), sizeof (S_GET_OFFSET (symbolP))); 302198090Srdivacky md_number_to_chars ((char *) &(S_GET_DESC (symbolP)), S_GET_DESC (symbolP), sizeof (S_GET_DESC (symbolP))); 303193323Sed md_number_to_chars ((char *) &(symbolP->sy_symbol.n_value), S_GET_VALUE (symbolP), sizeof (symbolP->sy_symbol.n_value)); 304221345Sdim 305218893Sdim append (where, (char *) &symbolP->sy_symbol, sizeof (obj_symbol_type)); 306218893Sdim} 307193323Sed 308221345Sdimvoid 309193323Sedobj_emit_symbols (where, symbol_rootP) 310193323Sed char **where; 311193323Sed symbolS *symbol_rootP; 312221345Sdim{ 313193323Sed symbolS *symbolP; 314193323Sed 315193323Sed /* Emit all symbols left in the symbol chain. */ 316193323Sed for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP)) 317193323Sed { 318221345Sdim /* Used to save the offset of the name. It is used to point 319193323Sed to the string in memory but must be a file offset. */ 320193323Sed register char *temp; 321193323Sed 322263508Sdim temp = S_GET_NAME (symbolP); 323263508Sdim S_SET_OFFSET (symbolP, symbolP->sy_name_offset); 324263508Sdim 325193323Sed /* Any symbol still undefined and is not a dbg symbol is made N_EXT. */ 326193323Sed if (!S_IS_DEBUG (symbolP) && !S_IS_DEFINED (symbolP)) 327193323Sed S_SET_EXTERNAL (symbolP); 328218893Sdim 329263508Sdim /* Adjust the type of a weak symbol. */ 330263508Sdim if (S_GET_WEAK (symbolP)) 331263508Sdim { 332193323Sed switch (S_GET_TYPE (symbolP)) 333193323Sed { 334193323Sed case N_UNDF: S_SET_TYPE (symbolP, N_WEAKU); break; 335193323Sed case N_ABS: S_SET_TYPE (symbolP, N_WEAKA); break; 336198090Srdivacky case N_TEXT: S_SET_TYPE (symbolP, N_WEAKT); break; 337198892Srdivacky case N_DATA: S_SET_TYPE (symbolP, N_WEAKD); break; 338198892Srdivacky case N_BSS: S_SET_TYPE (symbolP, N_WEAKB); break; 339263508Sdim default: as_bad ("%s: bad type for weak symbol", temp); break; 340263508Sdim } 341263508Sdim } 342193323Sed 343193323Sed obj_symbol_to_chars (where, symbolP); 344198892Srdivacky S_SET_NAME (symbolP, temp); 345198892Srdivacky } 346198892Srdivacky} 347263508Sdim 348263508Sdim#endif /* ! BFD_ASSEMBLER */ 349198892Srdivacky 350221345Sdimstatic void 351193323Sedobj_aout_line (ignore) 352193323Sed int ignore; 353198090Srdivacky{ 354198090Srdivacky /* Assume delimiter is part of expression. 355263508Sdim BSD4.2 as fails with delightful bug, so we 356263508Sdim are not being incompatible here. */ 357263508Sdim new_logical_line ((char *) NULL, (int) (get_absolute_expression ())); 358193323Sed demand_empty_rest_of_line (); 359193323Sed} /* obj_aout_line() */ 360193323Sed 361193323Sed/* Handle .weak. This is a GNU extension. */ 362193323Sed 363263508Sdimstatic void 364263508Sdimobj_aout_weak (ignore) 365263508Sdim int ignore; 366263508Sdim{ 367263508Sdim char *name; 368263508Sdim int c; 369263508Sdim symbolS *symbolP; 370263508Sdim 371263508Sdim do 372263508Sdim { 373263508Sdim name = input_line_pointer; 374263508Sdim c = get_symbol_end (); 375263508Sdim symbolP = symbol_find_or_make (name); 376263508Sdim *input_line_pointer = c; 377263508Sdim SKIP_WHITESPACE (); 378263508Sdim S_SET_WEAK (symbolP); 379263508Sdim if (c == ',') 380263508Sdim { 381193323Sed input_line_pointer++; 382194178Sed SKIP_WHITESPACE (); 383193323Sed if (*input_line_pointer == '\n') 384193323Sed c = '\n'; 385193323Sed } 386193323Sed } 387193323Sed while (c == ','); 388193323Sed demand_empty_rest_of_line (); 389218893Sdim} 390218893Sdim 391218893Sdim/* Handle .type. On {Net,Open}BSD, this is used to set the n_other field, 392218893Sdim which is then apparently used when doing dynamic linking. Older 393193323Sed versions ogas ignored the .type pseudo-op, so we also ignore it if 394226633Sdim we can't parse it. */ 395218893Sdim 396193323Sedstatic void 397193323Sedobj_aout_type (ignore) 398218893Sdim int ignore; 399218893Sdim{ 400218893Sdim char *name; 401218893Sdim int c; 402218893Sdim symbolS *sym; 403193323Sed 404193323Sed name = input_line_pointer; 405193323Sed c = get_symbol_end (); 406193323Sed sym = symbol_find (name); 407193323Sed *input_line_pointer = c; 408193323Sed if (sym != NULL) 409193323Sed { 410193323Sed SKIP_WHITESPACE (); 411193323Sed if (*input_line_pointer == ',') 412198090Srdivacky { 413263508Sdim ++input_line_pointer; 414263508Sdim SKIP_WHITESPACE (); 415263508Sdim if (*input_line_pointer == '@') 416193323Sed { 417239462Sdim ++input_line_pointer; 418193323Sed if (strncmp (input_line_pointer, "object", 6) == 0) 419195098Sed S_SET_OTHER (sym, 1); 420195098Sed else if (strncmp (input_line_pointer, "function", 8) == 0) 421195098Sed S_SET_OTHER (sym, 2); 422195098Sed } 423195098Sed } 424198090Srdivacky } 425198090Srdivacky 426195098Sed /* Ignore everything else on the line. */ 427251662Sdim s_ignore (0); 428251662Sdim} 429251662Sdim 430251662Sdimvoid 431251662Sdimobj_read_begin_hook () 432251662Sdim{ 433198892Srdivacky} 434198892Srdivacky 435198892Srdivacky#ifndef BFD_ASSEMBLER 436198892Srdivacky 437198892Srdivackyvoid 438198892Srdivackyobj_crawl_symbol_chain (headers) 439198892Srdivacky object_headers *headers; 440198892Srdivacky{ 441198892Srdivacky symbolS *symbolP; 442198892Srdivacky symbolS **symbolPP; 443198892Srdivacky int symbol_number = 0; 444198892Srdivacky 445198892Srdivacky tc_crawl_symbol_chain (headers); 446193323Sed 447198892Srdivacky symbolPP = &symbol_rootP; /*->last symbol chain link. */ 448193323Sed while ((symbolP = *symbolPP) != NULL) 449198892Srdivacky { 450198892Srdivacky if (symbolP->sy_mri_common) 451198892Srdivacky { 452198892Srdivacky if (S_IS_EXTERNAL (symbolP)) 453198892Srdivacky as_bad ("%s: global symbols not supported in common sections", 454193323Sed S_GET_NAME (symbolP)); 455198892Srdivacky *symbolPP = symbol_next (symbolP); 456193323Sed continue; 457193323Sed } 458193323Sed 459193323Sed if (flag_readonly_data_in_text && (S_GET_SEGMENT (symbolP) == SEG_DATA)) 460193323Sed { 461193323Sed S_SET_SEGMENT (symbolP, SEG_TEXT); 462193323Sed } /* if pusing data into text */ 463193323Sed 464193323Sed resolve_symbol_value (symbolP, 1); 465193323Sed 466193323Sed /* Skip symbols which were equated to undefined or common 467193323Sed symbols. */ 468193323Sed if (symbolP->sy_value.X_op == O_symbol 469193323Sed && (! S_IS_DEFINED (symbolP) || S_IS_COMMON (symbolP))) 470193323Sed { 471193323Sed *symbolPP = symbol_next (symbolP); 472193323Sed continue; 473193323Sed } 474193323Sed 475193323Sed /* OK, here is how we decide which symbols go out into the brave 476193323Sed new symtab. Symbols that do are: 477199481Srdivacky 478193323Sed * symbols with no name (stabd's?) 479193323Sed * symbols with debug info in their N_TYPE 480193323Sed 481193323Sed Symbols that don't are: 482193323Sed * symbols that are registers 483193323Sed * symbols with \1 as their 3rd character (numeric labels) 484221345Sdim * "local labels" as defined by S_LOCAL_NAME(name) if the -L 485193323Sed switch was passed to gas. 486203954Srdivacky 487193323Sed All other symbols are output. We complain if a deleted 488193323Sed symbol was marked external. */ 489193323Sed 490193323Sed 491193323Sed if (!S_IS_REGISTER (symbolP) 492193323Sed && (!S_GET_NAME (symbolP) 493221345Sdim || S_IS_DEBUG (symbolP) 494226633Sdim || !S_IS_DEFINED (symbolP) 495193323Sed || S_IS_EXTERNAL (symbolP) 496193323Sed || (S_GET_NAME (symbolP)[0] != '\001' 497198090Srdivacky && (flag_keep_locals || !S_LOCAL_NAME (symbolP))))) 498198090Srdivacky { 499198090Srdivacky symbolP->sy_number = symbol_number++; 500198090Srdivacky 501198090Srdivacky /* The + 1 after strlen account for the \0 at the 502198090Srdivacky end of each string */ 503198090Srdivacky if (!S_IS_STABD (symbolP)) 504198090Srdivacky { 505198090Srdivacky /* Ordinary case. */ 506198090Srdivacky symbolP->sy_name_offset = string_byte_count; 507198090Srdivacky string_byte_count += strlen (S_GET_NAME (symbolP)) + 1; 508198090Srdivacky } 509198090Srdivacky else /* .Stabd case. */ 510218893Sdim symbolP->sy_name_offset = 0; 511203954Srdivacky symbolPP = &(symbol_next (symbolP)); 512198090Srdivacky } 513198090Srdivacky else 514198090Srdivacky { 515263508Sdim if (S_IS_EXTERNAL (symbolP) || !S_IS_DEFINED (symbolP)) 516198090Srdivacky /* This warning should never get triggered any more. 517198090Srdivacky Well, maybe if you're doing twisted things with 518234353Sdim register names... */ 519226633Sdim { 520199481Srdivacky as_bad ("Local symbol %s never defined.", decode_local_label_name (S_GET_NAME (symbolP))); 521203954Srdivacky } /* oops. */ 522203954Srdivacky 523203954Srdivacky /* Unhook it from the chain */ 524218893Sdim *symbolPP = symbol_next (symbolP); 525198090Srdivacky } /* if this symbol should be in the output */ 526198090Srdivacky } /* for each symbol */ 527198090Srdivacky 528198090Srdivacky H_SET_SYMBOL_TABLE_SIZE (headers, symbol_number); 529198090Srdivacky} 530198090Srdivacky 531263508Sdim/* 532198090Srdivacky * Find strings by crawling along symbol table chain. 533234353Sdim */ 534198090Srdivacky 535226633Sdimvoid 536226633Sdimobj_emit_strings (where) 537218893Sdim char **where; 538198090Srdivacky{ 539198090Srdivacky symbolS *symbolP; 540218893Sdim 541198090Srdivacky#ifdef CROSS_COMPILE 542203954Srdivacky /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */ 543203954Srdivacky md_number_to_chars (*where, string_byte_count, sizeof (string_byte_count)); 544198090Srdivacky *where += sizeof (string_byte_count); 545198090Srdivacky#else /* CROSS_COMPILE */ 546198090Srdivacky append (where, (char *) &string_byte_count, (unsigned long) sizeof (string_byte_count)); 547198090Srdivacky#endif /* CROSS_COMPILE */ 548198090Srdivacky 549198090Srdivacky for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP)) 550198090Srdivacky { 551198090Srdivacky if (S_GET_NAME (symbolP)) 552198090Srdivacky append (&next_object_file_charP, S_GET_NAME (symbolP), 553263508Sdim (unsigned long) (strlen (S_GET_NAME (symbolP)) + 1)); 554263508Sdim } /* walk symbol chain */ 555263508Sdim} 556263508Sdim 557263508Sdim#ifndef AOUT_VERSION 558263508Sdim#define AOUT_VERSION 0 559263508Sdim#endif 560263508Sdim 561263508Sdimvoid 562263508Sdimobj_pre_write_hook (headers) 563263508Sdim object_headers *headers; 564263508Sdim{ 565263508Sdim H_SET_DYNAMIC (headers, 0); 566198090Srdivacky H_SET_VERSION (headers, AOUT_VERSION); 567263508Sdim H_SET_MACHTYPE (headers, AOUT_MACHTYPE); 568263508Sdim tc_aout_pre_write_hook (headers); 569263508Sdim} 570263508Sdim 571263508Sdimvoid 572263508SdimDEFUN_VOID (s_sect) 573263508Sdim{ 574198090Srdivacky /* Strip out the section name */ 575263508Sdim char *section_name; 576198090Srdivacky char *section_name_end; 577198090Srdivacky char c; 578198090Srdivacky 579198090Srdivacky unsigned int len; 580198090Srdivacky unsigned int exp; 581198090Srdivacky char *save; 582198090Srdivacky 583198090Srdivacky section_name = input_line_pointer; 584198090Srdivacky c = get_symbol_end (); 585198090Srdivacky section_name_end = input_line_pointer; 586198090Srdivacky 587198090Srdivacky len = section_name_end - section_name; 588198090Srdivacky input_line_pointer++; 589198090Srdivacky save = input_line_pointer; 590198090Srdivacky 591198090Srdivacky SKIP_WHITESPACE (); 592198090Srdivacky if (c == ',') 593198090Srdivacky { 594234353Sdim exp = get_absolute_expression (); 595234353Sdim } 596234353Sdim else if (*input_line_pointer == ',') 597234353Sdim { 598234353Sdim input_line_pointer++; 599234353Sdim exp = get_absolute_expression (); 600234353Sdim } 601226633Sdim else 602226633Sdim { 603226633Sdim input_line_pointer = save; 604226633Sdim exp = 0; 605226633Sdim } 606226633Sdim if (exp >= 1000) 607226633Sdim { 608199481Srdivacky as_bad ("subsegment index too high"); 609226633Sdim } 610226633Sdim 611199481Srdivacky if (strcmp (section_name, ".text") == 0) 612199481Srdivacky { 613199481Srdivacky subseg_set (SEG_TEXT, (subsegT) exp); 614199481Srdivacky } 615199481Srdivacky 616198090Srdivacky if (strcmp (section_name, ".data") == 0) 617198090Srdivacky { 618198090Srdivacky if (flag_readonly_data_in_text) 619198090Srdivacky subseg_set (SEG_TEXT, (subsegT) exp + 1000); 620198090Srdivacky else 621198090Srdivacky subseg_set (SEG_DATA, (subsegT) exp); 622198090Srdivacky } 623198090Srdivacky 624198090Srdivacky *section_name_end = c; 625198090Srdivacky} 626198090Srdivacky 627198090Srdivacky#endif /* ! BFD_ASSEMBLER */ 628203954Srdivacky 629203954Srdivacky/* end of obj-aout.c */ 630203954Srdivacky