1 /* coffgrok.c 2 Copyright 1994, 1995, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 3 2007, 2009 Free Software Foundation, Inc. 4 5 This file is part of GNU Binutils. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 20 MA 02110-1301, USA. */ 21 22 23 /* Written by Steve Chamberlain (sac@cygnus.com) 24 25 This module reads a coff file and builds a really simple type tree 26 which can be read by other programs. The first application is a 27 coff->sysroff converter. It can be tested with coffdump.c. */ 28 29 #include "sysdep.h" 30 #include "bfd.h" 31 #include "libiberty.h" 32 33 #include "coff/internal.h" 34 #include "../bfd/libcoff.h" 35 #include "bucomm.h" 36 #include "coffgrok.h" 37 38 static int lofile = 1; 39 static struct coff_scope *top_scope; 40 static struct coff_scope *file_scope; 41 static struct coff_ofile *ofile; 42 43 static struct coff_symbol *last_function_symbol; 44 static struct coff_type *last_function_type; 45 static struct coff_type *last_struct; 46 static struct coff_type *last_enum; 47 static struct coff_sfile *cur_sfile; 48 49 static struct coff_symbol **tindex; 50 51 52 static asymbol **syms; 53 static long symcount; 54 55 #define N(x) ((x)->_n._n_nptr[1]) 56 57 static struct coff_ptr_struct *rawsyms; 58 static int rawcount; 59 static bfd *abfd; 60 61 #define PTR_SIZE 4 62 #define SHORT_SIZE 2 63 #define INT_SIZE 4 64 #define LONG_SIZE 4 65 #define FLOAT_SIZE 4 66 #define DOUBLE_SIZE 8 67 68 #define INDEXOF(p) ((struct coff_ptr_struct *)(p)-(rawsyms)) 69 70 static struct coff_scope *empty_scope (void); 71 static struct coff_symbol *empty_symbol (void); 72 static void push_scope (int); 73 static void pop_scope (void); 74 static void do_sections_p1 (struct coff_ofile *); 75 static void do_sections_p2 (struct coff_ofile *); 76 static struct coff_where *do_where (int); 77 static struct coff_line *do_lines (int, char *); 78 static struct coff_type *do_type (int); 79 static struct coff_visible *do_visible (int); 80 static int do_define (int, struct coff_scope *); 81 static struct coff_ofile *doit (void); 82 83 static struct coff_scope * 84 empty_scope (void) 85 { 86 struct coff_scope *l; 87 l = (struct coff_scope *) (xcalloc (sizeof (struct coff_scope), 1)); 88 return l; 89 } 90 91 static struct coff_symbol * 92 empty_symbol (void) 93 { 94 return (struct coff_symbol *) (xcalloc (sizeof (struct coff_symbol), 1)); 95 } 96 97 /*int l;*/ 98 static void 99 push_scope (int slink) 100 { 101 struct coff_scope *n = empty_scope (); 102 103 if (slink) 104 { 105 if (top_scope) 106 { 107 if (top_scope->list_tail) 108 { 109 top_scope->list_tail->next = n; 110 } 111 else 112 { 113 top_scope->list_head = n; 114 } 115 top_scope->list_tail = n; 116 } 117 } 118 n->parent = top_scope; 119 120 top_scope = n; 121 } 122 123 static void 124 pop_scope (void) 125 { 126 top_scope = top_scope->parent; 127 } 128 129 static void 130 do_sections_p1 (struct coff_ofile *head) 131 { 132 asection *section; 133 int idx; 134 struct coff_section *all = (struct coff_section *) (xcalloc (abfd->section_count + 1, 135 sizeof (struct coff_section))); 136 head->nsections = abfd->section_count + 1; 137 head->sections = all; 138 139 for (idx = 0, section = abfd->sections; section; section = section->next, idx++) 140 { 141 long relsize; 142 int i = section->target_index; 143 arelent **relpp; 144 long relcount; 145 146 relsize = bfd_get_reloc_upper_bound (abfd, section); 147 if (relsize < 0) 148 bfd_fatal (bfd_get_filename (abfd)); 149 if (relsize == 0) 150 continue; 151 relpp = (arelent **) xmalloc (relsize); 152 relcount = bfd_canonicalize_reloc (abfd, section, relpp, syms); 153 if (relcount < 0) 154 bfd_fatal (bfd_get_filename (abfd)); 155 156 head->sections[i].name = (char *) (section->name); 157 head->sections[i].code = section->flags & SEC_CODE; 158 head->sections[i].data = section->flags & SEC_DATA; 159 if (strcmp (section->name, ".bss") == 0) 160 head->sections[i].data = 1; 161 head->sections[i].address = section->lma; 162 head->sections[i].size = bfd_get_section_size (section); 163 head->sections[i].number = idx; 164 head->sections[i].nrelocs = section->reloc_count; 165 head->sections[i].relocs = 166 (struct coff_reloc *) (xcalloc (section->reloc_count, 167 sizeof (struct coff_reloc))); 168 head->sections[i].bfd_section = section; 169 } 170 head->sections[0].name = "ABSOLUTE"; 171 head->sections[0].code = 0; 172 head->sections[0].data = 0; 173 head->sections[0].address = 0; 174 head->sections[0].size = 0; 175 head->sections[0].number = 0; 176 } 177 178 static void 179 do_sections_p2 (struct coff_ofile *head) 180 { 181 asection *section; 182 for (section = abfd->sections; section; section = section->next) 183 { 184 unsigned int j; 185 186 for (j = 0; j < section->reloc_count; j++) 187 { 188 int idx; 189 int i = section->target_index; 190 struct coff_reloc *r = head->sections[i].relocs + j; 191 arelent *sr = section->relocation + j; 192 r->offset = sr->address; 193 r->addend = sr->addend; 194 idx = ((coff_symbol_type *) (sr->sym_ptr_ptr[0]))->native - rawsyms; 195 r->symbol = tindex[idx]; 196 } 197 } 198 } 199 200 static struct coff_where * 201 do_where (int i) 202 { 203 struct internal_syment *sym = &rawsyms[i].u.syment; 204 struct coff_where *where = 205 (struct coff_where *) (xmalloc (sizeof (struct coff_where))); 206 where->offset = sym->n_value; 207 208 if (sym->n_scnum == -1) 209 sym->n_scnum = 0; 210 211 switch (sym->n_sclass) 212 { 213 case C_FIELD: 214 where->where = coff_where_member_of_struct; 215 where->offset = sym->n_value / 8; 216 where->bitoffset = sym->n_value % 8; 217 where->bitsize = rawsyms[i + 1].u.auxent.x_sym.x_misc.x_lnsz.x_size; 218 break; 219 case C_MOE: 220 where->where = coff_where_member_of_enum; 221 break; 222 case C_MOS: 223 case C_MOU: 224 where->where = coff_where_member_of_struct; 225 break; 226 case C_AUTO: 227 case C_ARG: 228 where->where = coff_where_stack; 229 break; 230 case C_EXT: 231 case C_STAT: 232 case C_EXTDEF: 233 case C_LABEL: 234 where->where = coff_where_memory; 235 where->section = &ofile->sections[sym->n_scnum]; 236 break; 237 case C_REG: 238 case C_REGPARM: 239 where->where = coff_where_register; 240 break; 241 case C_ENTAG: 242 where->where = coff_where_entag; 243 break; 244 case C_STRTAG: 245 case C_UNTAG: 246 where->where = coff_where_strtag; 247 break; 248 case C_TPDEF: 249 where->where = coff_where_typedef; 250 break; 251 default: 252 abort (); 253 break; 254 } 255 return where; 256 } 257 258 static 259 struct coff_line * 260 do_lines (int i, char *name ATTRIBUTE_UNUSED) 261 { 262 struct coff_line *res = (struct coff_line *) xcalloc (sizeof (struct coff_line), 1); 263 asection *s; 264 unsigned int l; 265 266 /* Find out if this function has any line numbers in the table */ 267 for (s = abfd->sections; s; s = s->next) 268 { 269 for (l = 0; l < s->lineno_count; l++) 270 { 271 if (s->lineno[l].line_number == 0) 272 { 273 if (rawsyms + i == ((coff_symbol_type *) (&(s->lineno[l].u.sym[0])))->native) 274 { 275 /* These lines are for this function - so count them and stick them on */ 276 int c = 0; 277 /* Find the linenumber of the top of the function, since coff linenumbers 278 are relative to the start of the function. */ 279 int start_line = rawsyms[i + 3].u.auxent.x_sym.x_misc.x_lnsz.x_lnno; 280 281 l++; 282 for (c = 0; s->lineno[l + c + 1].line_number; c++) 283 ; 284 285 /* Add two extra records, one for the prologue and one for the epilogue */ 286 c += 1; 287 res->nlines = c; 288 res->lines = (int *) (xcalloc (sizeof (int), c)); 289 res->addresses = (int *) (xcalloc (sizeof (int), c)); 290 res->lines[0] = start_line; 291 res->addresses[0] = rawsyms[i].u.syment.n_value - s->vma; 292 for (c = 0; s->lineno[l + c + 1].line_number; c++) 293 { 294 res->lines[c + 1] = s->lineno[l + c].line_number + start_line - 1; 295 res->addresses[c + 1] = s->lineno[l + c].u.offset; 296 } 297 return res; 298 } 299 } 300 } 301 } 302 return res; 303 } 304 305 static 306 struct coff_type * 307 do_type (int i) 308 { 309 struct internal_syment *sym = &rawsyms[i].u.syment; 310 union internal_auxent *aux = &rawsyms[i + 1].u.auxent; 311 struct coff_type *res = 312 (struct coff_type *) xmalloc (sizeof (struct coff_type)); 313 int type = sym->n_type; 314 int which_dt = 0; 315 int dimind = 0; 316 317 res->type = coff_basic_type; 318 res->u.basic = type & 0xf; 319 320 switch (type & 0xf) 321 { 322 case T_NULL: 323 case T_VOID: 324 if (sym->n_numaux && sym->n_sclass == C_STAT) 325 { 326 /* This is probably a section definition */ 327 res->type = coff_secdef_type; 328 res->size = aux->x_scn.x_scnlen; 329 } 330 else 331 { 332 if (type == 0) 333 { 334 /* Don't know what this is, let's make it a simple int */ 335 res->size = INT_SIZE; 336 res->u.basic = T_UINT; 337 } 338 else 339 { 340 /* Else it could be a function or pointer to void */ 341 res->size = 0; 342 } 343 } 344 break; 345 346 347 break; 348 case T_UCHAR: 349 case T_CHAR: 350 res->size = 1; 351 break; 352 case T_USHORT: 353 case T_SHORT: 354 res->size = SHORT_SIZE; 355 break; 356 case T_UINT: 357 case T_INT: 358 res->size = INT_SIZE; 359 break; 360 case T_ULONG: 361 case T_LONG: 362 res->size = LONG_SIZE; 363 break; 364 case T_FLOAT: 365 res->size = FLOAT_SIZE; 366 break; 367 case T_DOUBLE: 368 res->size = DOUBLE_SIZE; 369 break; 370 case T_STRUCT: 371 case T_UNION: 372 if (sym->n_numaux) 373 { 374 if (aux->x_sym.x_tagndx.p) 375 { 376 /* Referring to a struct defined elsewhere */ 377 res->type = coff_structref_type; 378 res->u.astructref.ref = tindex[INDEXOF (aux->x_sym.x_tagndx.p)]; 379 res->size = res->u.astructref.ref ? 380 res->u.astructref.ref->type->size : 0; 381 } 382 else 383 { 384 /* A definition of a struct */ 385 last_struct = res; 386 res->type = coff_structdef_type; 387 res->u.astructdef.elements = empty_scope (); 388 res->u.astructdef.idx = 0; 389 res->u.astructdef.isstruct = (type & 0xf) == T_STRUCT; 390 res->size = aux->x_sym.x_misc.x_lnsz.x_size; 391 } 392 } 393 else 394 { 395 /* No auxents - it's anonymous */ 396 res->type = coff_structref_type; 397 res->u.astructref.ref = 0; 398 res->size = 0; 399 } 400 break; 401 case T_ENUM: 402 if (aux->x_sym.x_tagndx.p) 403 { 404 /* Referring to a enum defined elsewhere */ 405 res->type = coff_enumref_type; 406 res->u.aenumref.ref = tindex[INDEXOF (aux->x_sym.x_tagndx.p)]; 407 res->size = res->u.aenumref.ref->type->size; 408 } 409 else 410 { 411 /* A definition of an enum */ 412 last_enum = res; 413 res->type = coff_enumdef_type; 414 res->u.aenumdef.elements = empty_scope (); 415 res->size = aux->x_sym.x_misc.x_lnsz.x_size; 416 } 417 break; 418 case T_MOE: 419 break; 420 } 421 422 for (which_dt = 5; which_dt >= 0; which_dt--) 423 { 424 switch ((type >> ((which_dt * 2) + 4)) & 0x3) 425 { 426 case 0: 427 break; 428 case DT_ARY: 429 { 430 struct coff_type *ptr = ((struct coff_type *) 431 xmalloc (sizeof (struct coff_type))); 432 int els = (dimind < DIMNUM 433 ? aux->x_sym.x_fcnary.x_ary.x_dimen[dimind] 434 : 0); 435 ++dimind; 436 ptr->type = coff_array_type; 437 ptr->size = els * res->size; 438 ptr->u.array.dim = els; 439 ptr->u.array.array_of = res; 440 res = ptr; 441 break; 442 } 443 case DT_PTR: 444 { 445 struct coff_type *ptr = 446 (struct coff_type *) xmalloc (sizeof (struct coff_type)); 447 ptr->size = PTR_SIZE; 448 ptr->type = coff_pointer_type; 449 ptr->u.pointer.points_to = res; 450 res = ptr; 451 break; 452 } 453 case DT_FCN: 454 { 455 struct coff_type *ptr 456 = (struct coff_type *) xmalloc (sizeof (struct coff_type)); 457 ptr->size = 0; 458 ptr->type = coff_function_type; 459 ptr->u.function.function_returns = res; 460 ptr->u.function.parameters = empty_scope (); 461 ptr->u.function.lines = do_lines (i, sym->_n._n_nptr[1]); 462 ptr->u.function.code = 0; 463 last_function_type = ptr; 464 res = ptr; 465 break; 466 } 467 } 468 } 469 return res; 470 } 471 472 static struct coff_visible * 473 do_visible (int i) 474 { 475 struct internal_syment *sym = &rawsyms[i].u.syment; 476 struct coff_visible *visible = 477 (struct coff_visible *) (xmalloc (sizeof (struct coff_visible))); 478 enum coff_vis_type t; 479 switch (sym->n_sclass) 480 { 481 case C_MOS: 482 case C_MOU: 483 case C_FIELD: 484 t = coff_vis_member_of_struct; 485 break; 486 case C_MOE: 487 t = coff_vis_member_of_enum; 488 break; 489 490 case C_REGPARM: 491 t = coff_vis_regparam; 492 break; 493 494 case C_REG: 495 t = coff_vis_register; 496 break; 497 case C_STRTAG: 498 case C_UNTAG: 499 case C_ENTAG: 500 case C_TPDEF: 501 t = coff_vis_tag; 502 break; 503 case C_AUTOARG: 504 case C_ARG: 505 t = coff_vis_autoparam; 506 break; 507 case C_AUTO: 508 509 510 t = coff_vis_auto; 511 break; 512 case C_LABEL: 513 case C_STAT: 514 t = coff_vis_int_def; 515 break; 516 case C_EXT: 517 if (sym->n_scnum == N_UNDEF) 518 { 519 if (sym->n_value) 520 t = coff_vis_common; 521 else 522 t = coff_vis_ext_ref; 523 } 524 else 525 t = coff_vis_ext_def; 526 break; 527 default: 528 abort (); 529 break; 530 531 } 532 visible->type = t; 533 return visible; 534 } 535 536 static int 537 do_define (int i, struct coff_scope *b) 538 { 539 static int symbol_index; 540 struct internal_syment *sym = &rawsyms[i].u.syment; 541 542 /* Define a symbol and attach to block b */ 543 struct coff_symbol *s = empty_symbol (); 544 545 s->number = ++symbol_index; 546 s->name = sym->_n._n_nptr[1]; 547 s->sfile = cur_sfile; 548 /* Glue onto the ofile list */ 549 if (lofile >= 0) 550 { 551 if (ofile->symbol_list_tail) 552 ofile->symbol_list_tail->next_in_ofile_list = s; 553 else 554 ofile->symbol_list_head = s; 555 ofile->symbol_list_tail = s; 556 /* And the block list */ 557 } 558 if (b->vars_tail) 559 b->vars_tail->next = s; 560 else 561 b->vars_head = s; 562 563 b->vars_tail = s; 564 b->nvars++; 565 s->type = do_type (i); 566 s->where = do_where (i); 567 s->visible = do_visible (i); 568 569 tindex[i] = s; 570 571 /* We remember the lowest address in each section for each source file */ 572 573 if (s->where->where == coff_where_memory 574 && s->type->type == coff_secdef_type) 575 { 576 struct coff_isection *is = cur_sfile->section + s->where->section->number; 577 578 if (!is->init) 579 { 580 is->low = s->where->offset; 581 is->high = s->where->offset + s->type->size; 582 is->init = 1; 583 is->parent = s->where->section; 584 } 585 586 } 587 588 if (s->type->type == coff_function_type) 589 last_function_symbol = s; 590 591 return i + sym->n_numaux + 1; 592 } 593 594 595 static 596 struct coff_ofile * 597 doit (void) 598 { 599 int i; 600 int infile = 0; 601 struct coff_ofile *head = 602 (struct coff_ofile *) xmalloc (sizeof (struct coff_ofile)); 603 ofile = head; 604 head->source_head = 0; 605 head->source_tail = 0; 606 head->nsources = 0; 607 head->symbol_list_tail = 0; 608 head->symbol_list_head = 0; 609 do_sections_p1 (head); 610 push_scope (1); 611 612 for (i = 0; i < rawcount;) 613 { 614 struct internal_syment *sym = &rawsyms[i].u.syment; 615 switch (sym->n_sclass) 616 { 617 case C_FILE: 618 { 619 /* new source file announced */ 620 struct coff_sfile *n = 621 (struct coff_sfile *) xmalloc (sizeof (struct coff_sfile)); 622 n->section = (struct coff_isection *) xcalloc (sizeof (struct coff_isection), abfd->section_count + 1); 623 cur_sfile = n; 624 n->name = sym->_n._n_nptr[1]; 625 n->next = 0; 626 627 if (infile) 628 { 629 pop_scope (); 630 } 631 infile = 1; 632 push_scope (1); 633 file_scope = n->scope = top_scope; 634 635 if (head->source_tail) 636 head->source_tail->next = n; 637 else 638 head->source_head = n; 639 head->source_tail = n; 640 head->nsources++; 641 i += sym->n_numaux + 1; 642 } 643 break; 644 case C_FCN: 645 { 646 char *name = sym->_n._n_nptr[1]; 647 if (name[1] == 'b') 648 { 649 /* Function start */ 650 push_scope (0); 651 last_function_type->u.function.code = top_scope; 652 top_scope->sec = ofile->sections + sym->n_scnum; 653 top_scope->offset = sym->n_value; 654 } 655 else 656 { 657 top_scope->size = sym->n_value - top_scope->offset + 1; 658 pop_scope (); 659 660 } 661 i += sym->n_numaux + 1; 662 } 663 break; 664 665 case C_BLOCK: 666 { 667 char *name = sym->_n._n_nptr[1]; 668 if (name[1] == 'b') 669 { 670 /* Block start */ 671 push_scope (1); 672 top_scope->sec = ofile->sections + sym->n_scnum; 673 top_scope->offset = sym->n_value; 674 675 } 676 else 677 { 678 top_scope->size = sym->n_value - top_scope->offset + 1; 679 pop_scope (); 680 } 681 i += sym->n_numaux + 1; 682 } 683 break; 684 case C_REGPARM: 685 case C_ARG: 686 i = do_define (i, last_function_symbol->type->u.function.parameters); 687 break; 688 case C_MOS: 689 case C_MOU: 690 case C_FIELD: 691 i = do_define (i, last_struct->u.astructdef.elements); 692 break; 693 case C_MOE: 694 i = do_define (i, last_enum->u.aenumdef.elements); 695 break; 696 case C_STRTAG: 697 case C_ENTAG: 698 case C_UNTAG: 699 /* Various definition */ 700 i = do_define (i, top_scope); 701 break; 702 case C_EXT: 703 case C_LABEL: 704 i = do_define (i, file_scope); 705 break; 706 case C_STAT: 707 case C_TPDEF: 708 case C_AUTO: 709 case C_REG: 710 i = do_define (i, top_scope); 711 break; 712 default: 713 abort (); 714 case C_EOS: 715 i += sym->n_numaux + 1; 716 break; 717 } 718 } 719 do_sections_p2 (head); 720 return head; 721 } 722 723 struct coff_ofile * 724 coff_grok (bfd *inabfd) 725 { 726 long storage; 727 struct coff_ofile *p; 728 abfd = inabfd; 729 storage = bfd_get_symtab_upper_bound (abfd); 730 731 if (storage < 0) 732 bfd_fatal (abfd->filename); 733 734 syms = (asymbol **) xmalloc (storage); 735 symcount = bfd_canonicalize_symtab (abfd, syms); 736 if (symcount < 0) 737 bfd_fatal (abfd->filename); 738 rawsyms = obj_raw_syments (abfd); 739 rawcount = obj_raw_syment_count (abfd);; 740 tindex = (struct coff_symbol **) (xcalloc (sizeof (struct coff_symbol *), rawcount)); 741 742 p = doit (); 743 return p; 744 } 745