1 /* Copyright (C) 2021 Free Software Foundation, Inc. 2 Contributed by Oracle. 3 4 This file is part of GNU Binutils. 5 6 This program 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 This program 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 this program; if not, write to the Free Software 18 Foundation, 51 Franklin Street - Fifth Floor, Boston, 19 MA 02110-1301, USA. */ 20 21 #include "config.h" 22 #include "util.h" 23 #include "DbeSession.h" 24 #include "Elf.h" 25 #include "Stabs.h" 26 #include "Dwarf.h" 27 #include "DataObject.h" 28 #include "Function.h" 29 #include "LoadObject.h" 30 #include "Module.h" 31 #include "DefaultMap.h" 32 33 static int 34 datatypeCmp (const void *a, const void *b) 35 { 36 uint32_t o1 = ((datatype_t *) a)->datatype_id; 37 uint32_t o2 = ((datatype_t *) b)->datatype_id; 38 return o1 == o2 ? 0 : (o1 < o2 ? -1 : 1); 39 } 40 41 static int 42 targetOffsetCmp (const void *a, const void *b) 43 { 44 uint32_t o1 = ((target_info_t *) a)->offset; 45 uint32_t o2 = ((target_info_t *) b)->offset; 46 return o1 == o2 ? 0 : (o1 < o2 ? -1 : 1); 47 } 48 49 50 ////////////////////////////////////////////////////////// 51 // class Dwr_type 52 class Dwr_type 53 { 54 public: 55 56 Dwr_type (int64_t _cu_die_offset, int _tag) 57 { 58 cu_die_offset = _cu_die_offset; 59 tag = _tag; 60 name = NULL; 61 dobj_name = NULL; 62 dtype = NULL; 63 extent = 0; 64 parent = 0; 65 child = 0; 66 next = 0; 67 ref_type = 0; 68 size = 0; 69 elems = 0; 70 offset = -1; 71 bit_size = 0; 72 }; 73 74 char *name, *dobj_name; 75 int64_t cu_die_offset, ref_type, extent, parent, child, next; 76 int64_t size, elems, offset; 77 int tag, bit_size; 78 79 DataObject *get_dobj (Dwarf_cnt *ctx); 80 char *get_dobjname (Dwarf_cnt *ctx); 81 char *dump (); 82 83 private: 84 datatype_t *dtype; 85 datatype_t *get_datatype (Dwarf_cnt *ctx); 86 void get_dobj_for_members (Dwarf_cnt *ctx); 87 void set_dobjname (char *spec, char *nm); 88 }; 89 90 91 ////////////////////////////////////////////////////////// 92 // class Dwarf_cnt 93 Dwarf_cnt::Dwarf_cnt () 94 { 95 cu_offset = 0; 96 parent = 0; 97 module = NULL; 98 name = NULL; 99 func = NULL; 100 fortranMAIN = NULL; 101 dwr_types = NULL; 102 inlinedSubr = NULL; 103 level = 0; 104 } 105 106 Dwr_type * 107 Dwarf_cnt::get_dwr_type (int64_t cu_die_offset) 108 { 109 Dwr_type *t = dwr_types->get (cu_die_offset); 110 if (t == NULL) 111 { 112 Dprintf (DUMP_DWARFLIB, "DWARF_ERROR: %s:%d wrong cu_die_offset=%lld in Dwarf_cnt::get_dwr_type\n", 113 get_basename (__FILE__), (int) __LINE__, 114 (long long) cu_die_offset); 115 t = put_dwr_type (cu_die_offset, 0); // DOBJ_UNSPECIFIED 116 } 117 return t; 118 } 119 120 Dwr_type * 121 Dwarf_cnt::put_dwr_type (int64_t cu_die_offset, int tag) 122 { 123 Dwr_type *t = new Dwr_type (cu_die_offset, tag); 124 dwr_types->put (cu_die_offset, t); 125 return t; 126 } 127 128 Dwr_type * 129 Dwarf_cnt::put_dwr_type (Dwr_Tag *dwrTag) 130 { 131 Dwr_type *t = new Dwr_type (dwrTag->die, dwrTag->tag); 132 dwr_types->put (dwrTag->die, t); 133 return t; 134 } 135 136 ////////////////////////////////////////////////////////// 137 // class Dwr_type 138 char * 139 Dwr_type::dump () 140 { 141 char *s = dbe_sprintf ("%lld %-15s name='%s' parent=%lld next=%lld child=%lld dtype=%llx", 142 (long long) cu_die_offset, DwrCU::tag2str (tag), 143 STR (name), (long long) parent, (long long) next, 144 (long long) child, (long long) dtype); 145 return s; 146 } 147 148 void 149 Dwr_type::set_dobjname (char *spec, char *nm) 150 { 151 if (spec) 152 { 153 if (nm) 154 dobj_name = dbe_sprintf ("%s%s", spec, nm); 155 else 156 dobj_name = dbe_sprintf ("%s<ANON=%lld>", spec, 157 (long long) cu_die_offset); 158 } 159 else 160 { 161 if (nm) 162 dobj_name = dbe_sprintf ("%s", nm); 163 else 164 dobj_name = dbe_sprintf ("<ANON=%lld>", (long long) cu_die_offset); 165 } 166 } 167 168 char * 169 Dwr_type::get_dobjname (Dwarf_cnt *ctx) 170 { 171 if (dobj_name) 172 return dobj_name; 173 switch (tag) 174 { 175 case DW_TAG_base_type: 176 set_dobjname (NULL, name); 177 for (int i = 0, len = (int) strlen (dobj_name); i < len; i++) 178 { 179 if (dobj_name[i] == ' ') 180 dobj_name[i] = '_'; 181 } 182 break; 183 case DW_TAG_constant: 184 case DW_TAG_formal_parameter: 185 case DW_TAG_variable: 186 { 187 Dwr_type *t = ctx->get_dwr_type (ref_type); 188 set_dobjname (NULL, t->get_dobjname (ctx)); 189 break; 190 } 191 case DW_TAG_unspecified_type: 192 set_dobjname (NTXT ("unspecified:"), name); 193 break; 194 case DW_TAG_enumeration_type: 195 set_dobjname (NTXT ("enumeration:"), name); 196 break; 197 case DW_TAG_typedef: 198 { 199 Dwr_type *t = ctx->get_dwr_type (ref_type); 200 dobj_name = dbe_sprintf ("%s=%s", name, t->get_dobjname (ctx)); 201 break; 202 } 203 case DW_TAG_const_type: 204 set_dobjname (NTXT ("const+"), name); 205 break; 206 case DW_TAG_volatile_type: 207 set_dobjname (NTXT ("volatile+"), name); 208 break; 209 case DW_TAG_pointer_type: 210 { 211 Dwr_type *t = ctx->get_dwr_type (ref_type); 212 set_dobjname (NTXT ("pointer+"), t->get_dobjname (ctx)); 213 break; 214 } 215 case DW_TAG_reference_type: 216 { 217 Dwr_type *t = ctx->get_dwr_type (ref_type); 218 set_dobjname (NTXT ("reference+"), t->get_dobjname (ctx)); 219 break; 220 } 221 case DW_TAG_array_type: 222 { 223 Dwr_type *t = ctx->get_dwr_type (ref_type); 224 if (elems > 0) 225 dobj_name = dbe_sprintf ("array[%lld]:%s", 226 (long long) elems, t->get_dobjname (ctx)); 227 else 228 dobj_name = dbe_sprintf ("array[]:%s", t->get_dobjname (ctx)); 229 break; 230 } 231 case DW_TAG_structure_type: 232 set_dobjname (NTXT ("structure:"), name); 233 break; 234 case DW_TAG_union_type: 235 set_dobjname (NTXT ("union:"), name); 236 break; 237 case DW_TAG_class_type: 238 set_dobjname (NTXT ("class:"), name); 239 break; 240 case DW_TAG_member: 241 { 242 Dwr_type *t = ctx->get_dwr_type (ref_type); 243 if (bit_size > 0) 244 dobj_name = dbe_sprintf (NTXT ("%s:%lld"), t->get_dobjname (ctx), 245 (long long) bit_size); 246 else 247 dobj_name = dbe_sprintf (NTXT ("%s"), t->get_dobjname (ctx)); 248 break; 249 } 250 default: 251 Dprintf (DUMP_DWARFLIB, NTXT ("DWARF_ERROR: %s:%d No case for %s cu_die_offset=%lld\n"), 252 get_basename (__FILE__), (int) __LINE__, 253 DwrCU::tag2str (tag), (long long) cu_die_offset); 254 set_dobjname (NTXT ("Undefined:"), NULL); 255 break; 256 } 257 return dobj_name; 258 } 259 260 datatype_t* 261 Dwr_type::get_datatype (Dwarf_cnt *ctx) 262 { 263 if (dtype) 264 return dtype; 265 dtype = new datatype_t; 266 dtype->datatype_id = (unsigned) cu_die_offset; 267 dtype->memop_refs = 0; 268 dtype->event_data = 0; 269 dtype->dobj = NULL; 270 ctx->module->datatypes->incorporate (dtype, datatypeCmp); 271 return dtype; 272 } 273 274 DataObject * 275 Dwr_type::get_dobj (Dwarf_cnt *ctx) 276 { 277 if (dtype == NULL) 278 dtype = get_datatype (ctx); 279 dtype->memop_refs++; 280 DataObject *dobj = dtype->dobj; 281 if (dobj) 282 return dobj; 283 284 if (tag == 0) 285 dobj = dbeSession->find_dobj_by_name (PTXT (DOBJ_UNSPECIFIED)); 286 else 287 { 288 dobj = dbeSession->createDataObject (); 289 dobj->size = size; 290 dobj->offset = offset; 291 dobj->scope = ctx->func ? (Histable*) ctx->func : (Histable*) ctx->module; 292 } 293 dtype->dobj = dobj; 294 if (parent) 295 { 296 Dwr_type *t = ctx->get_dwr_type (parent); 297 dobj->parent = t->get_dobj (ctx); 298 } 299 300 if (ref_type) 301 { 302 Dwr_type *t = ctx->get_dwr_type (ref_type); 303 t->get_dobj (ctx); 304 if (size == 0) 305 { 306 size = t->size; 307 dobj->size = size; 308 } 309 } 310 311 switch (tag) 312 { 313 case 0: 314 break; 315 case DW_TAG_array_type: 316 case DW_TAG_base_type: 317 case DW_TAG_unspecified_type: 318 case DW_TAG_enumeration_type: 319 case DW_TAG_typedef: 320 case DW_TAG_const_type: 321 case DW_TAG_volatile_type: 322 case DW_TAG_pointer_type: 323 case DW_TAG_reference_type: 324 dobj->set_dobjname (get_dobjname (ctx), NULL); 325 break; 326 case DW_TAG_structure_type: 327 case DW_TAG_union_type: 328 case DW_TAG_class_type: 329 dobj->set_dobjname (get_dobjname (ctx), NULL); 330 dobj->master = dbeSession->find_dobj_by_name (dobj_name); 331 get_dobj_for_members (ctx); 332 break; 333 case DW_TAG_constant: 334 case DW_TAG_formal_parameter: 335 case DW_TAG_member: 336 case DW_TAG_variable: 337 if (dobj->parent == NULL) 338 dobj->parent = dbeSession->get_Scalars_DataObject (); 339 dobj->set_dobjname (get_dobjname (ctx), name); 340 break; 341 default: 342 Dprintf (DUMP_DWARFLIB, NTXT ("DWARF_ERROR: %s:%d No case for %s cu_die_offset=%lld\n"), 343 get_basename (__FILE__), (int) __LINE__, 344 DwrCU::tag2str (tag), (long long) cu_die_offset); 345 break; 346 } 347 return dobj; 348 } 349 350 void 351 Dwr_type::get_dobj_for_members (Dwarf_cnt *ctx) 352 { 353 for (int64_t i = child; i != 0;) 354 { 355 Dwr_type *t = ctx->get_dwr_type (i); 356 t->get_dobj (ctx); 357 i = t->next; 358 } 359 } 360 361 ////////////////////////////////////////////////////////// 362 // class Dwarf 363 Dwarf::Dwarf (Stabs *_stabs) 364 { 365 stabs = _stabs; 366 status = Stabs::DBGD_ERR_NONE; 367 dwrCUs = 0; 368 debug_infoSec = NULL; 369 debug_abbrevSec = NULL; 370 debug_strSec = NULL; 371 debug_lineSec = NULL; 372 debug_rangesSec = NULL; 373 elf = stabs->openElf (true); 374 if (elf == NULL) 375 { 376 status = Stabs::DBGD_ERR_BAD_ELF_FORMAT; 377 return; 378 } 379 debug_infoSec = dwrGetSec (NTXT (".debug_info")); 380 if (debug_infoSec) 381 { 382 debug_infoSec->reloc = ElfReloc::get_elf_reloc (elf, NTXT (".rela.debug_info"), NULL); 383 debug_infoSec->reloc = ElfReloc::get_elf_reloc (elf, NTXT (".rel.debug_info"), debug_infoSec->reloc); 384 if (debug_infoSec->reloc) 385 debug_infoSec->reloc->dump (); 386 } 387 debug_abbrevSec = dwrGetSec (NTXT (".debug_abbrev")); 388 debug_strSec = dwrGetSec (NTXT (".debug_str")); 389 debug_lineSec = dwrGetSec (NTXT (".debug_line")); 390 debug_rangesSec = dwrGetSec (NTXT (".debug_ranges")); 391 392 if ((debug_infoSec == NULL) || (debug_abbrevSec == NULL) || (debug_lineSec == NULL)) 393 { 394 status = Stabs::DBGD_ERR_NO_DWARF; 395 return; 396 } 397 } 398 399 Dwarf::~Dwarf () 400 { 401 delete debug_infoSec; 402 delete debug_abbrevSec; 403 delete debug_strSec; 404 delete debug_lineSec; 405 delete debug_rangesSec; 406 Destroy (dwrCUs); 407 } 408 409 DwrSec * 410 Dwarf::dwrGetSec (const char *sec_name) 411 { 412 int secN = elf->elf_get_sec_num (sec_name); 413 if (secN > 0) 414 { 415 Elf_Data *elfData = elf->elf_getdata (secN); 416 if (elfData) 417 return new DwrSec ((unsigned char *) elfData->d_buf, elfData->d_size, 418 elf->need_swap_endian, 419 elf->elf_getclass () == ELFCLASS32); 420 } 421 return NULL; 422 } 423 424 uint64_t 425 DwrCU::get_low_pc () 426 { 427 uint64_t pc = Dwarf_addr (DW_AT_low_pc); 428 if (pc) 429 return pc; 430 return pc; 431 } 432 433 char * 434 DwrCU::get_linkage_name () 435 { 436 char *nm = Dwarf_string (DW_AT_linkage_name); 437 if (nm != NULL) 438 return nm; 439 nm = Dwarf_string (DW_AT_SUN_link_name); 440 if (nm != NULL) 441 return nm; 442 return Dwarf_string (DW_AT_MIPS_linkage_name); 443 } 444 445 void 446 DwrCU::parseChild (Dwarf_cnt *ctx) 447 { 448 if (!dwrTag.hasChild) 449 return; 450 uint64_t old_size = debug_infoSec->size; 451 uint64_t next_die_offset = 0; 452 Dwarf_Die next_die; 453 if (read_ref_attr (DW_AT_sibling, &next_die) == DW_DLV_OK) 454 { 455 next_die_offset = next_die + cu_offset; 456 if (next_die_offset <= debug_infoSec->offset) 457 { 458 Dprintf (DEBUG_ERR_MSG, NTXT ("DwrCU::parseChild: next_die(0x%llx) <= debug_infoSec->offset(%llx)\n"), 459 (long long) next_die, (long long) debug_infoSec->offset); 460 next_die_offset = 0; 461 } 462 else if (debug_infoSec->size > next_die_offset) 463 debug_infoSec->size = next_die_offset; 464 } 465 dwrTag.level++; 466 ctx->level++; 467 for (;;) 468 { 469 if (set_die (0) != DW_DLV_OK) 470 break; 471 Function *func; 472 char *old_name; 473 int hasChild = dwrTag.hasChild; 474 switch (dwrTag.tag) 475 { 476 case DW_TAG_imported_declaration: 477 if (Stabs::is_fortran (ctx->module->lang_code)) 478 { 479 char *link_name = Dwarf_string (DW_AT_name); 480 ctx->fortranMAIN = NULL; 481 parseChild (ctx); 482 hasChild = 0; 483 if (ctx->fortranMAIN) 484 { 485 ctx->fortranMAIN->set_match_name (link_name); 486 ctx->fortranMAIN = NULL; 487 } 488 } 489 break; 490 case DW_TAG_subprogram: 491 if (dwrTag.get_attr (DW_AT_abstract_origin)) 492 break; 493 if (dwrTag.get_attr (DW_AT_declaration)) 494 { 495 // Only declaration 496 if (Stabs::is_fortran (ctx->module->lang_code)) 497 { 498 char *link_name = Dwarf_string (DW_AT_name); 499 if (link_name && streq (link_name, NTXT ("MAIN"))) 500 ctx->fortranMAIN = Stabs::find_func (NTXT ("MAIN"), ctx->module->functions, true, true); 501 } 502 if (get_linkage_name () == NULL) 503 break; 504 } 505 func = append_Function (ctx); 506 if (func) 507 { 508 if (Stabs::is_fortran (ctx->module->lang_code) && 509 streq (func->get_match_name (), NTXT ("MAIN"))) 510 ctx->fortranMAIN = func; 511 old_name = ctx->name; 512 Function *old_func = ctx->func; 513 ctx->name = func->get_match_name (); 514 ctx->func = func; 515 parseChild (ctx); 516 hasChild = 0; 517 ctx->name = old_name; 518 ctx->func = old_func; 519 } 520 break; 521 case DW_TAG_module: 522 old_name = ctx->name; 523 ctx->name = Dwarf_string (DW_AT_SUN_link_name); 524 parseChild (ctx); 525 hasChild = 0; 526 ctx->name = old_name; 527 break; 528 case DW_TAG_class_type: 529 old_name = ctx->name; 530 ctx->name = Dwarf_string (DW_AT_name); 531 parseChild (ctx); 532 hasChild = 0; 533 ctx->name = old_name; 534 break; 535 case DW_TAG_structure_type: 536 old_name = ctx->name; 537 ctx->name = NULL; 538 parseChild (ctx); 539 hasChild = 0; 540 ctx->name = old_name; 541 break; 542 case DW_TAG_namespace: 543 old_name = ctx->name; 544 ctx->name = Dwarf_string (DW_AT_name); 545 parseChild (ctx); 546 hasChild = 0; 547 ctx->name = old_name; 548 break; 549 case DW_TAG_lexical_block: 550 old_name = ctx->name; 551 ctx->name = NULL; 552 parseChild (ctx); 553 hasChild = 0; 554 ctx->name = old_name; 555 break; 556 case DW_TAG_SUN_memop_info: 557 isMemop = true; 558 break; 559 case DW_TAG_inlined_subroutine: 560 if (ctx->module) 561 { 562 parse_inlined_subroutine (ctx); 563 hasChild = 0; 564 } 565 break; 566 default: // No more special cases 567 break; 568 } 569 if (hasChild) 570 parseChild (ctx); 571 } 572 ctx->level--; 573 dwrTag.level--; 574 if (next_die_offset != 0) 575 debug_infoSec->offset = next_die_offset; 576 debug_infoSec->size = old_size; 577 } 578 579 bool 580 Dwarf::archive_Dwarf (LoadObject *lo) 581 { 582 if (debug_infoSec == NULL) 583 return false; 584 if (dwrCUs) 585 return true; 586 dwrCUs = new Vector<DwrCU *>; 587 588 debug_infoSec->offset = 0; 589 while (debug_infoSec->offset < debug_infoSec->sizeSec) 590 { 591 DwrCU *dwrCU = new DwrCU (this); 592 dwrCUs->append (dwrCU); 593 debug_infoSec->size = debug_infoSec->sizeSec; 594 debug_infoSec->offset = dwrCU->next_cu_offset; 595 596 if (dwrCU->set_die (dwrCU->cu_header_offset) != DW_DLV_OK) 597 { 598 Dprintf (1, "DwrCU::archive_Dwarf: CU=%lld (offset=0x%llx); set_die(0x%llx) failed\n", 599 (long long) dwrCUs->size (), (long long) dwrCU->cu_offset, 600 (long long) dwrCU->cu_header_offset); 601 continue; 602 } 603 604 Module *mod = dwrCU->parse_cu_header (lo); 605 if (mod) 606 { 607 mod->hdrOffset = dwrCUs->size (); 608 DwrLineRegs *lineReg = dwrCU->get_dwrLineReg (); 609 dwrCU->srcFiles = new Vector<SourceFile *> (VecSize (lineReg->file_names)); 610 for (long i = 0, sz = VecSize (lineReg->file_names); i < sz; i++) 611 { 612 char *fname = lineReg->getPath (i + 1); 613 SourceFile *sf = mod->findSource (fname, true); 614 dwrCU->srcFiles->append (sf); 615 } 616 617 Dwarf_cnt ctx; 618 ctx.module = mod; 619 dwrCU->parseChild (&ctx); 620 if (dwrCU->dwrInlinedSubrs && DUMP_DWARFLIB) 621 { 622 char msg[128]; 623 char *lo_name = mod->loadobject ? mod->loadobject->get_name () 624 : NULL; 625 snprintf (msg, sizeof (msg), NTXT ("\ndwrCUs[%lld]: %s:%s\n"), 626 (long long) dwrCUs->size (), 627 STR (lo_name), STR (mod->get_name ())); 628 dwrCU->dwrInlinedSubrs->dump (msg); 629 } 630 } 631 } 632 return true; 633 } 634 635 void 636 Dwarf::srcline_Dwarf (Module *module) 637 { 638 if (module == NULL || module->hdrOffset == 0) 639 return; 640 DwrCU *dwrCU = dwrCUs->get (module->hdrOffset - 1); 641 dwrCU->map_dwarf_lines (module); 642 } 643 644 645 // parse hwcprof info for given module in loadobject 646 647 void 648 Dwarf::read_hwcprof_info (Module *module) 649 { 650 if (module->datatypes || (module->hdrOffset == 0)) 651 return; 652 DwrCU *dwrCU = dwrCUs->get (module->hdrOffset - 1); 653 if (!dwrCU->isMemop) 654 return; 655 module->datatypes = new Vector<datatype_t*>; 656 if (dwrCU->set_die (dwrCU->cu_header_offset) != DW_DLV_OK) 657 { 658 Dprintf (1, "Dwarf::read_hwcprof_info: CU=%lld (offset=0x%llx); set_die(0x%llx) failed\n", 659 (long long) module->hdrOffset, (long long) dwrCU->cu_offset, 660 (long long) dwrCU->cu_header_offset); 661 return; 662 } 663 Dwarf_cnt ctx; 664 ctx.module = module; 665 ctx.cu_offset = dwrCU->cu_offset; // CU header offset; 666 ctx.dwr_types = new DefaultMap<int64_t, Dwr_type*>; 667 ctx.put_dwr_type (0, 0); // for DOBJ_UNSPECIFIED 668 dwrCU->read_hwcprof_info (&ctx); 669 670 Vector<inst_info_t*> *infoList = module->infoList; 671 Dprintf (DUMP_DWARFLIB, 672 "\n\n ### Dwarf::read_hwcprof_info: module: '%s' infoList->size()=%lld\n", 673 STR (module->get_name ()), 674 (long long) (infoList ? infoList->size () : -1)); 675 for (int i = 0, sz = infoList ? infoList->size () : -1; i < sz; i++) 676 { 677 inst_info_t *ip = infoList->fetch (i); 678 memop_info_t *mp = ip->memop; 679 Dwr_type *t = ctx.get_dwr_type (mp->datatype_id); 680 t->get_dobj (&ctx); 681 } 682 683 #ifdef DEBUG 684 Dprintf (DUMP_DWARFLIB, 685 "\n\n ### Dwarf::read_hwcprof_info: '%s' infoList->size()=%lld\n", 686 STR (module->get_name ()), 687 (long long) (infoList ? infoList->size () : 1)); 688 for (int i = 0, sz = infoList ? infoList->size () : -1; i < sz; i++) 689 { 690 inst_info_t *ip = infoList->fetch (i); 691 memop_info_t *mp = ip->memop; 692 Dprintf (DUMP_DWARFLIB, 693 " %d id=%lld offset=%lld signature=%lld datatype_id=%lld \n", 694 i, (long long) mp->id, (long long) mp->offset, 695 (long long) mp->signature, (long long) mp->datatype_id); 696 } 697 698 Vector<int64_t> *keys = ctx.dwr_types->keySet (); 699 Dprintf (DUMP_DWARFLIB, 700 "\n\n ### Dwarf::read_hwcprof_info: '%s' keys->size()=%lld\n", 701 STR (module->get_name ()), (long long) (keys ? keys->size () : -1)); 702 for (int i = 0, sz = keys->size (); i < sz; i++) 703 { 704 int64_t ind = keys->fetch (i); 705 Dwr_type *t = ctx.get_dwr_type (ind); 706 Dprintf (DUMP_DWARFLIB, NTXT (" %d %lld %s\n"), i, 707 (long long) ind, t->dump ()); 708 } 709 #endif 710 } 711 712 void 713 DwrCU::read_hwcprof_info (Dwarf_cnt *ctx) 714 { 715 if (!dwrTag.hasChild) 716 return; 717 uint64_t old_size = debug_infoSec->size; 718 uint64_t next_die_offset = 0; 719 Dwarf_Die next_die; 720 if (read_ref_attr (DW_AT_sibling, &next_die) == DW_DLV_OK) 721 { 722 next_die_offset = next_die + cu_offset; 723 if (next_die_offset <= debug_infoSec->offset) 724 next_die_offset = 0; 725 else if (debug_infoSec->size > next_die_offset) 726 debug_infoSec->size = next_die_offset; 727 } 728 dwrTag.level++; 729 ctx->level++; 730 for (;;) 731 { 732 if (set_die (0) != DW_DLV_OK) 733 break; 734 Dprintf (DUMP_DWARFLIB, NTXT ("%s:%d <%lld:%lld> cu_die=%lld %-15s\n"), 735 get_basename (__FILE__), (int) __LINE__, (long long) ctx->level, 736 (long long) dwrTag.die, (long long) dwrTag.offset, 737 DwrCU::tag2str (dwrTag.tag)); 738 switch (dwrTag.tag) 739 { 740 case DW_TAG_SUN_memop_info: 741 { 742 if (ctx->func == NULL) 743 break; 744 Dwarf_Unsigned mid = Dwarf_data (DW_AT_SUN_profile_id); 745 Dwarf_Unsigned off = Dwarf_data (DW_AT_SUN_func_offset); 746 Dwarf_Unsigned sig = Dwarf_data (DW_AT_SUN_memop_signature); 747 Dwarf_Off ref = Dwarf_ref (DW_AT_SUN_memop_type_ref); 748 749 // define memop entry 750 memop_info_t *memop = new memop_info_t; 751 memop->id = (unsigned) mid; 752 memop->signature = (unsigned) sig; 753 memop->datatype_id = ref ? (unsigned) ref : 0; 754 memop->offset = (unsigned) (ctx->func->img_offset + off); 755 756 // define instop entry 757 inst_info_t *instop = new inst_info_t; 758 instop->type = CPF_INSTR_TYPE_PREFETCH; // XXXX UNKNOWN 759 instop->offset = memop->offset; 760 instop->memop = memop; 761 if (ctx->module->infoList == NULL) 762 ctx->module->infoList = new Vector<inst_info_t*>; 763 ctx->module->infoList->append (instop); 764 break; 765 } 766 case DW_TAG_SUN_codeflags: 767 { 768 if (ctx->func == NULL) 769 break; 770 Dwarf_Unsigned kind = Dwarf_data (DW_AT_SUN_cf_kind); 771 if (kind == DW_ATCF_SUN_branch_target) 772 { 773 DwrSec *secp = Dwarf_block (DW_AT_SUN_func_offsets); 774 if (secp) 775 { 776 int foffset = 0; 777 for (int i = 0; secp->offset < secp->size; i++) 778 { 779 int val = (int) secp->GetSLEB128 (); 780 if (i == 0 || val != 0) 781 { 782 foffset += val; 783 target_info_t *t = new target_info_t; 784 t->offset = (unsigned) (ctx->func->img_offset + foffset); 785 ctx->module->bTargets.incorporate (t, targetOffsetCmp); 786 } 787 } 788 delete(secp); 789 } 790 } 791 break; 792 } 793 case DW_TAG_subprogram: 794 { 795 Function *old_func = ctx->func; 796 if (dwrTag.get_attr (DW_AT_abstract_origin) 797 || dwrTag.get_attr (DW_AT_declaration)) 798 ctx->func = NULL; 799 else 800 ctx->func = append_Function (ctx); 801 read_hwcprof_info (ctx); 802 ctx->func = old_func; 803 break; 804 } 805 case DW_TAG_base_type: 806 { 807 Dwr_type *t = ctx->put_dwr_type (dwrTag.die, dwrTag.tag); 808 t->name = Dwarf_string (DW_AT_name); 809 t->size = Dwarf_data (DW_AT_byte_size); 810 break; 811 } 812 case DW_TAG_unspecified_type: 813 ctx->put_dwr_type (dwrTag.die, dwrTag.tag); 814 break; 815 case DW_TAG_enumeration_type: 816 { 817 Dwr_type *t = ctx->put_dwr_type (dwrTag.die, dwrTag.tag); 818 t->name = Dwarf_string (DW_AT_name); 819 t->size = Dwarf_data (DW_AT_byte_size); 820 break; 821 } 822 case DW_TAG_constant: 823 case DW_TAG_formal_parameter: 824 case DW_TAG_variable: 825 case DW_TAG_typedef: 826 case DW_TAG_const_type: 827 case DW_TAG_volatile_type: 828 { 829 Dwr_type *t = ctx->put_dwr_type (dwrTag.die, dwrTag.tag); 830 t->name = Dwarf_string (DW_AT_name); 831 t->ref_type = Dwarf_ref (DW_AT_type); 832 break; 833 } 834 case DW_TAG_pointer_type: 835 case DW_TAG_reference_type: 836 { 837 Dwr_type *t = ctx->put_dwr_type (dwrTag.die, dwrTag.tag); 838 t->name = Dwarf_string (DW_AT_name); 839 t->ref_type = Dwarf_ref (DW_AT_type); 840 t->size = (dwarf->stabs->get_class () == W64) ? 8 : 4; 841 break; 842 } 843 case DW_TAG_array_type: 844 { 845 Dwr_type *t = ctx->put_dwr_type (dwrTag.die, dwrTag.tag); 846 t->name = Dwarf_string (DW_AT_name); 847 t->ref_type = Dwarf_ref (DW_AT_type); 848 t->size = Dwarf_data (DW_AT_byte_size); 849 ctx->size = -1; 850 read_hwcprof_info (ctx); 851 t->elems = ctx->size; 852 break; 853 } 854 case DW_TAG_subrange_type: 855 { 856 int64_t ref_type = Dwarf_ref (DW_AT_type); 857 int64_t hi = Dwarf_data (DW_AT_upper_bound); 858 int64_t lo = Dwarf_data (DW_AT_lower_bound); 859 int64_t ss = Dwarf_data (DW_AT_stride_size); 860 ctx->size = 1 + hi - lo; 861 if (ss != 0) 862 ctx->size /= ss; 863 Dprintf (DUMP_DWARFLIB, 864 "Got subrange [%lld:%lld:%lld] indexed <%lld>: size=%lld\n", 865 (long long) lo, (long long) hi, (long long) ss, 866 (long long) ref_type, (long long) ctx->size); 867 break; 868 } 869 case DW_TAG_structure_type: 870 case DW_TAG_union_type: 871 case DW_TAG_class_type: 872 { 873 Dwr_type *t = ctx->put_dwr_type (dwrTag.die, dwrTag.tag); 874 t->name = Dwarf_string (DW_AT_name); 875 t->size = Dwarf_data (DW_AT_byte_size); 876 t->extent = Dwarf_ref (DW_AT_sibling); 877 int64_t old_parent = ctx->parent; 878 ctx->parent = t->cu_die_offset; 879 880 char *old_name = ctx->name; 881 ctx->name = (dwrTag.tag == DW_TAG_class_type) ? Dwarf_string (DW_AT_name) : NULL; 882 read_hwcprof_info (ctx); 883 ctx->name = old_name; 884 ctx->parent = old_parent; 885 // Reverse children 886 for (int64_t i = t->child, last = 0; i != 0;) 887 { 888 Dwr_type *t1 = ctx->get_dwr_type (i); 889 t->child = i; 890 i = t1->next; 891 t1->next = last; 892 last = t->child; 893 } 894 break; 895 } 896 case DW_TAG_member: 897 { 898 if (ctx->parent == 0) 899 { 900 Dprintf (DUMP_DWARFLIB, NTXT ("DWARF_ERROR: %s:%d %s cu_die_offset=%lld\n"), 901 get_basename (__FILE__), (int) __LINE__, 902 DwrCU::tag2str (dwrTag.tag), (long long) dwrTag.die); 903 break; 904 } 905 Dwr_type *t = ctx->put_dwr_type (dwrTag.die, dwrTag.tag); 906 t->name = Dwarf_string (DW_AT_name); 907 t->ref_type = Dwarf_ref (DW_AT_type); 908 t->offset = Dwarf_location (DW_AT_data_member_location); 909 Dwr_type *parent = ctx->get_dwr_type (ctx->parent); 910 t->parent = ctx->parent; 911 t->next = parent->child; // a reverse order of members 912 parent->child = t->cu_die_offset; 913 t->bit_size = (uint32_t) Dwarf_data (DW_AT_bit_size); 914 break; 915 } 916 case DW_TAG_module: 917 { 918 char *old_name = ctx->name; 919 ctx->name = Dwarf_string (DW_AT_SUN_link_name); 920 read_hwcprof_info (ctx); 921 ctx->name = old_name; 922 break; 923 } 924 case DW_TAG_namespace: 925 { 926 char *old_name = ctx->name; 927 ctx->name = Dwarf_string (DW_AT_name); 928 read_hwcprof_info (ctx); 929 ctx->name = old_name; 930 break; 931 } 932 case DW_TAG_lexical_block: 933 { 934 char *old_name = ctx->name; 935 ctx->name = NULL; 936 read_hwcprof_info (ctx); 937 ctx->name = old_name; 938 break; 939 } 940 default: // No more special cases 941 read_hwcprof_info (ctx); 942 break; 943 } 944 } 945 ctx->level--; 946 dwrTag.level--; 947 if (next_die_offset != 0) 948 debug_infoSec->offset = next_die_offset; 949 debug_infoSec->size = old_size; 950 } 951 952 // Append function to module 953 Function * 954 DwrCU::append_Function (Dwarf_cnt *ctx) 955 { 956 char *outerName = ctx->name, *name, tmpname[2048]; 957 Function *func; 958 char *fname = Dwarf_string (DW_AT_name); 959 if (fname && outerName && !strchr (fname, '.')) 960 { 961 size_t outerlen = strlen (outerName); 962 if (outerlen > 0 && outerName[outerlen - 1] == '_') 963 { 964 outerlen--; 965 snprintf (tmpname, sizeof (tmpname), NTXT ("%s"), outerName); 966 snprintf (tmpname + outerlen, sizeof (tmpname) - outerlen, NTXT (".%s_"), fname); 967 } 968 else 969 snprintf (tmpname, sizeof (tmpname), NTXT ("%s.%s"), outerName, fname); 970 name = tmpname; 971 Dprintf (DUMP_DWARFLIB, NTXT ("Generated innerfunc name %s\n"), name); 972 } 973 else 974 name = fname; 975 976 char *link_name = get_linkage_name (); 977 if (link_name == NULL) 978 link_name = name; 979 980 uint64_t pc = get_low_pc (); 981 func = dwarf->stabs->append_Function (module, link_name, pc); 982 if (func != NULL) 983 { 984 int lineno = (int) Dwarf_data (DW_AT_decl_line); 985 func->set_match_name (name); 986 if (lineno > 0) 987 { 988 func->setLineFirst (lineno); 989 if (dwrLineReg == NULL) 990 dwrLineReg = new DwrLineRegs (new DwrSec (dwarf->debug_lineSec, 991 stmt_list_offset), comp_dir); 992 int fileno = ((int) Dwarf_data (DW_AT_decl_file)) - 1; 993 SourceFile *sf = ((fileno >= 0) && (fileno < VecSize (srcFiles))) ? srcFiles->get (fileno) 994 : module->getMainSrc (); 995 func->setDefSrc (sf); 996 func->pushSrcFile (func->def_source, 0); 997 func->popSrcFile (); 998 } 999 } 1000 return func; 1001 } 1002 1003 // Get language code 1004 Sp_lang_code 1005 DwrCU::Dwarf_lang () 1006 { 1007 char *str = Dwarf_string (DW_AT_producer); 1008 if (str && strncmp (str, NTXT ("GNU"), 3) == 0) 1009 isGNU = true; 1010 int64_t lang = Dwarf_data (DW_AT_language); 1011 switch (lang) 1012 { 1013 case DW_LANG_C89: 1014 case DW_LANG_C: 1015 return Sp_lang_c; // Sp_lang_ansic? 1016 case DW_LANG_C99: 1017 return Sp_lang_c99; 1018 case DW_LANG_C_plus_plus: 1019 return isGNU ? Sp_lang_gcc : Sp_lang_cplusplus; 1020 case DW_LANG_Fortran90: 1021 return Sp_lang_fortran90; 1022 case DW_LANG_Fortran77: 1023 return Sp_lang_fortran; 1024 case DW_LANG_Java: 1025 return Sp_lang_java; 1026 case DW_LANG_Mips_Assembler: 1027 case DW_LANG_SUN_Assembler: 1028 return Sp_lang_asm; 1029 case DW_LANG_Pascal83: 1030 return Sp_lang_pascal; 1031 default: 1032 case DW_LANG_Ada83: 1033 case DW_LANG_Cobol74: 1034 case DW_LANG_Cobol85: 1035 case DW_LANG_Modula2: 1036 case DW_LANG_Ada95: 1037 case DW_LANG_Fortran95: 1038 case DW_LANG_lo_user: 1039 return Sp_lang_unknown; 1040 } 1041 } 1042