diff options
Diffstat (limited to 'gprofng/src')
-rw-r--r-- | gprofng/src/Dwarf.cc | 205 | ||||
-rw-r--r-- | gprofng/src/Dwarf.h | 2 | ||||
-rw-r--r-- | gprofng/src/DwarfLib.cc | 79 | ||||
-rw-r--r-- | gprofng/src/DwarfLib.h | 15 | ||||
-rw-r--r-- | gprofng/src/LoadObject.cc | 18 | ||||
-rw-r--r-- | gprofng/src/Makefile.am | 1 | ||||
-rw-r--r-- | gprofng/src/Makefile.in | 4 | ||||
-rw-r--r-- | gprofng/src/Stabs.cc | 166 | ||||
-rw-r--r-- | gprofng/src/Stabs.h | 5 | ||||
-rw-r--r-- | gprofng/src/Symbol.cc | 226 | ||||
-rw-r--r-- | gprofng/src/Symbol.h | 80 | ||||
-rw-r--r-- | gprofng/src/collect.h | 1 | ||||
-rw-r--r-- | gprofng/src/envsets.cc | 10 | ||||
-rw-r--r-- | gprofng/src/gp-collect-app.cc | 2 | ||||
-rw-r--r-- | gprofng/src/ipcio.cc | 5 |
15 files changed, 564 insertions, 255 deletions
diff --git a/gprofng/src/Dwarf.cc b/gprofng/src/Dwarf.cc index 3b3fd63..23ac5b9 100644 --- a/gprofng/src/Dwarf.cc +++ b/gprofng/src/Dwarf.cc @@ -29,6 +29,7 @@ #include "LoadObject.h" #include "Module.h" #include "DefaultMap.h" +#include "Symbol.h" static int datatypeCmp (const void *a, const void *b) @@ -46,7 +47,6 @@ targetOffsetCmp (const void *a, const void *b) return o1 == o2 ? 0 : (o1 < o2 ? -1 : 1); } - ////////////////////////////////////////////////////////// // class Dwr_type class Dwr_type @@ -441,7 +441,12 @@ DwrCU::get_linkage_name () nm = Dwarf_string (DW_AT_SUN_link_name); if (nm != NULL) return nm; - return Dwarf_string (DW_AT_MIPS_linkage_name); + if (nm != NULL) + return nm; + nm = Dwarf_string (DW_AT_MIPS_linkage_name); + if (nm != NULL) + return nm; + return Dwarf_string (DW_AT_name); } void @@ -490,8 +495,10 @@ DwrCU::parseChild (Dwarf_cnt *ctx) } break; case DW_TAG_subprogram: + { if (dwrTag.get_attr (DW_AT_abstract_origin)) break; + Symbol *sym = NULL; if (dwrTag.get_attr (DW_AT_declaration)) { // Only declaration @@ -499,26 +506,71 @@ DwrCU::parseChild (Dwarf_cnt *ctx) { char *link_name = Dwarf_string (DW_AT_name); if (link_name && streq (link_name, NTXT ("MAIN"))) - ctx->fortranMAIN = Stabs::find_func (NTXT ("MAIN"), ctx->module->functions, true, true); - } - break; + ctx->fortranMAIN = Stabs::find_func (NTXT ("MAIN"), + ctx->module->functions, true, true); + } + sym = Symbol::get_symbol (symbols_sorted_by_name, + get_linkage_name ()); + if (sym == NULL) + break; + func = append_Function (sym, ctx->name); + break; } - func = append_Function (ctx); - if (func) + + Dwr_Attr *dwrAttr = dwrTag.get_attr (DW_AT_specification); + if (dwrAttr) { - if (Stabs::is_fortran (ctx->module->lang_code) && - streq (func->get_match_name (), NTXT ("MAIN"))) - ctx->fortranMAIN = func; - old_name = ctx->name; - Function *old_func = ctx->func; - ctx->name = func->get_match_name (); - ctx->func = func; - parseChild (ctx); - hasChild = 0; - ctx->name = old_name; - ctx->func = old_func; + // Find previous declaration to inherit settings. + sym = find_declaration (dwrAttr->u.offset); + if (sym == NULL) + break; + func = sym->func; + if (func == NULL) + break; + set_source (func); + + Vector <Range *> *ranges = get_ranges (); + if (ranges) + { + Vector<Symbol *> *syms = Symbol::find_symbols (symbols, ranges); + Destroy (ranges); + for (int i = 0, sz = VecSize (syms); i < sz; i++) + { + Symbol *sp = syms->get (i); + if (sp->alias) + sp = sp->alias; + Function *f = sp->func; + if (f == NULL) + f = sp->createFunction (func->module); + f->setLineFirst (func->line_first); + f->setDefSrc (func->def_source); + } + delete (syms); + } + break; } + + sym = Symbol::get_symbol (symbols_sorted_by_name, get_linkage_name ()); + if (sym == NULL) + sym = Symbol::get_symbol (symbols, get_low_pc ()); + if (sym == NULL) + break; + func = append_Function (sym, ctx->name); + if (Stabs::is_fortran (ctx->module->lang_code) && + streq (func->get_match_name (), "MAIN")) + ctx->fortranMAIN = func; + set_source (func); + + old_name = ctx->name; + Function *old_func = ctx->func; + ctx->name = func->get_match_name (); + ctx->func = func; + parseChild (ctx); + hasChild = 0; + ctx->name = old_name; + ctx->func = old_func; break; + } case DW_TAG_module: old_name = ctx->name; ctx->name = Dwarf_string (DW_AT_SUN_link_name); @@ -631,6 +683,21 @@ Dwarf::archive_Dwarf (LoadObject *lo) STR (lo_name), STR (mod->get_name ())); dwrCU->dwrInlinedSubrs->dump (msg); } + for (int i = 0, sz = VecSize (dwrCU->symbols); i < sz; i++) + { + Symbol *sp = dwrCU->symbols->get (i); + Function *f = sp->func; + if (f == NULL) + { + f = sp->createFunction (mod); + if (sp->alias && sp->alias->func) + { + Function *func = sp->alias->func; + f->setLineFirst (func->line_first); + f->setDefSrc (func->def_source); + } + } + } } } return true; @@ -645,6 +712,38 @@ Dwarf::srcline_Dwarf (Module *module) dwrCU->map_dwarf_lines (module); } +static int +rangeCmp (const void *a, const void *b) +{ + Range *item1 = *((Range **) a); + Range *item2 = *((Range **) b); + return item1->low < item2->low ? -1 : (item1->low == item2->low ? 0 : 1); +} + +Vector<Range *> * +Dwarf::get_ranges (uint64_t offset) +{ + if (debug_rangesSec == NULL) + return NULL; + if (offset >= debug_rangesSec->size) + { + Dprintf (DUMP_DWARFLIB, "ERROR: Dwarf::get_ranges(0x%llx). size=0x%llx\n", + (long long) offset, (long long) debug_rangesSec->size); + return NULL; + } + Vector<Range*> *ranges = new Vector<Range*>(); + debug_rangesSec->offset = offset; + for (;;) + { + uint64_t low_pc = debug_rangesSec->GetADDR (); + uint64_t high_pc = debug_rangesSec->GetADDR (); + if (low_pc == 0 || low_pc > high_pc) + break; + ranges->append (new Range (low_pc, high_pc)); + } + ranges->sort (rangeCmp); + return ranges; +} // parse hwcprof info for given module in loadobject @@ -797,11 +896,17 @@ DwrCU::read_hwcprof_info (Dwarf_cnt *ctx) case DW_TAG_subprogram: { Function *old_func = ctx->func; - if (dwrTag.get_attr (DW_AT_abstract_origin) - || dwrTag.get_attr (DW_AT_declaration)) - ctx->func = NULL; - else - ctx->func = append_Function (ctx); + ctx->func = NULL; + if (dwrTag.get_attr (DW_AT_abstract_origin) == NULL + && dwrTag.get_attr (DW_AT_declaration) == NULL) + { + Symbol *sym = Symbol::get_symbol (symbols_sorted_by_name, + get_linkage_name ()); + if (sym == NULL) + sym = Symbol::get_symbol (symbols, get_low_pc ()); + if (sym != NULL) + ctx->func = sym->func; + } read_hwcprof_info (ctx); ctx->func = old_func; break; @@ -955,49 +1060,31 @@ DwrCU::read_hwcprof_info (Dwarf_cnt *ctx) // Append function to module Function * -DwrCU::append_Function (Dwarf_cnt *ctx) +DwrCU::append_Function (Symbol *sym, const char *outerName) { - char *outerName = ctx->name, *name, tmpname[2048]; - Function *func; + if (sym->func != NULL) + return sym->func; + Function *func = sym->createFunction (module); + char *fname = Dwarf_string (DW_AT_name); - if (fname && outerName && !strchr (fname, '.')) + if (fname) { - size_t outerlen = strlen (outerName); - if (outerlen > 0 && outerName[outerlen - 1] == '_') + if (outerName && !strchr (fname, '.')) { - outerlen--; - snprintf (tmpname, sizeof (tmpname), NTXT ("%s"), outerName); - snprintf (tmpname + outerlen, sizeof (tmpname) - outerlen, NTXT (".%s_"), fname); + char *tmpname; + int outerlen = (int) strlen (outerName); + if (outerlen > 0 && outerName[outerlen - 1] == '_') + tmpname = dbe_sprintf ("%.*s.%s_", outerlen - 1, outerName, fname); + else + tmpname = dbe_sprintf ("%s.%s", outerName, fname); + func->set_match_name (tmpname); + Dprintf (DUMP_DWARFLIB, "Generated innerfunc name %s\n", tmpname); + free(tmpname); } else - snprintf (tmpname, sizeof (tmpname), NTXT ("%s.%s"), outerName, fname); - name = tmpname; - Dprintf (DUMP_DWARFLIB, NTXT ("Generated innerfunc name %s\n"), name); - } - else - name = fname; - - char *link_name = get_linkage_name (); - if (link_name == NULL) - link_name = name; - - uint64_t pc = get_low_pc (); - func = dwarf->stabs->append_Function (module, link_name, pc); - if (func != NULL) - { - int lineno = (int) Dwarf_data (DW_AT_decl_line); - func->set_match_name (name); - if (lineno > 0) - { - func->setLineFirst (lineno); - int fileno = ((int) Dwarf_data (DW_AT_decl_file)); - SourceFile *sf = ((fileno >= 0) && (fileno < VecSize (srcFiles))) ? srcFiles->get (fileno) - : module->getMainSrc (); - func->setDefSrc (sf); - func->pushSrcFile (func->def_source, 0); - func->popSrcFile (); - } + func->set_match_name (fname); } + set_source (func); return func; } diff --git a/gprofng/src/Dwarf.h b/gprofng/src/Dwarf.h index 8e3ee7a..f46ad3f 100644 --- a/gprofng/src/Dwarf.h +++ b/gprofng/src/Dwarf.h @@ -60,6 +60,7 @@ class LoadObject; class Module; class DwrCU; class DwrSec; +class Range; class Dwarf { @@ -69,6 +70,7 @@ public: bool archive_Dwarf (LoadObject *lo); void srcline_Dwarf (Module *module); void read_hwcprof_info (Module *module); + Vector<Range *> *get_ranges (uint64_t offset); Stabs::Stab_status status; Vector<DwrCU *> *dwrCUs; diff --git a/gprofng/src/DwarfLib.cc b/gprofng/src/DwarfLib.cc index 3594c2f..9f55ab3 100644 --- a/gprofng/src/DwarfLib.cc +++ b/gprofng/src/DwarfLib.cc @@ -27,9 +27,9 @@ #include "Elf.h" #include "Function.h" #include "Module.h" -#include "StringBuilder.h" #include "DbeArray.h" #include "DbeSession.h" +#include "Symbol.h" #define NO_STMT_LIST ((uint64_t) -1) #define CASE_S(x) case x: s = (char *) #x; break @@ -1795,6 +1795,8 @@ DwrLineRegs::getPath (int fn) DwrCU::DwrCU (Dwarf *_dwarf) { dwarf = _dwarf; + symbols = NULL; + symbols_sorted_by_name = NULL; cu_offset = dwarf->debug_infoSec->offset; debug_infoSec = new DwrSec (dwarf->debug_infoSec, cu_offset); next_cu_offset = debug_infoSec->ReadLength (); @@ -1883,6 +1885,8 @@ DwrCU::~DwrCU () Destroy (dwrInlinedSubrs); delete srcFiles; delete dwrLineReg; + delete symbols; + delete symbols_sorted_by_name; free (comp_dir); } @@ -2187,9 +2191,80 @@ DwrCU::parse_cu_header (LoadObject *lo) else path = dbe_strdup (dwarf->stabs->path); module->set_name (path); + + // create a list of functions in this CU + Vector <Range *> *ranges = get_ranges (); + if (ranges) + { + Vector <Symbol *> *syms = dwarf->stabs->get_symbols (); + symbols = Symbol::find_symbols (syms, ranges); + symbols_sorted_by_name = Symbol::sort_by_name (syms); + Destroy (ranges); + } return module; } +Vector <Range *> * +DwrCU::get_ranges () +{ + Vector <Range *> *ranges = NULL; + Dwr_Attr *dwrAttr = dwrTag.get_attr (DW_AT_ranges); + if (dwrAttr) + { + Dprintf (DUMP_DWARFLIB, "DwrCU::get_ranges: 0x%llx\n", + (long long) dwrAttr->u.offset); + ranges = dwarf->get_ranges (dwrAttr->u.offset); + } + else + { + uint64_t low_pc = Dwarf_addr (DW_AT_low_pc); + if (low_pc > 0) + { + uint64_t high_pc = get_high_pc (low_pc); + ranges = new Vector <Range *> (1); + ranges->append (new Range (low_pc, high_pc)); + Dprintf (DUMP_DWARFLIB, "DwrCU::get_ranges: pc=0x%llx\n", + (long long) low_pc); + } + } + if (ranges && DUMP_DWARFLIB) + ranges->dump (" "); + return ranges; +} + +void +DwrCU::set_source (Function *func) +{ + int lineno = (int) Dwarf_data (DW_AT_decl_line); + func->setLineFirst (lineno); + + int fileno = (int) Dwarf_data (DW_AT_decl_file); + if (fileno > 0 && fileno < VecSize (srcFiles)) + func->setDefSrc (srcFiles->get (fileno)); +} + +Symbol * +DwrCU::find_declaration (int64_t offset) +{ + int64_t old_offset = dwrTag.offset; + Symbol *sym = NULL; + if (set_die (offset) == DW_DLV_OK) + { + sym = Symbol::get_symbol (symbols_sorted_by_name, get_linkage_name ()); + if (sym && sym->func == NULL) + { + Function *func = sym->createFunction (module); + int lineno = (int) Dwarf_data (DW_AT_decl_line); + func->setLineFirst (lineno); + int fileno = (int) Dwarf_data (DW_AT_decl_file); + if (fileno > 0 && fileno < VecSize (srcFiles)) + func->setDefSrc (srcFiles->get (fileno)); + } + } + set_die (old_offset); + return sym; +} + Dwr_Attr * Dwr_Tag::get_attr (Dwarf_Half attr) { @@ -2357,7 +2432,7 @@ DwrCU::map_dwarf_lines (Module *mod) InlinedSubr *p = func->inlinedSubr + func->inlinedSubrCnt; func->inlinedSubrCnt++; int fileno = inlinedSubr->file - 1; - SourceFile *sf = ((fileno >= 0) && (fileno < VecSize (srcFiles))) ? + SourceFile *sf = ((fileno > 0) && (fileno < VecSize (srcFiles))) ? srcFiles->get (fileno) : dbeSession->get_Unknown_Source (); p->dbeLine = sf->find_dbeline (inlinedSubr->line); p->high_pc = inlinedSubr->high_pc - low_pc; diff --git a/gprofng/src/DwarfLib.h b/gprofng/src/DwarfLib.h index 178801d..230e551 100644 --- a/gprofng/src/DwarfLib.h +++ b/gprofng/src/DwarfLib.h @@ -25,6 +25,8 @@ class ElfReloc; class Dwr_type; +class Function; +class Range; class SourceFile; template <class ITEM> class Vector; @@ -73,12 +75,6 @@ public: return (uint32_t) GetULEB128 (); } - bool - inRange (uint64_t left, uint64_t right) - { - return (offset >= left) && (offset < right); - }; - ElfReloc *reloc; uint64_t sizeSec; uint64_t size; @@ -280,6 +276,8 @@ public: uint64_t cu_header_offset; uint64_t cu_offset; uint64_t next_cu_offset; + Vector<Symbol*> *symbols; // all symbols in this CU are sorted by pc + Vector<Symbol*> *symbols_sorted_by_name; Vector<DwrInlinedSubr*> *dwrInlinedSubrs; Vector<SourceFile *> *srcFiles; bool isMemop; @@ -287,7 +285,10 @@ public: private: void build_abbrevTable (DwrSec *debug_abbrevSec, uint64_t stmt_list_offset); - Function *append_Function (Dwarf_cnt *ctx); + Function *append_Function (Symbol *sym, const char *outerName); + Symbol *find_declaration(int64_t offset); + Vector <Range *> *get_ranges(); + void set_source (Function *func); void parse_inlined_subroutine (Dwarf_cnt *ctx); uint64_t get_low_pc (); uint64_t get_high_pc (uint64_t low_pc); diff --git a/gprofng/src/LoadObject.cc b/gprofng/src/LoadObject.cc index 1ca6ab6..be7ad3a 100644 --- a/gprofng/src/LoadObject.cc +++ b/gprofng/src/LoadObject.cc @@ -20,6 +20,7 @@ #include "config.h" #include <errno.h> +#include <libgen.h> #include "util.h" #include "StringBuilder.h" @@ -303,13 +304,16 @@ LoadObject::dump_functions (FILE *out) { mname = fitem->module ? fitem->module->file_name : noname->file_name; sname = fitem->getDefSrcName (); - fprintf (out, - "id %6llu, @0x%llx - 0x%llx [save 0x%llx] o-%lld sz-%lld %s (module = %s)", - (ull_t) fitem->id, (ull_t) fitem->img_offset, - (ull_t) (fitem->img_offset + fitem->size), - (ull_t) fitem->save_addr, (ull_t) fitem->img_offset, - (ll_t) fitem->size, fitem->get_name (), mname); - if (sname && !streq (sname, mname)) + fprintf (out, "id %6llu, @0x%llx-0x%llx sz-%lld", (ull_t) fitem->id, + (ull_t) fitem->img_offset, + (ull_t) (fitem->img_offset + fitem->size), + (ll_t) fitem->size); + if (fitem->save_addr != 0) + fprintf (out, " [save 0x%llx]", (ull_t) fitem->save_addr); + if (strcmp (fitem->get_mangled_name (), fitem->get_name ()) != 0) + fprintf (out, " [%s]", fitem->get_mangled_name ()); + fprintf (out, " %s (module = %s)", fitem->get_name (), mname); + if (sname && strcmp (basename (sname), basename (mname)) != 0) fprintf (out, " (Source = %s)", sname); fprintf (out, "\n"); } diff --git a/gprofng/src/Makefile.am b/gprofng/src/Makefile.am index 0465cdb..f6d3f5d 100644 --- a/gprofng/src/Makefile.am +++ b/gprofng/src/Makefile.am @@ -78,6 +78,7 @@ CCSOURCES = \ Stabs.cc \ Stats_data.cc \ StringBuilder.cc \ + Symbol.cc \ Table.cc \ QLParser.tab.cc \ dbe_collctrl.cc \ diff --git a/gprofng/src/Makefile.in b/gprofng/src/Makefile.in index 9f07986..0cdd444 100644 --- a/gprofng/src/Makefile.in +++ b/gprofng/src/Makefile.in @@ -174,7 +174,7 @@ am__objects_1 = Application.lo BaseMetric.lo BaseMetricTreeNode.lo \ MemorySpace.lo Metric.lo MetricList.lo Module.lo Ovw_data.lo \ PRBTree.lo PathTree.lo PreviewExp.lo Print.lo \ SAXParserFactory.lo Sample.lo Settings.lo SourceFile.lo \ - Stabs.lo Stats_data.lo StringBuilder.lo Table.lo \ + Stabs.lo Stats_data.lo StringBuilder.lo Symbol.lo Table.lo \ QLParser.tab.lo dbe_collctrl.lo i18n.lo parse.lo UserLabel.lo \ util.lo Dbe.lo am__objects_2 = dbe_hwcdrv.lo dbe_hwcfuncs.lo dbe_hwctable.lo \ @@ -505,6 +505,7 @@ CCSOURCES = \ Stabs.cc \ Stats_data.cc \ StringBuilder.cc \ + Symbol.cc \ Table.cc \ QLParser.tab.cc \ dbe_collctrl.cc \ @@ -777,6 +778,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Stabs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Stats_data.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StringBuilder.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Symbol.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Table.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UserLabel.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/checks.Po@am__quote@ diff --git a/gprofng/src/Stabs.cc b/gprofng/src/Stabs.cc index b98ac28..ff83949 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 (); @@ -294,8 +182,6 @@ Stabs::Stabs (char *_path, char *_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>; @@ -341,8 +227,6 @@ Stabs::~Stabs () { delete SymLstByName; Destroy (SymLst); - Destroy (RelLst); - Destroy (RelPLTLst); Destroy (LocalFile); delete elfDis; delete dwarf; @@ -458,42 +342,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) { @@ -1761,10 +1609,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 +1689,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) @@ -2339,6 +2188,7 @@ Stabs::openDwarf () { dwarf = new Dwarf (this); check_Symtab (); + dump(); } return dwarf; } @@ -2363,8 +2213,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")); } diff --git a/gprofng/src/Stabs.h b/gprofng/src/Stabs.h index d34741f..c8da278 100644 --- a/gprofng/src/Stabs.h +++ b/gprofng/src/Stabs.h @@ -40,7 +40,6 @@ class ComC; class Elf; class Dwarf; class Symbol; -class Reloc; struct cpf_stabs_t; class SourceFile; template <typename Key_t, typename Value_t> class Map; @@ -86,12 +85,12 @@ class Stabs { Platform_t get_platform() { return platform; } WSize_t get_class() { return wsize;} Stab_status get_status() { return status;} + Vector<Symbol *> *get_symbols() { return SymLst; } Stab_status read_stabs(ino64_t srcInode, Module *module, Vector<ComC*> *comComs, bool readDwarf = false); Stab_status read_archive(LoadObject *lo); bool read_symbols(Vector<Function*> *functions); uint64_t mapOffsetToAddress(uint64_t img_offset); - char *sym_name(uint64_t target, uint64_t instr, int flag); Elf *openElf (bool dbg_info = false); void read_hwcprof_info(Module *module); void dump(); @@ -135,8 +134,6 @@ class Stabs { Symbol *pltSym; Vector<Symbol*> *SymLst; // list of func symbols Vector<Symbol*> *SymLstByName; // list of func symbols sorted by Name - Vector<Reloc*> *RelLst; // list of text relocations - Vector<Reloc*> *RelPLTLst; // list of PLT relocations Vector<Symbol*> *LocalLst; // list of local func symbols Vector<char*> *LocalFile; // list of local files Vector<int> *LocalFileIdx; // start index in LocalLst diff --git a/gprofng/src/Symbol.cc b/gprofng/src/Symbol.cc new file mode 100644 index 0000000..82fe788 --- /dev/null +++ b/gprofng/src/Symbol.cc @@ -0,0 +1,226 @@ +/* Copyright (C) 2025 Free Software Foundation, Inc. + Contributed by Oracle. + + This file is part of GNU Binutils. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +#include "config.h" + +#include "DbeSession.h" +#include "Function.h" +#include "LoadObject.h" +#include "Module.h" +#include "Symbol.h" + + +template<> void Vector<Symbol *>::dump (const char *msg) +{ + if (msg == NULL) + msg = "#"; + Dprintf (1, NTXT ("\n%s Vector<Symbol *> [%lld]\n"), msg, (long long) size ()); + if (size () > 0) + Dprintf (1, " value | img_offset | size | flags|local_ind|\n"); + for (long i = 0, sz = size (); i < sz; i++) + { + Symbol *sp = get (i); + Dprintf (1, " %3ld ", i); + sp->dump (); + } + if (size () > 0) + Dprintf (1, "===== END of Symbol::dump: %s =========\n\n", msg); +} + +void +Symbol::dump (const char *msg) +{ + if (msg) + Dprintf (1, "%s\n", msg); + Dprintf (1, "%8lld |%11lld |%6d |%5d |%8d |%s\n", (long long) value, + (long long) img_offset, (int) size, flags, local_ind, + name ? name : "NULL"); +} + +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); +} + +Symbol::~Symbol () +{ + free (name); +} + +static int +cmpSym (const void *a, const void *b) +{ + Symbol *item1 = *((Symbol **) a); + Symbol *item2 = *((Symbol **) b); + return (item1->value > item2->value) ? 1 : + (item1->value == item2->value) ? 0 : -1; +} + +static int +cmpSymName (const void *a, const void *b) +{ + Symbol *item1 = *((Symbol **) a); + Symbol *item2 = *((Symbol **) b); + return strcmp (item1->name, item2->name); +} + +Symbol * +Symbol::get_symbol (Vector<Symbol*> *syms, uint64_t pc) +{ + if (syms != NULL && pc != 0) + { + Symbol *sp = new Symbol; + sp->value = pc; + long i = syms->bisearch (0, -1, &sp, cmpSym); + delete sp; + if (i != -1) + return syms->get (i)->cardinal (); + } + return NULL; +} + +Symbol * +Symbol::get_symbol (Vector<Symbol*> *syms, char *linker_name) +{ + if (syms != NULL && linker_name != NULL) + { + Symbol *sp = new Symbol; + sp->name = linker_name; + long i = syms->bisearch (0, -1, &sp, cmpSymName); + sp->name = NULL; + delete sp; + if (i != -1) + return syms->get (i)->cardinal (); + } + return NULL; +} + +Vector<Symbol *> * +Symbol::sort_by_name (Vector<Symbol *> *syms) +{ + if (VecSize (syms) == 0) + return NULL; + Vector<Symbol *> *symbols = syms->copy (); + symbols->sort (cmpSymName); + return symbols; +} + +Vector<Symbol *> * +Symbol::find_symbols (Vector<Symbol*> *syms, Vector<Range *> *ranges) +{ + // 'syms' and 'ranges' must already be sorted. + // return symbols matched by 'ranges' + if (VecSize (syms) == 0 || VecSize (ranges) == 0) + return NULL; + Vector<Symbol *> *symbols = new Vector<Symbol*> (); + + // Use binary search to find a suitable index in 'syms' + int ind = 0; + uint64_t addr = ranges->get (0)->low; + for (int lo = 0, hi = syms->size (); lo < hi;) + { + int mid = (hi + lo) >> 1; + Symbol *sym = syms->get (mid); + if (sym->value == addr) + { + ind = mid; + break; + } + else if (sym->value > addr) + hi = mid - 1; + else + { + ind = mid; + lo = mid + 1; + } + } + + for (int i = 0, r_sz = ranges->size (), sz = syms->size (); ind < sz; ind++) + { + Symbol *sym = syms->get (ind); + while (i < r_sz) + { + Range *r = ranges->get (i); + if (sym->value < r->low) + break; + if (sym->value <= r->high) + { + symbols->append (sym); + break; + } + i++; + } + if (i >= r_sz) + break; + } + if (DUMP_ELF_SYM) + { + syms->dump ( "Symbol::find_symbols: syms"); + symbols->dump ("Symbol::find_symbols: symbols"); + } + if (symbols->size () != 0) + return symbols; + delete symbols; + return NULL; +} + +/* Create and append a new function to the 'module'. + * Copy attributes (size, name, etc) from Simbol, */ +Function * +Symbol::createFunction (Module *module) +{ + if (func) + return func; + func = dbeSession->createFunction (); + func->img_fname = module->file_name; + func->img_offset = img_offset; + func->save_addr = save; + func->size = size; + func->module = module; + func->set_name (name); + module->functions->append (func); + module->loadobject->functions->append (func); + return func; +} + +template<> void Vector<Range *>::dump (const char *msg) +{ + Dprintf (1, NTXT ("%s Vector<Range *> [%lld]\n"), + msg ? msg : "#", (long long) size ()); + for (long i = 0, sz = size (); i < sz; i++) + { + Range *p = get (i); + Dprintf (1, "%3ld 0x%08llx 0x%08llx (%lld - %lld)\n", i, + (long long) p->low, (long long) p->high, + (long long) p->low, (long long) p->high); + } +}
\ No newline at end of file diff --git a/gprofng/src/Symbol.h b/gprofng/src/Symbol.h new file mode 100644 index 0000000..25cceca --- /dev/null +++ b/gprofng/src/Symbol.h @@ -0,0 +1,80 @@ +/* Copyright (C) 2025 Free Software Foundation, Inc. + Contributed by Oracle. + + This file is part of GNU Binutils. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +class Function; +class Module; + +class Range +{ +public: + Range (uint64_t _low, uint64_t _high) + { + low = _low; + high = _high; + } + + inline bool + inside (uint64_t val) + { + return val >= low && val < high; + }; + + uint64_t low; + uint64_t high; +}; + +class Symbol +{ +public: + Symbol (Vector<Symbol *> *vec = NULL); + ~Symbol (); + + Symbol * + cardinal () + { + return alias ? alias : this; + } + + // Find symbols in 'syms' matched by 'ranges'. + static Vector<Symbol *> *find_symbols (Vector<Symbol *> *syms, + Vector<Range *> *ranges); + static Vector<Symbol *> *sort_by_name (Vector<Symbol *> *syms); + + // Find symbol in CU corresponding to pc or linker_name. + static Symbol *get_symbol (Vector<Symbol *> *syms, uint64_t pc); + static Symbol *get_symbol (Vector<Symbol *> *syms, char *linker_name); + + // Create and append a new function to the 'module'. + // Copy attributes (size, name, etc) from Simbol, + Function *createFunction(Module *module); + void dump (const char *msg = NULL); + + Function *func; + Sp_lang_code lang_code; + uint64_t value; + 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; +};
\ No newline at end of file diff --git a/gprofng/src/collect.h b/gprofng/src/collect.h index 18ab564..3ce6b28 100644 --- a/gprofng/src/collect.h +++ b/gprofng/src/collect.h @@ -32,7 +32,6 @@ class Coll_Ctrl; class Elf; #define MAXLABELS 10 /* maximum number of -C arguments */ -#define STDEBUFSIZE 24000 enum { MAX_LD_PRELOAD_TYPES = 3 }; diff --git a/gprofng/src/envsets.cc b/gprofng/src/envsets.cc index 30803aa..e92c017 100644 --- a/gprofng/src/envsets.cc +++ b/gprofng/src/envsets.cc @@ -31,16 +31,6 @@ #include "StringBuilder.h" #include "Settings.h" -#define STDEBUFSIZE 24000 - -#define LIBGP_COLLECTOR "libgp-collector.so" -#define GPROFNG_PRELOAD_LIBDIRS "GPROFNG_PRELOAD_LIBDIRS" -#define SP_COLLECTOR_EXPNAME "SP_COLLECTOR_EXPNAME" -#define SP_COLLECTOR_FOLLOW_SPEC "SP_COLLECTOR_FOLLOW_SPEC" -#define SP_COLLECTOR_PARAMS "SP_COLLECTOR_PARAMS" -#define SP_COLLECTOR_FOUNDER "SP_COLLECTOR_FOUNDER" -#define SP_COLLECTOR_ORIGIN_COLLECT "SP_COLLECTOR_ORIGIN_COLLECT" - static const char *LD_AUDIT[] = { // "LD_AUDIT", Do not set LD_AUDIT on Linux NULL diff --git a/gprofng/src/gp-collect-app.cc b/gprofng/src/gp-collect-app.cc index b94f410..695c4af 100644 --- a/gprofng/src/gp-collect-app.cc +++ b/gprofng/src/gp-collect-app.cc @@ -44,8 +44,6 @@ #include "collect.h" #include "StringBuilder.h" -#define SP_COLLECTOR_FOUNDER "SP_COLLECTOR_FOUNDER" - extern char **environ; static volatile int interrupt = 0; diff --git a/gprofng/src/ipcio.cc b/gprofng/src/ipcio.cc index 36d2ba5..2890c6a 100644 --- a/gprofng/src/ipcio.cc +++ b/gprofng/src/ipcio.cc @@ -23,10 +23,7 @@ #include <stdlib.h> #include <signal.h> #include <unistd.h> -#include <iostream> -#include <iomanip> -#include <sstream> -#include <queue> + #include "vec.h" #include "util.h" #include "ipcio.h" |