1/* coff object file format 2 Copyright (C) 1989-2022 Free Software Foundation, Inc. 3 4 This file is part of GAS. 5 6 GAS is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3, or (at your option) 9 any later version. 10 11 GAS is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GAS; see the file COPYING. If not, write to the Free 18 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 19 02110-1301, USA. */ 20 21#define OBJ_HEADER "obj-coff.h" 22 23#include "as.h" 24#include "safe-ctype.h" 25#include "subsegs.h" 26 27#ifdef TE_PE 28#include "coff/pe.h" 29#endif 30 31#ifdef OBJ_XCOFF 32#include "coff/xcoff.h" 33#endif 34 35#define streq(a,b) (strcmp ((a), (b)) == 0) 36 37/* I think this is probably always correct. */ 38#ifndef KEEP_RELOC_INFO 39#define KEEP_RELOC_INFO 40#endif 41 42/* obj_coff_section will use this macro to set a new section's 43 attributes when a directive has no valid flags or the "w" flag is 44 used. This default should be appropriate for most. */ 45#ifndef TC_COFF_SECTION_DEFAULT_ATTRIBUTES 46#define TC_COFF_SECTION_DEFAULT_ATTRIBUTES (SEC_LOAD | SEC_DATA) 47#endif 48 49/* This is used to hold the symbol built by a sequence of pseudo-ops 50 from .def and .endef. */ 51static symbolS *def_symbol_in_progress; 52#ifdef TE_PE 53/* PE weak alternate symbols begin with this string. */ 54static const char weak_altprefix[] = ".weak."; 55#endif /* TE_PE */ 56 57#include "obj-coff-seh.c" 58 59typedef struct 60 { 61 unsigned long chunk_size; 62 unsigned long element_size; 63 unsigned long size; 64 char *data; 65 unsigned long pointer; 66 } 67stack; 68 69 70/* Stack stuff. */ 71 72static stack * 73stack_init (unsigned long chunk_size, 74 unsigned long element_size) 75{ 76 stack *st; 77 78 st = XNEW (stack); 79 st->data = XNEWVEC (char, chunk_size); 80 if (!st->data) 81 { 82 free (st); 83 return NULL; 84 } 85 st->pointer = 0; 86 st->size = chunk_size; 87 st->chunk_size = chunk_size; 88 st->element_size = element_size; 89 return st; 90} 91 92static char * 93stack_push (stack *st, char *element) 94{ 95 if (st->pointer + st->element_size >= st->size) 96 { 97 st->size += st->chunk_size; 98 st->data = XRESIZEVEC (char, st->data, st->size); 99 } 100 memcpy (st->data + st->pointer, element, st->element_size); 101 st->pointer += st->element_size; 102 return st->data + st->pointer; 103} 104 105static char * 106stack_pop (stack *st) 107{ 108 if (st->pointer < st->element_size) 109 { 110 st->pointer = 0; 111 return NULL; 112 } 113 st->pointer -= st->element_size; 114 return st->data + st->pointer; 115} 116 117/* Maintain a list of the tagnames of the structures. */ 118 119static htab_t tag_hash; 120 121static void 122tag_init (void) 123{ 124 tag_hash = str_htab_create (); 125} 126 127static void 128tag_insert (const char *name, symbolS *symbolP) 129{ 130 str_hash_insert (tag_hash, name, symbolP, 1); 131} 132 133static symbolS * 134tag_find (char *name) 135{ 136 return (symbolS *) str_hash_find (tag_hash, name); 137} 138 139static symbolS * 140tag_find_or_make (char *name) 141{ 142 symbolS *symbolP; 143 144 if ((symbolP = tag_find (name)) == NULL) 145 { 146 symbolP = symbol_new (name, undefined_section, &zero_address_frag, 0); 147 148 tag_insert (S_GET_NAME (symbolP), symbolP); 149 symbol_table_insert (symbolP); 150 } 151 152 return symbolP; 153} 154 155/* We accept the .bss directive to set the section for backward 156 compatibility with earlier versions of gas. */ 157 158static void 159obj_coff_bss (int ignore ATTRIBUTE_UNUSED) 160{ 161 if (*input_line_pointer == '\n') 162 subseg_new (".bss", get_absolute_expression ()); 163 else 164 s_lcomm (0); 165} 166 167#ifdef TE_PE 168/* Called from read.c:s_comm after we've parsed .comm symbol, size. 169 Parse a possible alignment value. */ 170 171static symbolS * 172obj_coff_common_parse (int ignore ATTRIBUTE_UNUSED, symbolS *symbolP, addressT size) 173{ 174 addressT align = 0; 175 176 if (*input_line_pointer == ',') 177 { 178 align = parse_align (0); 179 if (align == (addressT) -1) 180 return NULL; 181 } 182 183 S_SET_VALUE (symbolP, size); 184 S_SET_EXTERNAL (symbolP); 185 S_SET_SEGMENT (symbolP, bfd_com_section_ptr); 186 187 symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT; 188 189 /* There is no S_SET_ALIGN (symbolP, align) in COFF/PE. 190 Instead we must add a note to the .drectve section. */ 191 if (align) 192 { 193 segT current_seg = now_seg; 194 subsegT current_subseg = now_subseg; 195 flagword oldflags; 196 asection *sec; 197 size_t pfxlen, numlen; 198 char *frag; 199 char numbuff[20]; 200 201 sec = subseg_new (".drectve", 0); 202 oldflags = bfd_section_flags (sec); 203 if (oldflags == SEC_NO_FLAGS) 204 { 205 if (!bfd_set_section_flags (sec, TC_COFF_SECTION_DEFAULT_ATTRIBUTES)) 206 as_warn (_("error setting flags for \"%s\": %s"), 207 bfd_section_name (sec), 208 bfd_errmsg (bfd_get_error ())); 209 } 210 211 /* Emit a string. Note no NUL-termination. */ 212 pfxlen = strlen (" -aligncomm:") + 2 + strlen (S_GET_NAME (symbolP)) + 1; 213 numlen = snprintf (numbuff, sizeof (numbuff), "%d", (int) align); 214 frag = frag_more (pfxlen + numlen); 215 (void) sprintf (frag, " -aligncomm:\"%s\",", S_GET_NAME (symbolP)); 216 memcpy (frag + pfxlen, numbuff, numlen); 217 /* Restore original subseg. */ 218 subseg_set (current_seg, current_subseg); 219 } 220 221 return symbolP; 222} 223 224static void 225obj_coff_comm (int ignore ATTRIBUTE_UNUSED) 226{ 227 s_comm_internal (ignore, obj_coff_common_parse); 228} 229#endif /* TE_PE */ 230 231/* @@ Ick. */ 232static segT 233fetch_coff_debug_section (void) 234{ 235 static segT debug_section; 236 237 if (!debug_section) 238 { 239 const asymbol *s; 240 241 s = bfd_make_debug_symbol (stdoutput, NULL, 0); 242 gas_assert (s != 0); 243 debug_section = s->section; 244 } 245 return debug_section; 246} 247 248void 249SA_SET_SYM_ENDNDX (symbolS *sym, symbolS *val) 250{ 251 combined_entry_type *entry, *p; 252 253 entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1]; 254 p = coffsymbol (symbol_get_bfdsym (val))->native; 255 entry->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = p; 256 entry->fix_end = 1; 257} 258 259static void 260SA_SET_SYM_TAGNDX (symbolS *sym, symbolS *val) 261{ 262 combined_entry_type *entry, *p; 263 264 entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1]; 265 p = coffsymbol (symbol_get_bfdsym (val))->native; 266 entry->u.auxent.x_sym.x_tagndx.p = p; 267 entry->fix_tag = 1; 268} 269 270static int 271S_GET_DATA_TYPE (symbolS *sym) 272{ 273 return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type; 274} 275 276int 277S_SET_DATA_TYPE (symbolS *sym, int val) 278{ 279 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type = val; 280 return val; 281} 282 283int 284S_GET_STORAGE_CLASS (symbolS *sym) 285{ 286 return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass; 287} 288 289int 290S_SET_STORAGE_CLASS (symbolS *sym, int val) 291{ 292 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass = val; 293 return val; 294} 295 296/* Merge a debug symbol containing debug information into a normal symbol. */ 297 298static void 299c_symbol_merge (symbolS *debug, symbolS *normal) 300{ 301 S_SET_DATA_TYPE (normal, S_GET_DATA_TYPE (debug)); 302 S_SET_STORAGE_CLASS (normal, S_GET_STORAGE_CLASS (debug)); 303 304 if (S_GET_NUMBER_AUXILIARY (debug) > S_GET_NUMBER_AUXILIARY (normal)) 305 /* Take the most we have. */ 306 S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug)); 307 308 if (S_GET_NUMBER_AUXILIARY (debug) > 0) 309 /* Move all the auxiliary information. */ 310 memcpy (SYM_AUXINFO (normal), SYM_AUXINFO (debug), 311 (S_GET_NUMBER_AUXILIARY (debug) 312 * sizeof (*SYM_AUXINFO (debug)))); 313 314 /* Move the debug flags. */ 315 SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug)); 316} 317 318void 319c_dot_file_symbol (const char *filename) 320{ 321 symbolS *symbolP; 322 323 /* BFD converts filename to a .file symbol with an aux entry. It 324 also handles chaining. */ 325 symbolP = symbol_new (filename, bfd_abs_section_ptr, &zero_address_frag, 0); 326 327 S_SET_STORAGE_CLASS (symbolP, C_FILE); 328 S_SET_NUMBER_AUXILIARY (symbolP, 1); 329 330 symbol_get_bfdsym (symbolP)->flags = BSF_DEBUGGING; 331 332#ifndef NO_LISTING 333 { 334 extern int listing; 335 336 if (listing) 337 listing_source_file (filename); 338 } 339#endif 340 341 /* Make sure that the symbol is first on the symbol chain. */ 342 if (symbol_rootP != symbolP) 343 { 344 symbol_remove (symbolP, &symbol_rootP, &symbol_lastP); 345 symbol_insert (symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP); 346 } 347} 348 349/* Line number handling. */ 350 351struct line_no 352{ 353 struct line_no *next; 354 fragS *frag; 355 alent l; 356}; 357 358int coff_line_base; 359 360/* Symbol of last function, which we should hang line#s off of. */ 361static symbolS *line_fsym; 362 363#define in_function() (line_fsym != 0) 364#define clear_function() (line_fsym = 0) 365#define set_function(F) (line_fsym = (F), coff_add_linesym (F)) 366 367 368void 369coff_obj_symbol_new_hook (symbolS *symbolP) 370{ 371 long sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type); 372 char * s = XNEWVEC (char, sz); 373 374 memset (s, 0, sz); 375 coffsymbol (symbol_get_bfdsym (symbolP))->native = (combined_entry_type *) s; 376 coffsymbol (symbol_get_bfdsym (symbolP))->native->is_sym = true; 377 378 S_SET_DATA_TYPE (symbolP, T_NULL); 379 S_SET_STORAGE_CLASS (symbolP, 0); 380 S_SET_NUMBER_AUXILIARY (symbolP, 0); 381 382 if (S_IS_STRING (symbolP)) 383 SF_SET_STRING (symbolP); 384 385 if (S_IS_LOCAL (symbolP)) 386 SF_SET_LOCAL (symbolP); 387} 388 389void 390coff_obj_symbol_clone_hook (symbolS *newsymP, symbolS *orgsymP) 391{ 392 long elts = OBJ_COFF_MAX_AUXENTRIES + 1; 393 combined_entry_type * s = XNEWVEC (combined_entry_type, elts); 394 395 memcpy (s, coffsymbol (symbol_get_bfdsym (orgsymP))->native, 396 elts * sizeof (combined_entry_type)); 397 coffsymbol (symbol_get_bfdsym (newsymP))->native = s; 398 399 SF_SET (newsymP, SF_GET (orgsymP)); 400} 401 402 403/* Handle .ln directives. */ 404 405static symbolS *current_lineno_sym; 406static struct line_no *line_nos; 407/* FIXME: Blindly assume all .ln directives will be in the .text section. */ 408int coff_n_line_nos; 409 410static void 411add_lineno (fragS * frag, addressT offset, int num) 412{ 413 struct line_no * new_line = XNEW (struct line_no); 414 415 if (!current_lineno_sym) 416 abort (); 417 418#ifndef OBJ_XCOFF 419 /* The native aix assembler accepts negative line number. */ 420 421 if (num <= 0) 422 { 423 /* Zero is used as an end marker in the file. */ 424 as_warn (_("Line numbers must be positive integers\n")); 425 num = 1; 426 } 427#endif /* OBJ_XCOFF */ 428 new_line->next = line_nos; 429 new_line->frag = frag; 430 new_line->l.line_number = num; 431 new_line->l.u.offset = offset; 432 line_nos = new_line; 433 coff_n_line_nos++; 434} 435 436void 437coff_add_linesym (symbolS *sym) 438{ 439 if (line_nos) 440 { 441 coffsymbol (symbol_get_bfdsym (current_lineno_sym))->lineno = 442 (alent *) line_nos; 443 coff_n_line_nos++; 444 line_nos = 0; 445 } 446 current_lineno_sym = sym; 447} 448 449static void 450obj_coff_ln (int ignore ATTRIBUTE_UNUSED) 451{ 452 int l; 453 454 if (def_symbol_in_progress != NULL) 455 { 456 as_warn (_(".ln pseudo-op inside .def/.endef: ignored.")); 457 demand_empty_rest_of_line (); 458 return; 459 } 460 461 l = get_absolute_expression (); 462 463 /* If there is no lineno symbol, treat a .ln directive 464 as if it were a (no longer existing) .appline one. */ 465 if (current_lineno_sym == NULL) 466 new_logical_line ((char *) NULL, l - 1); 467 else 468 add_lineno (frag_now, frag_now_fix (), l); 469 470#ifndef NO_LISTING 471 { 472 extern int listing; 473 474 if (listing) 475 { 476 l += coff_line_base - 1; 477 listing_source_line (l); 478 } 479 } 480#endif 481 482 demand_empty_rest_of_line (); 483} 484 485/* .loc is essentially the same as .ln; parse it for assembler 486 compatibility. */ 487 488static void 489obj_coff_loc (int ignore ATTRIBUTE_UNUSED) 490{ 491 int lineno; 492 493 /* FIXME: Why do we need this check? We need it for ECOFF, but why 494 do we need it for COFF? */ 495 if (now_seg != text_section) 496 { 497 as_warn (_(".loc outside of .text")); 498 demand_empty_rest_of_line (); 499 return; 500 } 501 502 if (def_symbol_in_progress != NULL) 503 { 504 as_warn (_(".loc pseudo-op inside .def/.endef: ignored.")); 505 demand_empty_rest_of_line (); 506 return; 507 } 508 509 /* Skip the file number. */ 510 SKIP_WHITESPACE (); 511 get_absolute_expression (); 512 SKIP_WHITESPACE (); 513 514 lineno = get_absolute_expression (); 515 516#ifndef NO_LISTING 517 { 518 extern int listing; 519 520 if (listing) 521 { 522 lineno += coff_line_base - 1; 523 listing_source_line (lineno); 524 } 525 } 526#endif 527 528 demand_empty_rest_of_line (); 529 530 add_lineno (frag_now, frag_now_fix (), lineno); 531} 532 533/* Handle the .ident pseudo-op. */ 534 535static void 536obj_coff_ident (int ignore ATTRIBUTE_UNUSED) 537{ 538 segT current_seg = now_seg; 539 subsegT current_subseg = now_subseg; 540 541#ifdef TE_PE 542 { 543 segT sec; 544 545 /* We could put it in .comment, but that creates an extra section 546 that shouldn't be loaded into memory, which requires linker 547 changes... For now, until proven otherwise, use .rdata. */ 548 sec = subseg_new (".rdata$zzz", 0); 549 bfd_set_section_flags (sec, 550 ((SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA) 551 & bfd_applicable_section_flags (stdoutput))); 552 } 553#else 554 subseg_new (".comment", 0); 555#endif 556 557 stringer (8 + 1); 558 subseg_set (current_seg, current_subseg); 559} 560 561/* Handle .def directives. 562 563 One might ask : why can't we symbol_new if the symbol does not 564 already exist and fill it with debug information. Because of 565 the C_EFCN special symbol. It would clobber the value of the 566 function symbol before we have a chance to notice that it is 567 a C_EFCN. And a second reason is that the code is more clear this 568 way. (at least I think it is :-). */ 569 570#define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';') 571#define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \ 572 *input_line_pointer == '\t') \ 573 input_line_pointer++; 574 575static void 576obj_coff_def (int what ATTRIBUTE_UNUSED) 577{ 578 char name_end; /* Char after the end of name. */ 579 char *symbol_name; /* Name of the debug symbol. */ 580 char *symbol_name_copy; /* Temporary copy of the name. */ 581 582 if (def_symbol_in_progress != NULL) 583 { 584 as_warn (_(".def pseudo-op used inside of .def/.endef: ignored.")); 585 demand_empty_rest_of_line (); 586 return; 587 } 588 589 SKIP_WHITESPACES (); 590 591 name_end = get_symbol_name (&symbol_name); 592 symbol_name_copy = xstrdup (symbol_name); 593#ifdef tc_canonicalize_symbol_name 594 symbol_name_copy = tc_canonicalize_symbol_name (symbol_name_copy); 595#endif 596 597 /* Initialize the new symbol. */ 598 def_symbol_in_progress = symbol_make (symbol_name_copy); 599 symbol_set_frag (def_symbol_in_progress, &zero_address_frag); 600 S_SET_VALUE (def_symbol_in_progress, 0); 601 602 if (S_IS_STRING (def_symbol_in_progress)) 603 SF_SET_STRING (def_symbol_in_progress); 604 605 (void) restore_line_pointer (name_end); 606 607 demand_empty_rest_of_line (); 608} 609 610static void 611obj_coff_endef (int ignore ATTRIBUTE_UNUSED) 612{ 613 symbolS *symbolP = NULL; 614 615 if (def_symbol_in_progress == NULL) 616 { 617 as_warn (_(".endef pseudo-op used outside of .def/.endef: ignored.")); 618 demand_empty_rest_of_line (); 619 return; 620 } 621 622 /* Set the section number according to storage class. */ 623 switch (S_GET_STORAGE_CLASS (def_symbol_in_progress)) 624 { 625 case C_STRTAG: 626 case C_ENTAG: 627 case C_UNTAG: 628 SF_SET_TAG (def_symbol_in_progress); 629 /* Fall through. */ 630 case C_FILE: 631 case C_TPDEF: 632 SF_SET_DEBUG (def_symbol_in_progress); 633 S_SET_SEGMENT (def_symbol_in_progress, fetch_coff_debug_section ()); 634 break; 635 636 case C_EFCN: 637 SF_SET_LOCAL (def_symbol_in_progress); /* Do not emit this symbol. */ 638 /* Fall through. */ 639 case C_BLOCK: 640 SF_SET_PROCESS (def_symbol_in_progress); /* Will need processing before writing. */ 641 /* Fall through. */ 642 case C_FCN: 643 { 644 const char *name; 645 646 S_SET_SEGMENT (def_symbol_in_progress, text_section); 647 648 name = S_GET_NAME (def_symbol_in_progress); 649 if (name[0] == '.' && name[2] == 'f' && name[3] == '\0') 650 { 651 switch (name[1]) 652 { 653 case 'b': 654 /* .bf */ 655 if (! in_function ()) 656 as_warn (_("`%s' symbol without preceding function"), name); 657 /* Will need relocating. */ 658 SF_SET_PROCESS (def_symbol_in_progress); 659 clear_function (); 660 break; 661#ifdef TE_PE 662 case 'e': 663 /* .ef */ 664 /* The MS compilers output the actual endline, not the 665 function-relative one... we want to match without 666 changing the assembler input. */ 667 SA_SET_SYM_LNNO (def_symbol_in_progress, 668 (SA_GET_SYM_LNNO (def_symbol_in_progress) 669 + coff_line_base)); 670 break; 671#endif 672 } 673 } 674 } 675 break; 676 677#ifdef C_AUTOARG 678 case C_AUTOARG: 679#endif /* C_AUTOARG */ 680 case C_AUTO: 681 case C_REG: 682 case C_ARG: 683 case C_REGPARM: 684 case C_FIELD: 685 686 /* According to the COFF documentation: 687 688 http://osr5doc.sco.com:1996/topics/COFF_SectNumFld.html 689 690 A special section number (-2) marks symbolic debugging symbols, 691 including structure/union/enumeration tag names, typedefs, and 692 the name of the file. A section number of -1 indicates that the 693 symbol has a value but is not relocatable. Examples of 694 absolute-valued symbols include automatic and register variables, 695 function arguments, and .eos symbols. 696 697 But from Ian Lance Taylor: 698 699 http://sources.redhat.com/ml/binutils/2000-08/msg00202.html 700 701 the actual tools all marked them as section -1. So the GNU COFF 702 assembler follows historical COFF assemblers. 703 704 However, it causes problems for djgpp 705 706 http://sources.redhat.com/ml/binutils/2000-08/msg00210.html 707 708 By defining STRICTCOFF, a COFF port can make the assembler to 709 follow the documented behavior. */ 710#ifdef STRICTCOFF 711 case C_MOS: 712 case C_MOE: 713 case C_MOU: 714 case C_EOS: 715#endif 716 SF_SET_DEBUG (def_symbol_in_progress); 717 S_SET_SEGMENT (def_symbol_in_progress, absolute_section); 718 break; 719 720#ifndef STRICTCOFF 721 case C_MOS: 722 case C_MOE: 723 case C_MOU: 724 case C_EOS: 725 S_SET_SEGMENT (def_symbol_in_progress, absolute_section); 726 break; 727#endif 728 729 case C_EXT: 730 case C_WEAKEXT: 731#ifdef TE_PE 732 case C_NT_WEAK: 733#endif 734 case C_STAT: 735 case C_LABEL: 736 /* Valid but set somewhere else (s_comm, s_lcomm, colon). */ 737 break; 738 739 default: 740 case C_USTATIC: 741 case C_EXTDEF: 742 case C_ULABEL: 743 as_warn (_("unexpected storage class %d"), 744 S_GET_STORAGE_CLASS (def_symbol_in_progress)); 745 break; 746 } 747 748 /* Now that we have built a debug symbol, try to find if we should 749 merge with an existing symbol or not. If a symbol is C_EFCN or 750 absolute_section or untagged SEG_DEBUG it never merges. We also 751 don't merge labels, which are in a different namespace, nor 752 symbols which have not yet been defined since they are typically 753 unique, nor do we merge tags with non-tags. */ 754 755 /* Two cases for functions. Either debug followed by definition or 756 definition followed by debug. For definition first, we will 757 merge the debug symbol into the definition. For debug first, the 758 lineno entry MUST point to the definition function or else it 759 will point off into space when obj_crawl_symbol_chain() merges 760 the debug symbol into the real symbol. Therefor, let's presume 761 the debug symbol is a real function reference. */ 762 763 /* FIXME-SOON If for some reason the definition label/symbol is 764 never seen, this will probably leave an undefined symbol at link 765 time. */ 766 767 if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN 768 || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_LABEL 769 || (streq (bfd_section_name (S_GET_SEGMENT (def_symbol_in_progress)), 770 "*DEBUG*") 771 && !SF_GET_TAG (def_symbol_in_progress)) 772 || S_GET_SEGMENT (def_symbol_in_progress) == absolute_section 773 || ! symbol_constant_p (def_symbol_in_progress) 774 || (symbolP = symbol_find (S_GET_NAME (def_symbol_in_progress))) == NULL 775 || SF_GET_TAG (def_symbol_in_progress) != SF_GET_TAG (symbolP)) 776 { 777 /* If it already is at the end of the symbol list, do nothing */ 778 if (def_symbol_in_progress != symbol_lastP) 779 { 780 symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP); 781 symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, 782 &symbol_lastP); 783 } 784 } 785 else 786 { 787 /* This symbol already exists, merge the newly created symbol 788 into the old one. This is not mandatory. The linker can 789 handle duplicate symbols correctly. But I guess that it save 790 a *lot* of space if the assembly file defines a lot of 791 symbols. [loic] */ 792 793 /* The debug entry (def_symbol_in_progress) is merged into the 794 previous definition. */ 795 796 c_symbol_merge (def_symbol_in_progress, symbolP); 797 symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP); 798 799 def_symbol_in_progress = symbolP; 800 801 if (SF_GET_FUNCTION (def_symbol_in_progress) 802 || SF_GET_TAG (def_symbol_in_progress) 803 || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_STAT) 804 { 805 /* For functions, and tags, and static symbols, the symbol 806 *must* be where the debug symbol appears. Move the 807 existing symbol to the current place. */ 808 /* If it already is at the end of the symbol list, do nothing. */ 809 if (def_symbol_in_progress != symbol_lastP) 810 { 811 symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP); 812 symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP); 813 } 814 } 815 } 816 817 if (SF_GET_TAG (def_symbol_in_progress)) 818 { 819 symbolS *oldtag; 820 821 oldtag = symbol_find (S_GET_NAME (def_symbol_in_progress)); 822 if (oldtag == NULL || ! SF_GET_TAG (oldtag)) 823 tag_insert (S_GET_NAME (def_symbol_in_progress), 824 def_symbol_in_progress); 825 } 826 827 if (SF_GET_FUNCTION (def_symbol_in_progress)) 828 { 829 set_function (def_symbol_in_progress); 830 SF_SET_PROCESS (def_symbol_in_progress); 831 832 if (symbolP == NULL) 833 /* That is, if this is the first time we've seen the 834 function. */ 835 symbol_table_insert (def_symbol_in_progress); 836 837 } 838 839 def_symbol_in_progress = NULL; 840 demand_empty_rest_of_line (); 841} 842 843static void 844obj_coff_dim (int ignore ATTRIBUTE_UNUSED) 845{ 846 int d_index; 847 848 if (def_symbol_in_progress == NULL) 849 { 850 as_warn (_(".dim pseudo-op used outside of .def/.endef: ignored.")); 851 demand_empty_rest_of_line (); 852 return; 853 } 854 855 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1); 856 857 for (d_index = 0; d_index < DIMNUM; d_index++) 858 { 859 SKIP_WHITESPACES (); 860 SA_SET_SYM_DIMEN (def_symbol_in_progress, d_index, 861 get_absolute_expression ()); 862 863 switch (*input_line_pointer) 864 { 865 case ',': 866 input_line_pointer++; 867 break; 868 869 default: 870 as_warn (_("badly formed .dim directive ignored")); 871 /* Fall through. */ 872 case '\n': 873 case ';': 874 d_index = DIMNUM; 875 break; 876 } 877 } 878 879 demand_empty_rest_of_line (); 880} 881 882static void 883obj_coff_line (int ignore ATTRIBUTE_UNUSED) 884{ 885 int this_base; 886 887 if (def_symbol_in_progress == NULL) 888 { 889 /* Probably stabs-style line? */ 890 obj_coff_ln (0); 891 return; 892 } 893 894 this_base = get_absolute_expression (); 895 if (streq (".bf", S_GET_NAME (def_symbol_in_progress))) 896 coff_line_base = this_base; 897 898 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1); 899 SA_SET_SYM_LNNO (def_symbol_in_progress, this_base); 900 901 demand_empty_rest_of_line (); 902 903#ifndef NO_LISTING 904 if (streq (".bf", S_GET_NAME (def_symbol_in_progress))) 905 { 906 extern int listing; 907 908 if (listing) 909 listing_source_line ((unsigned int) this_base); 910 } 911#endif 912} 913 914static void 915obj_coff_size (int ignore ATTRIBUTE_UNUSED) 916{ 917 if (def_symbol_in_progress == NULL) 918 { 919 as_warn (_(".size pseudo-op used outside of .def/.endef: ignored.")); 920 demand_empty_rest_of_line (); 921 return; 922 } 923 924 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1); 925 SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ()); 926 demand_empty_rest_of_line (); 927} 928 929static void 930obj_coff_scl (int ignore ATTRIBUTE_UNUSED) 931{ 932 if (def_symbol_in_progress == NULL) 933 { 934 as_warn (_(".scl pseudo-op used outside of .def/.endef: ignored.")); 935 demand_empty_rest_of_line (); 936 return; 937 } 938 939 S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ()); 940 demand_empty_rest_of_line (); 941} 942 943static void 944obj_coff_tag (int ignore ATTRIBUTE_UNUSED) 945{ 946 char *symbol_name; 947 char name_end; 948 949 if (def_symbol_in_progress == NULL) 950 { 951 as_warn (_(".tag pseudo-op used outside of .def/.endef: ignored.")); 952 demand_empty_rest_of_line (); 953 return; 954 } 955 956 S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1); 957 name_end = get_symbol_name (&symbol_name); 958 959#ifdef tc_canonicalize_symbol_name 960 symbol_name = tc_canonicalize_symbol_name (symbol_name); 961#endif 962 963 /* Assume that the symbol referred to by .tag is always defined. 964 This was a bad assumption. I've added find_or_make. xoxorich. */ 965 SA_SET_SYM_TAGNDX (def_symbol_in_progress, 966 tag_find_or_make (symbol_name)); 967 if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L) 968 as_warn (_("tag not found for .tag %s"), symbol_name); 969 970 SF_SET_TAGGED (def_symbol_in_progress); 971 972 (void) restore_line_pointer (name_end); 973 demand_empty_rest_of_line (); 974} 975 976static void 977obj_coff_type (int ignore ATTRIBUTE_UNUSED) 978{ 979 if (def_symbol_in_progress == NULL) 980 { 981 as_warn (_(".type pseudo-op used outside of .def/.endef: ignored.")); 982 demand_empty_rest_of_line (); 983 return; 984 } 985 986 S_SET_DATA_TYPE (def_symbol_in_progress, get_absolute_expression ()); 987 988 if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress)) && 989 S_GET_STORAGE_CLASS (def_symbol_in_progress) != C_TPDEF) 990 SF_SET_FUNCTION (def_symbol_in_progress); 991 992 demand_empty_rest_of_line (); 993} 994 995static void 996obj_coff_val (int ignore ATTRIBUTE_UNUSED) 997{ 998 if (def_symbol_in_progress == NULL) 999 { 1000 as_warn (_(".val pseudo-op used outside of .def/.endef: ignored.")); 1001 demand_empty_rest_of_line (); 1002 return; 1003 } 1004 1005 if (is_name_beginner (*input_line_pointer)) 1006 { 1007 char *symbol_name; 1008 char name_end = get_symbol_name (&symbol_name); 1009 1010#ifdef tc_canonicalize_symbol_name 1011 symbol_name = tc_canonicalize_symbol_name (symbol_name); 1012#endif 1013 if (streq (symbol_name, ".")) 1014 { 1015 /* If the .val is != from the .def (e.g. statics). */ 1016 symbol_set_frag (def_symbol_in_progress, frag_now); 1017 S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ()); 1018 } 1019 else if (! streq (S_GET_NAME (def_symbol_in_progress), symbol_name)) 1020 { 1021 expressionS exp; 1022 1023 exp.X_op = O_symbol; 1024 exp.X_add_symbol = symbol_find_or_make (symbol_name); 1025 exp.X_op_symbol = NULL; 1026 exp.X_add_number = 0; 1027 symbol_set_value_expression (def_symbol_in_progress, &exp); 1028 1029 /* If the segment is undefined when the forward reference is 1030 resolved, then copy the segment id from the forward 1031 symbol. */ 1032 SF_SET_GET_SEGMENT (def_symbol_in_progress); 1033 1034 /* FIXME: gcc can generate address expressions here in 1035 unusual cases (search for "obscure" in sdbout.c). We 1036 just ignore the offset here, thus generating incorrect 1037 debugging information. We ignore the rest of the line 1038 just below. */ 1039 } 1040 /* Otherwise, it is the name of a non debug symbol and its value 1041 will be calculated later. */ 1042 (void) restore_line_pointer (name_end); 1043 } 1044 else 1045 { 1046 S_SET_VALUE (def_symbol_in_progress, get_absolute_expression ()); 1047 } 1048 1049 demand_empty_rest_of_line (); 1050} 1051 1052#ifdef TE_PE 1053 1054/* Return nonzero if name begins with weak alternate symbol prefix. */ 1055 1056static int 1057weak_is_altname (const char * name) 1058{ 1059 return startswith (name, weak_altprefix); 1060} 1061 1062/* Return the name of the alternate symbol 1063 name corresponding to a weak symbol's name. */ 1064 1065static const char * 1066weak_name2altname (const char * name) 1067{ 1068 return concat (weak_altprefix, name, (char *) NULL); 1069} 1070 1071/* Return the name of the weak symbol corresponding to an 1072 alternate symbol. */ 1073 1074static const char * 1075weak_altname2name (const char * name) 1076{ 1077 gas_assert (weak_is_altname (name)); 1078 return xstrdup (name + 6); 1079} 1080 1081/* Make a weak symbol name unique by 1082 appending the name of an external symbol. */ 1083 1084static const char * 1085weak_uniquify (const char * name) 1086{ 1087 const char * unique = ""; 1088 1089#ifdef TE_PE 1090 if (an_external_name != NULL) 1091 unique = an_external_name; 1092#endif 1093 gas_assert (weak_is_altname (name)); 1094 1095 return concat (name, ".", unique, (char *) NULL); 1096} 1097 1098void 1099pecoff_obj_set_weak_hook (symbolS *symbolP) 1100{ 1101 symbolS *alternateP; 1102 1103 /* See _Microsoft Portable Executable and Common Object 1104 File Format Specification_, section 5.5.3. 1105 Create a symbol representing the alternate value. 1106 coff_frob_symbol will set the value of this symbol from 1107 the value of the weak symbol itself. */ 1108 S_SET_STORAGE_CLASS (symbolP, C_NT_WEAK); 1109 S_SET_NUMBER_AUXILIARY (symbolP, 1); 1110 SA_SET_SYM_FSIZE (symbolP, IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY); 1111 1112 alternateP = symbol_find_or_make (weak_name2altname (S_GET_NAME (symbolP))); 1113 S_SET_EXTERNAL (alternateP); 1114 S_SET_STORAGE_CLASS (alternateP, C_NT_WEAK); 1115 1116 SA_SET_SYM_TAGNDX (symbolP, alternateP); 1117} 1118 1119void 1120pecoff_obj_clear_weak_hook (symbolS *symbolP) 1121{ 1122 symbolS *alternateP; 1123 1124 S_SET_STORAGE_CLASS (symbolP, 0); 1125 SA_SET_SYM_FSIZE (symbolP, 0); 1126 1127 alternateP = symbol_find (weak_name2altname (S_GET_NAME (symbolP))); 1128 S_CLEAR_EXTERNAL (alternateP); 1129} 1130 1131#endif /* TE_PE */ 1132 1133/* Handle .weak. This is a GNU extension in formats other than PE. */ 1134 1135static void 1136obj_coff_weak (int ignore ATTRIBUTE_UNUSED) 1137{ 1138 char *name; 1139 int c; 1140 symbolS *symbolP; 1141 1142 do 1143 { 1144 c = get_symbol_name (&name); 1145 if (*name == 0) 1146 { 1147 as_warn (_("badly formed .weak directive ignored")); 1148 ignore_rest_of_line (); 1149 return; 1150 } 1151 c = 0; 1152 symbolP = symbol_find_or_make (name); 1153 *input_line_pointer = c; 1154 SKIP_WHITESPACE_AFTER_NAME (); 1155 S_SET_WEAK (symbolP); 1156 1157 if (c == ',') 1158 { 1159 input_line_pointer++; 1160 SKIP_WHITESPACE (); 1161 if (*input_line_pointer == '\n') 1162 c = '\n'; 1163 } 1164 1165 } 1166 while (c == ','); 1167 1168 demand_empty_rest_of_line (); 1169} 1170 1171void 1172coff_obj_read_begin_hook (void) 1173{ 1174 /* These had better be the same. Usually 18 bytes. */ 1175 know (sizeof (SYMENT) == sizeof (AUXENT)); 1176 know (SYMESZ == AUXESZ); 1177 tag_init (); 1178} 1179 1180symbolS *coff_last_function; 1181#ifndef OBJ_XCOFF 1182static symbolS *coff_last_bf; 1183#endif 1184 1185void 1186coff_frob_symbol (symbolS *symp, int *punt) 1187{ 1188 static symbolS *last_tagP; 1189 static stack *block_stack; 1190 static symbolS *set_end; 1191 symbolS *next_set_end = NULL; 1192 1193 if (symp == &abs_symbol) 1194 { 1195 *punt = 1; 1196 return; 1197 } 1198 1199 if (current_lineno_sym) 1200 coff_add_linesym (NULL); 1201 1202 if (!block_stack) 1203 block_stack = stack_init (512, sizeof (symbolS*)); 1204 1205#ifdef TE_PE 1206 if (S_GET_STORAGE_CLASS (symp) == C_NT_WEAK 1207 && ! S_IS_WEAK (symp) 1208 && weak_is_altname (S_GET_NAME (symp))) 1209 { 1210 /* This is a weak alternate symbol. All processing of 1211 PECOFFweak symbols is done here, through the alternate. */ 1212 symbolS *weakp = symbol_find_noref (weak_altname2name 1213 (S_GET_NAME (symp)), 1); 1214 1215 gas_assert (weakp); 1216 gas_assert (S_GET_NUMBER_AUXILIARY (weakp) == 1); 1217 1218 if (! S_IS_WEAK (weakp)) 1219 { 1220 /* The symbol was turned from weak to strong. Discard altname. */ 1221 *punt = 1; 1222 return; 1223 } 1224 else if (symbol_equated_p (weakp)) 1225 { 1226 /* The weak symbol has an alternate specified; symp is unneeded. */ 1227 S_SET_STORAGE_CLASS (weakp, C_NT_WEAK); 1228 SA_SET_SYM_TAGNDX (weakp, 1229 symbol_get_value_expression (weakp)->X_add_symbol); 1230 1231 S_CLEAR_EXTERNAL (symp); 1232 *punt = 1; 1233 return; 1234 } 1235 else 1236 { 1237 /* The weak symbol has been assigned an alternate value. 1238 Copy this value to symp, and set symp as weakp's alternate. */ 1239 if (S_GET_STORAGE_CLASS (weakp) != C_NT_WEAK) 1240 { 1241 S_SET_STORAGE_CLASS (symp, S_GET_STORAGE_CLASS (weakp)); 1242 S_SET_STORAGE_CLASS (weakp, C_NT_WEAK); 1243 } 1244 1245 if (S_IS_DEFINED (weakp)) 1246 { 1247 /* This is a defined weak symbol. Copy value information 1248 from the weak symbol itself to the alternate symbol. */ 1249 symbol_set_value_expression (symp, 1250 symbol_get_value_expression (weakp)); 1251 symbol_set_frag (symp, symbol_get_frag (weakp)); 1252 S_SET_SEGMENT (symp, S_GET_SEGMENT (weakp)); 1253 } 1254 else 1255 { 1256 /* This is an undefined weak symbol. 1257 Define the alternate symbol to zero. */ 1258 S_SET_VALUE (symp, 0); 1259 S_SET_SEGMENT (symp, absolute_section); 1260 } 1261 1262 S_SET_NAME (symp, weak_uniquify (S_GET_NAME (symp))); 1263 S_SET_STORAGE_CLASS (symp, C_EXT); 1264 1265 S_SET_VALUE (weakp, 0); 1266 S_SET_SEGMENT (weakp, undefined_section); 1267 } 1268 } 1269#else /* TE_PE */ 1270 if (S_IS_WEAK (symp)) 1271 S_SET_STORAGE_CLASS (symp, C_WEAKEXT); 1272#endif /* TE_PE */ 1273 1274 if (!S_IS_DEFINED (symp) 1275 && !S_IS_WEAK (symp) 1276 && S_GET_STORAGE_CLASS (symp) != C_STAT) 1277 S_SET_STORAGE_CLASS (symp, C_EXT); 1278 1279 if (!SF_GET_DEBUG (symp)) 1280 { 1281 symbolS * real; 1282 1283 if (!SF_GET_LOCAL (symp) 1284 && !SF_GET_STATICS (symp) 1285 && S_GET_STORAGE_CLASS (symp) != C_LABEL 1286 && symbol_constant_p (symp) 1287 && (real = symbol_find_noref (S_GET_NAME (symp), 1)) 1288 && S_GET_STORAGE_CLASS (real) == C_NULL 1289 && real != symp) 1290 { 1291 c_symbol_merge (symp, real); 1292 *punt = 1; 1293 return; 1294 } 1295 1296 if (!S_IS_DEFINED (symp) && !SF_GET_LOCAL (symp)) 1297 { 1298 gas_assert (S_GET_VALUE (symp) == 0); 1299 if (S_IS_WEAKREFD (symp)) 1300 *punt = 1; 1301 else 1302 S_SET_EXTERNAL (symp); 1303 } 1304 else if (S_GET_STORAGE_CLASS (symp) == C_NULL) 1305 { 1306 if (S_GET_SEGMENT (symp) == text_section 1307 && symp != seg_info (text_section)->sym) 1308 S_SET_STORAGE_CLASS (symp, C_LABEL); 1309 else 1310 S_SET_STORAGE_CLASS (symp, C_STAT); 1311 } 1312 1313 if (SF_GET_PROCESS (symp)) 1314 { 1315 if (S_GET_STORAGE_CLASS (symp) == C_BLOCK) 1316 { 1317 if (streq (S_GET_NAME (symp), ".bb")) 1318 stack_push (block_stack, (char *) &symp); 1319 else 1320 { 1321 symbolS *begin; 1322 1323 begin = *(symbolS **) stack_pop (block_stack); 1324 if (begin == 0) 1325 as_warn (_("mismatched .eb")); 1326 else 1327 next_set_end = begin; 1328 } 1329 } 1330 1331 if (coff_last_function == 0 && SF_GET_FUNCTION (symp) 1332 && S_IS_DEFINED (symp)) 1333 { 1334 union internal_auxent *auxp; 1335 1336 coff_last_function = symp; 1337 if (S_GET_NUMBER_AUXILIARY (symp) < 1) 1338 S_SET_NUMBER_AUXILIARY (symp, 1); 1339 auxp = SYM_AUXENT (symp); 1340 memset (auxp->x_sym.x_fcnary.x_ary.x_dimen, 0, 1341 sizeof (auxp->x_sym.x_fcnary.x_ary.x_dimen)); 1342 } 1343 1344 if (S_GET_STORAGE_CLASS (symp) == C_EFCN 1345 && S_IS_DEFINED (symp)) 1346 { 1347 if (coff_last_function == 0) 1348 as_fatal (_("C_EFCN symbol for %s out of scope"), 1349 S_GET_NAME (symp)); 1350 SA_SET_SYM_FSIZE (coff_last_function, 1351 (long) (S_GET_VALUE (symp) 1352 - S_GET_VALUE (coff_last_function))); 1353 next_set_end = coff_last_function; 1354 coff_last_function = 0; 1355 } 1356 } 1357 1358 if (S_IS_EXTERNAL (symp)) 1359 S_SET_STORAGE_CLASS (symp, C_EXT); 1360 else if (SF_GET_LOCAL (symp)) 1361 *punt = 1; 1362 1363 if (SF_GET_FUNCTION (symp)) 1364 symbol_get_bfdsym (symp)->flags |= BSF_FUNCTION; 1365 } 1366 1367 /* Double check weak symbols. */ 1368 if (S_IS_WEAK (symp) && S_IS_COMMON (symp)) 1369 as_bad (_("Symbol `%s' can not be both weak and common"), 1370 S_GET_NAME (symp)); 1371 1372 if (SF_GET_TAG (symp)) 1373 last_tagP = symp; 1374 else if (S_GET_STORAGE_CLASS (symp) == C_EOS) 1375 next_set_end = last_tagP; 1376 1377#ifdef OBJ_XCOFF 1378 /* This is pretty horrible, but we have to set *punt correctly in 1379 order to call SA_SET_SYM_ENDNDX correctly. */ 1380 if (! symbol_used_in_reloc_p (symp) 1381 && S_GET_STORAGE_CLASS (symp) != C_DWARF 1382 && ((symbol_get_bfdsym (symp)->flags & BSF_SECTION_SYM) != 0 1383 || (! (S_IS_EXTERNAL (symp) || S_IS_WEAK (symp)) 1384 && ! symbol_get_tc (symp)->output 1385 && S_GET_STORAGE_CLASS (symp) != C_FILE))) 1386 *punt = 1; 1387#endif 1388 1389 if (set_end != (symbolS *) NULL 1390 && ! *punt 1391 && ((symbol_get_bfdsym (symp)->flags & BSF_NOT_AT_END) != 0 1392 || (S_IS_DEFINED (symp) 1393 && ! S_IS_COMMON (symp) 1394 && (! S_IS_EXTERNAL (symp) || SF_GET_FUNCTION (symp))))) 1395 { 1396 SA_SET_SYM_ENDNDX (set_end, symp); 1397 set_end = NULL; 1398 } 1399 1400 if (next_set_end != NULL) 1401 { 1402 if (set_end != NULL) 1403 as_warn (_("Warning: internal error: forgetting to set endndx of %s"), 1404 S_GET_NAME (set_end)); 1405 set_end = next_set_end; 1406 } 1407 1408#ifndef OBJ_XCOFF 1409 if (! *punt 1410 && S_GET_STORAGE_CLASS (symp) == C_FCN 1411 && streq (S_GET_NAME (symp), ".bf")) 1412 { 1413 if (coff_last_bf != NULL) 1414 SA_SET_SYM_ENDNDX (coff_last_bf, symp); 1415 coff_last_bf = symp; 1416 } 1417#endif 1418 if (coffsymbol (symbol_get_bfdsym (symp))->lineno) 1419 { 1420 int i; 1421 struct line_no *lptr; 1422 alent *l; 1423 1424 lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno; 1425 for (i = 0; lptr; lptr = lptr->next) 1426 i++; 1427 lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno; 1428 1429 /* We need i entries for line numbers, plus 1 for the first 1430 entry which BFD will override, plus 1 for the last zero 1431 entry (a marker for BFD). */ 1432 l = XNEWVEC (alent, (i + 2)); 1433 coffsymbol (symbol_get_bfdsym (symp))->lineno = l; 1434 l[i + 1].line_number = 0; 1435 l[i + 1].u.sym = NULL; 1436 for (; i > 0; i--) 1437 { 1438 if (lptr->frag) 1439 lptr->l.u.offset += lptr->frag->fr_address / OCTETS_PER_BYTE; 1440 l[i] = lptr->l; 1441 lptr = lptr->next; 1442 } 1443 } 1444} 1445 1446void 1447coff_adjust_section_syms (bfd *abfd ATTRIBUTE_UNUSED, 1448 asection *sec, 1449 void * x ATTRIBUTE_UNUSED) 1450{ 1451 symbolS *secsym; 1452 segment_info_type *seginfo = seg_info (sec); 1453 int nlnno, nrelocs = 0; 1454 1455 /* RS/6000 gas creates a .debug section manually in ppc_frob_file in 1456 tc-ppc.c. Do not get confused by it. */ 1457 if (seginfo == NULL) 1458 return; 1459 1460 if (streq (sec->name, ".text")) 1461 nlnno = coff_n_line_nos; 1462 else 1463 nlnno = 0; 1464 { 1465 /* @@ Hope that none of the fixups expand to more than one reloc 1466 entry... */ 1467 fixS *fixp = seginfo->fix_root; 1468 while (fixp) 1469 { 1470 if (! fixp->fx_done) 1471 nrelocs++; 1472 fixp = fixp->fx_next; 1473 } 1474 } 1475 if (bfd_section_size (sec) == 0 1476 && nrelocs == 0 1477 && nlnno == 0 1478 && sec != text_section 1479 && sec != data_section 1480 && sec != bss_section) 1481 return; 1482 1483 secsym = section_symbol (sec); 1484 /* This is an estimate; we'll plug in the real value using 1485 SET_SECTION_RELOCS later */ 1486#ifdef OBJ_XCOFF 1487 if (S_GET_STORAGE_CLASS (secsym) == C_DWARF) 1488 SA_SET_SECT_NRELOC (secsym, nrelocs); 1489 else 1490 { 1491 SA_SET_SCN_NRELOC (secsym, nrelocs); 1492 SA_SET_SCN_NLINNO (secsym, nlnno); 1493 } 1494#else 1495 SA_SET_SCN_NRELOC (secsym, nrelocs); 1496 SA_SET_SCN_NLINNO (secsym, nlnno); 1497#endif 1498} 1499 1500void 1501coff_frob_file_after_relocs (void) 1502{ 1503 bfd_map_over_sections (stdoutput, coff_adjust_section_syms, NULL); 1504} 1505 1506/* Implement the .section pseudo op: 1507 .section name {, "flags"} 1508 ^ ^ 1509 | +--- optional flags: 'b' for bss 1510 | 'i' for info 1511 +-- section name 'l' for lib 1512 'n' for noload 1513 'o' for over 1514 'w' for data 1515 'd' (apparently m88k for data) 1516 'e' for exclude 1517 'x' for text 1518 'r' for read-only data 1519 's' for shared data (PE) 1520 'y' for noread 1521 '0' - '9' for power-of-two alignment (GNU extension). 1522 But if the argument is not a quoted string, treat it as a 1523 subsegment number. 1524 1525 Note the 'a' flag is silently ignored. This allows the same 1526 .section directive to be parsed in both ELF and COFF formats. */ 1527 1528void 1529obj_coff_section (int ignore ATTRIBUTE_UNUSED) 1530{ 1531 /* Strip out the section name. */ 1532 char *section_name; 1533 char c; 1534 int alignment = -1; 1535 char *name; 1536 unsigned int exp; 1537 flagword flags, oldflags; 1538 asection *sec; 1539 bool is_bss = false; 1540 1541 if (flag_mri) 1542 { 1543 char type; 1544 1545 s_mri_sect (&type); 1546 return; 1547 } 1548 1549 c = get_symbol_name (§ion_name); 1550 name = xmemdup0 (section_name, input_line_pointer - section_name); 1551 *input_line_pointer = c; 1552 SKIP_WHITESPACE_AFTER_NAME (); 1553 1554 exp = 0; 1555 flags = SEC_NO_FLAGS; 1556 1557 if (*input_line_pointer == ',') 1558 { 1559 ++input_line_pointer; 1560 SKIP_WHITESPACE (); 1561 if (*input_line_pointer != '"') 1562 exp = get_absolute_expression (); 1563 else 1564 { 1565 unsigned char attr; 1566 int readonly_removed = 0; 1567 int load_removed = 0; 1568 1569 while (attr = *++input_line_pointer, 1570 attr != '"' 1571 && ! is_end_of_line[attr]) 1572 { 1573 if (ISDIGIT (attr)) 1574 { 1575 alignment = attr - '0'; 1576 continue; 1577 } 1578 switch (attr) 1579 { 1580 case 'e': 1581 /* Exclude section from linking. */ 1582 flags |= SEC_EXCLUDE; 1583 break; 1584 1585 case 'b': 1586 /* Uninitialised data section. */ 1587 flags |= SEC_ALLOC; 1588 flags &=~ SEC_LOAD; 1589 is_bss = true; 1590 break; 1591 1592 case 'n': 1593 /* Section not loaded. */ 1594 flags &=~ SEC_LOAD; 1595 flags |= SEC_NEVER_LOAD; 1596 load_removed = 1; 1597 break; 1598 1599 case 's': 1600 /* Shared section. */ 1601 flags |= SEC_COFF_SHARED; 1602 /* Fall through. */ 1603 case 'd': 1604 /* Data section. */ 1605 flags |= SEC_DATA; 1606 if (! load_removed) 1607 flags |= SEC_LOAD; 1608 flags &=~ SEC_READONLY; 1609 break; 1610 1611 case 'w': 1612 /* Writable section. */ 1613 flags &=~ SEC_READONLY; 1614 readonly_removed = 1; 1615 break; 1616 1617 case 'a': 1618 /* Ignore. Here for compatibility with ELF. */ 1619 break; 1620 1621 case 'r': /* Read-only section. Implies a data section. */ 1622 readonly_removed = 0; 1623 /* Fall through. */ 1624 case 'x': /* Executable section. */ 1625 /* If we are setting the 'x' attribute or if the 'r' 1626 attribute is being used to restore the readonly status 1627 of a code section (eg "wxr") then set the SEC_CODE flag, 1628 otherwise set the SEC_DATA flag. */ 1629 flags |= (attr == 'x' || (flags & SEC_CODE) ? SEC_CODE : SEC_DATA); 1630 if (! load_removed) 1631 flags |= SEC_LOAD; 1632 /* Note - the READONLY flag is set here, even for the 'x' 1633 attribute in order to be compatible with the MSVC 1634 linker. */ 1635 if (! readonly_removed) 1636 flags |= SEC_READONLY; 1637 break; 1638 1639 case 'y': 1640 flags |= SEC_COFF_NOREAD | SEC_READONLY; 1641 break; 1642 1643 case 'i': /* STYP_INFO */ 1644 case 'l': /* STYP_LIB */ 1645 case 'o': /* STYP_OVER */ 1646 as_warn (_("unsupported section attribute '%c'"), attr); 1647 break; 1648 1649 default: 1650 as_warn (_("unknown section attribute '%c'"), attr); 1651 break; 1652 } 1653 } 1654 if (attr == '"') 1655 ++input_line_pointer; 1656 } 1657 } 1658 1659 sec = subseg_new (name, (subsegT) exp); 1660 1661 if (is_bss) 1662 seg_info (sec)->bss = 1; 1663 1664 if (alignment >= 0) 1665 sec->alignment_power = alignment; 1666 1667 oldflags = bfd_section_flags (sec); 1668 if (oldflags == SEC_NO_FLAGS) 1669 { 1670 /* Set section flags for a new section just created by subseg_new. 1671 Provide a default if no flags were parsed. */ 1672 if (flags == SEC_NO_FLAGS) 1673 flags = TC_COFF_SECTION_DEFAULT_ATTRIBUTES; 1674 1675#ifdef COFF_LONG_SECTION_NAMES 1676 /* Add SEC_LINK_ONCE and SEC_LINK_DUPLICATES_DISCARD to .gnu.linkonce 1677 sections so adjust_reloc_syms in write.c will correctly handle 1678 relocs which refer to non-local symbols in these sections. */ 1679 if (startswith (name, ".gnu.linkonce")) 1680 flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD; 1681#endif 1682 1683 if (!bfd_set_section_flags (sec, flags)) 1684 as_warn (_("error setting flags for \"%s\": %s"), 1685 bfd_section_name (sec), 1686 bfd_errmsg (bfd_get_error ())); 1687 } 1688 else if (flags != SEC_NO_FLAGS) 1689 { 1690 /* This section's attributes have already been set. Warn if the 1691 attributes don't match. */ 1692 flagword matchflags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE 1693 | SEC_DATA | SEC_COFF_SHARED | SEC_NEVER_LOAD 1694 | SEC_COFF_NOREAD); 1695 if ((flags ^ oldflags) & matchflags) 1696 as_warn (_("Ignoring changed section attributes for %s"), name); 1697 } 1698 1699 demand_empty_rest_of_line (); 1700} 1701 1702void 1703coff_adjust_symtab (void) 1704{ 1705 if (symbol_rootP == NULL 1706 || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE) 1707 c_dot_file_symbol ("fake"); 1708} 1709 1710void 1711coff_frob_section (segT sec) 1712{ 1713 segT strsec; 1714 char *p; 1715 fragS *fragp; 1716 bfd_vma n_entries; 1717 1718 /* The COFF back end in BFD requires that all section sizes be 1719 rounded up to multiples of the corresponding section alignments, 1720 supposedly because standard COFF has no other way of encoding alignment 1721 for sections. If your COFF flavor has a different way of encoding 1722 section alignment, then skip this step, as TICOFF does. */ 1723 bfd_vma size = bfd_section_size (sec); 1724#if !defined(TICOFF) 1725 bfd_vma align_power = (bfd_vma) sec->alignment_power + OCTETS_PER_BYTE_POWER; 1726 bfd_vma mask = ((bfd_vma) 1 << align_power) - 1; 1727 1728 if (size & mask) 1729 { 1730 bfd_vma new_size; 1731 fragS *last; 1732 1733 new_size = (size + mask) & ~mask; 1734 bfd_set_section_size (sec, new_size); 1735 1736 /* If the size had to be rounded up, add some padding in 1737 the last non-empty frag. */ 1738 fragp = seg_info (sec)->frchainP->frch_root; 1739 last = seg_info (sec)->frchainP->frch_last; 1740 while (fragp->fr_next != last) 1741 fragp = fragp->fr_next; 1742 last->fr_address = size; 1743 fragp->fr_offset += new_size - size; 1744 } 1745#endif 1746 1747 /* If the section size is non-zero, the section symbol needs an aux 1748 entry associated with it, indicating the size. We don't know 1749 all the values yet; coff_frob_symbol will fill them in later. */ 1750#ifndef TICOFF 1751 if (size != 0 1752 || sec == text_section 1753 || sec == data_section 1754 || sec == bss_section) 1755#endif 1756 { 1757 symbolS *secsym = section_symbol (sec); 1758 unsigned char sclass = C_STAT; 1759 1760#ifdef OBJ_XCOFF 1761 if (bfd_section_flags (sec) & SEC_DEBUGGING) 1762 sclass = C_DWARF; 1763#endif 1764 S_SET_STORAGE_CLASS (secsym, sclass); 1765 S_SET_NUMBER_AUXILIARY (secsym, 1); 1766 SF_SET_STATICS (secsym); 1767#ifdef OBJ_XCOFF 1768 SA_SET_SECT_SCNLEN (secsym, size); 1769#else 1770 SA_SET_SCN_SCNLEN (secsym, size); 1771#endif 1772 } 1773 /* FIXME: These should be in a "stabs.h" file, or maybe as.h. */ 1774#ifndef STAB_SECTION_NAME 1775#define STAB_SECTION_NAME ".stab" 1776#endif 1777#ifndef STAB_STRING_SECTION_NAME 1778#define STAB_STRING_SECTION_NAME ".stabstr" 1779#endif 1780 if (! streq (STAB_STRING_SECTION_NAME, sec->name)) 1781 return; 1782 1783 strsec = sec; 1784 sec = subseg_get (STAB_SECTION_NAME, 0); 1785 /* size is already rounded up, since other section will be listed first */ 1786 size = bfd_section_size (strsec); 1787 1788 n_entries = bfd_section_size (sec) / 12 - 1; 1789 1790 /* Find first non-empty frag. It should be large enough. */ 1791 fragp = seg_info (sec)->frchainP->frch_root; 1792 while (fragp && fragp->fr_fix == 0) 1793 fragp = fragp->fr_next; 1794 gas_assert (fragp != 0 && fragp->fr_fix >= 12); 1795 1796 /* Store the values. */ 1797 p = fragp->fr_literal; 1798 bfd_h_put_16 (stdoutput, n_entries, (bfd_byte *) p + 6); 1799 bfd_h_put_32 (stdoutput, size, (bfd_byte *) p + 8); 1800} 1801 1802void 1803obj_coff_init_stab_section (segT seg) 1804{ 1805 const char *file; 1806 char *p; 1807 char *stabstr_name; 1808 unsigned int stroff; 1809 1810 /* Make space for this first symbol. */ 1811 p = frag_more (12); 1812 /* Zero it out. */ 1813 memset (p, 0, 12); 1814 file = as_where ((unsigned int *) NULL); 1815 stabstr_name = concat (seg->name, "str", (char *) NULL); 1816 stroff = get_stab_string_offset (file, stabstr_name, true); 1817 know (stroff == 1); 1818 md_number_to_chars (p, stroff, 4); 1819} 1820 1821#ifdef DEBUG 1822const char * s_get_name (symbolS *); 1823 1824const char * 1825s_get_name (symbolS *s) 1826{ 1827 return ((s == NULL) ? "(NULL)" : S_GET_NAME (s)); 1828} 1829 1830void symbol_dump (void); 1831 1832void 1833symbol_dump (void) 1834{ 1835 symbolS *symbolP; 1836 1837 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP)) 1838 printf (_("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n"), 1839 (unsigned long) symbolP, 1840 S_GET_NAME (symbolP), 1841 (long) S_GET_DATA_TYPE (symbolP), 1842 S_GET_STORAGE_CLASS (symbolP), 1843 (int) S_GET_SEGMENT (symbolP)); 1844} 1845 1846#endif /* DEBUG */ 1847 1848const pseudo_typeS coff_pseudo_table[] = 1849{ 1850 {"ABORT", s_abort, 0}, 1851 /* We accept the .bss directive for backward compatibility with 1852 earlier versions of gas. */ 1853 {"bss", obj_coff_bss, 0}, 1854#ifdef TE_PE 1855 /* PE provides an enhanced version of .comm with alignment. */ 1856 {"comm", obj_coff_comm, 0}, 1857#endif /* TE_PE */ 1858 {"def", obj_coff_def, 0}, 1859 {"dim", obj_coff_dim, 0}, 1860 {"endef", obj_coff_endef, 0}, 1861 {"ident", obj_coff_ident, 0}, 1862 {"line", obj_coff_line, 0}, 1863 {"ln", obj_coff_ln, 0}, 1864 {"scl", obj_coff_scl, 0}, 1865 {"sect", obj_coff_section, 0}, 1866 {"sect.s", obj_coff_section, 0}, 1867 {"section", obj_coff_section, 0}, 1868 {"section.s", obj_coff_section, 0}, 1869 /* FIXME: We ignore the MRI short attribute. */ 1870 {"size", obj_coff_size, 0}, 1871 {"tag", obj_coff_tag, 0}, 1872 {"type", obj_coff_type, 0}, 1873 {"val", obj_coff_val, 0}, 1874 {"version", s_ignore, 0}, 1875 {"loc", obj_coff_loc, 0}, 1876 {"optim", s_ignore, 0}, /* For sun386i cc (?) */ 1877 {"weak", obj_coff_weak, 0}, 1878#if defined TC_TIC4X 1879 /* The tic4x uses sdef instead of def. */ 1880 {"sdef", obj_coff_def, 0}, 1881#endif 1882#if defined(SEH_CMDS) 1883 SEH_CMDS 1884#endif 1885 {NULL, NULL, 0} 1886}; 1887 1888 1889/* Support for a COFF emulation. */ 1890 1891static void 1892coff_pop_insert (void) 1893{ 1894 pop_insert (coff_pseudo_table); 1895} 1896 1897static int 1898coff_separate_stab_sections (void) 1899{ 1900 return 1; 1901} 1902 1903const struct format_ops coff_format_ops = 1904{ 1905 bfd_target_coff_flavour, 1906 0, /* dfl_leading_underscore */ 1907 1, /* emit_section_symbols */ 1908 0, /* begin */ 1909 c_dot_file_symbol, 1910 coff_frob_symbol, 1911 0, /* frob_file */ 1912 0, /* frob_file_before_adjust */ 1913 0, /* frob_file_before_fix */ 1914 coff_frob_file_after_relocs, 1915 0, /* s_get_size */ 1916 0, /* s_set_size */ 1917 0, /* s_get_align */ 1918 0, /* s_set_align */ 1919 0, /* s_get_other */ 1920 0, /* s_set_other */ 1921 0, /* s_get_desc */ 1922 0, /* s_set_desc */ 1923 0, /* s_get_type */ 1924 0, /* s_set_type */ 1925 0, /* copy_symbol_attributes */ 1926 0, /* generate_asm_lineno */ 1927 0, /* process_stab */ 1928 coff_separate_stab_sections, 1929 obj_coff_init_stab_section, 1930 0, /* sec_sym_ok_for_reloc */ 1931 coff_pop_insert, 1932 0, /* ecoff_set_ext */ 1933 coff_obj_read_begin_hook, 1934 coff_obj_symbol_new_hook, 1935 coff_obj_symbol_clone_hook, 1936 coff_adjust_symtab 1937}; 1938