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 <sys/param.h> 23 24#include "util.h" 25#include "Elf.h" 26#include "Dwarf.h" 27#include "stab.h" 28#include "DbeSession.h" 29#include "CompCom.h" 30#include "Stabs.h" 31#include "LoadObject.h" 32#include "Module.h" 33#include "Function.h" 34#include "info.h" 35#include "StringBuilder.h" 36#include "DbeFile.h" 37#include "StringMap.h" 38 39#define DISASM_REL_NONE 0 /* symtab search only */ 40#define DISASM_REL_ONLY 1 /* relocation search only */ 41#define DISASM_REL_TARG 2 /* relocatoin then symtab */ 42 43/////////////////////////////////////////////////////////////////////////////// 44// class StabReader 45class StabReader 46{ 47public: 48 StabReader (Elf *_elf, Platform_t platform, int StabSec, int StabStrSec); 49 ~StabReader () { }; 50 char *get_type_name (int t); 51 char *get_stab (struct stab *np, bool comdat); 52 void parse_N_OPT (Module *mod, char *str); 53 int stabCnt; 54 int stabNum; 55 56private: 57 Elf *elf; 58 char *StabData; 59 char *StabStrtab; 60 char *StabStrtabEnd; 61 int StrTabSize; 62 int StabEntSize; 63}; 64 65/////////////////////////////////////////////////////////////////////////////// 66// class Symbol 67 68class Symbol 69{ 70public: 71 Symbol (Vector<Symbol*> *vec = NULL); 72 73 ~Symbol () 74 { 75 free (name); 76 } 77 78 inline Symbol * 79 cardinal () 80 { 81 return alias ? alias : this; 82 } 83 84 static void dump (Vector<Symbol*> *vec, char*msg); 85 86 Function *func; 87 Sp_lang_code lang_code; 88 uint64_t value; // st_value used in sym_name() 89 uint64_t save; 90 int64_t size; 91 uint64_t img_offset; // image offset in the ELF file 92 char *name; 93 Symbol *alias; 94 int local_ind; 95 int flags; 96 bool defined; 97}; 98 99Symbol::Symbol (Vector<Symbol*> *vec) 100{ 101 func = NULL; 102 lang_code = Sp_lang_unknown; 103 value = 0; 104 save = 0; 105 size = 0; 106 img_offset = 0; 107 name = NULL; 108 alias = NULL; 109 local_ind = -1; 110 flags = 0; 111 defined = false; 112 if (vec) 113 vec->append (this); 114} 115 116void 117Symbol::dump (Vector<Symbol*> *vec, char*msg) 118{ 119 if (!DUMP_ELF_SYM || vec == NULL || vec->size () == 0) 120 return; 121 printf (NTXT ("======= Symbol::dump: %s =========\n" 122 " value | img_offset | flags|local_ind|\n"), msg); 123 for (int i = 0; i < vec->size (); i++) 124 { 125 Symbol *sp = vec->fetch (i); 126 printf (NTXT (" %3d %8lld |0x%016llx |%5d |%8d |%s\n"), 127 i, (long long) sp->value, (long long) sp->img_offset, sp->flags, 128 sp->local_ind, sp->name ? sp->name : NTXT ("NULL")); 129 } 130 printf (NTXT ("\n===== END of Symbol::dump: %s =========\n\n"), msg); 131} 132 133// end of class Symbol 134/////////////////////////////////////////////////////////////////////////////// 135 136/////////////////////////////////////////////////////////////////////////////// 137// class Reloc 138class Reloc 139{ 140public: 141 Reloc (); 142 ~Reloc (); 143 uint64_t type; 144 uint64_t value; 145 uint64_t addend; 146 char *name; 147}; 148 149Reloc::Reloc () 150{ 151 type = 0; 152 value = 0; 153 addend = 0; 154 name = NULL; 155} 156 157Reloc::~Reloc () 158{ 159 free (name); 160} 161// end of class Reloc 162/////////////////////////////////////////////////////////////////////////////// 163 164enum 165{ 166 SYM_PLT = 1 << 0, 167 SYM_UNDEF = 1 << 1 168}; 169 170enum Section_type 171{ 172 COMM1_SEC = 0x10000000, 173 COMM_SEC = 0x20000000, 174 INFO_SEC = 0x30000000, 175 LOOP_SEC = 0x40000000 176}; 177 178struct cpf_stabs_t 179{ 180 uint32_t type; // Archive::AnalyzerInfoType 181 uint32_t offset; // offset in .__analyzer_info 182 Module *module; // table for appropriate Module 183}; 184 185static char *get_info_com (int type, int32_t copy_inout); 186static char *get_lp_com (unsigned hints, int parallel, char *dep); 187static int ComCmp (const void *a, const void *b); 188static ino64_t _src_inode = 0; 189static char *_src_name; 190 191// Comparing name 192static int 193SymNameCmp (const void *a, const void *b) 194{ 195 Symbol *item1 = *((Symbol **) a); 196 Symbol *item2 = *((Symbol **) b); 197 return (item1->name == NULL) ? -1 : 198 (item2->name == NULL) ? 1 : strcmp (item1->name, item2->name); 199} 200 201// Comparing value: for sorting 202static int 203SymValueCmp (const void *a, const void *b) 204{ 205 Symbol *item1 = *((Symbol **) a); 206 Symbol *item2 = *((Symbol **) b); 207 return (item1->value > item2->value) ? 1 : 208 (item1->value == item2->value) ? SymNameCmp (a, b) : -1; 209} 210 211// Comparing value: for searching (source name is always NULL) 212static int 213SymFindCmp (const void *a, const void *b) 214{ 215 Symbol *item1 = *((Symbol **) a); 216 Symbol *item2 = *((Symbol **) b); 217 if (item1->value < item2->value) 218 return -1; 219 if (item1->value < item2->value + item2->size 220 || item1->value == item2->value) // item2->size == 0 221 return 0; 222 return 1; 223} 224 225// Comparing value for sorting. It is used only for searching aliases. 226static int 227SymImgOffsetCmp (const void *a, const void *b) 228{ 229 Symbol *item1 = *((Symbol **) a); 230 Symbol *item2 = *((Symbol **) b); 231 return (item1->img_offset > item2->img_offset) ? 1 : 232 (item1->img_offset == item2->img_offset) ? SymNameCmp (a, b) : -1; 233} 234 235static int 236RelValueCmp (const void *a, const void *b) 237{ 238 Reloc *item1 = *((Reloc **) a); 239 Reloc *item2 = *((Reloc **) b); 240 return (item1->value > item2->value) ? 1 : 241 (item1->value == item2->value) ? 0 : -1; 242} 243 244Stabs * 245Stabs::NewStabs (char *_path, char *lo_name) 246{ 247 Stabs *stabs = new Stabs (_path, lo_name); 248 if (stabs->status != Stabs::DBGD_ERR_NONE) 249 { 250 delete stabs; 251 return NULL; 252 } 253 return stabs; 254} 255 256Stabs::Stabs (char *_path, char *_lo_name) 257{ 258 path = dbe_strdup (_path); 259 lo_name = dbe_strdup (_lo_name); 260 SymLstByName = NULL; 261 pltSym = NULL; 262 SymLst = new Vector<Symbol*>; 263 RelLst = new Vector<Reloc*>; 264 RelPLTLst = new Vector<Reloc*>; 265 LocalLst = new Vector<Symbol*>; 266 LocalFile = new Vector<char*>; 267 LocalFileIdx = new Vector<int>; 268 last_PC_to_sym = NULL; 269 dwarf = NULL; 270 elfDbg = NULL; 271 elfDis = NULL; 272 stabsModules = NULL; 273 textsz = 0; 274 wsize = Wnone; 275 st_check_symtab = st_check_relocs = false; 276 status = DBGD_ERR_NONE; 277 278 if (openElf (false) == NULL) 279 return; 280 switch (elfDis->elf_getclass ()) 281 { 282 case ELFCLASS32: 283 wsize = W32; 284 break; 285 case ELFCLASS64: 286 wsize = W64; 287 break; 288 } 289 isRelocatable = elfDis->elf_getehdr ()->e_type == ET_REL; 290 for (unsigned int pnum = 0; pnum < elfDis->elf_getehdr ()->e_phnum; pnum++) 291 { 292 Elf_Internal_Phdr *phdr = elfDis->get_phdr (pnum); 293 if (phdr->p_type == PT_LOAD && phdr->p_flags == (PF_R | PF_X)) 294 { 295 if (textsz == 0) 296 textsz = phdr->p_memsz; 297 else 298 { 299 textsz = 0; 300 break; 301 } 302 } 303 } 304} 305 306Stabs::~Stabs () 307{ 308 delete pltSym; 309 delete SymLstByName; 310 Destroy (SymLst); 311 Destroy (RelLst); 312 Destroy (RelPLTLst); 313 Destroy (LocalFile); 314 delete elfDis; 315 delete dwarf; 316 delete LocalLst; 317 delete LocalFileIdx; 318 delete stabsModules; 319 free (path); 320 free (lo_name); 321} 322 323Elf * 324Stabs::openElf (char *fname, Stab_status &st) 325{ 326 Elf::Elf_status elf_status; 327 Elf *elf = Elf::elf_begin (fname, &elf_status); 328 if (elf == NULL) 329 { 330 switch (elf_status) 331 { 332 case Elf::ELF_ERR_CANT_OPEN_FILE: 333 case Elf::ELF_ERR_CANT_MMAP: 334 case Elf::ELF_ERR_BIG_FILE: 335 st = DBGD_ERR_CANT_OPEN_FILE; 336 break; 337 case Elf::ELF_ERR_BAD_ELF_FORMAT: 338 default: 339 st = DBGD_ERR_BAD_ELF_FORMAT; 340 break; 341 } 342 return NULL; 343 } 344 if (elf->elf_version (EV_CURRENT) == EV_NONE) 345 { 346 // ELF library out of date 347 delete elf; 348 st = DBGD_ERR_BAD_ELF_LIB; 349 return NULL; 350 } 351 352 Elf_Internal_Ehdr *ehdrp = elf->elf_getehdr (); 353 if (ehdrp == NULL) 354 { 355 // check machine 356 delete elf; 357 st = DBGD_ERR_BAD_ELF_FORMAT; 358 return NULL; 359 } 360 switch (ehdrp->e_machine) 361 { 362 case EM_SPARC: 363 platform = Sparc; 364 break; 365 case EM_SPARC32PLUS: 366 platform = Sparcv8plus; 367 break; 368 case EM_SPARCV9: 369 platform = Sparcv9; 370 break; 371 case EM_386: 372 // case EM_486: 373 platform = Intel; 374 break; 375 case EM_X86_64: 376 platform = Amd64; 377 break; 378 case EM_AARCH64: 379 platform = Aarch64; 380 break; 381 default: 382 platform = Unknown; 383 break; 384 } 385 return elf; 386} 387 388Elf * 389Stabs::openElf (bool dbg_info) 390{ 391 if (status != DBGD_ERR_NONE) 392 return NULL; 393 if (elfDis == NULL) 394 { 395 elfDis = openElf (path, status); 396 if (elfDis == NULL) 397 return NULL; 398 } 399 if (!dbg_info) 400 return elfDis; 401 if (elfDbg == NULL) 402 { 403 elfDbg = elfDis->find_ancillary_files (lo_name); 404 if (elfDbg == NULL) 405 elfDbg = elfDis; 406 } 407 return elfDbg; 408} 409 410bool 411Stabs::read_symbols (Vector<Function*> *functions) 412{ 413 if (openElf (true) == NULL) 414 return false; 415 check_Symtab (); 416 check_Relocs (); 417 if (functions) 418 { 419 Function *fp; 420 int index; 421 Vec_loop (Function*, functions, index, fp) 422 { 423 fp->img_fname = path; 424 } 425 } 426 return true; 427} 428 429char * 430Stabs::sym_name (uint64_t target, uint64_t instr, int flag) 431{ 432 long index; 433 if (flag == DISASM_REL_ONLY || flag == DISASM_REL_TARG) 434 { 435 Reloc *relptr = new Reloc; 436 relptr->value = instr; 437 index = RelLst->bisearch (0, -1, &relptr, RelValueCmp); 438 if (index >= 0) 439 { 440 delete relptr; 441 return RelLst->fetch (index)->name; 442 } 443 if (!is_relocatable ()) 444 { 445 relptr->value = target; 446 index = RelPLTLst->bisearch (0, -1, &relptr, RelValueCmp); 447 if (index >= 0) 448 { 449 delete relptr; 450 return RelPLTLst->fetch (index)->name; 451 } 452 } 453 delete relptr; 454 } 455 if (flag == DISASM_REL_NONE || flag == DISASM_REL_TARG || !is_relocatable ()) 456 { 457 Symbol *sptr; 458 sptr = map_PC_to_sym (target); 459 if (sptr && sptr->value == target) 460 return sptr->name; 461 } 462 return NULL; 463} 464 465Symbol * 466Stabs::map_PC_to_sym (uint64_t pc) 467{ 468 if (pc == 0) 469 return NULL; 470 if (last_PC_to_sym && last_PC_to_sym->value <= pc 471 && last_PC_to_sym->value + last_PC_to_sym->size > pc) 472 return last_PC_to_sym; 473 Symbol *sym = new Symbol; 474 sym->value = pc; 475 long index = SymLst->bisearch (0, -1, &sym, SymFindCmp); 476 delete sym; 477 if (index >= 0) 478 { 479 last_PC_to_sym = SymLst->fetch (index)->cardinal (); 480 return last_PC_to_sym; 481 } 482 return NULL; 483} 484 485Function * 486Stabs::map_PC_to_func (uint64_t pc, uint64_t &low_pc, Vector<Function*> *functions) 487{ 488 int index; 489 Function *func; 490 Symbol *sptr = map_PC_to_sym (pc); 491 if (sptr == NULL) 492 return NULL; 493 if (sptr->func) 494 { 495 low_pc = sptr->value; 496 return sptr->func; 497 } 498 if (functions) 499 { 500 Vec_loop (Function*, functions, index, func) 501 { 502 if (func->img_offset == sptr->img_offset) 503 { 504 sptr->func = func->cardinal (); 505 low_pc = sptr->value; 506 return sptr->func; 507 } 508 } 509 } 510 return NULL; 511} 512 513Stabs::Stab_status 514Stabs::read_stabs (ino64_t srcInode, Module *module, Vector<ComC*> *comComs, 515 bool readDwarf) 516{ 517 if (module) 518 module->setIncludeFile (NULL); 519 520 if (openElf (true) == NULL) 521 return status; 522 check_Symtab (); 523 524 // read compiler commentary from .compcom1, .compcom, 525 // .info, .loops, and .loopview sections 526 if (comComs) 527 { 528 _src_inode = srcInode; 529 _src_name = module && module->file_name ? get_basename (module->file_name) : NULL; 530 if (!check_Comm (comComs)) 531 // .loops, and .loopview are now in .compcom 532 check_Loop (comComs); 533 534 // should not read it after .info goes into .compcom 535 check_Info (comComs); 536 comComs->sort (ComCmp); 537 } 538 539 // get stabs info 540 Stab_status statusStabs = DBGD_ERR_NO_STABS; 541#define SRC_LINE_STABS(sec, secStr, comdat) \ 542 if ((elfDbg->sec) && (elfDbg->secStr) && \ 543 srcline_Stabs(module, elfDbg->sec, elfDbg->secStr, comdat) == DBGD_ERR_NONE) \ 544 statusStabs = DBGD_ERR_NONE 545 546 SRC_LINE_STABS (stabExcl, stabExclStr, false); 547 SRC_LINE_STABS (stab, stabStr, false); 548 SRC_LINE_STABS (stabIndex, stabIndexStr, true); 549 550 // read Dwarf, if any sections found 551 if (elfDbg->dwarf && readDwarf) 552 { 553 openDwarf ()->srcline_Dwarf (module); 554 if (dwarf && dwarf->status == DBGD_ERR_NONE) 555 return DBGD_ERR_NONE; 556 } 557 return statusStabs; 558} 559 560static int 561ComCmp (const void *a, const void *b) 562{ 563 ComC *item1 = *((ComC **) a); 564 ComC *item2 = *((ComC **) b); 565 return (item1->line > item2->line) ? 1 : 566 (item1->line < item2->line) ? -1 : 567 (item1->sec > item2->sec) ? 1 : 568 (item1->sec < item2->sec) ? -1 : 0; 569} 570 571static int 572check_src_name (char *srcName) 573{ 574 if (_src_name && srcName && streq (_src_name, get_basename (srcName))) 575 return 1; 576 if (_src_inode == (ino64_t) - 1) 577 return 0; 578 DbeFile *dbeFile = dbeSession->getDbeFile (srcName, DbeFile::F_SOURCE); 579 char *path = dbeFile->get_location (); 580 return (path == NULL || dbeFile->sbuf.st_ino != _src_inode) ? 0 : 1; 581} 582 583bool 584Stabs::check_Comm (Vector<ComC*> *comComs) 585{ 586 int sz = comComs->size (); 587 Elf *elf = openElf (true); 588 if (elf == NULL) 589 return false; 590 591 for (unsigned int sec = 1; sec < elf->elf_getehdr ()->e_shnum; sec++) 592 { 593 char *name = elf->get_sec_name (sec); 594 if (name == NULL) 595 continue; 596 Section_type sec_type; 597 if (streq (name, NTXT (".compcom"))) 598 sec_type = COMM_SEC; 599 else if (streq (name, NTXT (".compcom1"))) 600 sec_type = COMM1_SEC; 601 else 602 continue; 603 604 // find header, set messages id & visibility if succeed 605 CompComment *cc = new CompComment (elf, sec); 606 int cnt = cc->compcom_open ((CheckSrcName) check_src_name); 607 // process messages 608 for (int index = 0; index < cnt; index++) 609 { 610 int visible; 611 compmsg msg; 612 char *str = cc->compcom_format (index, &msg, visible); 613 if (str) 614 { 615 ComC *citem = new ComC; 616 citem->sec = sec_type + index; 617 citem->type = msg.msg_type; 618 citem->visible = visible; 619 citem->line = (msg.lineno < 1) ? 1 : msg.lineno; 620 citem->com_str = str; 621 comComs->append (citem); 622 } 623 } 624 delete cc; 625 } 626 return (sz != comComs->size ()); 627} 628 629static int 630targetOffsetCmp (const void *a, const void *b) 631{ 632 uint32_t o1 = ((target_info_t *) a)->offset; 633 uint32_t o2 = ((target_info_t *) b)->offset; 634 return (o1 >= o2); 635} 636 637void 638Stabs::check_AnalyzerInfo () 639{ 640 Elf *elf = openElf (true); 641 if ((elf == NULL) || (elf->analyzerInfo == 0)) 642 { 643 Dprintf (DEBUG_STABS, NTXT ("Stabs::check_AnalyzerInfo: Null AnalyzerInfo section\n")); 644 return; // inappropriate, but ignored anyway 645 } 646 Elf_Data *data = elf->elf_getdata (elf->analyzerInfo); 647 int InfoSize = (int) data->d_size; 648 char *InfoData = (char *) data->d_buf; 649 int InfoAlign = (int) data->d_align; 650 AnalyzerInfoHdr h; 651 unsigned infoHdr_sz = sizeof (AnalyzerInfoHdr); 652 int table, entry; 653 int read = 0; 654 Module *mitem; 655 int index = 0; 656 if (InfoSize <= 0) 657 return; 658 uint64_t baseAddr = elf->get_baseAddr (); 659 Dprintf (DEBUG_STABS, NTXT ("Stabs::check_AnalyzerInfo size=%d @0x%lx (align=%d) base=0x%llx\n"), 660 InfoSize, (ul_t) InfoData, InfoAlign, (long long) baseAddr); 661 Dprintf (DEBUG_STABS, NTXT ("analyzerInfoMap has %lld entries\n"), (long long) analyzerInfoMap.size ()); 662 if (analyzerInfoMap.size () == 0) 663 { 664 Dprintf (DEBUG_STABS, NTXT ("No analyzerInfoMap available!\n")); 665 return; 666 } 667 668 // verify integrity of analyzerInfoMap before reading analyzerInfo 669 unsigned count = 0; 670 Module *lastmod = NULL; 671 for (index = 0; index < analyzerInfoMap.size (); index++) 672 { 673 cpf_stabs_t map = analyzerInfoMap.fetch (index); 674 if (map.type > 3) 675 { 676 Dprintf (DEBUG_STABS, NTXT ("analyzerInfo contains table of unknown type %d for %s\n"), 677 map.type, map.module->get_name ()); 678 return; 679 } 680 if (map.module != lastmod) 681 { 682 if (lastmod != NULL) 683 Dprintf (DEBUG_STABS, "analyzerInfo contains %d 0x0 offset tables for %s\n", 684 count, lastmod->get_name ()); 685 count = 0; 686 } 687 count += (map.offset == 0x0); // only check for 0x0 tables for now 688 if (count > 4) 689 { 690 Dprintf (DEBUG_STABS, NTXT ("analyzerInfo contains too many 0x0 offset tables for %s\n"), 691 map.module->get_name ()); 692 return; 693 } 694 lastmod = map.module; 695 } 696 697 index = 0; 698 while ((index < analyzerInfoMap.size ()) && (read < InfoSize)) 699 { 700 for (table = 0; table < 3; table++) 701 { // memory operations (ld, st, prefetch) 702 // read the table header 703 memcpy ((void *) &h, (const void *) InfoData, infoHdr_sz); 704 InfoData += infoHdr_sz; 705 read += infoHdr_sz; 706 707 // use map for appropriate module 708 cpf_stabs_t map = analyzerInfoMap.fetch (index); 709 index++; 710 mitem = map.module; 711 Dprintf (DEBUG_STABS, "Table %d offset=0x%04x " 712 "text_labelref=0x%08llx entries=%d version=%d\n" 713 "itype %d offset=0x%04x module=%s\n", table, read, 714 (long long) (h.text_labelref - baseAddr), h.entries, 715 h.version, map.type, map.offset, map.module->get_name ()); 716 // read the table entries 717 for (entry = 0; entry < h.entries; entry++) 718 { 719 memop_info_t *m = new memop_info_t; 720 unsigned memop_info_sz = sizeof (memop_info_t); 721 memcpy ((void *) m, (const void *) InfoData, memop_info_sz); 722 InfoData += memop_info_sz; 723 read += memop_info_sz; 724 m->offset += (uint32_t) (h.text_labelref - baseAddr); 725 Dprintf (DEBUG_STABS, NTXT ("%4d(%d): offset=0x%04x id=0x%08x sig=0x%08x dtid=0x%08x\n"), 726 entry, table, m->offset, m->id, m->signature, m->datatype_id); 727 switch (table) 728 { 729 case CPF_INSTR_TYPE_LD: 730 mitem->ldMemops.append (m); 731 break; 732 case CPF_INSTR_TYPE_ST: 733 mitem->stMemops.append (m); 734 break; 735 case CPF_INSTR_TYPE_PREFETCH: 736 mitem->pfMemops.append (m); 737 break; 738 } 739 } 740 // following re-alignment should be redundant 741 //InfoData+=(read%InfoAlign); read+=(read%InfoAlign); // re-align 742 } 743 for (table = 3; table < 4; table++) 744 { // branch targets 745 memcpy ((void *) &h, (const void *) InfoData, infoHdr_sz); 746 InfoData += infoHdr_sz; 747 read += infoHdr_sz; 748 749 // use map for appropriate module 750 cpf_stabs_t map = analyzerInfoMap.fetch (index); 751 index++; 752 mitem = map.module; 753 Dprintf (DEBUG_STABS, "Table %d offset=0x%04x " 754 "text_labelref=0x%08llx entries=%d version=%d\n" 755 "itype %d offset=0x%04x module=%s\n", table, read, 756 (long long) (h.text_labelref - baseAddr), h.entries, 757 h.version, map.type, map.offset, map.module->get_name ()); 758 for (entry = 0; entry < h.entries; entry++) 759 { 760 target_info_t *t = new target_info_t; 761 unsigned target_info_sz = sizeof (target_info_t); 762 memcpy ((void *) t, (const void *) InfoData, target_info_sz); 763 InfoData += target_info_sz; 764 read += target_info_sz; 765 t->offset += (uint32_t) (h.text_labelref - baseAddr); 766 Dprintf (DEBUG_STABS, NTXT ("%4d(%d): offset=0x%04x\n"), entry, 767 table, t->offset); 768 // the list of branch targets needs to be in offset sorted order 769 // and doing it here before archiving avoids the need to do it 770 // each time the archive is read. 771 mitem->bTargets.incorporate (t, targetOffsetCmp); 772 } 773 Dprintf (DEBUG_STABS, NTXT ("bTargets for %s has %lld items (last=0x%04x)\n"), 774 mitem->get_name (), (long long) mitem->bTargets.size (), 775 (mitem->bTargets.fetch (mitem->bTargets.size () - 1))->offset); 776 Dprintf (DEBUG_STABS, "read=%d at end of bTargets (InfoData=0x%lx)\n", 777 read, (ul_t) InfoData); 778 InfoData += (read % InfoAlign); 779 read += (read % InfoAlign); // re-align 780 Dprintf (DEBUG_STABS, "read=%d at end of bTargets (InfoData=0x%lx)\n", 781 read, (ul_t) InfoData); 782 } 783 Dprintf (DEBUG_STABS, "Stabs::check_AnalyzerInfo bytes read=%lld (index=%lld/%lld)\n", 784 (long long) read, (long long) index, 785 (long long) analyzerInfoMap.size ()); 786 } 787} 788 789void 790Stabs::check_Info (Vector<ComC*> *comComs) 791{ 792 Elf *elf = openElf (true); 793 if (elf == NULL || elf->info == 0) 794 return; 795 Elf_Data *data = elf->elf_getdata (elf->info); 796 uint64_t InfoSize = data->d_size; 797 char *InfoData = (char *) data->d_buf; 798 bool get_src = false; 799 for (int h_num = 0; InfoSize; h_num++) 800 { 801 if (InfoSize < sizeof (struct info_header)) 802 return; 803 struct info_header *h = (struct info_header*) InfoData; 804 if (h->endian != '\0' || h->magic[0] != 'S' || h->magic[1] != 'U' 805 || h->magic[2] != 'N') 806 return; 807 if (h->len < InfoSize || h->len < sizeof (struct info_header) || (h->len & 3)) 808 return; 809 810 char *fname = InfoData + sizeof (struct info_header); 811 InfoData += h->len; 812 InfoSize -= h->len; 813 get_src = check_src_name (fname); 814 for (uint32_t e_num = 0; e_num < h->cnt; ++e_num) 815 { 816 if (InfoSize < sizeof (struct entry_header)) 817 return; 818 struct entry_header *e = (struct entry_header*) InfoData; 819 if (InfoSize < e->len) 820 return; 821 int32_t copy_inout = 0; 822 if (e->len > sizeof (struct entry_header)) 823 if (e->type == F95_COPYINOUT) 824 copy_inout = *(int32_t*) (InfoData + sizeof (struct entry_header)); 825 InfoData += e->len; 826 InfoSize -= e->len; 827 if (get_src) 828 { 829 ComC *citem = new ComC; 830 citem->sec = INFO_SEC + h_num; 831 citem->type = e->msgnum & 0xFFFFFF; 832 citem->visible = CCMV_ALL; 833 citem->line = e->line; 834 citem->com_str = get_info_com (citem->type, copy_inout); 835 comComs->append (citem); 836 } 837 } 838 if (get_src) 839 break; 840 } 841} 842 843static char * 844get_info_com (int type, int32_t copy_inout) 845{ 846 switch (type) 847 { 848 case 1: 849 return dbe_sprintf (GTXT ("In the call below, parameter number %d caused a copy-in -- loop(s) inserted"), 850 copy_inout); 851 case 2: 852 return dbe_sprintf (GTXT ("In the call below, parameter number %d caused a copy-out -- loop(s) inserted"), 853 copy_inout); 854 case 3: 855 return dbe_sprintf (GTXT ("In the call below, parameter number %d caused a copy-in and a copy-out -- loops inserted"), 856 copy_inout); 857 case 4: 858 return dbe_strdup (GTXT ("Alignment of variables in common block may cause performance degradation")); 859 case 5: 860 return dbe_strdup (GTXT ("DO statement bounds lead to no executions of the loop")); 861 default: 862 return dbe_strdup (NTXT ("")); 863 } 864} 865 866void 867Stabs::check_Loop (Vector<ComC*> *comComs) 868{ 869 Elf *elf = openElf (true); 870 if (elf == NULL) 871 return; 872 873 StringBuilder sb; 874 for (unsigned int sec = 1; sec < elf->elf_getehdr ()->e_shnum; sec++) 875 { 876 char *name = elf->get_sec_name (sec); 877 if (name == NULL) 878 continue; 879 if (!streq (name, NTXT (".loops")) && !streq (name, NTXT (".loopview"))) 880 continue; 881 882 Elf_Data *data = elf->elf_getdata (sec); 883 size_t LoopSize = (size_t) data->d_size, len; 884 char *LoopData = (char *) data->d_buf; 885 int remainder, i; 886 char src[2 * MAXPATHLEN], buf1[MAXPATHLEN], buf2[MAXPATHLEN]; 887 char **dep_str = NULL; 888 bool get_src = false; 889 while ((LoopSize > 0) && !get_src && 890 (strncmp (LoopData, NTXT ("Source:"), 7) == 0)) 891 { 892 // The first three items in a .loops subsection are three strings. 893 // Source: ... 894 // Version: ... 895 // Number of loops: ... 896 sscanf (LoopData, NTXT ("%*s%s"), src); 897 len = strlen (LoopData) + 1; 898 LoopData += len; 899 LoopSize -= len; 900 sscanf (LoopData, NTXT ("%*s%*s%s"), buf1); 901 // double version = atof(buf1); 902 len = strlen (LoopData) + 1; 903 LoopData += len; 904 LoopSize -= len; 905 get_src = check_src_name (src); 906 sscanf (LoopData, NTXT ("%*s%*s%*s%s%s"), buf1, buf2); 907 int n_loop = atoi (buf1); 908 int n_depend = atoi (buf2); 909 len = strlen (LoopData) + 1; 910 LoopData += len; 911 LoopSize -= len; 912 if (get_src && (n_loop > 0)) 913 { 914 dep_str = new char*[n_loop]; 915 for (i = 0; i < n_loop; i++) 916 dep_str[i] = NULL; 917 } 918 919 // printf("Source: %s\nVersion: %f\nLoop#: %d\nDepend#: %d\n", 920 // src, version, n_loop, n_depend); 921 922 // Read in the strings that contain the list of variables that cause 923 // data dependencies inside of loops. Not every loop has such a list 924 // of variables. 925 // 926 // Example: if loop #54 has data dependencies caused by the 927 // variables named i, j and foo, then the string that represents 928 // this in the .loops section looks like this: 929 // 930 // .asciz "54:i.j.foo" 931 // 932 // The variable names are delimited with . 933 // 934 // For now, store these strings in an array, and add them into 935 // the loop structure when we read in the numeric loop info 936 // (that's what we read in next.) 937 // 938 // printf("\tDependenncies:\n"); 939 for (i = 0; i < n_depend; i++) 940 { 941 len = strlen (LoopData) + 1; 942 LoopData += len; 943 LoopSize -= len; 944 if (dep_str != NULL) 945 { 946 char *dep_buf1 = dbe_strdup (LoopData); 947 char *ptr = strtok (dep_buf1, NTXT (":")); 948 if (ptr != NULL) 949 { 950 int index = atoi (ptr); 951 bool dep_first = true; 952 sb.setLength (0); 953 while ((ptr = strtok (NULL, NTXT (", "))) != NULL) 954 { 955 if (dep_first) 956 dep_first = false; 957 else 958 sb.append (NTXT (", ")); 959 sb.append (ptr); 960 } 961 if (sb.length () > 0 && index < n_loop) 962 dep_str[index] = sb.toString (); 963 } 964 free (dep_buf1); 965 } 966 } 967 968 // Adjust Data pointer so that it is word aligned. 969 remainder = (int) (((unsigned long) LoopData) % 4); 970 if (remainder != 0) 971 { 972 len = 4 - remainder; 973 LoopData += len; 974 LoopSize -= len; 975 } 976 977 // Read in the loop info, one loop at a time. 978 for (i = 0; i < n_loop; i++) 979 { 980 int loopid = *((int *) LoopData); 981 LoopData += 4; 982 int line_no = *((int *) LoopData); 983 if (line_no < 1) // compiler has trouble on this 984 line_no = 1; 985 LoopData += 4; 986 // int nest = *((int *) LoopData); 987 LoopData += 4; 988 int parallel = *((int *) LoopData); 989 LoopData += 4; 990 unsigned hints = *((unsigned *) LoopData); 991 LoopData += 4; 992 // int count = *((int *) LoopData); 993 LoopData += 4; 994 LoopSize -= 24; 995 if (!get_src || (loopid >= n_loop)) 996 continue; 997 ComC *citem = new ComC; 998 citem->sec = LOOP_SEC + i; 999 citem->type = hints; 1000 citem->visible = CCMV_ALL; 1001 citem->line = line_no; 1002 citem->com_str = get_lp_com (hints, parallel, dep_str[loopid]); 1003 comComs->append (citem); 1004 } 1005 if (dep_str) 1006 { 1007 for (i = 0; i < n_loop; i++) 1008 free (dep_str[i]); 1009 delete[] dep_str; 1010 dep_str = NULL; 1011 } 1012 } 1013 } 1014} 1015 1016static char * 1017get_lp_com (unsigned hints, int parallel, char *dep) 1018{ 1019 StringBuilder sb; 1020 if (parallel == -1) 1021 sb.append (GTXT ("Loop below is serial, but parallelizable: ")); 1022 else if (parallel == 0) 1023 sb.append (GTXT ("Loop below is not parallelized: ")); 1024 else 1025 sb.append (GTXT ("Loop below is parallelized: ")); 1026 switch (hints) 1027 { 1028 case 0: 1029 // No loop mesg will print 1030 // strcat(com, GTXT("no hint available")); 1031 break; 1032 case 1: 1033 sb.append (GTXT ("loop contains procedure call")); 1034 break; 1035 case 2: 1036 sb.append (GTXT ("compiler generated two versions of this loop")); 1037 break; 1038 case 3: 1039 { 1040 StringBuilder sb_tmp; 1041 sb_tmp.sprintf (GTXT ("the variable(s) \"%s\" cause a data dependency in this loop"), 1042 dep ? dep : GTXT ("<Unknown>")); 1043 sb.append (&sb_tmp); 1044 } 1045 break; 1046 case 4: 1047 sb.append (GTXT ("loop was significantly transformed during optimization")); 1048 break; 1049 case 5: 1050 sb.append (GTXT ("loop may or may not hold enough work to be profitably parallelized")); 1051 break; 1052 case 6: 1053 sb.append (GTXT ("loop was marked by user-inserted pragma")); 1054 break; 1055 case 7: 1056 sb.append (GTXT ("loop contains multiple exits")); 1057 break; 1058 case 8: 1059 sb.append (GTXT ("loop contains I/O, or other function calls, that are not MT safe")); 1060 break; 1061 case 9: 1062 sb.append (GTXT ("loop contains backward flow of control")); 1063 break; 1064 case 10: 1065 sb.append (GTXT ("loop may have been distributed")); 1066 break; 1067 case 11: 1068 sb.append (GTXT ("two loops or more may have been fused")); 1069 break; 1070 case 12: 1071 sb.append (GTXT ("two or more loops may have been interchanged")); 1072 break; 1073 default: 1074 break; 1075 } 1076 return sb.toString (); 1077} 1078 1079StabReader::StabReader (Elf *_elf, Platform_t platform, int StabSec, int StabStrSec) 1080{ 1081 stabCnt = -1; 1082 stabNum = 0; 1083 if (_elf == NULL) 1084 return; 1085 elf = _elf; 1086 1087 // Get ELF data 1088 Elf_Data *data = elf->elf_getdata (StabSec); 1089 if (data == NULL) 1090 return; 1091 uint64_t stabSize = data->d_size; 1092 StabData = (char *) data->d_buf; 1093 Elf_Internal_Shdr *shdr = elf->get_shdr (StabSec); 1094 if (shdr == NULL) 1095 return; 1096 1097 // GCC bug: sh_entsize is 20 for 64 apps on Linux 1098 StabEntSize = (platform == Amd64 || platform == Sparcv9) ? 12 : (unsigned) shdr->sh_entsize; 1099 if (stabSize == 0 || StabEntSize == 0) 1100 return; 1101 data = elf->elf_getdata (StabStrSec); 1102 if (data == NULL) 1103 return; 1104 shdr = elf->get_shdr (StabStrSec); 1105 if (shdr == NULL) 1106 return; 1107 StabStrtab = (char *) data->d_buf; 1108 StabStrtabEnd = StabStrtab + shdr->sh_size; 1109 StrTabSize = 0; 1110 stabCnt = (int) (stabSize / StabEntSize); 1111} 1112 1113char * 1114StabReader::get_stab (struct stab *np, bool comdat) 1115{ 1116 struct stab *stbp = (struct stab *) (StabData + stabNum * StabEntSize); 1117 stabNum++; 1118 *np = *stbp; 1119 np->n_desc = elf->decode (stbp->n_desc); 1120 np->n_strx = elf->decode (stbp->n_strx); 1121 np->n_value = elf->decode (stbp->n_value); 1122 switch (np->n_type) 1123 { 1124 case N_UNDF: 1125 case N_ILDPAD: 1126 // Start of new stab section (or padding) 1127 StabStrtab += StrTabSize; 1128 StrTabSize = np->n_value; 1129 } 1130 1131 char *str = NULL; 1132 if (np->n_strx) 1133 { 1134 if (comdat && np->n_type == N_FUN && np->n_other == 1) 1135 { 1136 if (np->n_strx == 1) 1137 StrTabSize++; 1138 str = StabStrtab + StrTabSize; 1139 // Each COMDAT string must be sized to find the next string: 1140 StrTabSize += strlen (str) + 1; 1141 } 1142 else 1143 str = StabStrtab + np->n_strx; 1144 if (str >= StabStrtabEnd) 1145 str = NULL; 1146 } 1147 if (DEBUG_STABS) 1148 { 1149 char buf[128]; 1150 char *s = get_type_name (np->n_type); 1151 if (s == NULL) 1152 { 1153 snprintf (buf, sizeof (buf), NTXT ("n_type=%d"), np->n_type); 1154 s = buf; 1155 } 1156 if (str) 1157 { 1158 Dprintf (DEBUG_STABS, NTXT ("%4d: .stabs \"%s\",%s,0x%x,0x%x,0x%x\n"), 1159 stabNum - 1, str, s, (int) np->n_other, (int) np->n_desc, 1160 (int) np->n_value); 1161 } 1162 else 1163 Dprintf (DEBUG_STABS, NTXT ("%4d: .stabn %s,0x%x,0x%x,0x%x\n"), 1164 stabNum - 1, s, (int) np->n_other, (int) np->n_desc, 1165 (int) np->n_value); 1166 } 1167 return str; 1168} 1169 1170void 1171StabReader::parse_N_OPT (Module *mod, char *str) 1172{ 1173 if (mod == NULL || str == NULL) 1174 return; 1175 for (char *s = str; 1; s++) 1176 { 1177 switch (*s) 1178 { 1179 case 'd': 1180 if (s[1] == 'i' && s[2] == ';') 1181 { 1182 delete mod->dot_o_file; 1183 mod->dot_o_file = NULL; 1184 } 1185 break; 1186 case 's': 1187 if ((s[1] == 'i' || s[1] == 'n') && s[2] == ';') 1188 { 1189 delete mod->dot_o_file; 1190 mod->dot_o_file = NULL; 1191 } 1192 break; 1193 } 1194 s = strchr (s, ';'); 1195 if (s == NULL) 1196 break; 1197 } 1198} 1199 1200Stabs::Stab_status 1201Stabs::srcline_Stabs (Module *module, unsigned int StabSec, 1202 unsigned int StabStrSec, bool comdat) 1203{ 1204 StabReader *stabReader = new StabReader (openElf (true), platform, StabSec, StabStrSec); 1205 int tot = stabReader->stabCnt; 1206 if (tot < 0) 1207 { 1208 delete stabReader; 1209 return DBGD_ERR_NO_STABS; 1210 } 1211 int n, lineno; 1212 char *sbase, *n_so = NTXT (""), curr_src[2 * MAXPATHLEN]; 1213 Function *newFunc; 1214 Sp_lang_code _lang_code = module->lang_code; 1215 Vector<Function*> *functions = module->functions; 1216 bool no_stabs = true; 1217 *curr_src = '\0'; 1218 Function *func = NULL; 1219 int phase = 0; 1220 int stabs_level = 0; 1221 int xline = 0; 1222 1223 // Find module 1224 for (n = 0; n < tot; n++) 1225 { 1226 struct stab stb; 1227 char *str = stabReader->get_stab (&stb, comdat); 1228 if (stb.n_type == N_UNDF) 1229 phase = 0; 1230 else if (stb.n_type == N_SO) 1231 { 1232 if (str == NULL || *str == '\0') 1233 continue; 1234 if (phase == 0) 1235 { 1236 phase = 1; 1237 n_so = str; 1238 continue; 1239 } 1240 phase = 0; 1241 sbase = str; 1242 if (*str == '/') 1243 { 1244 if (streq (sbase, module->file_name)) 1245 break; 1246 } 1247 else 1248 { 1249 size_t last = strlen (n_so); 1250 if (n_so[last - 1] == '/') 1251 last--; 1252 if (strncmp (n_so, module->file_name, last) == 0 && 1253 module->file_name[last] == '/' && 1254 streq (sbase, module->file_name + last + 1)) 1255 break; 1256 } 1257 } 1258 } 1259 if (n >= tot) 1260 { 1261 delete stabReader; 1262 return DBGD_ERR_NO_STABS; 1263 } 1264 1265 Include *includes = new Include; 1266 includes->new_src_file (module->getMainSrc (), 0, NULL); 1267 module->hasStabs = true; 1268 *curr_src = '\0'; 1269 phase = 0; 1270 for (n++; n < tot; n++) 1271 { 1272 struct stab stb; 1273 char *str = stabReader->get_stab (&stb, comdat); 1274 int n_desc = (int) ((unsigned short) stb.n_desc); 1275 switch (stb.n_type) 1276 { 1277 case N_UNDF: 1278 case N_SO: 1279 case N_ENDM: 1280 n = tot; 1281 break; 1282 case N_ALIAS: 1283 if (str == NULL) 1284 break; 1285 if (is_fortran (_lang_code)) 1286 { 1287 char *p = strchr (str, ':'); 1288 if (p && streq (p + 1, NTXT ("FMAIN"))) 1289 { 1290 Function *afunc = find_func (NTXT ("MAIN"), functions, true); 1291 if (afunc) 1292 afunc->set_match_name (dbe_strndup (str, p - str)); 1293 break; 1294 } 1295 } 1296 case N_FUN: 1297 case N_OUTL: 1298 if (str == NULL) 1299 break; 1300 if (*str == '@') 1301 { 1302 str++; 1303 if (*str == '>' || *str == '<') 1304 str++; 1305 } 1306 if (stabs_level != 0) 1307 break; 1308 1309 // find address of the enclosed function 1310 newFunc = find_func (str, functions, is_fortran (_lang_code)); 1311 if (newFunc == NULL) 1312 break; 1313 if (func) 1314 while (func->popSrcFile ()) 1315 ; 1316 func = newFunc; 1317 1318 // First line info to cover function from the beginning 1319 lineno = xline + n_desc; 1320 if (lineno > 0) 1321 { 1322 // Set the chain of includes for the new function 1323 includes->push_src_files (func); 1324 func->add_PC_info (0, lineno); 1325 no_stabs = false; 1326 } 1327 break; 1328 case N_ENTRY: 1329 break; 1330 case N_CMDLINE: 1331 if (str && !module->comp_flags) 1332 { 1333 char *comp_flags = strchr (str, ';'); 1334 if (comp_flags) 1335 { 1336 module->comp_flags = dbe_strdup (comp_flags + 1); 1337 module->comp_dir = dbe_strndup (str, comp_flags - str); 1338 } 1339 } 1340 break; 1341 case N_LBRAC: 1342 stabs_level++; 1343 break; 1344 case N_RBRAC: 1345 stabs_level--; 1346 break; 1347 case N_XLINE: 1348 xline = n_desc << 16; 1349 break; 1350 case N_SLINE: 1351 if (func == NULL) 1352 break; 1353 no_stabs = false; 1354 lineno = xline + n_desc; 1355 if (func->line_first <= 0) 1356 { 1357 // Set the chain of includes for the new function 1358 includes->push_src_files (func); 1359 func->add_PC_info (0, lineno); 1360 break; 1361 } 1362 if (func->curr_srcfile == NULL) 1363 includes->push_src_files (func); 1364 if (func->line_first != lineno || 1365 !streq (curr_src, func->getDefSrc ()->get_name ())) 1366 func->add_PC_info (stb.n_value, lineno); 1367 break; 1368 case N_OPT: 1369 if ((str != NULL) && streq (str, NTXT ("gcc2_compiled."))) 1370 _lang_code = Sp_lang_gcc; 1371 switch (elfDbg->elf_getehdr ()->e_type) 1372 { 1373 case ET_EXEC: 1374 case ET_DYN: 1375 // set the real object timestamp from the executable's N_OPT stab 1376 // due to bug #4796329 1377 module->real_timestamp = stb.n_value; 1378 break; 1379 default: 1380 module->curr_timestamp = stb.n_value; 1381 break; 1382 } 1383 break; 1384 case N_GSYM: 1385 if ((str == NULL) || strncmp (str, NTXT ("__KAI_K"), 7)) 1386 break; 1387 str += 7; 1388 if (!strncmp (str, NTXT ("CC_"), 3)) 1389 _lang_code = Sp_lang_KAI_KCC; 1390 else if (!strncmp (str, NTXT ("cc_"), 3)) 1391 _lang_code = Sp_lang_KAI_Kcc; 1392 else if (!strncmp (str, NTXT ("PTS_"), 4) && 1393 (_lang_code != Sp_lang_KAI_KCC) && 1394 (_lang_code != Sp_lang_KAI_Kcc)) 1395 _lang_code = Sp_lang_KAI_KPTS; 1396 break; 1397 case N_BINCL: 1398 includes->new_include_file (module->setIncludeFile (str), func); 1399 break; 1400 case N_EINCL: 1401 includes->end_include_file (func); 1402 break; 1403 case N_SOL: 1404 if (str == NULL) 1405 break; 1406 lineno = xline + n_desc; 1407 if (lineno > 0 && func && func->line_first <= 0) 1408 { 1409 includes->push_src_files (func); 1410 func->add_PC_info (0, lineno); 1411 no_stabs = false; 1412 } 1413 if (streq (sbase, str)) 1414 { 1415 module->setIncludeFile (NULL); 1416 snprintf (curr_src, sizeof (curr_src), NTXT ("%s"), module->file_name); 1417 includes->new_src_file (module->getMainSrc (), lineno, func); 1418 } 1419 else 1420 { 1421 if (streq (sbase, get_basename (str))) 1422 { 1423 module->setIncludeFile (NULL); 1424 snprintf (curr_src, sizeof (curr_src), NTXT ("%s"), module->file_name); 1425 includes->new_src_file (module->setIncludeFile (curr_src), lineno, func); 1426 } 1427 else 1428 { 1429 if (*str == '/') 1430 snprintf (curr_src, sizeof (curr_src), NTXT ("%s"), str); 1431 else 1432 { 1433 size_t last = strlen (n_so); 1434 if (last == 0 || n_so[last - 1] != '/') 1435 snprintf (curr_src, sizeof (curr_src), NTXT ("%s/%s"), n_so, str); 1436 else 1437 snprintf (curr_src, sizeof (curr_src), NTXT ("%s%s"), n_so, str); 1438 } 1439 includes->new_src_file (module->setIncludeFile (curr_src), lineno, func); 1440 } 1441 } 1442 break; 1443 } 1444 } 1445 delete includes; 1446 delete stabReader; 1447 return no_stabs ? DBGD_ERR_NO_STABS : DBGD_ERR_NONE; 1448}//srcline_Stabs 1449 1450static bool 1451cmp_func_name (char *fname, size_t len, char *name, bool fortran) 1452{ 1453 return (strncmp (name, fname, len) == 0 1454 && (name[len] == 0 1455 || (fortran && name[len] == '_' && name[len + 1] == 0))); 1456} 1457 1458Function * 1459Stabs::find_func (char *fname, Vector<Function*> *functions, bool fortran, bool inner_names) 1460{ 1461 char *arg, *name; 1462 Function *item; 1463 int index; 1464 size_t len; 1465 1466 len = strlen (fname); 1467 arg = strchr (fname, ':'); 1468 if (arg != NULL) 1469 { 1470 if (arg[1] == 'P') // Prototype for function 1471 return NULL; 1472 len -= strlen (arg); 1473 } 1474 1475 Vec_loop (Function*, functions, index, item) 1476 { 1477 name = item->get_mangled_name (); 1478 if (cmp_func_name (fname, len, name, fortran)) 1479 return item->cardinal (); 1480 } 1481 1482 if (inner_names) 1483 { 1484 // Dwarf subprograms may only have plain (non-linker) names 1485 // Retry with inner names only 1486 1487 Vec_loop (Function*, functions, index, item) 1488 { 1489 name = strrchr (item->get_mangled_name (), '.'); 1490 if (!name) continue; 1491 name++; 1492 if (cmp_func_name (fname, len, name, fortran)) 1493 return item->cardinal (); 1494 } 1495 } 1496 return NULL; 1497} 1498 1499Map<const char*, Symbol*> * 1500Stabs::get_elf_symbols () 1501{ 1502 Elf *elf = openElf (false); 1503 if (elf->elfSymbols == NULL) 1504 { 1505 Map<const char*, Symbol*> *elfSymbols = new StringMap<Symbol*>(128, 128); 1506 elf->elfSymbols = elfSymbols; 1507 for (int i = 0, sz = SymLst ? SymLst->size () : 0; i < sz; i++) 1508 { 1509 Symbol *sym = SymLst->fetch (i); 1510 elfSymbols->put (sym->name, sym); 1511 } 1512 } 1513 return elf->elfSymbols; 1514} 1515 1516void 1517Stabs::read_dwarf_from_dot_o (Module *mod) 1518{ 1519 Dprintf (DEBUG_STABS, NTXT ("stabsModules: %s\n"), STR (mod->get_name ())); 1520 Vector<Module*> *mods = mod->dot_o_file->seg_modules; 1521 char *bname = get_basename (mod->get_name ()); 1522 for (int i1 = 0, sz1 = mods ? mods->size () : 0; i1 < sz1; i1++) 1523 { 1524 Module *m = mods->fetch (i1); 1525 Dprintf (DEBUG_STABS, NTXT (" MOD: %s\n"), STR (m->get_name ())); 1526 if (dbe_strcmp (bname, get_basename (m->get_name ())) == 0) 1527 { 1528 mod->indexStabsLink = m; 1529 m->indexStabsLink = mod; 1530 break; 1531 } 1532 } 1533 if (mod->indexStabsLink) 1534 { 1535 mod->dot_o_file->objStabs->openDwarf ()->srcline_Dwarf (mod->indexStabsLink); 1536 Map<const char*, Symbol*> *elfSymbols = get_elf_symbols (); 1537 Vector<Function*> *funcs = mod->indexStabsLink->functions; 1538 for (int i1 = 0, sz1 = funcs ? funcs->size () : 0; i1 < sz1; i1++) 1539 { 1540 Function *f1 = funcs->fetch (i1); 1541 Symbol *sym = elfSymbols->get (f1->get_mangled_name ()); 1542 if (sym == NULL) 1543 continue; 1544 Dprintf (DEBUG_STABS, NTXT (" Symbol: %s func=%p\n"), STR (sym->name), sym->func); 1545 Function *f = sym->func; 1546 if (f->indexStabsLink) 1547 continue; 1548 f->indexStabsLink = f1; 1549 f1->indexStabsLink = f; 1550 f->copy_PCInfo (f1); 1551 } 1552 } 1553} 1554 1555Stabs::Stab_status 1556Stabs::read_archive (LoadObject *lo) 1557{ 1558 if (openElf (true) == NULL) 1559 return status; 1560 check_Symtab (); 1561 if (elfDbg->dwarf) 1562 openDwarf ()->archive_Dwarf (lo); 1563 1564 // get Module/Function lists from stabs info 1565 Stab_status statusStabs = DBGD_ERR_NO_STABS; 1566#define ARCHIVE_STABS(sec, secStr, comdat) \ 1567 if ((elfDbg->sec) != 0 && (elfDbg->secStr) != 0 && \ 1568 archive_Stabs(lo, elfDbg->sec, elfDbg->secStr, comdat) == DBGD_ERR_NONE) \ 1569 statusStabs = DBGD_ERR_NONE 1570 1571 // prefer index stabs (where they exist) since they're most appropriate 1572 // for loadobjects and might have N_CPROF stabs for ABS/CPF 1573 ARCHIVE_STABS (stabIndex, stabIndexStr, true); 1574 ARCHIVE_STABS (stabExcl, stabExclStr, false); 1575 ARCHIVE_STABS (stab, stabStr, false); 1576 1577 // Add all unassigned functions to the <unknown> module 1578 Symbol *sitem, *alias; 1579 int index; 1580 Vec_loop (Symbol*, SymLst, index, sitem) 1581 { 1582 if (sitem->func || (sitem->size == 0) || (sitem->flags & SYM_UNDEF)) 1583 continue; 1584 alias = sitem->alias; 1585 if (alias) 1586 { 1587 if (alias->func == NULL) 1588 { 1589 alias->func = createFunction (lo, lo->noname, alias); 1590 alias->func->alias = alias->func; 1591 } 1592 if (alias != sitem) 1593 { 1594 sitem->func = createFunction (lo, alias->func->module, sitem); 1595 sitem->func->alias = alias->func; 1596 } 1597 } 1598 else 1599 sitem->func = createFunction (lo, lo->noname, sitem); 1600 } 1601 if (pltSym) 1602 { 1603 pltSym->func = createFunction (lo, lo->noname, pltSym); 1604 pltSym->func->flags |= FUNC_FLAG_PLT; 1605 } 1606 1607 // need Module association, so this must be done after handling Modules 1608 check_AnalyzerInfo (); 1609 1610 if (dwarf && dwarf->status == DBGD_ERR_NONE) 1611 return DBGD_ERR_NONE; 1612 return statusStabs; 1613}//read_archive 1614 1615Function * 1616Stabs::createFunction (LoadObject *lo, Module *module, Symbol *sym) 1617{ 1618 Function *func = dbeSession->createFunction (); 1619 func->module = module; 1620 func->img_fname = path; 1621 func->img_offset = (off_t) sym->img_offset; 1622 func->save_addr = sym->save; 1623 func->size = (uint32_t) sym->size; 1624 func->set_name (sym->name); 1625 func->elfSym = sym; 1626 module->functions->append (func); 1627 lo->functions->append (func); 1628 return func; 1629} 1630 1631void 1632Stabs::fixSymtabAlias () 1633{ 1634 int ind, i, k; 1635 Symbol *sym, *bestAlias; 1636 SymLst->sort (SymImgOffsetCmp); 1637 ind = SymLst->size () - 1; 1638 for (i = 0; i < ind; i++) 1639 { 1640 bestAlias = SymLst->fetch (i); 1641 if (bestAlias->img_offset == 0) // Ignore this bad symbol 1642 continue; 1643 sym = SymLst->fetch (i + 1); 1644 if (bestAlias->img_offset != sym->img_offset) 1645 { 1646 if ((bestAlias->size == 0) || 1647 (sym->img_offset < bestAlias->img_offset + bestAlias->size)) 1648 bestAlias->size = sym->img_offset - bestAlias->img_offset; 1649 continue; 1650 } 1651 1652 // Find a "best" alias 1653 size_t bestLen = strlen (bestAlias->name); 1654 int64_t maxSize = bestAlias->size; 1655 for (k = i + 1; k <= ind; k++) 1656 { 1657 sym = SymLst->fetch (k); 1658 if (bestAlias->img_offset != sym->img_offset) 1659 { // no more aliases 1660 if ((maxSize == 0) || 1661 (sym->img_offset < bestAlias->img_offset + maxSize)) 1662 maxSize = sym->img_offset - bestAlias->img_offset; 1663 break; 1664 } 1665 if (maxSize < sym->size) 1666 maxSize = sym->size; 1667 size_t len = strlen (sym->name); 1668 if (len < bestLen) 1669 { 1670 bestAlias = sym; 1671 bestLen = len; 1672 } 1673 } 1674 for (; i < k; i++) 1675 { 1676 sym = SymLst->fetch (i); 1677 sym->alias = bestAlias; 1678 sym->size = maxSize; 1679 } 1680 i--; 1681 } 1682} 1683 1684void 1685Stabs::check_Symtab () 1686{ 1687 if (st_check_symtab) 1688 return; 1689 st_check_symtab = true; 1690 1691 Elf *elf = openElf (true); 1692 if (elf == NULL) 1693 return; 1694 if (elfDis->plt != 0) 1695 { 1696 Elf_Internal_Shdr *shdr = elfDis->get_shdr (elfDis->plt); 1697 if (shdr) 1698 { 1699 pltSym = new Symbol (); 1700 pltSym->value = shdr->sh_addr; 1701 pltSym->size = shdr->sh_size; 1702 pltSym->img_offset = shdr->sh_offset; 1703 pltSym->name = dbe_strdup (NTXT ("@plt")); 1704 pltSym->flags |= SYM_PLT; 1705 } 1706 } 1707 if (elf->symtab) 1708 readSymSec (elf->symtab, elf); 1709 else 1710 { 1711 readSymSec (elf->SUNW_ldynsym, elf); 1712 readSymSec (elf->dynsym, elf); 1713 } 1714} 1715 1716void 1717Stabs::readSymSec (unsigned int sec, Elf *elf) 1718{ 1719 Symbol *sitem; 1720 Sp_lang_code local_lcode; 1721 if (sec == 0) 1722 return; 1723 // Get ELF data 1724 Elf_Data *data = elf->elf_getdata (sec); 1725 if (data == NULL) 1726 return; 1727 uint64_t SymtabSize = data->d_size; 1728 Elf_Internal_Shdr *shdr = elf->get_shdr (sec); 1729 1730 if ((SymtabSize == 0) || (shdr->sh_entsize == 0)) 1731 return; 1732 Elf_Data *data_str = elf->elf_getdata (shdr->sh_link); 1733 if (data_str == NULL) 1734 return; 1735 char *Strtab = (char *) data_str->d_buf; 1736 1737 // read func symbolic table 1738 for (unsigned int n = 0, tot = SymtabSize / shdr->sh_entsize; n < tot; n++) 1739 { 1740 Elf_Internal_Sym Sym; 1741 elf->elf_getsym (data, n, &Sym); 1742 const char *st_name = Sym.st_name < data_str->d_size ? 1743 (Strtab + Sym.st_name) : NTXT ("no_name"); 1744 switch (GELF_ST_TYPE (Sym.st_info)) 1745 { 1746 case STT_FUNC: 1747 // Skip UNDEF symbols (bug 4817083) 1748 if (Sym.st_shndx == 0) 1749 { 1750 if (Sym.st_value == 0) 1751 break; 1752 sitem = new Symbol (SymLst); 1753 sitem->flags |= SYM_UNDEF; 1754 if (pltSym) 1755 sitem->img_offset = (uint32_t) (pltSym->img_offset + 1756 Sym.st_value - pltSym->value); 1757 } 1758 else 1759 { 1760 Elf_Internal_Shdr *shdrp = elfDis->get_shdr (Sym.st_shndx); 1761 if (shdrp == NULL) 1762 break; 1763 sitem = new Symbol (SymLst); 1764 sitem->img_offset = (uint32_t) (shdrp->sh_offset + 1765 Sym.st_value - shdrp->sh_addr); 1766 } 1767 sitem->size = Sym.st_size; 1768 sitem->name = dbe_strdup (st_name); 1769 sitem->value = is_relocatable () ? sitem->img_offset : Sym.st_value; 1770 if (GELF_ST_BIND (Sym.st_info) == STB_LOCAL) 1771 { 1772 sitem->local_ind = LocalFile->size () - 1; 1773 LocalLst->append (sitem); 1774 } 1775 break; 1776 case STT_NOTYPE: 1777 if (streq (st_name, NTXT ("gcc2_compiled."))) 1778 { 1779 sitem = new Symbol (SymLst); 1780 sitem->lang_code = Sp_lang_gcc; 1781 sitem->name = dbe_strdup (st_name); 1782 sitem->local_ind = LocalFile->size () - 1; 1783 LocalLst->append (sitem); 1784 } 1785 break; 1786 case STT_OBJECT: 1787 if (!strncmp (st_name, NTXT ("__KAI_KPTS_"), 11)) 1788 local_lcode = Sp_lang_KAI_KPTS; 1789 else if (!strncmp (st_name, NTXT ("__KAI_KCC_"), 10)) 1790 local_lcode = Sp_lang_KAI_KCC; 1791 else if (!strncmp (st_name, NTXT ("__KAI_Kcc_"), 10)) 1792 local_lcode = Sp_lang_KAI_Kcc; 1793 else 1794 break; 1795 sitem = new Symbol (LocalLst); 1796 sitem->lang_code = local_lcode; 1797 sitem->name = dbe_strdup (st_name); 1798 break; 1799 case STT_FILE: 1800 { 1801 int last = LocalFile->size () - 1; 1802 if (last >= 0 && LocalFileIdx->fetch (last) == LocalLst->size ()) 1803 { 1804 // There were no local functions in the latest file. 1805 free (LocalFile->get (last)); 1806 LocalFile->store (last, dbe_strdup (st_name)); 1807 } 1808 else 1809 { 1810 LocalFile->append (dbe_strdup (st_name)); 1811 LocalFileIdx->append (LocalLst->size ()); 1812 } 1813 break; 1814 } 1815 } 1816 } 1817 fixSymtabAlias (); 1818 SymLst->sort (SymValueCmp); 1819 get_save_addr (elf->need_swap_endian); 1820 dump (); 1821}//check_Symtab 1822 1823void 1824Stabs::check_Relocs () 1825{ 1826 // We may have many relocation tables to process: .rela.text%foo, 1827 // rela.text%bar, etc. On Intel, compilers generate .rel.text sections 1828 // which have to be processed as well. A lot of rework is needed here. 1829 Symbol *sptr = NULL; 1830 if (st_check_relocs) 1831 return; 1832 st_check_relocs = true; 1833 1834 Elf *elf = openElf (false); 1835 if (elf == NULL) 1836 return; 1837 for (unsigned int sec = 1; sec < elf->elf_getehdr ()->e_shnum; sec++) 1838 { 1839 bool use_rela, use_PLT; 1840 char *name = elf->get_sec_name (sec); 1841 if (name == NULL) 1842 continue; 1843 if (strncmp (name, NTXT (".rela.text"), 10) == 0) 1844 { 1845 use_rela = true; 1846 use_PLT = false; 1847 } 1848 else if (streq (name, NTXT (".rela.plt"))) 1849 { 1850 use_rela = true; 1851 use_PLT = true; 1852 } 1853 else if (strncmp (name, NTXT (".rel.text"), 9) == 0) 1854 { 1855 use_rela = false; 1856 use_PLT = false; 1857 } 1858 else if (streq (name, NTXT (".rel.plt"))) 1859 { 1860 use_rela = false; 1861 use_PLT = true; 1862 } 1863 else 1864 continue; 1865 1866 Elf_Internal_Shdr *shdr = elf->get_shdr (sec); 1867 if (shdr == NULL) 1868 continue; 1869 1870 // Get ELF data 1871 Elf_Data *data = elf->elf_getdata (sec); 1872 if (data == NULL) 1873 continue; 1874 uint64_t ScnSize = data->d_size; 1875 uint64_t EntSize = shdr->sh_entsize; 1876 if ((ScnSize == 0) || (EntSize == 0)) 1877 continue; 1878 int tot = (int) (ScnSize / EntSize); 1879 1880 // Get corresponding text section 1881 Elf_Internal_Shdr *shdr_txt = elf->get_shdr (shdr->sh_info); 1882 if (shdr_txt == NULL) 1883 continue; 1884 if (!(shdr_txt->sh_flags & SHF_EXECINSTR)) 1885 continue; 1886 1887 // Get corresponding symbol table section 1888 Elf_Internal_Shdr *shdr_sym = elf->get_shdr (shdr->sh_link); 1889 if (shdr_sym == NULL) 1890 continue; 1891 Elf_Data *data_sym = elf->elf_getdata (shdr->sh_link); 1892 1893 // Get corresponding string table section 1894 Elf_Data *data_str = elf->elf_getdata (shdr_sym->sh_link); 1895 if (data_str == NULL) 1896 continue; 1897 char *Strtab = (char*) data_str->d_buf; 1898 for (int n = 0; n < tot; n++) 1899 { 1900 Elf_Internal_Sym sym; 1901 Elf_Internal_Rela rela; 1902 char *symName; 1903 if (use_rela) 1904 elf->elf_getrela (data, n, &rela); 1905 else 1906 { 1907 // GElf_Rela is extended GElf_Rel 1908 elf->elf_getrel (data, n, &rela); 1909 rela.r_addend = 0; 1910 } 1911 1912 int ndx = (int) GELF_R_SYM (rela.r_info); 1913 elf->elf_getsym (data_sym, ndx, &sym); 1914 switch (GELF_ST_TYPE (sym.st_info)) 1915 { 1916 case STT_FUNC: 1917 case STT_OBJECT: 1918 case STT_NOTYPE: 1919 if (sym.st_name == 0 || sym.st_name >= data_str->d_size) 1920 continue; 1921 symName = Strtab + sym.st_name; 1922 break; 1923 case STT_SECTION: 1924 { 1925 Elf_Internal_Shdr *secHdr = elf->get_shdr (sym.st_shndx); 1926 if (secHdr == NULL) 1927 continue; 1928 if (sptr == NULL) 1929 sptr = new Symbol; 1930 sptr->value = secHdr->sh_offset + rela.r_addend; 1931 long index = SymLst->bisearch (0, -1, &sptr, SymFindCmp); 1932 if (index == -1) 1933 continue; 1934 Symbol *sp = SymLst->fetch (index); 1935 if (sptr->value != sp->value) 1936 continue; 1937 symName = sp->name; 1938 break; 1939 } 1940 default: 1941 continue; 1942 } 1943 Reloc *reloc = new Reloc; 1944 reloc->name = dbe_strdup (symName); 1945 reloc->type = GELF_R_TYPE (rela.r_info); 1946 reloc->value = use_PLT ? rela.r_offset 1947 : rela.r_offset + shdr_txt->sh_offset; 1948 reloc->addend = rela.r_addend; 1949 if (use_PLT) 1950 RelPLTLst->append (reloc); 1951 else 1952 RelLst->append (reloc); 1953 } 1954 } 1955 delete sptr; 1956 RelLst->sort (RelValueCmp); 1957} //check_Relocs 1958 1959void 1960Stabs::get_save_addr (bool need_swap_endian) 1961{ 1962 if (elfDis->is_Intel ()) 1963 { 1964 for (int j = 0, sz = SymLst ? SymLst->size () : 0; j < sz; j++) 1965 { 1966 Symbol *sitem = SymLst->fetch (j); 1967 sitem->save = 0; 1968 } 1969 return; 1970 } 1971 for (int j = 0, sz = SymLst ? SymLst->size () : 0; j < sz; j++) 1972 { 1973 Symbol *sitem = SymLst->fetch (j); 1974 sitem->save = FUNC_NO_SAVE; 1975 1976 // If an image offset is not known skip it. 1977 // Works for artificial symbols like '@plt' as well. 1978 if (sitem->img_offset == 0) 1979 continue; 1980 1981 bool is_o7_moved = false; 1982 int64_t off = sitem->img_offset; 1983 for (int i = 0; i < sitem->size; i += 4) 1984 { 1985 unsigned int cmd; 1986 if (elfDis->get_data (off, sizeof (cmd), &cmd) == NULL) 1987 break; 1988 if (need_swap_endian) 1989 SWAP_ENDIAN (cmd); 1990 off += sizeof (cmd); 1991 if ((cmd & 0xffffc000) == 0x9de38000) 1992 { // save %sp, ??, %sp 1993 sitem->save = i; 1994 break; 1995 } 1996 else if ((cmd & 0xc0000000) == 0x40000000 || // call ?? 1997 (cmd & 0xfff80000) == 0xbfc00000) 1998 { // jmpl ??, %o7 1999 if (!is_o7_moved) 2000 { 2001 sitem->save = FUNC_ROOT; 2002 break; 2003 } 2004 } 2005 else if ((cmd & 0xc1ffe01f) == 0x8010000f) // or %g0,%o7,?? 2006 is_o7_moved = true; 2007 } 2008 } 2009} 2010 2011uint64_t 2012Stabs::mapOffsetToAddress (uint64_t img_offset) 2013{ 2014 Elf *elf = openElf (false); 2015 if (elf == NULL) 2016 return 0; 2017 if (is_relocatable ()) 2018 return img_offset; 2019 for (unsigned int sec = 1; sec < elf->elf_getehdr ()->e_shnum; sec++) 2020 { 2021 Elf_Internal_Shdr *shdr = elf->get_shdr (sec); 2022 if (shdr == NULL) 2023 continue; 2024 if (img_offset >= (uint64_t) shdr->sh_offset 2025 && img_offset < (uint64_t) (shdr->sh_offset + shdr->sh_size)) 2026 return shdr->sh_addr + (img_offset - shdr->sh_offset); 2027 } 2028 return 0; 2029} 2030 2031Stabs::Stab_status 2032Stabs::archive_Stabs (LoadObject *lo, unsigned int StabSec, 2033 unsigned int StabStrSec, bool comdat) 2034{ 2035 StabReader *stabReader = new StabReader (openElf (true), platform, StabSec, StabStrSec); 2036 int tot = stabReader->stabCnt; 2037 if (tot < 0) 2038 { 2039 delete stabReader; 2040 return DBGD_ERR_NO_STABS; 2041 } 2042 2043 char *sbase = NTXT (""), *arg, *fname, sname[2 * MAXPATHLEN]; 2044 int lastMod, phase, stabs_level, modCnt = 0; 2045 Function *func = NULL; 2046 Module *mod; 2047#define INIT_MOD phase = 0; stabs_level = 0; *sname = '\0'; mod = NULL 2048 2049 bool updateStabsMod = false; 2050 if (comdat && ((elfDbg->elf_getehdr ()->e_type == ET_EXEC) || (elfDbg->elf_getehdr ()->e_type == ET_DYN))) 2051 { 2052 if (stabsModules == NULL) 2053 stabsModules = new Vector<Module*>(); 2054 updateStabsMod = true; 2055 } 2056 INIT_MOD; 2057 lastMod = lo->seg_modules->size (); 2058 2059 for (int n = 0; n < tot; n++) 2060 { 2061 struct stab stb; 2062 char *str = stabReader->get_stab (&stb, comdat); 2063 switch (stb.n_type) 2064 { 2065 case N_FUN: 2066 // Ignore a COMDAT function, if there are two or more modules in 'lo' 2067 if (comdat && stb.n_other == 1 && modCnt > 1) 2068 break; 2069 case N_OUTL: 2070 case N_ALIAS: 2071 case N_ENTRY: 2072 if (mod == NULL || str == NULL 2073 || (stb.n_type != N_ENTRY && stabs_level != 0)) 2074 break; 2075 if (*str == '@') 2076 { 2077 str++; 2078 if (*str == '>' || *str == '<') 2079 str++; 2080 } 2081 2082 fname = dbe_strdup (str); 2083 arg = strchr (fname, ':'); 2084 if (arg != NULL) 2085 { 2086 if (!strncmp (arg, NTXT (":P"), 2)) 2087 { // just prototype 2088 free (fname); 2089 break; 2090 } 2091 *arg = '\0'; 2092 } 2093 2094 func = append_Function (mod, fname); 2095 free (fname); 2096 break; 2097 case N_CMDLINE: 2098 if (str && mod) 2099 { 2100 char *comp_flags = strchr (str, ';'); 2101 if (comp_flags) 2102 { 2103 mod->comp_flags = dbe_strdup (comp_flags + 1); 2104 mod->comp_dir = dbe_strndup (str, comp_flags - str); 2105 } 2106 } 2107 break; 2108 case N_LBRAC: 2109 stabs_level++; 2110 break; 2111 case N_RBRAC: 2112 stabs_level--; 2113 break; 2114 case N_UNDF: 2115 INIT_MOD; 2116 break; 2117 case N_ENDM: 2118 INIT_MOD; 2119 break; 2120 case N_OPT: 2121 stabReader->parse_N_OPT (mod, str); 2122 if (mod && (str != NULL) && streq (str, NTXT ("gcc2_compiled."))) 2123 // Is it anachronism ? 2124 mod->lang_code = Sp_lang_gcc; 2125 break; 2126 case N_GSYM: 2127 if (mod && (str != NULL)) 2128 { 2129 if (strncmp (str, NTXT ("__KAI_K"), 7)) 2130 break; 2131 str += 7; 2132 if (!strncmp (str, NTXT ("CC_"), 3)) 2133 mod->lang_code = Sp_lang_KAI_KCC; 2134 else if (!strncmp (str, NTXT ("cc_"), 3)) 2135 mod->lang_code = Sp_lang_KAI_Kcc; 2136 else if (!strncmp (str, NTXT ("PTS_"), 4) && 2137 (mod->lang_code != Sp_lang_KAI_KCC) && 2138 (mod->lang_code != Sp_lang_KAI_Kcc)) 2139 mod->lang_code = Sp_lang_KAI_KPTS; 2140 } 2141 break; 2142 case N_SO: 2143 if (str == NULL || *str == '\0') 2144 { 2145 INIT_MOD; 2146 break; 2147 } 2148 if (phase == 0) 2149 { 2150 phase = 1; 2151 sbase = str; 2152 } 2153 else 2154 { 2155 if (*str == '/') 2156 sbase = str; 2157 else 2158 { 2159 size_t last = strlen (sbase); 2160 if (last == 0 || sbase[last - 1] != '/') 2161 snprintf (sname, sizeof (sname), NTXT ("%s/%s"), sbase, str); 2162 else 2163 snprintf (sname, sizeof (sname), NTXT ("%s%s"), sbase, str); 2164 sbase = sname; 2165 } 2166 mod = append_Module (lo, sbase, lastMod); 2167 if (updateStabsMod) 2168 stabsModules->append (mod); 2169 mod->hasStabs = true; 2170 modCnt++; 2171 if ((mod->lang_code != Sp_lang_gcc) && 2172 (mod->lang_code != Sp_lang_KAI_KPTS) && 2173 (mod->lang_code != Sp_lang_KAI_KCC) && 2174 (mod->lang_code != Sp_lang_KAI_Kcc)) 2175 mod->lang_code = (Sp_lang_code) stb.n_desc; 2176 *sname = '\0'; 2177 phase = 0; 2178 } 2179 break; 2180 case N_OBJ: 2181 if (str == NULL) 2182 break; 2183 if (phase == 0) 2184 { 2185 phase = 1; 2186 sbase = str; 2187 } 2188 else 2189 { 2190 if (*str == '/') 2191 sbase = str; 2192 else 2193 { 2194 size_t last = strlen (sbase); 2195 if (last == 0 || sbase[last - 1] != '/') 2196 snprintf (sname, sizeof (sname), NTXT ("%s/%s"), sbase, str); 2197 else 2198 snprintf (sname, sizeof (sname), NTXT ("%s%s"), sbase, str); 2199 sbase = sname; 2200 } 2201 if (mod && (mod->dot_o_file == NULL)) 2202 { 2203 if (strcmp (sbase, NTXT ("/")) == 0) 2204 mod->set_name (dbe_strdup (path)); 2205 else 2206 { 2207 mod->set_name (dbe_strdup (sbase)); 2208 mod->dot_o_file = mod->createLoadObject (sbase); 2209 } 2210 } 2211 *sname = '\0'; 2212 phase = 0; 2213 } 2214 break; 2215 case N_CPROF: 2216 cpf_stabs_t map; 2217 Dprintf (DEBUG_STABS, NTXT ("N_CPROF n_desc=%x n_value=0x%04x mod=%s\n"), 2218 stb.n_desc, stb.n_value, (mod == NULL) ? NTXT ("???") : mod->get_name ()); 2219 map.type = stb.n_desc; 2220 map.offset = stb.n_value; 2221 map.module = mod; 2222 analyzerInfoMap.append (map); 2223 break; 2224 } 2225 } 2226 delete stabReader; 2227 return func ? DBGD_ERR_NONE : DBGD_ERR_NO_STABS; 2228} 2229 2230Module * 2231Stabs::append_Module (LoadObject *lo, char *name, int lastMod) 2232{ 2233 Module *module; 2234 int size; 2235 Symbol *sitem; 2236 2237 if (lo->seg_modules != NULL) 2238 { 2239 size = lo->seg_modules->size (); 2240 if (size < lastMod) 2241 lastMod = size; 2242 for (int i = 0; i < lastMod; i++) 2243 { 2244 module = lo->seg_modules->fetch (i); 2245 if (module->linkerStabName && streq (module->linkerStabName, name)) 2246 return module; 2247 } 2248 } 2249 module = dbeSession->createModule (lo, NULL); 2250 module->set_file_name (dbe_strdup (name)); 2251 module->linkerStabName = dbe_strdup (module->file_name); 2252 2253 // Append all functions with 'local_ind == -1' to the module. 2254 if (LocalLst->size () > 0) 2255 { 2256 sitem = LocalLst->fetch (0); 2257 if (!sitem->defined && sitem->local_ind == -1) 2258 // Append all functions with 'local_ind == -1' to the module. 2259 append_local_funcs (module, 0); 2260 } 2261 2262 // Append local func 2263 char *basename = get_basename (name); 2264 size = LocalFile->size (); 2265 for (int i = 0; i < size; i++) 2266 { 2267 if (streq (basename, LocalFile->fetch (i))) 2268 { 2269 int local_ind = LocalFileIdx->fetch (i); 2270 if (local_ind >= LocalLst->size ()) 2271 break; 2272 sitem = LocalLst->fetch (local_ind); 2273 if (!sitem->defined) 2274 { 2275 append_local_funcs (module, local_ind); 2276 break; 2277 } 2278 } 2279 } 2280 return module; 2281} 2282 2283void 2284Stabs::append_local_funcs (Module *module, int first_ind) 2285{ 2286 Symbol *sitem = LocalLst->fetch (first_ind); 2287 int local_ind = sitem->local_ind; 2288 int size = LocalLst->size (); 2289 for (int i = first_ind; i < size; i++) 2290 { 2291 sitem = LocalLst->fetch (i); 2292 if (sitem->local_ind != local_ind) 2293 break; 2294 sitem->defined = true; 2295 2296 // 3rd party compiled. e.g., Gcc or KAI compiled 2297 if (sitem->lang_code != Sp_lang_unknown) 2298 { 2299 if (module->lang_code == Sp_lang_unknown) 2300 module->lang_code = sitem->lang_code; 2301 continue; 2302 } 2303 if (sitem->func) 2304 continue; 2305 Function *func = dbeSession->createFunction (); 2306 sitem->func = func; 2307 func->img_fname = path; 2308 func->img_offset = (off_t) sitem->img_offset; 2309 func->save_addr = (uint32_t) sitem->save; 2310 func->size = (uint32_t) sitem->size; 2311 func->module = module; 2312 func->set_name (sitem->name); 2313 module->functions->append (func); 2314 module->loadobject->functions->append (func); 2315 } 2316} 2317 2318Function * 2319Stabs::append_Function (Module *module, char *fname) 2320{ 2321 Symbol *sitem, *sptr; 2322 Function *func; 2323 long sid, index; 2324 char *name; 2325 if (SymLstByName == NULL) 2326 { 2327 SymLstByName = SymLst->copy (); 2328 SymLstByName->sort (SymNameCmp); 2329 } 2330 sptr = new Symbol; 2331 if (module->lang_code == N_SO_FORTRAN || module->lang_code == N_SO_FORTRAN90) 2332 { 2333 char *fortran = dbe_sprintf (NTXT ("%s_"), fname); // FORTRAN name 2334 sptr->name = fortran; 2335 sid = SymLstByName->bisearch (0, -1, &sptr, SymNameCmp); 2336 if (sid == -1) 2337 { 2338 free (fortran); 2339 sptr->name = fname; 2340 sid = SymLstByName->bisearch (0, -1, &sptr, SymNameCmp); 2341 } 2342 else 2343 fname = fortran; 2344 } 2345 else 2346 { 2347 sptr->name = fname; 2348 sid = SymLstByName->bisearch (0, -1, &sptr, SymNameCmp); 2349 } 2350 sptr->name = NULL; 2351 delete sptr; 2352 2353 if (sid == -1) 2354 { 2355 Vec_loop (Symbol*, SymLstByName, index, sitem) 2356 { 2357 if (strncmp (sitem->name, NTXT ("$X"), 2) == 0 2358 || strncmp (sitem->name, NTXT (".X"), 2) == 0) 2359 { 2360 char *n = strchr (((sitem->name) + 2), (int) '.'); 2361 if (n != NULL) 2362 name = n + 1; 2363 else 2364 name = sitem->name; 2365 } 2366 else 2367 name = sitem->name; 2368 if (name != NULL && fname != NULL && (strcmp (name, fname) == 0)) 2369 { 2370 sid = index; 2371 break; 2372 } 2373 } 2374 } 2375 if (sid != -1) 2376 { 2377 sitem = SymLstByName->fetch (sid); 2378 if (sitem->alias) 2379 sitem = sitem->alias; 2380 if (sitem->func) 2381 return sitem->func; 2382 sitem->func = func = dbeSession->createFunction (); 2383 func->img_fname = path; 2384 func->img_offset = (off_t) sitem->img_offset; 2385 func->save_addr = (uint32_t) sitem->save; 2386 func->size = (uint32_t) sitem->size; 2387 } 2388 else 2389 func = dbeSession->createFunction (); 2390 2391 func->module = module; 2392 func->set_name (fname); 2393 module->functions->append (func); 2394 module->loadobject->functions->append (func); 2395 return func; 2396} 2397 2398Function * 2399Stabs::append_Function (Module *module, char *linkerName, uint64_t pc) 2400{ 2401 Dprintf (DEBUG_STABS, NTXT ("Stabs::append_Function: module=%s linkerName=%s pc=0x%llx\n"), 2402 STR (module->get_name ()), STR (linkerName), (unsigned long long) pc); 2403 long i; 2404 Symbol *sitem = NULL, *sp; 2405 Function *func; 2406 sp = new Symbol; 2407 if (pc) 2408 { 2409 sp->value = pc; 2410 i = SymLst->bisearch (0, -1, &sp, SymFindCmp); 2411 if (i != -1) 2412 sitem = SymLst->fetch (i); 2413 } 2414 2415 if (!sitem && linkerName) 2416 { 2417 if (SymLstByName == NULL) 2418 { 2419 SymLstByName = SymLst->copy (); 2420 SymLstByName->sort (SymNameCmp); 2421 } 2422 sp->name = linkerName; 2423 i = SymLstByName->bisearch (0, -1, &sp, SymNameCmp); 2424 sp->name = NULL; 2425 if (i != -1) 2426 sitem = SymLstByName->fetch (i); 2427 } 2428 delete sp; 2429 2430 if (!sitem) 2431 return NULL; 2432 if (sitem->alias) 2433 sitem = sitem->alias; 2434 if (sitem->func) 2435 return sitem->func; 2436 2437 sitem->func = func = dbeSession->createFunction (); 2438 func->img_fname = path; 2439 func->img_offset = (off_t) sitem->img_offset; 2440 func->save_addr = (uint32_t) sitem->save; 2441 func->size = (uint32_t) sitem->size; 2442 func->module = module; 2443 func->set_name (sitem->name); //XXXX ?? Now call it to set obj->name 2444 module->functions->append (func); 2445 module->loadobject->functions->append (func); 2446 return func; 2447}// Stabs::append_Function 2448 2449Dwarf * 2450Stabs::openDwarf () 2451{ 2452 if (dwarf == NULL) 2453 { 2454 dwarf = new Dwarf (this); 2455 check_Symtab (); 2456 } 2457 return dwarf; 2458} 2459 2460void 2461Stabs::read_hwcprof_info (Module *module) 2462{ 2463 openDwarf ()->read_hwcprof_info (module); 2464} 2465 2466void 2467Stabs::dump () 2468{ 2469 if (!DUMP_ELF_SYM) 2470 return; 2471 printf (NTXT ("\n======= Stabs::dump: %s =========\n"), path ? path : NTXT ("NULL")); 2472 int i, sz; 2473 if (LocalFile) 2474 { 2475 sz = LocalFile->size (); 2476 for (i = 0; i < sz; i++) 2477 printf (" %3d: %5d '%s'\n", i, LocalFileIdx->fetch (i), 2478 LocalFile->fetch (i)); 2479 } 2480 Symbol::dump (SymLst, NTXT ("SymLst")); 2481 Symbol::dump (LocalLst, NTXT ("LocalLst")); 2482 printf (NTXT ("\n===== END of Stabs::dump: %s =========\n\n"), 2483 path ? path : NTXT ("NULL")); 2484} 2485 2486/////////////////////////////////////////////////////////////////////////////// 2487// Class Include 2488Include::Include () 2489{ 2490 stack = new Vector<SrcFileInfo*>; 2491} 2492 2493Include::~Include () 2494{ 2495 Destroy (stack); 2496} 2497 2498void 2499Include::new_src_file (SourceFile *source, int lineno, Function *func) 2500{ 2501 for (int index = stack->size () - 1; index >= 0; index--) 2502 { 2503 if (source == stack->fetch (index)->srcfile) 2504 { 2505 for (int i = stack->size () - 1; i > index; i--) 2506 { 2507 delete stack->remove (i); 2508 if (func && func->line_first > 0) 2509 func->popSrcFile (); 2510 } 2511 return; 2512 } 2513 } 2514 if (func && func->line_first > 0) 2515 func->pushSrcFile (source, lineno); 2516 2517 SrcFileInfo *sfinfo = new SrcFileInfo; 2518 sfinfo->srcfile = source; 2519 sfinfo->lineno = lineno; 2520 stack->append (sfinfo); 2521} 2522 2523void 2524Include::push_src_files (Function *func) 2525{ 2526 int index; 2527 SrcFileInfo *sfinfo; 2528 2529 if (func->line_first <= 0 && stack->size () > 0) 2530 { 2531 sfinfo = stack->fetch (stack->size () - 1); 2532 func->setDefSrc (sfinfo->srcfile); 2533 } 2534 Vec_loop (SrcFileInfo*, stack, index, sfinfo) 2535 { 2536 func->pushSrcFile (sfinfo->srcfile, sfinfo->lineno); 2537 } 2538} 2539 2540void 2541Include::new_include_file (SourceFile *source, Function *func) 2542{ 2543 if (stack->size () == 1 && stack->fetch (0)->srcfile == source) 2544 // workaroud for gcc; gcc creates 'N_BINCL' stab for main source 2545 return; 2546 if (func && func->line_first > 0) 2547 func->pushSrcFile (source, 0); 2548 2549 SrcFileInfo *sfinfo = new SrcFileInfo; 2550 sfinfo->srcfile = source; 2551 sfinfo->lineno = 0; 2552 stack->append (sfinfo); 2553} 2554 2555void 2556Include::end_include_file (Function *func) 2557{ 2558 int index = stack->size () - 1; 2559 if (index > 0) 2560 { 2561 delete stack->remove (index); 2562 if (func && func->line_first > 0) 2563 func->popSrcFile (); 2564 } 2565} 2566 2567#define RET_S(x) if (t == x) return (char *) #x 2568char * 2569StabReader::get_type_name (int t) 2570{ 2571 RET_S (N_UNDF); 2572 RET_S (N_ABS); 2573 RET_S (N_TEXT); 2574 RET_S (N_DATA); 2575 RET_S (N_BSS); 2576 RET_S (N_COMM); 2577 RET_S (N_FN); 2578 RET_S (N_EXT); 2579 RET_S (N_TYPE); 2580 RET_S (N_GSYM); 2581 RET_S (N_FNAME); 2582 RET_S (N_FUN); 2583 RET_S (N_OUTL); 2584 RET_S (N_STSYM); 2585 RET_S (N_TSTSYM); 2586 RET_S (N_LCSYM); 2587 RET_S (N_TLCSYM); 2588 RET_S (N_MAIN); 2589 RET_S (N_ROSYM); 2590 RET_S (N_FLSYM); 2591 RET_S (N_TFLSYM); 2592 RET_S (N_PC); 2593 RET_S (N_CMDLINE); 2594 RET_S (N_OBJ); 2595 RET_S (N_OPT); 2596 RET_S (N_RSYM); 2597 RET_S (N_SLINE); 2598 RET_S (N_XLINE); 2599 RET_S (N_ILDPAD); 2600 RET_S (N_SSYM); 2601 RET_S (N_ENDM); 2602 RET_S (N_SO); 2603 RET_S (N_MOD); 2604 RET_S (N_EMOD); 2605 RET_S (N_READ_MOD); 2606 RET_S (N_ALIAS); 2607 RET_S (N_LSYM); 2608 RET_S (N_BINCL); 2609 RET_S (N_SOL); 2610 RET_S (N_PSYM); 2611 RET_S (N_EINCL); 2612 RET_S (N_ENTRY); 2613 RET_S (N_SINCL); 2614 RET_S (N_LBRAC); 2615 RET_S (N_EXCL); 2616 RET_S (N_USING); 2617 RET_S (N_ISYM); 2618 RET_S (N_ESYM); 2619 RET_S (N_PATCH); 2620 RET_S (N_CONSTRUCT); 2621 RET_S (N_DESTRUCT); 2622 RET_S (N_CODETAG); 2623 RET_S (N_FUN_CHILD); 2624 RET_S (N_RBRAC); 2625 RET_S (N_BCOMM); 2626 RET_S (N_TCOMM); 2627 RET_S (N_ECOMM); 2628 RET_S (N_XCOMM); 2629 RET_S (N_ECOML); 2630 RET_S (N_WITH); 2631 RET_S (N_LENG); 2632 RET_S (N_CPROF); 2633 RET_S (N_BROWS); 2634 RET_S (N_FUN_PURE); 2635 RET_S (N_FUN_ELEMENTAL); 2636 RET_S (N_FUN_RECURSIVE); 2637 RET_S (N_FUN_AMD64_PARMDUMP); 2638 RET_S (N_SYM_OMP_TLS); 2639 RET_S (N_SO_AS); 2640 RET_S (N_SO_C); 2641 RET_S (N_SO_ANSI_C); 2642 RET_S (N_SO_CC); 2643 RET_S (N_SO_FORTRAN); 2644 RET_S (N_SO_FORTRAN77); 2645 RET_S (N_SO_PASCAL); 2646 RET_S (N_SO_FORTRAN90); 2647 RET_S (N_SO_JAVA); 2648 RET_S (N_SO_C99); 2649 return NULL; 2650} 2651