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