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