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