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