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