diff options
Diffstat (limited to 'gprofng/src/Stabs.cc')
-rw-r--r-- | gprofng/src/Stabs.cc | 353 |
1 files changed, 42 insertions, 311 deletions
diff --git a/gprofng/src/Stabs.cc b/gprofng/src/Stabs.cc index b98ac28..116316e 100644 --- a/gprofng/src/Stabs.cc +++ b/gprofng/src/Stabs.cc @@ -35,10 +35,7 @@ #include "StringBuilder.h" #include "DbeFile.h" #include "StringMap.h" - -#define DISASM_REL_NONE 0 /* symtab search only */ -#define DISASM_REL_ONLY 1 /* relocation search only */ -#define DISASM_REL_TARG 2 /* relocatoin then symtab */ +#include "Symbol.h" /////////////////////////////////////////////////////////////////////////////// // class StabReader @@ -62,105 +59,6 @@ private: int StabEntSize; }; -/////////////////////////////////////////////////////////////////////////////// -// class Symbol - -class Symbol -{ -public: - Symbol (Vector<Symbol*> *vec = NULL); - - ~Symbol () - { - free (name); - } - - inline Symbol * - cardinal () - { - return alias ? alias : this; - } - - static void dump (Vector<Symbol*> *vec, char*msg); - - Function *func; - Sp_lang_code lang_code; - uint64_t value; // st_value used in sym_name() - uint64_t save; - int64_t size; - uint64_t img_offset; // image offset in the ELF file - char *name; - Symbol *alias; - int local_ind; - int flags; - bool defined; -}; - -Symbol::Symbol (Vector<Symbol*> *vec) -{ - func = NULL; - lang_code = Sp_lang_unknown; - value = 0; - save = 0; - size = 0; - img_offset = 0; - name = NULL; - alias = NULL; - local_ind = -1; - flags = 0; - defined = false; - if (vec) - vec->append (this); -} - -void -Symbol::dump (Vector<Symbol*> *vec, char*msg) -{ - if (!DUMP_ELF_SYM || vec == NULL || vec->size () == 0) - return; - printf (NTXT ("======= Symbol::dump: %s =========\n" - " value | img_offset | flags|local_ind|\n"), msg); - for (int i = 0; i < vec->size (); i++) - { - Symbol *sp = vec->fetch (i); - printf (NTXT (" %3d %8lld |0x%016llx |%5d |%8d |%s\n"), - i, (long long) sp->value, (long long) sp->img_offset, sp->flags, - sp->local_ind, sp->name ? sp->name : NTXT ("NULL")); - } - printf (NTXT ("\n===== END of Symbol::dump: %s =========\n\n"), msg); -} - -// end of class Symbol -/////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////// -// class Reloc -class Reloc -{ -public: - Reloc (); - ~Reloc (); - uint64_t type; - uint64_t value; - uint64_t addend; - char *name; -}; - -Reloc::Reloc () -{ - type = 0; - value = 0; - addend = 0; - name = NULL; -} - -Reloc::~Reloc () -{ - free (name); -} -// end of class Reloc -/////////////////////////////////////////////////////////////////////////////// - enum { SYM_PLT = 1 << 0, @@ -232,15 +130,6 @@ SymImgOffsetCmp (const void *a, const void *b) (item1->img_offset == item2->img_offset) ? SymNameCmp (a, b) : -1; } -static int -RelValueCmp (const void *a, const void *b) -{ - Reloc *item1 = *((Reloc **) a); - Reloc *item2 = *((Reloc **) b); - return (item1->value > item2->value) ? 1 : - (item1->value == item2->value) ? 0 : -1; -} - /* Remove all duplicate symbols which can be in SymLst. The duplication is due to processing of both static and dynamic symbols. This function is called before computing symbol @@ -252,7 +141,6 @@ Stabs::removeDupSyms () long ind, i, last; Symbol *symA, *symB; SymLst->sort (SymImgOffsetCmp); - dump (); last = 0; ind = SymLst->size (); @@ -275,42 +163,26 @@ Stabs::removeDupSyms () SymLst->truncate (last); } -Stabs * -Stabs::NewStabs (char *_path, char *lo_name) -{ - Stabs *stabs = new Stabs (_path, lo_name); - if (stabs->status != Stabs::DBGD_ERR_NONE) - { - delete stabs; - return NULL; - } - return stabs; -} - -Stabs::Stabs (char *_path, char *_lo_name) +Stabs::Stabs (Elf *elf, char *_lo_name) { - path = dbe_strdup (_path); + elfDis = elf; + elfDbg = elf->gnu_debug_file ? elf->gnu_debug_file : elf; + path = dbe_strdup (elf->get_location ()); lo_name = dbe_strdup (_lo_name); SymLstByName = NULL; pltSym = NULL; SymLst = new Vector<Symbol*>; - RelLst = new Vector<Reloc*>; - RelPLTLst = new Vector<Reloc*>; LocalLst = new Vector<Symbol*>; LocalFile = new Vector<char*>; LocalFileIdx = new Vector<int>; last_PC_to_sym = NULL; dwarf = NULL; - elfDbg = NULL; - elfDis = NULL; stabsModules = NULL; textsz = 0; wsize = Wnone; st_check_symtab = false; status = DBGD_ERR_NONE; - if (openElf (false) == NULL) - return; switch (elfDis->elf_getclass ()) { case ELFCLASS32: @@ -320,6 +192,31 @@ Stabs::Stabs (char *_path, char *_lo_name) wsize = W64; break; } + switch (elfDis->elf_getehdr ()->e_machine) + { + case EM_SPARC: + platform = Sparc; + break; + case EM_SPARC32PLUS: + platform = Sparcv8plus; + break; + case EM_SPARCV9: + platform = Sparcv9; + break; + case EM_386: + // case EM_486: + platform = Intel; + break; + case EM_X86_64: + platform = Amd64; + break; + case EM_AARCH64: + platform = Aarch64; + break; + default: + platform = Unknown; + break; + } isRelocatable = elfDis->elf_getehdr ()->e_type == ET_REL; for (unsigned int pnum = 0; pnum < elfDis->elf_getehdr ()->e_phnum; pnum++) { @@ -341,10 +238,7 @@ Stabs::~Stabs () { delete SymLstByName; Destroy (SymLst); - Destroy (RelLst); - Destroy (RelPLTLst); Destroy (LocalFile); - delete elfDis; delete dwarf; delete LocalLst; delete LocalFileIdx; @@ -354,90 +248,11 @@ Stabs::~Stabs () } Elf * -Stabs::openElf (char *fname, Stab_status &st) -{ - Elf::Elf_status elf_status; - Elf *elf = Elf::elf_begin (fname, &elf_status); - if (elf == NULL) - { - switch (elf_status) - { - case Elf::ELF_ERR_CANT_OPEN_FILE: - case Elf::ELF_ERR_CANT_MMAP: - case Elf::ELF_ERR_BIG_FILE: - st = DBGD_ERR_CANT_OPEN_FILE; - break; - case Elf::ELF_ERR_BAD_ELF_FORMAT: - default: - st = DBGD_ERR_BAD_ELF_FORMAT; - break; - } - return NULL; - } - if (elf->elf_version (EV_CURRENT) == EV_NONE) - { - // ELF library out of date - delete elf; - st = DBGD_ERR_BAD_ELF_LIB; - return NULL; - } - - Elf_Internal_Ehdr *ehdrp = elf->elf_getehdr (); - if (ehdrp == NULL) - { - // check machine - delete elf; - st = DBGD_ERR_BAD_ELF_FORMAT; - return NULL; - } - switch (ehdrp->e_machine) - { - case EM_SPARC: - platform = Sparc; - break; - case EM_SPARC32PLUS: - platform = Sparcv8plus; - break; - case EM_SPARCV9: - platform = Sparcv9; - break; - case EM_386: - // case EM_486: - platform = Intel; - break; - case EM_X86_64: - platform = Amd64; - break; - case EM_AARCH64: - platform = Aarch64; - break; - default: - platform = Unknown; - break; - } - return elf; -} - -Elf * Stabs::openElf (bool dbg_info) { - if (status != DBGD_ERR_NONE) - return NULL; - if (elfDis == NULL) - { - elfDis = openElf (path, status); - if (elfDis == NULL) - return NULL; - } - if (!dbg_info) - return elfDis; - if (elfDbg == NULL) - { - elfDbg = elfDis->find_ancillary_files (lo_name); - if (elfDbg == NULL) - elfDbg = elfDis; - } - return elfDbg; + if (dbg_info) + return elfDbg; + return elfDis; } bool @@ -458,42 +273,6 @@ Stabs::read_symbols (Vector<Function*> *functions) return true; } -char * -Stabs::sym_name (uint64_t target, uint64_t instr, int flag) -{ - long index; - if (flag == DISASM_REL_ONLY || flag == DISASM_REL_TARG) - { - Reloc *relptr = new Reloc; - relptr->value = instr; - index = RelLst->bisearch (0, -1, &relptr, RelValueCmp); - if (index >= 0) - { - delete relptr; - return RelLst->fetch (index)->name; - } - if (!is_relocatable ()) - { - relptr->value = target; - index = RelPLTLst->bisearch (0, -1, &relptr, RelValueCmp); - if (index >= 0) - { - delete relptr; - return RelPLTLst->fetch (index)->name; - } - } - delete relptr; - } - if (flag == DISASM_REL_NONE || flag == DISASM_REL_TARG || !is_relocatable ()) - { - Symbol *sptr; - sptr = map_PC_to_sym (target); - if (sptr && sptr->value == target) - return sptr->name; - } - return NULL; -} - Symbol * Stabs::map_PC_to_sym (uint64_t pc) { @@ -1706,7 +1485,8 @@ Stabs::fixSymtabAlias () for (; i < k; i++) { sym = SymLst->fetch (i); - sym->alias = bestAlias; + if (sym != bestAlias) + sym->alias = bestAlias; sym->size = maxSize; } i--; @@ -1761,10 +1541,12 @@ Stabs::readSymSec (Elf *elf, bool is_dynamic) if (asym == NULL) break; const char *st_name = bfd_asymbol_name (asym); + if (st_name == NULL) + continue; switch (GELF_ST_TYPE (Sym.st_info)) { case STT_FUNC: - if (Sym.st_size == 0) + if (Sym.st_size == 0 || ELF_ST_BIND (Sym.st_info) == STB_WEAK) break; if (Sym.st_shndx == 0) { @@ -1839,8 +1621,7 @@ Stabs::readSymSec (Elf *elf, bool is_dynamic) fixSymtabAlias (); SymLst->sort (SymValueCmp); get_save_addr (elf->need_swap_endian); - dump (); -}//check_Symtab +} void Stabs::get_save_addr (bool need_swap_endian) @@ -2281,57 +2062,6 @@ Stabs::append_Function (Module *module, char *fname) return func; } -Function * -Stabs::append_Function (Module *module, char *linkerName, uint64_t pc) -{ - Dprintf (DEBUG_STABS, NTXT ("Stabs::append_Function: module=%s linkerName=%s pc=0x%llx\n"), - STR (module->get_name ()), STR (linkerName), (unsigned long long) pc); - long i; - Symbol *sitem = NULL, *sp; - Function *func; - sp = new Symbol; - if (pc) - { - sp->value = pc; - i = SymLst->bisearch (0, -1, &sp, SymFindCmp); - if (i != -1) - sitem = SymLst->fetch (i); - } - - if (!sitem && linkerName) - { - if (SymLstByName == NULL) - { - SymLstByName = SymLst->copy (); - SymLstByName->sort (SymNameCmp); - } - sp->name = linkerName; - i = SymLstByName->bisearch (0, -1, &sp, SymNameCmp); - sp->name = NULL; - if (i != -1) - sitem = SymLstByName->fetch (i); - } - delete sp; - - if (!sitem) - return NULL; - if (sitem->alias) - sitem = sitem->alias; - if (sitem->func) - return sitem->func; - - sitem->func = func = dbeSession->createFunction (); - func->img_fname = path; - func->img_offset = sitem->img_offset; - func->save_addr = sitem->save; - func->size = sitem->size; - func->module = module; - func->set_name (sitem->name); //XXXX ?? Now call it to set obj->name - module->functions->append (func); - module->loadobject->functions->append (func); - return func; -}// Stabs::append_Function - Dwarf * Stabs::openDwarf () { @@ -2339,6 +2069,7 @@ Stabs::openDwarf () { dwarf = new Dwarf (this); check_Symtab (); + dump(); } return dwarf; } @@ -2363,8 +2094,8 @@ Stabs::dump () printf (" %3d: %5d '%s'\n", i, LocalFileIdx->fetch (i), LocalFile->fetch (i)); } - Symbol::dump (SymLst, NTXT ("SymLst")); - Symbol::dump (LocalLst, NTXT ("LocalLst")); + SymLst->dump ("SymLst"); + LocalLst->dump ("LocalLst"); printf (NTXT ("\n===== END of Stabs::dump: %s =========\n\n"), path ? path : NTXT ("NULL")); } |