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