obj-elf.c revision 89857
1/* ELF object file format 2 Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 3 Free Software Foundation, Inc. 4 5 This file is part of GAS, the GNU Assembler. 6 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. 11 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. 16 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 20 02111-1307, USA. */ 21 22#define OBJ_HEADER "obj-elf.h" 23#include "as.h" 24#include "safe-ctype.h" 25#include "subsegs.h" 26#include "obstack.h" 27 28#ifndef ECOFF_DEBUGGING 29#define ECOFF_DEBUGGING 0 30#else 31#define NEED_ECOFF_DEBUG 32#endif 33 34#ifdef NEED_ECOFF_DEBUG 35#include "ecoff.h" 36#endif 37 38#ifdef TC_ALPHA 39#include "elf/alpha.h" 40#endif 41 42#ifdef TC_MIPS 43#include "elf/mips.h" 44#endif 45 46#ifdef TC_PPC 47#include "elf/ppc.h" 48#endif 49 50#ifdef TC_I370 51#include "elf/i370.h" 52#endif 53 54static bfd_vma elf_s_get_size PARAMS ((symbolS *)); 55static void elf_s_set_size PARAMS ((symbolS *, bfd_vma)); 56static bfd_vma elf_s_get_align PARAMS ((symbolS *)); 57static void elf_s_set_align PARAMS ((symbolS *, bfd_vma)); 58static void elf_s_set_other PARAMS ((symbolS *, int)); 59static int elf_sec_sym_ok_for_reloc PARAMS ((asection *)); 60static void adjust_stab_sections PARAMS ((bfd *, asection *, PTR)); 61static void build_group_lists PARAMS ((bfd *, asection *, PTR)); 62static int elf_separate_stab_sections PARAMS ((void)); 63static void elf_init_stab_section PARAMS ((segT)); 64 65#ifdef NEED_ECOFF_DEBUG 66static boolean elf_get_extr PARAMS ((asymbol *, EXTR *)); 67static void elf_set_index PARAMS ((asymbol *, bfd_size_type)); 68#endif 69 70static void obj_elf_line PARAMS ((int)); 71void obj_elf_version PARAMS ((int)); 72static void obj_elf_size PARAMS ((int)); 73static void obj_elf_type PARAMS ((int)); 74static void obj_elf_ident PARAMS ((int)); 75static void obj_elf_weak PARAMS ((int)); 76static void obj_elf_local PARAMS ((int)); 77static void obj_elf_visibility PARAMS ((int)); 78static void obj_elf_change_section 79 PARAMS ((const char *, int, int, int, const char *, int)); 80static int obj_elf_parse_section_letters PARAMS ((char *, size_t)); 81static int obj_elf_section_word PARAMS ((char *, size_t)); 82static char *obj_elf_section_name PARAMS ((void)); 83static int obj_elf_section_type PARAMS ((char *, size_t)); 84static void obj_elf_symver PARAMS ((int)); 85static void obj_elf_subsection PARAMS ((int)); 86static void obj_elf_popsection PARAMS ((int)); 87 88static const pseudo_typeS elf_pseudo_table[] = 89{ 90 {"comm", obj_elf_common, 0}, 91 {"common", obj_elf_common, 1}, 92 {"ident", obj_elf_ident, 0}, 93 {"local", obj_elf_local, 0}, 94 {"previous", obj_elf_previous, 0}, 95 {"section", obj_elf_section, 0}, 96 {"section.s", obj_elf_section, 0}, 97 {"sect", obj_elf_section, 0}, 98 {"sect.s", obj_elf_section, 0}, 99 {"pushsection", obj_elf_section, 1}, 100 {"popsection", obj_elf_popsection, 0}, 101 {"size", obj_elf_size, 0}, 102 {"type", obj_elf_type, 0}, 103 {"version", obj_elf_version, 0}, 104 {"weak", obj_elf_weak, 0}, 105 106 /* These define symbol visibility. */ 107 {"internal", obj_elf_visibility, STV_INTERNAL}, 108 {"hidden", obj_elf_visibility, STV_HIDDEN}, 109 {"protected", obj_elf_visibility, STV_PROTECTED}, 110 111 /* These are used for stabs-in-elf configurations. */ 112 {"line", obj_elf_line, 0}, 113 114 /* This is a GNU extension to handle symbol versions. */ 115 {"symver", obj_elf_symver, 0}, 116 117 /* A GNU extension to change subsection only. */ 118 {"subsection", obj_elf_subsection, 0}, 119 120 /* These are GNU extensions to aid in garbage collecting C++ vtables. */ 121 {"vtable_inherit", (void (*) PARAMS ((int))) &obj_elf_vtable_inherit, 0}, 122 {"vtable_entry", (void (*) PARAMS ((int))) &obj_elf_vtable_entry, 0}, 123 124 /* These are used for dwarf. */ 125 {"2byte", cons, 2}, 126 {"4byte", cons, 4}, 127 {"8byte", cons, 8}, 128 129 /* We need to trap the section changing calls to handle .previous. */ 130 {"data", obj_elf_data, 0}, 131 {"text", obj_elf_text, 0}, 132 133 /* End sentinel. */ 134 {NULL, NULL, 0}, 135}; 136 137static const pseudo_typeS ecoff_debug_pseudo_table[] = 138{ 139#ifdef NEED_ECOFF_DEBUG 140 /* COFF style debugging information for ECOFF. .ln is not used; .loc 141 is used instead. */ 142 { "def", ecoff_directive_def, 0 }, 143 { "dim", ecoff_directive_dim, 0 }, 144 { "endef", ecoff_directive_endef, 0 }, 145 { "file", ecoff_directive_file, 0 }, 146 { "scl", ecoff_directive_scl, 0 }, 147 { "tag", ecoff_directive_tag, 0 }, 148 { "val", ecoff_directive_val, 0 }, 149 150 /* COFF debugging requires pseudo-ops .size and .type, but ELF 151 already has meanings for those. We use .esize and .etype 152 instead. These are only generated by gcc anyhow. */ 153 { "esize", ecoff_directive_size, 0 }, 154 { "etype", ecoff_directive_type, 0 }, 155 156 /* ECOFF specific debugging information. */ 157 { "begin", ecoff_directive_begin, 0 }, 158 { "bend", ecoff_directive_bend, 0 }, 159 { "end", ecoff_directive_end, 0 }, 160 { "ent", ecoff_directive_ent, 0 }, 161 { "fmask", ecoff_directive_fmask, 0 }, 162 { "frame", ecoff_directive_frame, 0 }, 163 { "loc", ecoff_directive_loc, 0 }, 164 { "mask", ecoff_directive_mask, 0 }, 165 166 /* Other ECOFF directives. */ 167 { "extern", ecoff_directive_extern, 0 }, 168 169 /* These are used on Irix. I don't know how to implement them. */ 170 { "alias", s_ignore, 0 }, 171 { "bgnb", s_ignore, 0 }, 172 { "endb", s_ignore, 0 }, 173 { "lab", s_ignore, 0 }, 174 { "noalias", s_ignore, 0 }, 175 { "verstamp", s_ignore, 0 }, 176 { "vreg", s_ignore, 0 }, 177#endif 178 179 {NULL, NULL, 0} /* end sentinel */ 180}; 181 182#undef NO_RELOC 183#include "aout/aout64.h" 184 185/* This is called when the assembler starts. */ 186 187void 188elf_begin () 189{ 190 /* Add symbols for the known sections to the symbol table. */ 191 symbol_table_insert (section_symbol (bfd_get_section_by_name (stdoutput, 192 TEXT_SECTION_NAME))); 193 symbol_table_insert (section_symbol (bfd_get_section_by_name (stdoutput, 194 DATA_SECTION_NAME))); 195 symbol_table_insert (section_symbol (bfd_get_section_by_name (stdoutput, 196 BSS_SECTION_NAME))); 197} 198 199void 200elf_pop_insert () 201{ 202 pop_insert (elf_pseudo_table); 203 if (ECOFF_DEBUGGING) 204 pop_insert (ecoff_debug_pseudo_table); 205} 206 207static bfd_vma 208elf_s_get_size (sym) 209 symbolS *sym; 210{ 211 return S_GET_SIZE (sym); 212} 213 214static void 215elf_s_set_size (sym, sz) 216 symbolS *sym; 217 bfd_vma sz; 218{ 219 S_SET_SIZE (sym, sz); 220} 221 222static bfd_vma 223elf_s_get_align (sym) 224 symbolS *sym; 225{ 226 return S_GET_ALIGN (sym); 227} 228 229static void 230elf_s_set_align (sym, align) 231 symbolS *sym; 232 bfd_vma align; 233{ 234 S_SET_ALIGN (sym, align); 235} 236 237int 238elf_s_get_other (sym) 239 symbolS *sym; 240{ 241 return elf_symbol (symbol_get_bfdsym (sym))->internal_elf_sym.st_other; 242} 243 244static void 245elf_s_set_other (sym, other) 246 symbolS *sym; 247 int other; 248{ 249 S_SET_OTHER (sym, other); 250} 251 252static int 253elf_sec_sym_ok_for_reloc (sec) 254 asection *sec; 255{ 256 return obj_sec_sym_ok_for_reloc (sec); 257} 258 259void 260elf_file_symbol (s) 261 const char *s; 262{ 263 symbolS *sym; 264 265 sym = symbol_new (s, absolute_section, (valueT) 0, (struct frag *) 0); 266 symbol_set_frag (sym, &zero_address_frag); 267 symbol_get_bfdsym (sym)->flags |= BSF_FILE; 268 269 if (symbol_rootP != sym) 270 { 271 symbol_remove (sym, &symbol_rootP, &symbol_lastP); 272 symbol_insert (sym, symbol_rootP, &symbol_rootP, &symbol_lastP); 273#ifdef DEBUG 274 verify_symbol_chain (symbol_rootP, symbol_lastP); 275#endif 276 } 277 278#ifdef NEED_ECOFF_DEBUG 279 ecoff_new_file (s); 280#endif 281} 282 283void 284obj_elf_common (is_common) 285 int is_common; 286{ 287 char *name; 288 char c; 289 char *p; 290 int temp, size; 291 symbolS *symbolP; 292 int have_align; 293 294 if (flag_mri && is_common) 295 { 296 s_mri_common (0); 297 return; 298 } 299 300 name = input_line_pointer; 301 c = get_symbol_end (); 302 /* just after name is now '\0' */ 303 p = input_line_pointer; 304 *p = c; 305 SKIP_WHITESPACE (); 306 if (*input_line_pointer != ',') 307 { 308 as_bad (_("expected comma after symbol-name")); 309 ignore_rest_of_line (); 310 return; 311 } 312 input_line_pointer++; /* skip ',' */ 313 if ((temp = get_absolute_expression ()) < 0) 314 { 315 as_bad (_(".COMMon length (%d.) <0! Ignored."), temp); 316 ignore_rest_of_line (); 317 return; 318 } 319 size = temp; 320 *p = 0; 321 symbolP = symbol_find_or_make (name); 322 *p = c; 323 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP)) 324 { 325 as_bad (_("symbol `%s' is already defined"), S_GET_NAME (symbolP)); 326 ignore_rest_of_line (); 327 return; 328 } 329 if (S_GET_VALUE (symbolP) != 0) 330 { 331 if (S_GET_VALUE (symbolP) != (valueT) size) 332 { 333 as_warn (_("length of .comm \"%s\" is already %ld; not changed to %d"), 334 S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size); 335 } 336 } 337 know (symbolP->sy_frag == &zero_address_frag); 338 if (*input_line_pointer != ',') 339 have_align = 0; 340 else 341 { 342 have_align = 1; 343 input_line_pointer++; 344 SKIP_WHITESPACE (); 345 } 346 if (! have_align || *input_line_pointer != '"') 347 { 348 if (! have_align) 349 temp = 0; 350 else 351 { 352 temp = get_absolute_expression (); 353 if (temp < 0) 354 { 355 temp = 0; 356 as_warn (_("common alignment negative; 0 assumed")); 357 } 358 } 359 if (symbol_get_obj (symbolP)->local) 360 { 361 segT old_sec; 362 int old_subsec; 363 char *pfrag; 364 int align; 365 366 /* allocate_bss: */ 367 old_sec = now_seg; 368 old_subsec = now_subseg; 369 if (temp) 370 { 371 /* convert to a power of 2 alignment */ 372 for (align = 0; (temp & 1) == 0; temp >>= 1, ++align); 373 if (temp != 1) 374 { 375 as_bad (_("common alignment not a power of 2")); 376 ignore_rest_of_line (); 377 return; 378 } 379 } 380 else 381 align = 0; 382 record_alignment (bss_section, align); 383 subseg_set (bss_section, 0); 384 if (align) 385 frag_align (align, 0, 0); 386 if (S_GET_SEGMENT (symbolP) == bss_section) 387 symbol_get_frag (symbolP)->fr_symbol = 0; 388 symbol_set_frag (symbolP, frag_now); 389 pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, 390 (offsetT) size, (char *) 0); 391 *pfrag = 0; 392 S_SET_SIZE (symbolP, size); 393 S_SET_SEGMENT (symbolP, bss_section); 394 S_CLEAR_EXTERNAL (symbolP); 395 subseg_set (old_sec, old_subsec); 396 } 397 else 398 { 399 allocate_common: 400 S_SET_VALUE (symbolP, (valueT) size); 401 S_SET_ALIGN (symbolP, temp); 402 S_SET_EXTERNAL (symbolP); 403 S_SET_SEGMENT (symbolP, bfd_com_section_ptr); 404 } 405 } 406 else 407 { 408 input_line_pointer++; 409 /* @@ Some use the dot, some don't. Can we get some consistency?? */ 410 if (*input_line_pointer == '.') 411 input_line_pointer++; 412 /* @@ Some say data, some say bss. */ 413 if (strncmp (input_line_pointer, "bss\"", 4) 414 && strncmp (input_line_pointer, "data\"", 5)) 415 { 416 while (*--input_line_pointer != '"') 417 ; 418 input_line_pointer--; 419 goto bad_common_segment; 420 } 421 while (*input_line_pointer++ != '"') 422 ; 423 goto allocate_common; 424 } 425 426 symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT; 427 428 demand_empty_rest_of_line (); 429 return; 430 431 { 432 bad_common_segment: 433 p = input_line_pointer; 434 while (*p && *p != '\n') 435 p++; 436 c = *p; 437 *p = '\0'; 438 as_bad (_("bad .common segment %s"), input_line_pointer + 1); 439 *p = c; 440 input_line_pointer = p; 441 ignore_rest_of_line (); 442 return; 443 } 444} 445 446static void 447obj_elf_local (ignore) 448 int ignore ATTRIBUTE_UNUSED; 449{ 450 char *name; 451 int c; 452 symbolS *symbolP; 453 454 do 455 { 456 name = input_line_pointer; 457 c = get_symbol_end (); 458 symbolP = symbol_find_or_make (name); 459 *input_line_pointer = c; 460 SKIP_WHITESPACE (); 461 S_CLEAR_EXTERNAL (symbolP); 462 symbol_get_obj (symbolP)->local = 1; 463 if (c == ',') 464 { 465 input_line_pointer++; 466 SKIP_WHITESPACE (); 467 if (*input_line_pointer == '\n') 468 c = '\n'; 469 } 470 } 471 while (c == ','); 472 demand_empty_rest_of_line (); 473} 474 475static void 476obj_elf_weak (ignore) 477 int ignore ATTRIBUTE_UNUSED; 478{ 479 char *name; 480 int c; 481 symbolS *symbolP; 482 483 do 484 { 485 name = input_line_pointer; 486 c = get_symbol_end (); 487 symbolP = symbol_find_or_make (name); 488 *input_line_pointer = c; 489 SKIP_WHITESPACE (); 490 S_SET_WEAK (symbolP); 491 symbol_get_obj (symbolP)->local = 1; 492 if (c == ',') 493 { 494 input_line_pointer++; 495 SKIP_WHITESPACE (); 496 if (*input_line_pointer == '\n') 497 c = '\n'; 498 } 499 } 500 while (c == ','); 501 demand_empty_rest_of_line (); 502} 503 504static void 505obj_elf_visibility (visibility) 506 int visibility; 507{ 508 char *name; 509 int c; 510 symbolS *symbolP; 511 asymbol *bfdsym; 512 elf_symbol_type *elfsym; 513 514 do 515 { 516 name = input_line_pointer; 517 c = get_symbol_end (); 518 symbolP = symbol_find_or_make (name); 519 *input_line_pointer = c; 520 521 SKIP_WHITESPACE (); 522 523 bfdsym = symbol_get_bfdsym (symbolP); 524 elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym); 525 526 assert (elfsym); 527 528 elfsym->internal_elf_sym.st_other = visibility; 529 530 if (c == ',') 531 { 532 input_line_pointer ++; 533 534 SKIP_WHITESPACE (); 535 536 if (*input_line_pointer == '\n') 537 c = '\n'; 538 } 539 } 540 while (c == ','); 541 542 demand_empty_rest_of_line (); 543} 544 545static segT previous_section; 546static int previous_subsection; 547 548struct section_stack 549{ 550 struct section_stack *next; 551 segT seg, prev_seg; 552 int subseg, prev_subseg; 553}; 554 555static struct section_stack *section_stack; 556 557/* Handle the .section pseudo-op. This code supports two different 558 syntaxes. 559 560 The first is found on Solaris, and looks like 561 .section ".sec1",#alloc,#execinstr,#write 562 Here the names after '#' are the SHF_* flags to turn on for the 563 section. I'm not sure how it determines the SHT_* type (BFD 564 doesn't really give us control over the type, anyhow). 565 566 The second format is found on UnixWare, and probably most SVR4 567 machines, and looks like 568 .section .sec1,"a",@progbits 569 The quoted string may contain any combination of a, w, x, and 570 represents the SHF_* flags to turn on for the section. The string 571 beginning with '@' can be progbits or nobits. There should be 572 other possibilities, but I don't know what they are. In any case, 573 BFD doesn't really let us set the section type. */ 574 575/* Certain named sections have particular defined types, listed on p. 576 4-19 of the ABI. */ 577struct special_section 578{ 579 const char *name; 580 int type; 581 int attributes; 582}; 583 584static struct special_section const special_sections[] = 585{ 586 { ".bss", SHT_NOBITS, SHF_ALLOC + SHF_WRITE }, 587 { ".comment", SHT_PROGBITS, 0 }, 588 { ".data", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, 589 { ".data1", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, 590 { ".debug", SHT_PROGBITS, 0 }, 591 { ".fini", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR }, 592 { ".init", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR }, 593 { ".line", SHT_PROGBITS, 0 }, 594 { ".note", SHT_NOTE, 0 }, 595 { ".rodata", SHT_PROGBITS, SHF_ALLOC }, 596 { ".rodata1", SHT_PROGBITS, SHF_ALLOC }, 597 { ".text", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR }, 598 599#ifdef ELF_TC_SPECIAL_SECTIONS 600 ELF_TC_SPECIAL_SECTIONS 601#endif 602 603#if 0 604 /* The following section names are special, but they can not 605 reasonably appear in assembler code. Some of the attributes are 606 processor dependent. */ 607 { ".dynamic", SHT_DYNAMIC, SHF_ALLOC /* + SHF_WRITE */ }, 608 { ".dynstr", SHT_STRTAB, SHF_ALLOC }, 609 { ".dynsym", SHT_DYNSYM, SHF_ALLOC }, 610 { ".got", SHT_PROGBITS, 0 }, 611 { ".hash", SHT_HASH, SHF_ALLOC }, 612 { ".interp", SHT_PROGBITS, /* SHF_ALLOC */ }, 613 { ".plt", SHT_PROGBITS, 0 }, 614 { ".shstrtab",SHT_STRTAB, 0 }, 615 { ".strtab", SHT_STRTAB, /* SHF_ALLOC */ }, 616 { ".symtab", SHT_SYMTAB, /* SHF_ALLOC */ }, 617#endif 618 619 { NULL, 0, 0 } 620}; 621 622static void 623obj_elf_change_section (name, type, attr, entsize, group_name, push) 624 const char *name; 625 int type; 626 int attr; 627 int entsize; 628 const char *group_name; 629 int push; 630{ 631 asection *old_sec; 632 segT sec; 633 flagword flags; 634 int i; 635 636#ifdef md_flush_pending_output 637 md_flush_pending_output (); 638#endif 639 640 /* Switch to the section, creating it if necessary. */ 641 if (push) 642 { 643 struct section_stack *elt; 644 elt = xmalloc (sizeof (struct section_stack)); 645 elt->next = section_stack; 646 elt->seg = now_seg; 647 elt->prev_seg = previous_section; 648 elt->subseg = now_subseg; 649 elt->prev_subseg = previous_subsection; 650 section_stack = elt; 651 } 652 previous_section = now_seg; 653 previous_subsection = now_subseg; 654 655 old_sec = bfd_get_section_by_name (stdoutput, name); 656 sec = subseg_new (name, 0); 657 658 /* See if this is one of the special sections. */ 659 for (i = 0; special_sections[i].name != NULL; i++) 660 if (strcmp (name, special_sections[i].name) == 0) 661 { 662 if (type == SHT_NULL) 663 type = special_sections[i].type; 664 else if (type != special_sections[i].type) 665 { 666 if (old_sec == NULL) 667 { 668 as_warn (_("setting incorrect section type for %s"), name); 669 } 670 else 671 { 672 as_warn (_("ignoring incorrect section type for %s"), name); 673 type = special_sections[i].type; 674 } 675 } 676 if ((attr &~ special_sections[i].attributes) != 0 677 && old_sec == NULL) 678 { 679 /* As a GNU extension, we permit a .note section to be 680 allocatable. If the linker sees an allocateable .note 681 section, it will create a PT_NOTE segment in the output 682 file. */ 683 if (strcmp (name, ".note") != 0 684 || attr != SHF_ALLOC) 685 as_warn (_("setting incorrect section attributes for %s"), 686 name); 687 } 688 attr |= special_sections[i].attributes; 689 break; 690 } 691 692 /* Convert ELF type and flags to BFD flags. */ 693 flags = (SEC_RELOC 694 | ((attr & SHF_WRITE) ? 0 : SEC_READONLY) 695 | ((attr & SHF_ALLOC) ? SEC_ALLOC : 0) 696 | (((attr & SHF_ALLOC) && type != SHT_NOBITS) ? SEC_LOAD : 0) 697 | ((attr & SHF_EXECINSTR) ? SEC_CODE : 0) 698 | ((attr & SHF_MERGE) ? SEC_MERGE : 0) 699 | ((attr & SHF_STRINGS) ? SEC_STRINGS : 0)); 700#ifdef md_elf_section_flags 701 flags = md_elf_section_flags (flags, attr, type); 702#endif 703 704 if (old_sec == NULL) 705 { 706 symbolS *secsym; 707 708 /* Prevent SEC_HAS_CONTENTS from being inadvertently set. */ 709 if (type == SHT_NOBITS) 710 seg_info (sec)->bss = 1; 711 712 bfd_set_section_flags (stdoutput, sec, flags); 713 if (flags & SEC_MERGE) 714 sec->entsize = entsize; 715 elf_group_name (sec) = group_name; 716 717 /* Add a symbol for this section to the symbol table. */ 718 secsym = symbol_find (name); 719 if (secsym != NULL) 720 symbol_set_bfdsym (secsym, sec->symbol); 721 else 722 symbol_table_insert (section_symbol (sec)); 723 } 724 else if (attr != 0) 725 { 726 /* If section attributes are specified the second time we see a 727 particular section, then check that they are the same as we 728 saw the first time. */ 729 if ((old_sec->flags ^ flags) 730 & (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE 731 | SEC_EXCLUDE | SEC_SORT_ENTRIES | SEC_MERGE | SEC_STRINGS)) 732 as_warn (_("ignoring changed section attributes for %s"), name); 733 else if ((flags & SEC_MERGE) && old_sec->entsize != (unsigned) entsize) 734 as_warn (_("ignoring changed section entity size for %s"), name); 735 else if ((attr & SHF_GROUP) != 0 736 && strcmp (elf_group_name (old_sec), group_name) != 0) 737 as_warn (_("ignoring new section group for %s"), name); 738 } 739 740#ifdef md_elf_section_change_hook 741 md_elf_section_change_hook (); 742#endif 743} 744 745static int 746obj_elf_parse_section_letters (str, len) 747 char *str; 748 size_t len; 749{ 750 int attr = 0; 751 752 while (len > 0) 753 { 754 switch (*str) 755 { 756 case 'a': 757 attr |= SHF_ALLOC; 758 break; 759 case 'w': 760 attr |= SHF_WRITE; 761 break; 762 case 'x': 763 attr |= SHF_EXECINSTR; 764 break; 765 case 'M': 766 attr |= SHF_MERGE; 767 break; 768 case 'S': 769 attr |= SHF_STRINGS; 770 break; 771 case 'G': 772 attr |= SHF_GROUP; 773 break; 774 /* Compatibility. */ 775 case 'm': 776 if (*(str - 1) == 'a') 777 { 778 attr |= SHF_MERGE; 779 if (len > 1 && str[1] == 's') 780 { 781 attr |= SHF_STRINGS; 782 str++, len--; 783 } 784 break; 785 } 786 default: 787 { 788 char *bad_msg = _("unrecognized .section attribute: want a,w,x,M,S,G"); 789#ifdef md_elf_section_letter 790 int md_attr = md_elf_section_letter (*str, &bad_msg); 791 if (md_attr >= 0) 792 attr |= md_attr; 793 else 794#endif 795 { 796 as_warn ("%s", bad_msg); 797 attr = -1; 798 } 799 } 800 break; 801 } 802 str++, len--; 803 } 804 805 return attr; 806} 807 808static int 809obj_elf_section_word (str, len) 810 char *str; 811 size_t len; 812{ 813 if (len == 5 && strncmp (str, "write", 5) == 0) 814 return SHF_WRITE; 815 if (len == 5 && strncmp (str, "alloc", 5) == 0) 816 return SHF_ALLOC; 817 if (len == 9 && strncmp (str, "execinstr", 9) == 0) 818 return SHF_EXECINSTR; 819 820#ifdef md_elf_section_word 821 { 822 int md_attr = md_elf_section_word (str, len); 823 if (md_attr >= 0) 824 return md_attr; 825 } 826#endif 827 828 as_warn (_("unrecognized section attribute")); 829 return 0; 830} 831 832static int 833obj_elf_section_type (str, len) 834 char *str; 835 size_t len; 836{ 837 if (len == 8 && strncmp (str, "progbits", 8) == 0) 838 return SHT_PROGBITS; 839 if (len == 6 && strncmp (str, "nobits", 6) == 0) 840 return SHT_NOBITS; 841 842#ifdef md_elf_section_type 843 { 844 int md_type = md_elf_section_type (str, len); 845 if (md_type >= 0) 846 return md_type; 847 } 848#endif 849 850 as_warn (_("unrecognized section type")); 851 return 0; 852} 853 854/* Get name of section. */ 855static char * 856obj_elf_section_name () 857{ 858 char *name; 859 860 SKIP_WHITESPACE (); 861 if (*input_line_pointer == '"') 862 { 863 int dummy; 864 865 name = demand_copy_C_string (&dummy); 866 if (name == NULL) 867 { 868 ignore_rest_of_line (); 869 return NULL; 870 } 871 } 872 else 873 { 874 char *end = input_line_pointer; 875 876 while (0 == strchr ("\n\t,; ", *end)) 877 end++; 878 if (end == input_line_pointer) 879 { 880 as_warn (_("missing name")); 881 ignore_rest_of_line (); 882 return NULL; 883 } 884 885 name = xmalloc (end - input_line_pointer + 1); 886 memcpy (name, input_line_pointer, end - input_line_pointer); 887 name[end - input_line_pointer] = '\0'; 888 input_line_pointer = end; 889 } 890 SKIP_WHITESPACE (); 891 return name; 892} 893 894void 895obj_elf_section (push) 896 int push; 897{ 898 char *name, *group_name, *beg; 899 int type, attr, dummy; 900 int entsize; 901 902#ifndef TC_I370 903 if (flag_mri) 904 { 905 char mri_type; 906 907#ifdef md_flush_pending_output 908 md_flush_pending_output (); 909#endif 910 911 previous_section = now_seg; 912 previous_subsection = now_subseg; 913 914 s_mri_sect (&mri_type); 915 916#ifdef md_elf_section_change_hook 917 md_elf_section_change_hook (); 918#endif 919 920 return; 921 } 922#endif /* ! defined (TC_I370) */ 923 924 name = obj_elf_section_name (); 925 if (name == NULL) 926 return; 927 type = SHT_NULL; 928 attr = 0; 929 group_name = NULL; 930 entsize = 0; 931 932 if (*input_line_pointer == ',') 933 { 934 /* Skip the comma. */ 935 ++input_line_pointer; 936 SKIP_WHITESPACE (); 937 938 if (*input_line_pointer == '"') 939 { 940 beg = demand_copy_C_string (&dummy); 941 if (beg == NULL) 942 { 943 ignore_rest_of_line (); 944 return; 945 } 946 attr |= obj_elf_parse_section_letters (beg, strlen (beg)); 947 948 SKIP_WHITESPACE (); 949 if (*input_line_pointer == ',') 950 { 951 char c; 952 char *save = input_line_pointer; 953 954 ++input_line_pointer; 955 SKIP_WHITESPACE (); 956 c = *input_line_pointer; 957 if (c == '"') 958 { 959 beg = demand_copy_C_string (&dummy); 960 if (beg == NULL) 961 { 962 ignore_rest_of_line (); 963 return; 964 } 965 type = obj_elf_section_type (beg, strlen (beg)); 966 } 967 else if (c == '@' || c == '%') 968 { 969 beg = ++input_line_pointer; 970 c = get_symbol_end (); 971 *input_line_pointer = c; 972 type = obj_elf_section_type (beg, input_line_pointer - beg); 973 } 974 else 975 input_line_pointer = save; 976 } 977 978 SKIP_WHITESPACE (); 979 if ((attr & SHF_MERGE) != 0 && *input_line_pointer == ',') 980 { 981 ++input_line_pointer; 982 SKIP_WHITESPACE (); 983 entsize = get_absolute_expression (); 984 SKIP_WHITESPACE (); 985 if (entsize < 0) 986 { 987 as_warn (_("invalid merge entity size")); 988 attr &= ~SHF_MERGE; 989 entsize = 0; 990 } 991 } 992 else if ((attr & SHF_MERGE) != 0) 993 { 994 as_warn (_("entity size for SHF_MERGE not specified")); 995 attr &= ~SHF_MERGE; 996 } 997 998 if ((attr & SHF_GROUP) != 0 && *input_line_pointer == ',') 999 { 1000 ++input_line_pointer; 1001 group_name = obj_elf_section_name (); 1002 if (group_name == NULL) 1003 attr &= ~SHF_GROUP; 1004 } 1005 else if ((attr & SHF_GROUP) != 0) 1006 { 1007 as_warn (_("group name for SHF_GROUP not specified")); 1008 attr &= ~SHF_GROUP; 1009 } 1010 } 1011 else 1012 { 1013 do 1014 { 1015 char c; 1016 1017 SKIP_WHITESPACE (); 1018 if (*input_line_pointer != '#') 1019 { 1020 as_warn (_("character following name is not '#'")); 1021 ignore_rest_of_line (); 1022 return; 1023 } 1024 beg = ++input_line_pointer; 1025 c = get_symbol_end (); 1026 *input_line_pointer = c; 1027 1028 attr |= obj_elf_section_word (beg, input_line_pointer - beg); 1029 1030 SKIP_WHITESPACE (); 1031 } 1032 while (*input_line_pointer++ == ','); 1033 --input_line_pointer; 1034 } 1035 } 1036 1037 demand_empty_rest_of_line (); 1038 1039 obj_elf_change_section (name, type, attr, entsize, group_name, push); 1040} 1041 1042/* Change to the .data section. */ 1043 1044void 1045obj_elf_data (i) 1046 int i; 1047{ 1048#ifdef md_flush_pending_output 1049 md_flush_pending_output (); 1050#endif 1051 1052 previous_section = now_seg; 1053 previous_subsection = now_subseg; 1054 s_data (i); 1055 1056#ifdef md_elf_section_change_hook 1057 md_elf_section_change_hook (); 1058#endif 1059} 1060 1061/* Change to the .text section. */ 1062 1063void 1064obj_elf_text (i) 1065 int i; 1066{ 1067#ifdef md_flush_pending_output 1068 md_flush_pending_output (); 1069#endif 1070 1071 previous_section = now_seg; 1072 previous_subsection = now_subseg; 1073 s_text (i); 1074 1075#ifdef md_elf_section_change_hook 1076 md_elf_section_change_hook (); 1077#endif 1078} 1079 1080static void 1081obj_elf_subsection (ignore) 1082 int ignore ATTRIBUTE_UNUSED; 1083{ 1084 register int temp; 1085 1086#ifdef md_flush_pending_output 1087 md_flush_pending_output (); 1088#endif 1089 1090 previous_section = now_seg; 1091 previous_subsection = now_subseg; 1092 1093 temp = get_absolute_expression (); 1094 subseg_set (now_seg, (subsegT) temp); 1095 demand_empty_rest_of_line (); 1096 1097#ifdef md_elf_section_change_hook 1098 md_elf_section_change_hook (); 1099#endif 1100} 1101 1102/* This can be called from the processor backends if they change 1103 sections. */ 1104 1105void 1106obj_elf_section_change_hook () 1107{ 1108 previous_section = now_seg; 1109 previous_subsection = now_subseg; 1110} 1111 1112void 1113obj_elf_previous (ignore) 1114 int ignore ATTRIBUTE_UNUSED; 1115{ 1116 segT new_section; 1117 int new_subsection; 1118 1119 if (previous_section == 0) 1120 { 1121 as_warn (_(".previous without corresponding .section; ignored")); 1122 return; 1123 } 1124 1125#ifdef md_flush_pending_output 1126 md_flush_pending_output (); 1127#endif 1128 1129 new_section = previous_section; 1130 new_subsection = previous_subsection; 1131 previous_section = now_seg; 1132 previous_subsection = now_subseg; 1133 subseg_set (new_section, new_subsection); 1134 1135#ifdef md_elf_section_change_hook 1136 md_elf_section_change_hook (); 1137#endif 1138} 1139 1140static void 1141obj_elf_popsection (xxx) 1142 int xxx ATTRIBUTE_UNUSED; 1143{ 1144 struct section_stack *top = section_stack; 1145 1146 if (top == NULL) 1147 { 1148 as_warn (_(".popsection without corresponding .pushsection; ignored")); 1149 return; 1150 } 1151 1152#ifdef md_flush_pending_output 1153 md_flush_pending_output (); 1154#endif 1155 1156 section_stack = top->next; 1157 previous_section = top->prev_seg; 1158 previous_subsection = top->prev_subseg; 1159 subseg_set (top->seg, top->subseg); 1160 free (top); 1161 1162#ifdef md_elf_section_change_hook 1163 md_elf_section_change_hook (); 1164#endif 1165} 1166 1167static void 1168obj_elf_line (ignore) 1169 int ignore ATTRIBUTE_UNUSED; 1170{ 1171 /* Assume delimiter is part of expression. BSD4.2 as fails with 1172 delightful bug, so we are not being incompatible here. */ 1173 new_logical_line ((char *) NULL, (int) (get_absolute_expression ())); 1174 demand_empty_rest_of_line (); 1175} 1176 1177/* This handles the .symver pseudo-op, which is used to specify a 1178 symbol version. The syntax is ``.symver NAME,SYMVERNAME''. 1179 SYMVERNAME may contain ELF_VER_CHR ('@') characters. This 1180 pseudo-op causes the assembler to emit a symbol named SYMVERNAME 1181 with the same value as the symbol NAME. */ 1182 1183static void 1184obj_elf_symver (ignore) 1185 int ignore ATTRIBUTE_UNUSED; 1186{ 1187 char *name; 1188 char c; 1189 char old_lexat; 1190 symbolS *sym; 1191 1192 name = input_line_pointer; 1193 c = get_symbol_end (); 1194 1195 sym = symbol_find_or_make (name); 1196 1197 *input_line_pointer = c; 1198 1199 SKIP_WHITESPACE (); 1200 if (*input_line_pointer != ',') 1201 { 1202 as_bad (_("expected comma after name in .symver")); 1203 ignore_rest_of_line (); 1204 return; 1205 } 1206 1207 ++input_line_pointer; 1208 name = input_line_pointer; 1209 1210 /* Temporarily include '@' in symbol names. */ 1211 old_lexat = lex_type[(unsigned char) '@']; 1212 lex_type[(unsigned char) '@'] |= LEX_NAME; 1213 c = get_symbol_end (); 1214 lex_type[(unsigned char) '@'] = old_lexat; 1215 1216 if (symbol_get_obj (sym)->versioned_name == NULL) 1217 { 1218 symbol_get_obj (sym)->versioned_name = xstrdup (name); 1219 1220 *input_line_pointer = c; 1221 1222 if (strchr (symbol_get_obj (sym)->versioned_name, 1223 ELF_VER_CHR) == NULL) 1224 { 1225 as_bad (_("missing version name in `%s' for symbol `%s'"), 1226 symbol_get_obj (sym)->versioned_name, 1227 S_GET_NAME (sym)); 1228 ignore_rest_of_line (); 1229 return; 1230 } 1231 } 1232 else 1233 { 1234 if (strcmp (symbol_get_obj (sym)->versioned_name, name)) 1235 { 1236 as_bad (_("multiple versions [`%s'|`%s'] for symbol `%s'"), 1237 name, symbol_get_obj (sym)->versioned_name, 1238 S_GET_NAME (sym)); 1239 ignore_rest_of_line (); 1240 return; 1241 } 1242 1243 *input_line_pointer = c; 1244 } 1245 1246 demand_empty_rest_of_line (); 1247} 1248 1249/* This handles the .vtable_inherit pseudo-op, which is used to indicate 1250 to the linker the hierarchy in which a particular table resides. The 1251 syntax is ".vtable_inherit CHILDNAME, PARENTNAME". */ 1252 1253struct fix * 1254obj_elf_vtable_inherit (ignore) 1255 int ignore ATTRIBUTE_UNUSED; 1256{ 1257 char *cname, *pname; 1258 symbolS *csym, *psym; 1259 char c, bad = 0; 1260 1261 if (*input_line_pointer == '#') 1262 ++input_line_pointer; 1263 1264 cname = input_line_pointer; 1265 c = get_symbol_end (); 1266 csym = symbol_find (cname); 1267 1268 /* GCFIXME: should check that we don't have two .vtable_inherits for 1269 the same child symbol. Also, we can currently only do this if the 1270 child symbol is already exists and is placed in a fragment. */ 1271 1272 if (csym == NULL || symbol_get_frag (csym) == NULL) 1273 { 1274 as_bad ("expected `%s' to have already been set for .vtable_inherit", 1275 cname); 1276 bad = 1; 1277 } 1278 1279 *input_line_pointer = c; 1280 1281 SKIP_WHITESPACE (); 1282 if (*input_line_pointer != ',') 1283 { 1284 as_bad ("expected comma after name in .vtable_inherit"); 1285 ignore_rest_of_line (); 1286 return NULL; 1287 } 1288 1289 ++input_line_pointer; 1290 SKIP_WHITESPACE (); 1291 1292 if (*input_line_pointer == '#') 1293 ++input_line_pointer; 1294 1295 if (input_line_pointer[0] == '0' 1296 && (input_line_pointer[1] == '\0' 1297 || ISSPACE (input_line_pointer[1]))) 1298 { 1299 psym = section_symbol (absolute_section); 1300 ++input_line_pointer; 1301 } 1302 else 1303 { 1304 pname = input_line_pointer; 1305 c = get_symbol_end (); 1306 psym = symbol_find_or_make (pname); 1307 *input_line_pointer = c; 1308 } 1309 1310 demand_empty_rest_of_line (); 1311 1312 if (bad) 1313 return NULL; 1314 1315 assert (symbol_get_value_expression (csym)->X_op == O_constant); 1316 return fix_new (symbol_get_frag (csym), 1317 symbol_get_value_expression (csym)->X_add_number, 1318 0, psym, 0, 0, BFD_RELOC_VTABLE_INHERIT); 1319} 1320 1321/* This handles the .vtable_entry pseudo-op, which is used to indicate 1322 to the linker that a vtable slot was used. The syntax is 1323 ".vtable_entry tablename, offset". */ 1324 1325struct fix * 1326obj_elf_vtable_entry (ignore) 1327 int ignore ATTRIBUTE_UNUSED; 1328{ 1329 char *name; 1330 symbolS *sym; 1331 offsetT offset; 1332 char c; 1333 1334 if (*input_line_pointer == '#') 1335 ++input_line_pointer; 1336 1337 name = input_line_pointer; 1338 c = get_symbol_end (); 1339 sym = symbol_find_or_make (name); 1340 *input_line_pointer = c; 1341 1342 SKIP_WHITESPACE (); 1343 if (*input_line_pointer != ',') 1344 { 1345 as_bad ("expected comma after name in .vtable_entry"); 1346 ignore_rest_of_line (); 1347 return NULL; 1348 } 1349 1350 ++input_line_pointer; 1351 if (*input_line_pointer == '#') 1352 ++input_line_pointer; 1353 1354 offset = get_absolute_expression (); 1355 1356 demand_empty_rest_of_line (); 1357 1358 return fix_new (frag_now, frag_now_fix (), 0, sym, offset, 0, 1359 BFD_RELOC_VTABLE_ENTRY); 1360} 1361 1362void 1363elf_obj_read_begin_hook () 1364{ 1365#ifdef NEED_ECOFF_DEBUG 1366 if (ECOFF_DEBUGGING) 1367 ecoff_read_begin_hook (); 1368#endif 1369} 1370 1371void 1372elf_obj_symbol_new_hook (symbolP) 1373 symbolS *symbolP; 1374{ 1375 struct elf_obj_sy *sy_obj; 1376 1377 sy_obj = symbol_get_obj (symbolP); 1378 sy_obj->size = NULL; 1379 sy_obj->versioned_name = NULL; 1380 1381#ifdef NEED_ECOFF_DEBUG 1382 if (ECOFF_DEBUGGING) 1383 ecoff_symbol_new_hook (symbolP); 1384#endif 1385} 1386 1387/* When setting one symbol equal to another, by default we probably 1388 want them to have the same "size", whatever it means in the current 1389 context. */ 1390 1391void 1392elf_copy_symbol_attributes (dest, src) 1393 symbolS *dest, *src; 1394{ 1395 struct elf_obj_sy *srcelf = symbol_get_obj (src); 1396 struct elf_obj_sy *destelf = symbol_get_obj (dest); 1397 if (srcelf->size) 1398 { 1399 if (destelf->size == NULL) 1400 destelf->size = 1401 (expressionS *) xmalloc (sizeof (expressionS)); 1402 *destelf->size = *srcelf->size; 1403 } 1404 else 1405 { 1406 if (destelf->size != NULL) 1407 free (destelf->size); 1408 destelf->size = NULL; 1409 } 1410 S_SET_SIZE (dest, S_GET_SIZE (src)); 1411 S_SET_OTHER (dest, S_GET_OTHER (src)); 1412} 1413 1414void 1415obj_elf_version (ignore) 1416 int ignore ATTRIBUTE_UNUSED; 1417{ 1418 char *name; 1419 unsigned int c; 1420 char *p; 1421 asection *seg = now_seg; 1422 subsegT subseg = now_subseg; 1423 Elf_Internal_Note i_note; 1424 Elf_External_Note e_note; 1425 asection *note_secp = (asection *) NULL; 1426 int len; 1427 1428 SKIP_WHITESPACE (); 1429 if (*input_line_pointer == '\"') 1430 { 1431 ++input_line_pointer; /* -> 1st char of string. */ 1432 name = input_line_pointer; 1433 1434 while (is_a_char (c = next_char_of_string ())) 1435 ; 1436 c = *input_line_pointer; 1437 *input_line_pointer = '\0'; 1438 *(input_line_pointer - 1) = '\0'; 1439 *input_line_pointer = c; 1440 1441 /* create the .note section */ 1442 1443 note_secp = subseg_new (".note", 0); 1444 bfd_set_section_flags (stdoutput, 1445 note_secp, 1446 SEC_HAS_CONTENTS | SEC_READONLY); 1447 1448 /* process the version string */ 1449 1450 len = strlen (name); 1451 1452 i_note.namesz = ((len + 1) + 3) & ~3; /* round this to word boundary */ 1453 i_note.descsz = 0; /* no description */ 1454 i_note.type = NT_VERSION; 1455 p = frag_more (sizeof (e_note.namesz)); 1456 md_number_to_chars (p, (valueT) i_note.namesz, sizeof (e_note.namesz)); 1457 p = frag_more (sizeof (e_note.descsz)); 1458 md_number_to_chars (p, (valueT) i_note.descsz, sizeof (e_note.descsz)); 1459 p = frag_more (sizeof (e_note.type)); 1460 md_number_to_chars (p, (valueT) i_note.type, sizeof (e_note.type)); 1461 p = frag_more (len + 1); 1462 strcpy (p, name); 1463 1464 frag_align (2, 0, 0); 1465 1466 subseg_set (seg, subseg); 1467 } 1468 else 1469 { 1470 as_bad (_("expected quoted string")); 1471 } 1472 demand_empty_rest_of_line (); 1473} 1474 1475static void 1476obj_elf_size (ignore) 1477 int ignore ATTRIBUTE_UNUSED; 1478{ 1479 char *name = input_line_pointer; 1480 char c = get_symbol_end (); 1481 char *p; 1482 expressionS exp; 1483 symbolS *sym; 1484 1485 p = input_line_pointer; 1486 *p = c; 1487 SKIP_WHITESPACE (); 1488 if (*input_line_pointer != ',') 1489 { 1490 *p = 0; 1491 as_bad (_("expected comma after name `%s' in .size directive"), name); 1492 *p = c; 1493 ignore_rest_of_line (); 1494 return; 1495 } 1496 input_line_pointer++; 1497 expression (&exp); 1498 if (exp.X_op == O_absent) 1499 { 1500 as_bad (_("missing expression in .size directive")); 1501 exp.X_op = O_constant; 1502 exp.X_add_number = 0; 1503 } 1504 *p = 0; 1505 sym = symbol_find_or_make (name); 1506 *p = c; 1507 if (exp.X_op == O_constant) 1508 { 1509 S_SET_SIZE (sym, exp.X_add_number); 1510 if (symbol_get_obj (sym)->size) 1511 { 1512 xfree (symbol_get_obj (sym)->size); 1513 symbol_get_obj (sym)->size = NULL; 1514 } 1515 } 1516 else 1517 { 1518 symbol_get_obj (sym)->size = 1519 (expressionS *) xmalloc (sizeof (expressionS)); 1520 *symbol_get_obj (sym)->size = exp; 1521 } 1522 demand_empty_rest_of_line (); 1523} 1524 1525/* Handle the ELF .type pseudo-op. This sets the type of a symbol. 1526 There are five syntaxes: 1527 1528 The first (used on Solaris) is 1529 .type SYM,#function 1530 The second (used on UnixWare) is 1531 .type SYM,@function 1532 The third (reportedly to be used on Irix 6.0) is 1533 .type SYM STT_FUNC 1534 The fourth (used on NetBSD/Arm and Linux/ARM) is 1535 .type SYM,%function 1536 The fifth (used on SVR4/860) is 1537 .type SYM,"function" 1538 */ 1539 1540static void 1541obj_elf_type (ignore) 1542 int ignore ATTRIBUTE_UNUSED; 1543{ 1544 char *name; 1545 char c; 1546 int type; 1547 const char *typename; 1548 symbolS *sym; 1549 elf_symbol_type *elfsym; 1550 1551 name = input_line_pointer; 1552 c = get_symbol_end (); 1553 sym = symbol_find_or_make (name); 1554 elfsym = (elf_symbol_type *) symbol_get_bfdsym (sym); 1555 *input_line_pointer = c; 1556 1557 SKIP_WHITESPACE (); 1558 if (*input_line_pointer == ',') 1559 ++input_line_pointer; 1560 1561 SKIP_WHITESPACE (); 1562 if ( *input_line_pointer == '#' 1563 || *input_line_pointer == '@' 1564 || *input_line_pointer == '"' 1565 || *input_line_pointer == '%') 1566 ++input_line_pointer; 1567 1568 typename = input_line_pointer; 1569 c = get_symbol_end (); 1570 1571 type = 0; 1572 if (strcmp (typename, "function") == 0 1573 || strcmp (typename, "STT_FUNC") == 0) 1574 type = BSF_FUNCTION; 1575 else if (strcmp (typename, "object") == 0 1576 || strcmp (typename, "STT_OBJECT") == 0) 1577 type = BSF_OBJECT; 1578#ifdef md_elf_symbol_type 1579 else if ((type = md_elf_symbol_type (typename, sym, elfsym)) != -1) 1580 ; 1581#endif 1582 else 1583 as_bad (_("unrecognized symbol type \"%s\""), typename); 1584 1585 *input_line_pointer = c; 1586 1587 if (*input_line_pointer == '"') 1588 ++input_line_pointer; 1589 1590 elfsym->symbol.flags |= type; 1591 1592 demand_empty_rest_of_line (); 1593} 1594 1595static void 1596obj_elf_ident (ignore) 1597 int ignore ATTRIBUTE_UNUSED; 1598{ 1599 static segT comment_section; 1600 segT old_section = now_seg; 1601 int old_subsection = now_subseg; 1602 1603#ifdef md_flush_pending_output 1604 md_flush_pending_output (); 1605#endif 1606 1607 if (!comment_section) 1608 { 1609 char *p; 1610 comment_section = subseg_new (".comment", 0); 1611 bfd_set_section_flags (stdoutput, comment_section, 1612 SEC_READONLY | SEC_HAS_CONTENTS); 1613 p = frag_more (1); 1614 *p = 0; 1615 } 1616 else 1617 subseg_set (comment_section, 0); 1618 stringer (1); 1619 subseg_set (old_section, old_subsection); 1620} 1621 1622#ifdef INIT_STAB_SECTION 1623 1624/* The first entry in a .stabs section is special. */ 1625 1626void 1627obj_elf_init_stab_section (seg) 1628 segT seg; 1629{ 1630 char *file; 1631 char *p; 1632 char *stabstr_name; 1633 unsigned int stroff; 1634 1635 /* Force the section to align to a longword boundary. Without this, 1636 UnixWare ar crashes. */ 1637 bfd_set_section_alignment (stdoutput, seg, 2); 1638 1639 /* Make space for this first symbol. */ 1640 p = frag_more (12); 1641 /* Zero it out. */ 1642 memset (p, 0, 12); 1643 as_where (&file, (unsigned int *) NULL); 1644 stabstr_name = (char *) xmalloc (strlen (segment_name (seg)) + 4); 1645 strcpy (stabstr_name, segment_name (seg)); 1646 strcat (stabstr_name, "str"); 1647 stroff = get_stab_string_offset (file, stabstr_name); 1648 know (stroff == 1); 1649 md_number_to_chars (p, stroff, 4); 1650 seg_info (seg)->stabu.p = p; 1651} 1652 1653#endif 1654 1655/* Fill in the counts in the first entry in a .stabs section. */ 1656 1657static void 1658adjust_stab_sections (abfd, sec, xxx) 1659 bfd *abfd; 1660 asection *sec; 1661 PTR xxx ATTRIBUTE_UNUSED; 1662{ 1663 char *name; 1664 asection *strsec; 1665 char *p; 1666 int strsz, nsyms; 1667 1668 if (strncmp (".stab", sec->name, 5)) 1669 return; 1670 if (!strcmp ("str", sec->name + strlen (sec->name) - 3)) 1671 return; 1672 1673 name = (char *) alloca (strlen (sec->name) + 4); 1674 strcpy (name, sec->name); 1675 strcat (name, "str"); 1676 strsec = bfd_get_section_by_name (abfd, name); 1677 if (strsec) 1678 strsz = bfd_section_size (abfd, strsec); 1679 else 1680 strsz = 0; 1681 nsyms = bfd_section_size (abfd, sec) / 12 - 1; 1682 1683 p = seg_info (sec)->stabu.p; 1684 assert (p != 0); 1685 1686 bfd_h_put_16 (abfd, (bfd_vma) nsyms, (bfd_byte *) p + 6); 1687 bfd_h_put_32 (abfd, (bfd_vma) strsz, (bfd_byte *) p + 8); 1688} 1689 1690#ifdef NEED_ECOFF_DEBUG 1691 1692/* This function is called by the ECOFF code. It is supposed to 1693 record the external symbol information so that the backend can 1694 write it out correctly. The ELF backend doesn't actually handle 1695 this at the moment, so we do it ourselves. We save the information 1696 in the symbol. */ 1697 1698void 1699elf_ecoff_set_ext (sym, ext) 1700 symbolS *sym; 1701 struct ecoff_extr *ext; 1702{ 1703 symbol_get_bfdsym (sym)->udata.p = (PTR) ext; 1704} 1705 1706/* This function is called by bfd_ecoff_debug_externals. It is 1707 supposed to *EXT to the external symbol information, and return 1708 whether the symbol should be used at all. */ 1709 1710static boolean 1711elf_get_extr (sym, ext) 1712 asymbol *sym; 1713 EXTR *ext; 1714{ 1715 if (sym->udata.p == NULL) 1716 return false; 1717 *ext = *(EXTR *) sym->udata.p; 1718 return true; 1719} 1720 1721/* This function is called by bfd_ecoff_debug_externals. It has 1722 nothing to do for ELF. */ 1723 1724/*ARGSUSED*/ 1725static void 1726elf_set_index (sym, indx) 1727 asymbol *sym ATTRIBUTE_UNUSED; 1728 bfd_size_type indx ATTRIBUTE_UNUSED; 1729{ 1730} 1731 1732#endif /* NEED_ECOFF_DEBUG */ 1733 1734void 1735elf_frob_symbol (symp, puntp) 1736 symbolS *symp; 1737 int *puntp; 1738{ 1739 struct elf_obj_sy *sy_obj; 1740 1741#ifdef NEED_ECOFF_DEBUG 1742 if (ECOFF_DEBUGGING) 1743 ecoff_frob_symbol (symp); 1744#endif 1745 1746 sy_obj = symbol_get_obj (symp); 1747 1748 if (sy_obj->size != NULL) 1749 { 1750 switch (sy_obj->size->X_op) 1751 { 1752 case O_subtract: 1753 S_SET_SIZE (symp, 1754 (S_GET_VALUE (sy_obj->size->X_add_symbol) 1755 + sy_obj->size->X_add_number 1756 - S_GET_VALUE (sy_obj->size->X_op_symbol))); 1757 break; 1758 case O_constant: 1759 S_SET_SIZE (symp, 1760 (S_GET_VALUE (sy_obj->size->X_add_symbol) 1761 + sy_obj->size->X_add_number)); 1762 break; 1763 default: 1764 as_bad (_(".size expression too complicated to fix up")); 1765 break; 1766 } 1767 free (sy_obj->size); 1768 sy_obj->size = NULL; 1769 } 1770 1771 if (sy_obj->versioned_name != NULL) 1772 { 1773 char *p; 1774 1775 p = strchr (sy_obj->versioned_name, ELF_VER_CHR); 1776 know (p != NULL); 1777 1778 /* This symbol was given a new name with the .symver directive. 1779 1780 If this is an external reference, just rename the symbol to 1781 include the version string. This will make the relocs be 1782 against the correct versioned symbol. 1783 1784 If this is a definition, add an alias. FIXME: Using an alias 1785 will permit the debugging information to refer to the right 1786 symbol. However, it's not clear whether it is the best 1787 approach. */ 1788 1789 if (! S_IS_DEFINED (symp)) 1790 { 1791 /* Verify that the name isn't using the @@ syntax--this is 1792 reserved for definitions of the default version to link 1793 against. */ 1794 if (p[1] == ELF_VER_CHR) 1795 { 1796 as_bad (_("invalid attempt to declare external version name as default in symbol `%s'"), 1797 sy_obj->versioned_name); 1798 *puntp = true; 1799 } 1800 S_SET_NAME (symp, sy_obj->versioned_name); 1801 } 1802 else 1803 { 1804 if (p [1] == ELF_VER_CHR && p [2] == ELF_VER_CHR) 1805 { 1806 size_t l; 1807 1808 /* The @@@ syntax is a special case. It renames the 1809 symbol name to versioned_name with one `@' removed. */ 1810 l = strlen (&p[3]) + 1; 1811 memmove (&p [2], &p[3], l); 1812 S_SET_NAME (symp, sy_obj->versioned_name); 1813 } 1814 else 1815 { 1816 symbolS *symp2; 1817 1818 /* FIXME: Creating a new symbol here is risky. We're 1819 in the final loop over the symbol table. We can 1820 get away with it only because the symbol goes to 1821 the end of the list, where the loop will still see 1822 it. It would probably be better to do this in 1823 obj_frob_file_before_adjust. */ 1824 1825 symp2 = symbol_find_or_make (sy_obj->versioned_name); 1826 1827 /* Now we act as though we saw symp2 = sym. */ 1828 1829 S_SET_SEGMENT (symp2, S_GET_SEGMENT (symp)); 1830 1831 /* Subtracting out the frag address here is a hack 1832 because we are in the middle of the final loop. */ 1833 S_SET_VALUE (symp2, 1834 (S_GET_VALUE (symp) 1835 - symbol_get_frag (symp)->fr_address)); 1836 1837 symbol_set_frag (symp2, symbol_get_frag (symp)); 1838 1839 /* This will copy over the size information. */ 1840 copy_symbol_attributes (symp2, symp); 1841 1842 if (S_IS_WEAK (symp)) 1843 S_SET_WEAK (symp2); 1844 1845 if (S_IS_EXTERNAL (symp)) 1846 S_SET_EXTERNAL (symp2); 1847 } 1848 } 1849 } 1850 1851 /* Double check weak symbols. */ 1852 if (S_IS_WEAK (symp)) 1853 { 1854 if (S_IS_COMMON (symp)) 1855 as_bad (_("symbol `%s' can not be both weak and common"), 1856 S_GET_NAME (symp)); 1857 } 1858 1859#ifdef TC_MIPS 1860 /* The Irix 5 and 6 assemblers set the type of any common symbol and 1861 any undefined non-function symbol to STT_OBJECT. We try to be 1862 compatible, since newer Irix 5 and 6 linkers care. However, we 1863 only set undefined symbols to be STT_OBJECT if we are on Irix, 1864 because that is the only time gcc will generate the necessary 1865 .global directives to mark functions. */ 1866 1867 if (S_IS_COMMON (symp)) 1868 symbol_get_bfdsym (symp)->flags |= BSF_OBJECT; 1869 1870 if (strstr (TARGET_OS, "irix") != NULL 1871 && ! S_IS_DEFINED (symp) 1872 && (symbol_get_bfdsym (symp)->flags & BSF_FUNCTION) == 0) 1873 symbol_get_bfdsym (symp)->flags |= BSF_OBJECT; 1874#endif 1875 1876#if 0 /* TC_PPC */ 1877 /* If TC_PPC is defined, we used to force the type of a symbol to be 1878 BSF_OBJECT if it was otherwise unset. This was required by some 1879 version of VxWorks. Thomas de Lellis <tdel@windriver.com> says 1880 that this is no longer needed, so it is now commented out. */ 1881 if ((symbol_get_bfdsym (symp)->flags 1882 & (BSF_FUNCTION | BSF_FILE | BSF_SECTION_SYM)) == 0 1883 && S_IS_DEFINED (symp)) 1884 symbol_get_bfdsym (symp)->flags |= BSF_OBJECT; 1885#endif 1886} 1887 1888struct group_list 1889{ 1890 asection **head; /* Section lists. */ 1891 unsigned int *elt_count; /* Number of sections in each list. */ 1892 unsigned int num_group; /* Number of lists. */ 1893}; 1894 1895/* Called via bfd_map_over_sections. If SEC is a member of a group, 1896 add it to a list of sections belonging to the group. INF is a 1897 pointer to a struct group_list, which is where we store the head of 1898 each list. */ 1899 1900static void 1901build_group_lists (abfd, sec, inf) 1902 bfd *abfd ATTRIBUTE_UNUSED; 1903 asection *sec; 1904 PTR inf; 1905{ 1906 struct group_list *list = (struct group_list *) inf; 1907 const char *group_name = elf_group_name (sec); 1908 unsigned int i; 1909 1910 if (group_name == NULL) 1911 return; 1912 1913 /* If this group already has a list, add the section to the head of 1914 the list. */ 1915 for (i = 0; i < list->num_group; i++) 1916 { 1917 if (strcmp (group_name, elf_group_name (list->head[i])) == 0) 1918 { 1919 elf_next_in_group (sec) = list->head[i]; 1920 list->head[i] = sec; 1921 list->elt_count[i] += 1; 1922 return; 1923 } 1924 } 1925 1926 /* New group. Make the arrays bigger in chunks to minimize calls to 1927 realloc. */ 1928 i = list->num_group; 1929 if ((i & 127) == 0) 1930 { 1931 unsigned int newsize = i + 128; 1932 list->head = xrealloc (list->head, newsize * sizeof (*list->head)); 1933 list->elt_count = xrealloc (list->elt_count, 1934 newsize * sizeof (*list->elt_count)); 1935 } 1936 list->head[i] = sec; 1937 list->elt_count[i] = 1; 1938 list->num_group += 1; 1939} 1940 1941void 1942elf_frob_file () 1943{ 1944 struct group_list list; 1945 unsigned int i; 1946 1947 bfd_map_over_sections (stdoutput, adjust_stab_sections, (PTR) 0); 1948 1949 /* Go find section groups. */ 1950 list.num_group = 0; 1951 list.head = NULL; 1952 list.elt_count = NULL; 1953 bfd_map_over_sections (stdoutput, build_group_lists, (PTR) &list); 1954 1955 /* Make the SHT_GROUP sections that describe each section group. We 1956 can't set up the section contents here yet, because elf section 1957 indices have yet to be calculated. elf.c:set_group_contents does 1958 the rest of the work. */ 1959 for (i = 0; i < list.num_group; i++) 1960 { 1961 const char *group_name = elf_group_name (list.head[i]); 1962 asection *s; 1963 flagword flags; 1964 1965 s = subseg_force_new (group_name, 0); 1966 flags = SEC_READONLY | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_GROUP; 1967 if (s == NULL 1968 || !bfd_set_section_flags (stdoutput, s, flags) 1969 || !bfd_set_section_alignment (stdoutput, s, 2)) 1970 { 1971 as_fatal (_("can't create group: %s"), 1972 bfd_errmsg (bfd_get_error ())); 1973 } 1974 1975 /* Pass a pointer to the first section in this group. */ 1976 elf_next_in_group (s) = list.head[i]; 1977 1978 s->_raw_size = 4 * (list.elt_count[i] + 1); 1979 s->contents = frag_more (s->_raw_size); 1980 frag_now->fr_fix = frag_now_fix_octets (); 1981 } 1982 1983#ifdef elf_tc_final_processing 1984 elf_tc_final_processing (); 1985#endif 1986} 1987 1988/* It removes any unneeded versioned symbols from the symbol table. */ 1989 1990void 1991elf_frob_file_before_adjust () 1992{ 1993 if (symbol_rootP) 1994 { 1995 symbolS *symp; 1996 1997 for (symp = symbol_rootP; symp; symp = symbol_next (symp)) 1998 if (symbol_get_obj (symp)->versioned_name) 1999 { 2000 if (!S_IS_DEFINED (symp)) 2001 { 2002 char *p; 2003 2004 /* The @@@ syntax is a special case. If the symbol is 2005 not defined, 2 `@'s will be removed from the 2006 versioned_name. */ 2007 2008 p = strchr (symbol_get_obj (symp)->versioned_name, 2009 ELF_VER_CHR); 2010 know (p != NULL); 2011 if (p [1] == ELF_VER_CHR && p [2] == ELF_VER_CHR) 2012 { 2013 size_t l = strlen (&p[3]) + 1; 2014 memmove (&p [1], &p[3], l); 2015 } 2016 if (symbol_used_p (symp) == 0 2017 && symbol_used_in_reloc_p (symp) == 0) 2018 symbol_remove (symp, &symbol_rootP, &symbol_lastP); 2019 } 2020 } 2021 } 2022} 2023 2024/* It is required that we let write_relocs have the opportunity to 2025 optimize away fixups before output has begun, since it is possible 2026 to eliminate all fixups for a section and thus we never should 2027 have generated the relocation section. */ 2028 2029void 2030elf_frob_file_after_relocs () 2031{ 2032#ifdef NEED_ECOFF_DEBUG 2033 if (ECOFF_DEBUGGING) 2034 /* Generate the ECOFF debugging information. */ 2035 { 2036 const struct ecoff_debug_swap *debug_swap; 2037 struct ecoff_debug_info debug; 2038 char *buf; 2039 asection *sec; 2040 2041 debug_swap 2042 = get_elf_backend_data (stdoutput)->elf_backend_ecoff_debug_swap; 2043 know (debug_swap != (const struct ecoff_debug_swap *) NULL); 2044 ecoff_build_debug (&debug.symbolic_header, &buf, debug_swap); 2045 2046 /* Set up the pointers in debug. */ 2047#define SET(ptr, offset, type) \ 2048 debug.ptr = (type) (buf + debug.symbolic_header.offset) 2049 2050 SET (line, cbLineOffset, unsigned char *); 2051 SET (external_dnr, cbDnOffset, PTR); 2052 SET (external_pdr, cbPdOffset, PTR); 2053 SET (external_sym, cbSymOffset, PTR); 2054 SET (external_opt, cbOptOffset, PTR); 2055 SET (external_aux, cbAuxOffset, union aux_ext *); 2056 SET (ss, cbSsOffset, char *); 2057 SET (external_fdr, cbFdOffset, PTR); 2058 SET (external_rfd, cbRfdOffset, PTR); 2059 /* ssext and external_ext are set up just below. */ 2060 2061#undef SET 2062 2063 /* Set up the external symbols. */ 2064 debug.ssext = debug.ssext_end = NULL; 2065 debug.external_ext = debug.external_ext_end = NULL; 2066 if (! bfd_ecoff_debug_externals (stdoutput, &debug, debug_swap, true, 2067 elf_get_extr, elf_set_index)) 2068 as_fatal (_("failed to set up debugging information: %s"), 2069 bfd_errmsg (bfd_get_error ())); 2070 2071 sec = bfd_get_section_by_name (stdoutput, ".mdebug"); 2072 assert (sec != NULL); 2073 2074 know (stdoutput->output_has_begun == false); 2075 2076 /* We set the size of the section, call bfd_set_section_contents 2077 to force the ELF backend to allocate a file position, and then 2078 write out the data. FIXME: Is this really the best way to do 2079 this? */ 2080 sec->_raw_size = bfd_ecoff_debug_size (stdoutput, &debug, debug_swap); 2081 2082 /* Pass BUF to bfd_set_section_contents because this will 2083 eventually become a call to fwrite, and ISO C prohibits 2084 passing a NULL pointer to a stdio function even if the 2085 pointer will not be used. */ 2086 if (! bfd_set_section_contents (stdoutput, sec, (PTR) buf, 2087 (file_ptr) 0, (bfd_size_type) 0)) 2088 as_fatal (_("can't start writing .mdebug section: %s"), 2089 bfd_errmsg (bfd_get_error ())); 2090 2091 know (stdoutput->output_has_begun == true); 2092 know (sec->filepos != 0); 2093 2094 if (! bfd_ecoff_write_debug (stdoutput, &debug, debug_swap, 2095 sec->filepos)) 2096 as_fatal (_("could not write .mdebug section: %s"), 2097 bfd_errmsg (bfd_get_error ())); 2098 } 2099#endif /* NEED_ECOFF_DEBUG */ 2100} 2101 2102#ifdef SCO_ELF 2103 2104/* Heavily plagarized from obj_elf_version. The idea is to emit the 2105 SCO specific identifier in the .notes section to satisfy the SCO 2106 linker. 2107 2108 This looks more complicated than it really is. As opposed to the 2109 "obvious" solution, this should handle the cross dev cases 2110 correctly. (i.e, hosting on a 64 bit big endian processor, but 2111 generating SCO Elf code) Efficiency isn't a concern, as there 2112 should be exactly one of these sections per object module. 2113 2114 SCO OpenServer 5 identifies it's ELF modules with a standard ELF 2115 .note section. 2116 2117 int_32 namesz = 4 ; Name size 2118 int_32 descsz = 12 ; Descriptive information 2119 int_32 type = 1 ; 2120 char name[4] = "SCO" ; Originator name ALWAYS SCO + NULL 2121 int_32 version = (major ver # << 16) | version of tools ; 2122 int_32 source = (tool_id << 16 ) | 1 ; 2123 int_32 info = 0 ; These are set by the SCO tools, but we 2124 don't know enough about the source 2125 environment to set them. SCO ld currently 2126 ignores them, and recommends we set them 2127 to zero. */ 2128 2129#define SCO_MAJOR_VERSION 0x1 2130#define SCO_MINOR_VERSION 0x1 2131 2132void 2133sco_id () 2134{ 2135 2136 char *name; 2137 unsigned int c; 2138 char ch; 2139 char *p; 2140 asection *seg = now_seg; 2141 subsegT subseg = now_subseg; 2142 Elf_Internal_Note i_note; 2143 Elf_External_Note e_note; 2144 asection *note_secp = (asection *) NULL; 2145 int i, len; 2146 2147 /* create the .note section */ 2148 2149 note_secp = subseg_new (".note", 0); 2150 bfd_set_section_flags (stdoutput, 2151 note_secp, 2152 SEC_HAS_CONTENTS | SEC_READONLY); 2153 2154 /* process the version string */ 2155 2156 i_note.namesz = 4; 2157 i_note.descsz = 12; /* 12 descriptive bytes */ 2158 i_note.type = NT_VERSION; /* Contains a version string */ 2159 2160 p = frag_more (sizeof (i_note.namesz)); 2161 md_number_to_chars (p, (valueT) i_note.namesz, 4); 2162 2163 p = frag_more (sizeof (i_note.descsz)); 2164 md_number_to_chars (p, (valueT) i_note.descsz, 4); 2165 2166 p = frag_more (sizeof (i_note.type)); 2167 md_number_to_chars (p, (valueT) i_note.type, 4); 2168 2169 p = frag_more (4); 2170 strcpy (p, "SCO"); 2171 2172 /* Note: this is the version number of the ELF we're representing */ 2173 p = frag_more (4); 2174 md_number_to_chars (p, (SCO_MAJOR_VERSION << 16) | (SCO_MINOR_VERSION), 4); 2175 2176 /* Here, we pick a magic number for ourselves (yes, I "registered" 2177 it with SCO. The bottom bit shows that we are compat with the 2178 SCO ABI. */ 2179 p = frag_more (4); 2180 md_number_to_chars (p, 0x4c520000 | 0x0001, 4); 2181 2182 /* If we knew (or cared) what the source language options were, we'd 2183 fill them in here. SCO has given us permission to ignore these 2184 and just set them to zero. */ 2185 p = frag_more (4); 2186 md_number_to_chars (p, 0x0000, 4); 2187 2188 frag_align (2, 0, 0); 2189 2190 /* We probably can't restore the current segment, for there likely 2191 isn't one yet... */ 2192 if (seg && subseg) 2193 subseg_set (seg, subseg); 2194 2195} 2196 2197#endif /* SCO_ELF */ 2198 2199static int 2200elf_separate_stab_sections () 2201{ 2202#ifdef NEED_ECOFF_DEBUG 2203 return (!ECOFF_DEBUGGING); 2204#else 2205 return 1; 2206#endif 2207} 2208 2209static void 2210elf_init_stab_section (seg) 2211 segT seg; 2212{ 2213#ifdef NEED_ECOFF_DEBUG 2214 if (!ECOFF_DEBUGGING) 2215#endif 2216 obj_elf_init_stab_section (seg); 2217} 2218 2219const struct format_ops elf_format_ops = 2220{ 2221 bfd_target_elf_flavour, 2222 0, /* dfl_leading_underscore */ 2223 1, /* emit_section_symbols */ 2224 elf_begin, 2225 elf_file_symbol, 2226 elf_frob_symbol, 2227 elf_frob_file, 2228 elf_frob_file_before_adjust, 2229 elf_frob_file_after_relocs, 2230 elf_s_get_size, elf_s_set_size, 2231 elf_s_get_align, elf_s_set_align, 2232 elf_s_get_other, 2233 elf_s_set_other, 2234 0, /* s_get_desc */ 2235 0, /* s_set_desc */ 2236 0, /* s_get_type */ 2237 0, /* s_set_type */ 2238 elf_copy_symbol_attributes, 2239#ifdef NEED_ECOFF_DEBUG 2240 ecoff_generate_asm_lineno, 2241 ecoff_stab, 2242#else 2243 0, /* generate_asm_lineno */ 2244 0, /* process_stab */ 2245#endif 2246 elf_separate_stab_sections, 2247 elf_init_stab_section, 2248 elf_sec_sym_ok_for_reloc, 2249 elf_pop_insert, 2250#ifdef NEED_ECOFF_DEBUG 2251 elf_ecoff_set_ext, 2252#else 2253 0, /* ecoff_set_ext */ 2254#endif 2255 elf_obj_read_begin_hook, 2256 elf_obj_symbol_new_hook 2257}; 2258