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