aboutsummaryrefslogtreecommitdiff
path: root/gprofng/src
diff options
context:
space:
mode:
Diffstat (limited to 'gprofng/src')
-rw-r--r--gprofng/src/DbeSession.cc11
-rw-r--r--gprofng/src/DbeSession.h1
-rw-r--r--gprofng/src/Disasm.cc15
-rw-r--r--gprofng/src/Disasm.h3
-rw-r--r--gprofng/src/Dwarf.cc278
-rw-r--r--gprofng/src/Dwarf.h4
-rw-r--r--gprofng/src/DwarfLib.cc599
-rw-r--r--gprofng/src/DwarfLib.h67
-rw-r--r--gprofng/src/Elf.cc115
-rw-r--r--gprofng/src/Elf.h30
-rw-r--r--gprofng/src/Experiment.cc9
-rw-r--r--gprofng/src/Experiment.h1
-rw-r--r--gprofng/src/LoadObject.cc21
-rw-r--r--gprofng/src/LoadObject.h1
-rw-r--r--gprofng/src/Makefile.am1
-rw-r--r--gprofng/src/Makefile.in4
-rw-r--r--gprofng/src/Stabs.cc232
-rw-r--r--gprofng/src/Stabs.h7
-rw-r--r--gprofng/src/Symbol.cc218
-rw-r--r--gprofng/src/Symbol.h84
-rw-r--r--gprofng/src/collect.h1
-rw-r--r--gprofng/src/envsets.cc10
-rw-r--r--gprofng/src/gp-collect-app.cc2
-rw-r--r--gprofng/src/ipcio.cc5
24 files changed, 950 insertions, 769 deletions
diff --git a/gprofng/src/DbeSession.cc b/gprofng/src/DbeSession.cc
index f3426ce..b0aa745 100644
--- a/gprofng/src/DbeSession.cc
+++ b/gprofng/src/DbeSession.cc
@@ -2017,6 +2017,17 @@ DbeSession::is_omp_available ()
}
bool
+DbeSession::is_bigendian ()
+{
+#ifdef WORDS_BIGENDIAN
+ return true;
+#else
+ return false;
+#endif
+
+}
+
+bool
DbeSession::has_java ()
{
int status_has_java = 0;
diff --git a/gprofng/src/DbeSession.h b/gprofng/src/DbeSession.h
index 5cbddae..7db0998 100644
--- a/gprofng/src/DbeSession.h
+++ b/gprofng/src/DbeSession.h
@@ -120,6 +120,7 @@ public:
bool is_timeline_available ();
bool is_ifreq_available ();
bool is_omp_available ();
+ static bool is_bigendian ();
bool has_java ();
bool has_ompavail ();
diff --git a/gprofng/src/Disasm.cc b/gprofng/src/Disasm.cc
index 42fb777..348718b 100644
--- a/gprofng/src/Disasm.cc
+++ b/gprofng/src/Disasm.cc
@@ -50,19 +50,6 @@ struct DisContext
static const int MAX_DISASM_STR = 2048;
-Disasm::Disasm (char *fname)
-{
- dwin = NULL;
- dis_str = NULL;
- need_swap_endian = false;
- my_stabs = Stabs::NewStabs (fname, fname);
- if (my_stabs == NULL)
- return;
- stabs = my_stabs;
- platform = stabs->get_platform ();
- disasm_open ();
-}
-
Disasm::Disasm (Platform_t _platform, Stabs *_stabs)
{
dwin = NULL;
@@ -70,7 +57,6 @@ Disasm::Disasm (Platform_t _platform, Stabs *_stabs)
need_swap_endian = false;
stabs = _stabs;
platform = _platform;
- my_stabs = NULL;
disasm_open ();
}
@@ -263,7 +249,6 @@ Disasm::disasm_open ()
Disasm::~Disasm ()
{
- delete my_stabs;
delete dwin;
delete dis_str;
}
diff --git a/gprofng/src/Disasm.h b/gprofng/src/Disasm.h
index 0326b5c..3d7159d 100644
--- a/gprofng/src/Disasm.h
+++ b/gprofng/src/Disasm.h
@@ -31,7 +31,6 @@ enum Platform_t;
class Disasm
{
public:
- Disasm (char *fname);
Disasm (Platform_t _platform, Stabs *_stabs);
~Disasm ();
void remove_disasm_hndl (void *hndl);
@@ -59,7 +58,7 @@ private:
disassemble_info dis_info;
Data_window *dwin;
- Stabs *stabs, *my_stabs;
+ Stabs *stabs;
Platform_t platform;
char addr_fmt[32];
int hex_visible;
diff --git a/gprofng/src/Dwarf.cc b/gprofng/src/Dwarf.cc
index a613c63..a54cdb1 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
@@ -378,18 +378,12 @@ Dwarf::Dwarf (Stabs *_stabs)
return;
}
debug_infoSec = dwrGetSec (NTXT (".debug_info"));
- if (debug_infoSec)
- {
- debug_infoSec->reloc = ElfReloc::get_elf_reloc (elf, NTXT (".rela.debug_info"), NULL);
- debug_infoSec->reloc = ElfReloc::get_elf_reloc (elf, NTXT (".rel.debug_info"), debug_infoSec->reloc);
- if (debug_infoSec->reloc)
- debug_infoSec->reloc->dump ();
- }
debug_abbrevSec = dwrGetSec (NTXT (".debug_abbrev"));
debug_strSec = dwrGetSec (NTXT (".debug_str"));
debug_lineSec = dwrGetSec (NTXT (".debug_line"));
debug_rangesSec = dwrGetSec (NTXT (".debug_ranges"));
debug_line_strSec = dwrGetSec (".debug_line_str");
+ debug_rnglists = NULL;
if ((debug_infoSec == NULL) || (debug_abbrevSec == NULL) || (debug_lineSec == NULL))
{
@@ -441,7 +435,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
@@ -454,7 +453,7 @@ DwrCU::parseChild (Dwarf_cnt *ctx)
Dwarf_Die next_die;
if (read_ref_attr (DW_AT_sibling, &next_die) == DW_DLV_OK)
{
- next_die_offset = next_die + cu_offset;
+ next_die_offset = next_die;
if (next_die_offset <= debug_infoSec->offset)
{
Dprintf (DEBUG_ERR_MSG, NTXT ("DwrCU::parseChild: next_die(0x%llx) <= debug_infoSec->offset(%llx)\n"),
@@ -490,8 +489,25 @@ DwrCU::parseChild (Dwarf_cnt *ctx)
}
break;
case DW_TAG_subprogram:
- if (dwrTag.get_attr (DW_AT_abstract_origin))
- break;
+ {
+ Symbol *sym = NULL;
+ Vector<Symbol *> *syms = NULL;
+ Dwr_Attr *dwrAttr = dwrTag.get_attr (DW_AT_abstract_origin);
+ if (dwrAttr)
+ {
+ // Set up functions from DW_AT_{ranges,low_pc,linkage_name}
+ set_up_funcs (dwrAttr->u.offset);
+ break;
+ }
+
+ dwrAttr = dwrTag.get_attr (DW_AT_specification);
+ if (dwrAttr)
+ {
+ // Set up functions from DW_AT_{ranges,low_pc,linkage_name}
+ set_up_funcs (dwrAttr->u.offset);
+ break;
+ }
+
if (dwrTag.get_attr (DW_AT_declaration))
{
// Only declaration
@@ -499,26 +515,39 @@ 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);
+ 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)
+ func = append_Function (sym, ctx->name);
break;
}
- func = append_Function (ctx);
- if (func)
+
+ func = NULL;
+ syms = get_symbols (tmp_syms);
+ for (int i = 0, sz = VecSize (syms); i < sz; i++)
{
+ sym = syms->get (i);
+ func = append_Function (sym, ctx->name);
if (Stabs::is_fortran (ctx->module->lang_code) &&
- streq (func->get_match_name (), NTXT ("MAIN")))
+ streq (func->get_match_name (), "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;
}
+ if (func == NULL)
+ break;
+
+ 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 +660,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 +689,29 @@ Dwarf::srcline_Dwarf (Module *module)
dwrCU->map_dwarf_lines (module);
}
+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));
+ }
+ return ranges;
+}
// parse hwcprof info for given module in loadobject
@@ -723,7 +790,7 @@ DwrCU::read_hwcprof_info (Dwarf_cnt *ctx)
Dwarf_Die next_die;
if (read_ref_attr (DW_AT_sibling, &next_die) == DW_DLV_OK)
{
- next_die_offset = next_die + cu_offset;
+ next_die_offset = next_die;
if (next_die_offset <= debug_infoSec->offset)
next_die_offset = 0;
else if (debug_infoSec->size > next_die_offset)
@@ -797,11 +864,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 +1028,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;
}
@@ -1040,3 +1095,94 @@ DwrCU::Dwarf_lang ()
return Sp_lang_unknown;
}
}
+
+Vector <Dwr_rng_entry *> *
+Dwarf::get_debug_rnglists ()
+{
+ if (debug_rnglists != NULL)
+ return debug_rnglists;
+ debug_rnglists = new Vector <Dwr_rng_entry *> ();
+
+ DwrSec *debug_rnglistsSec = dwrGetSec (".debug_rnglists");
+ if (debug_rnglistsSec == NULL)
+ {
+ Dprintf (1, "No section .debug_rnglists\n");
+ return debug_rnglists;
+ }
+ while (debug_rnglistsSec->offset < debug_rnglistsSec->sizeSec)
+ {
+ uint64_t base_address = 0;
+ uint64_t length = debug_rnglistsSec->ReadLength ();
+ Dwr_rng_entry *rng = new Dwr_rng_entry ();
+ debug_rnglists->append (rng);
+ rng->offset = debug_rnglistsSec->offset;
+ rng->length = length;
+ rng->fmt64 = debug_rnglistsSec->fmt64;
+ rng->version = debug_rnglistsSec->Get_16 ();
+ rng->address_size = debug_rnglistsSec->Get_8 ();
+ rng->segment_selector_size = debug_rnglistsSec->Get_8 ();
+ rng->offset_entry_count = debug_rnglistsSec->Get_32 ();
+ while (debug_rnglistsSec->offset < debug_rnglistsSec->size)
+ {
+ uint64_t off = debug_rnglistsSec->offset;
+ uint64_t low_pc;
+ uint64_t high_pc;
+ int re = debug_rnglistsSec->Get_8 ();
+ switch (re)
+ {
+ case DW_RLE_end_of_list:
+ low_pc = 0;
+ high_pc = 0;
+ break;
+ case DW_RLE_base_address:
+ base_address = debug_rnglistsSec->GetADDR ();
+ low_pc = base_address;
+ high_pc = 0;
+ continue;
+ case DW_RLE_start_length:
+ low_pc = debug_rnglistsSec->GetADDR ();
+ high_pc = low_pc + debug_rnglistsSec->GetULEB128 ();
+ break;
+ case DW_RLE_offset_pair:
+ low_pc = base_address + debug_rnglistsSec->GetULEB128 ();
+ high_pc = base_address + debug_rnglistsSec->GetULEB128 ();
+ break;
+ case DW_RLE_start_end:
+ low_pc = debug_rnglistsSec->GetADDR ();
+ high_pc = debug_rnglistsSec->GetADDR ();
+ break;
+ case DW_RLE_base_addressx:
+ base_address = debug_rnglistsSec->GetULEB128 ();
+ low_pc = base_address;
+ high_pc = 0;
+ continue;
+
+ // TODO x-variants need .debug_addr support used for split-dwarf
+ case DW_RLE_startx_endx:
+ low_pc = debug_rnglistsSec->GetRef ();
+ high_pc = debug_rnglistsSec->GetRef ();
+ Dprintf (1, "DW_RLE_startx_endx is not implemented\n");
+ continue;
+ case DW_RLE_startx_length:
+ low_pc = debug_rnglistsSec->GetRef ();
+ high_pc = low_pc + debug_rnglistsSec->GetULEB128 ();
+ Dprintf (1, "DW_RLE_startx_length is not implemented\n");
+ continue;
+ default:
+ Dprintf (1, "Unknown tag DW_RLE: %d, offset=0x%llx\n", re,
+ (long long) off);
+ debug_rnglistsSec->offset = debug_rnglistsSec->size;
+ continue;
+ }
+ Dprintf (DUMP_DWARFLIB, "0x%08llx %d-%-20s [0x%08llx - 0x%08llx)\n",
+ (long long) off, re, Dwr_rng_entry::rng_entry2str (re),
+ (long long) low_pc, (long long) high_pc);
+ rng->ranges->append (new ExtRange (off, low_pc, high_pc));
+ }
+ debug_rnglistsSec->size = debug_rnglistsSec->sizeSec;
+ debug_rnglistsSec->offset = length;
+ }
+ delete debug_rnglistsSec;
+ debug_rnglists->dump ("Dwarf::get_debug_rnglists");
+ return debug_rnglists;
+}
diff --git a/gprofng/src/Dwarf.h b/gprofng/src/Dwarf.h
index 8e3ee7a..bf8ffb4 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,8 @@ public:
bool archive_Dwarf (LoadObject *lo);
void srcline_Dwarf (Module *module);
void read_hwcprof_info (Module *module);
+ Vector<Range *> *get_ranges (uint64_t offset);
+ Vector <Dwr_rng_entry *> *get_debug_rnglists ();
Stabs::Stab_status status;
Vector<DwrCU *> *dwrCUs;
@@ -82,6 +85,7 @@ public:
Stabs *stabs;
private:
+ Vector <Dwr_rng_entry *> *debug_rnglists;
DwrSec *dwrGetSec (const char *sec_name);
};
diff --git a/gprofng/src/DwarfLib.cc b/gprofng/src/DwarfLib.cc
index d399c33..9e11658 100644
--- a/gprofng/src/DwarfLib.cc
+++ b/gprofng/src/DwarfLib.cc
@@ -27,39 +27,14 @@
#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
static char *
-gelf_st_type2str (int type)
-{
- static char buf[128];
- char *s;
- switch (type)
- {
- CASE_S (STT_NOTYPE);
- CASE_S (STT_OBJECT);
- CASE_S (STT_FUNC);
- CASE_S (STT_SECTION);
- CASE_S (STT_FILE);
- CASE_S (STT_COMMON);
- CASE_S (STT_TLS);
- // CASE_S(STT_NUM);
- CASE_S (STT_LOPROC);
- CASE_S (STT_HIPROC);
- default: s = NTXT ("???");
- break;
- }
- snprintf (buf, sizeof (buf), NTXT ("%s(%d)"), s, type);
- buf[sizeof (buf) - 1] = 0;
- return buf;
-}
-
-static char *
special_opcode2str (int opcode)
{
static char buf[128];
@@ -167,233 +142,6 @@ get_string (DwrSec *sec, uint64_t off)
}
-//////////////////////////////////////////////////////////
-// class ElfReloc
-
-ElfReloc::ElfReloc (Elf *_elf)
-{
- elf = _elf;
- reloc = NULL;
- cur_reloc_ind = 0;
-}
-
-ElfReloc::~ElfReloc ()
-{
- if (reloc)
- {
- reloc->destroy ();
- delete reloc;
- }
-}
-
-void
-ElfReloc::dump_rela_debug_sec (int sec)
-{
- if (!DUMP_RELA_SEC)
- return;
- Elf_Internal_Shdr *shdr = elf->get_shdr (sec);
- if (shdr == NULL)
- return;
-
- Elf_Data *data = elf->elf_getdata (sec);
- if (data == NULL)
- return;
-
- uint64_t ScnSize = data->d_size;
- uint64_t EntSize = shdr->sh_entsize;
- if (ScnSize == 0 || EntSize == 0)
- return;
-
- Elf_Internal_Rela rela;
- int n, cnt = (int) (ScnSize / EntSize);
-
- char *sec_name = elf->get_sec_name (sec);
- if (sec_name == NULL) // It can not be, but let's check
- return;
- Dprintf (DUMP_RELA_SEC,
- "======= DwarfLib::dump_rela_debug_sec Section:%2d '%s'\n",
- sec, sec_name);
- Dprintf (DUMP_RELA_SEC,
- " N |addend| offset | r_info | stt_type |\n");
- for (n = 0; n < cnt; n++)
- {
- if (strncmp (sec_name, NTXT (".rela."), 6) == 0)
- elf->elf_getrela (data, n, &rela);
- else
- {
- elf->elf_getrel (data, n, &rela);
- rela.r_addend = 0;
- }
- int ndx = (int) GELF_R_SYM (rela.r_info);
- Elf_Internal_Shdr *secHdr;
- Elf_Internal_Sym sym;
- asymbol *asym;
- asym = elf->elf_getsym (ndx, &sym, false);
- Dprintf (DUMP_RELA_SEC, NTXT ("%3d:%5d |%11lld |0x%016llx | %-15s|"),
- n, (int) rela.r_addend,
- (long long) rela.r_offset, (long long) rela.r_info,
- gelf_st_type2str ((int) GELF_ST_TYPE (sym.st_info)));
- switch (GELF_ST_TYPE (sym.st_info))
- {
- case STT_FUNC:
- case STT_OBJECT:
- case STT_NOTYPE:
- Dprintf (DUMP_RELA_SEC, NTXT (" img_offset=0x%llx"),
- (long long) (bfd_asymbol_value (asym)));
- Dprintf (DUMP_RELA_SEC, NTXT (" %s"), bfd_asymbol_name (asym));
- break;
- case STT_SECTION:
- secHdr = elf->get_shdr (sym.st_shndx);
- if (secHdr)
- {
- Dprintf (DUMP_RELA_SEC, NTXT (" value=0x%016llx (%lld)"),
- (long long) (secHdr->sh_offset + rela.r_addend),
- (long long) (secHdr->sh_offset + rela.r_addend));
- }
- break;
- default:
- break;
- }
- Dprintf (DUMP_RELA_SEC, NTXT ("\n"));
- }
- Dprintf (DUMP_RELA_SEC, NTXT ("\n"));
-}
-
-void
-ElfReloc::dump ()
-{
- if (!DUMP_ELF_RELOC || (reloc == NULL) || (reloc->size () == 0))
- return;
- Dprintf (DUMP_ELF_RELOC, NTXT ("======= ElfReloc::dump\n"));
- Dprintf (DUMP_ELF_RELOC, NTXT (" N | offset | value | STT_TYPE\n"));
- for (int i = 0; i < reloc->size (); i++)
- {
- Sreloc *srlc = reloc->fetch (i);
- Dprintf (DUMP_ELF_RELOC, NTXT ("%3d:%11lld |%11lld | %s\n"),
- i, (long long) srlc->offset, (long long) srlc->value,
- gelf_st_type2str (srlc->stt_type));
- }
- Dprintf (DUMP_ELF_RELOC, NTXT ("\n"));
-}
-
-static int
-DwrRelocOffsetCmp (const void *a, const void *b)
-{
- ElfReloc::Sreloc *item1 = *((ElfReloc::Sreloc **) a);
- ElfReloc::Sreloc *item2 = *((ElfReloc::Sreloc **) b);
- return item1->offset < item2->offset ? -1 :
- item1->offset == item2->offset ? 0 : 1;
-}
-
-ElfReloc *
-ElfReloc::get_elf_reloc (Elf *elfp, char *sec_name, ElfReloc *rlc)
-{
- int et = elfp->elf_getehdr ()->e_type;
- if (et == ET_EXEC || et == ET_DYN)
- return rlc;
- int sec = elfp->elf_get_sec_num (sec_name);
- if (sec == 0)
- return rlc;
- Elf_Internal_Shdr *shdr = elfp->get_shdr (sec);
- if (shdr == NULL || shdr->sh_entsize == 0)
- return rlc;
-
- Elf_Data *data = elfp->elf_getdata (sec);
- if (data == NULL || data->d_size == 0)
- return rlc;
-
- int cnt = (int) (data->d_size / shdr->sh_entsize);
- Vector<Sreloc *> *vp = NULL;
-
- for (int n = 0; n < cnt; n++)
- {
- Elf_Internal_Shdr *secHdr;
- Sreloc *srlc;
- Elf_Internal_Rela rela;
- if (strncmp (sec_name, NTXT (".rela."), 6) == 0)
- elfp->elf_getrela (data, n, &rela);
- else
- {
- elfp->elf_getrel (data, n, &rela);
- rela.r_addend = 0;
- }
- int ndx = (int) GELF_R_SYM (rela.r_info);
- Elf_Internal_Sym sym;
- elfp->elf_getsym (ndx, &sym, false);
-
- srlc = new Sreloc;
- srlc->offset = rela.r_offset;
- srlc->value = 0;
- srlc->stt_type = (int) GELF_ST_TYPE (sym.st_info);
- switch (GELF_ST_TYPE (sym.st_info))
- {
- case STT_FUNC:
- secHdr = elfp->get_shdr (sym.st_shndx);
- if (secHdr)
- srlc->value = secHdr->sh_offset + sym.st_value;
- break;
- case STT_OBJECT:
- case STT_NOTYPE:
- secHdr = elfp->get_shdr (shdr->sh_info);
- if (secHdr)
- {
- srlc->offset = rela.r_info;
- srlc->value = secHdr->sh_offset + rela.r_addend;
- }
- break;
- case STT_SECTION:
- secHdr = elfp->get_shdr (sym.st_shndx);
- if (secHdr)
- srlc->value = rela.r_addend;
- break;
- default:
- srlc->value = 0;
- break;
- }
- if (rlc == NULL)
- {
- rlc = new ElfReloc (elfp);
- vp = rlc->reloc;
- }
- if (vp == NULL)
- {
- vp = new Vector<Sreloc*>;
- rlc->reloc = vp;
- }
- vp->append (srlc);
- }
- if (vp)
- vp->sort (DwrRelocOffsetCmp);
- if (rlc)
- {
- rlc->dump_rela_debug_sec (sec);
- rlc->dump ();
- }
- return rlc;
-}
-
-long long
-ElfReloc::get_reloc_addr (long long offset)
-{
- Sreloc *srlc;
- int i = cur_reloc_ind - 1;
- if (i >= 0 && i < reloc->size ())
- {
- srlc = reloc->fetch (i);
- if (srlc->offset > offset) // need to reset
- cur_reloc_ind = 0;
- }
- for (; cur_reloc_ind < reloc->size (); cur_reloc_ind++)
- {
- srlc = reloc->fetch (cur_reloc_ind);
- if (srlc->offset == offset)
- return srlc->value;
- if (srlc->offset > offset)
- return 0;
- }
- return 0;
-}
-
DwrLocation *
DwrCU::dwr_get_location (DwrSec *secp, DwrLocation *lp)
{
@@ -998,7 +746,6 @@ Dwr_Tag::dump ()
case DW_FORM_strx2:
case DW_FORM_strx3:
case DW_FORM_strx4:
- case DW_FORM_implicit_const:
Dprintf (DUMP_DWARFLIB, " \"%s\"", atrp->u.str ? atrp->u.str : "<NULL>");
break;
case DW_FORM_block:
@@ -1037,6 +784,7 @@ Dwr_Tag::dump ()
case DW_FORM_exprloc:
case DW_FORM_ref_sig8:
case DW_FORM_flag_present:
+ case DW_FORM_implicit_const:
Dprintf (DUMP_DWARFLIB, " 0x%llx (%lld)", (long long) atrp->u.val,
(long long) atrp->u.val);
break;
@@ -1058,34 +806,28 @@ Dwr_Tag::dump ()
DwrSec::DwrSec (unsigned char *_data, uint64_t _size, bool _need_swap_endian, bool _addr32)
{
- isCopy = false;
data = _data;
sizeSec = _size;
size = (data ? _size : 0);
offset = 0;
fmt64 = false;
- reloc = NULL;
need_swap_endian = _need_swap_endian;
addr32 = _addr32;
}
DwrSec::DwrSec (DwrSec *secp, uint64_t _offset)
{
- isCopy = true;
data = secp->data;
sizeSec = secp->sizeSec;
size = secp->size;
offset = _offset;
fmt64 = secp->fmt64;
- reloc = secp->reloc;
need_swap_endian = secp->need_swap_endian;
addr32 = secp->addr32;
}
DwrSec::~DwrSec ()
{
- if (!isCopy)
- delete reloc;
}
bool
@@ -1095,6 +837,7 @@ DwrSec::bounds_violation (uint64_t sz)
{
Dprintf (DEBUG_ERR_MSG, "DwrSec::bounds_violation: offset=%lld + sz=%lld > size=%lld\n",
(long long) offset, (long long) sz, (long long) size);
+ offset = size;
return true;
}
return false;
@@ -1212,17 +955,13 @@ DwrSec::GetLong ()
uint64_t
DwrSec::GetADDR_32 ()
{
- uint64_t res = reloc ? reloc->get_reloc_addr (offset) : 0;
- res += Get_32 ();
- return res;
+ return Get_32 ();
}
uint64_t
DwrSec::GetADDR_64 ()
{
- uint64_t res = reloc ? reloc->get_reloc_addr (offset) : 0;
- res += Get_64 ();
- return res;
+ return Get_64 ();
}
uint64_t
@@ -1795,6 +1534,12 @@ DwrLineRegs::getPath (int fn)
DwrCU::DwrCU (Dwarf *_dwarf)
{
dwarf = _dwarf;
+ tmp_syms = new Vector<Symbol*>();
+ rng_list = NULL;
+ rng_list_inited = false;
+ base_address = 0;
+ 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 ();
@@ -1847,7 +1592,7 @@ DwrCU::DwrCU (Dwarf *_dwarf)
(long long) cu_offset, (long long) cu_offset,
(long long) next_cu_offset, (long long) next_cu_offset,
(long long) debug_abbrev_offset, (long long) debug_abbrev_offset,
- (long long) (next_cu_offset - cu_offset),
+ (long long) (next_cu_offset),
(int) version, (int) address_size,
debug_infoSec->fmt64 ? "true" : "false",
debug_infoSec->need_swap_endian ? "true" : "false",
@@ -1883,6 +1628,9 @@ DwrCU::~DwrCU ()
Destroy (dwrInlinedSubrs);
delete srcFiles;
delete dwrLineReg;
+ delete symbols;
+ delete symbols_sorted_by_name;
+ delete tmp_syms;
free (comp_dir);
}
@@ -1925,7 +1673,7 @@ DwrCU::build_abbrevTable (DwrSec *_debug_abbrevSec, uint64_t _offset)
switch (atf.at_form)
{
case DW_FORM_implicit_const:
- atf.len = debug_abbrevSec->GetSLEB128 ();
+ atf.u.val = debug_abbrevSec->GetSLEB128 ();
break;
}
abbrevAtForm->append (atf);
@@ -1945,7 +1693,7 @@ DwrCU::set_die (Dwarf_Die die)
|| debug_infoSec->offset >= debug_infoSec->size)
return DW_DLV_ERROR;
dwrTag.offset = debug_infoSec->offset;
- dwrTag.die = debug_infoSec->offset - cu_offset;
+ dwrTag.die = debug_infoSec->offset;
dwrTag.num = debug_infoSec->GetULEB128_32 ();
if (dwrTag.num == 0)
return DW_DLV_NO_ENTRY;
@@ -1994,19 +1742,19 @@ DwrCU::set_die (Dwarf_Die die)
atf->u.str = debug_infoSec->GetData (atf->len);
break;
case DW_FORM_ref1:
- atf->u.offset = debug_infoSec->Get_8 ();
+ atf->u.offset = debug_infoSec->Get_8 () + cu_offset;
break;
case DW_FORM_ref2:
- atf->u.offset = debug_infoSec->Get_16 ();
+ atf->u.offset = debug_infoSec->Get_16 () + cu_offset;
break;
case DW_FORM_ref4:
- atf->u.offset = debug_infoSec->Get_32 ();
+ atf->u.offset = debug_infoSec->Get_32 () + cu_offset;
break;
case DW_FORM_ref8:
- atf->u.offset = debug_infoSec->Get_64 ();
+ atf->u.offset = debug_infoSec->Get_64 () + cu_offset;
break;
case DW_FORM_ref_udata:
- atf->u.offset = debug_infoSec->GetULEB128 ();
+ atf->u.offset = debug_infoSec->GetULEB128 () + cu_offset;
break;
case DW_FORM_data1:
atf->u.offset = debug_infoSec->Get_8 ();
@@ -2109,7 +1857,7 @@ DwrCU::set_die (Dwarf_Die die)
atf->len = 0;
break;
case DW_FORM_implicit_const:
- atf->u.str = NULL;
+ // atf->u.val is already set
break;
default:
DEBUG_CODE
@@ -2187,9 +1935,241 @@ 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
+ base_address = get_low_pc ();
+ Vector <Range *> *ranges = get_ranges ();
+ if (ranges)
+ {
+ Vector <Symbol *> *syms = dwarf->stabs->get_symbols ();
+ symbols = Symbol::find_symbols (syms, ranges, new Vector <Symbol *> ());
+ symbols_sorted_by_name = Symbol::sort_by_name (symbols);
+ if (DUMP_ELF_SYM)
+ symbols->dump ("DwrCU::parse_cu_header: symbols");
+ Destroy (ranges);
+ }
return module;
}
+
+static int
+cmp_ExtRange (const void *a, const void *b)
+{
+ uint64_t a1 = *((uint64_t *) a);
+ ExtRange *rng = *((ExtRange **) b);
+ uint64_t b1 = rng->offset;
+ return a1 < b1 ? -1 : (a1 == b1 ? 0 : 1);
+}
+
+static int
+cmp_offset (const void *a, const void *b)
+{
+ uint64_t off = *((uint64_t *) a);
+ Dwr_rng_entry *rng = *((Dwr_rng_entry **) b);
+ return off < rng->offset ? -1 : (off < rng->length ? 0 : 1);
+}
+
+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 *> *
+DwrCU::get_ranges ()
+{
+ Vector <Range *> *ranges = NULL;
+ Dwr_Attr *dwrAttr = dwrTag.get_attr (DW_AT_ranges);
+ if (dwrAttr)
+ {
+ uint64_t offset = dwrAttr->u.offset;
+ Dprintf (DUMP_DWARFLIB, "DwrCU::get_ranges: 0x%llx\n", (long long) offset);
+ if (version < 5)
+ ranges = dwarf->get_ranges (offset);
+ else
+ {
+ if (rng_list == NULL && !rng_list_inited)
+ {
+ rng_list_inited = true;
+ // Find the corresponding section in .debug_rnglists
+ Vector <Dwr_rng_entry *> *rng_entrys = dwarf->get_debug_rnglists ();
+ if (rng_entrys == NULL)
+ return NULL;
+ int ind = rng_entrys->bisearch (0, -1, &offset, cmp_offset);
+ if (ind != -1)
+ rng_list = rng_entrys->get (ind);
+ else
+ {
+ Dprintf (1, "Cannot find rnglist. DW_AT_ranges=0x%llx\n",
+ (long long) offset);
+ return NULL;
+ }
+ }
+ if (rng_list == NULL)
+ return NULL;
+ int ind = rng_list->ranges->bisearch (0, -1, &offset, cmp_ExtRange);
+ if (ind == -1)
+ {
+ Dprintf (1, "Cannot find rnglist. DW_AT_ranges=0x%llx\n",
+ (long long) offset);
+ return NULL;
+ }
+ ranges = new Vector <Range *> ();
+ for (long i = ind, sz = VecSize (rng_list->ranges); i < sz; i++)
+ {
+ ExtRange *r = rng_list->ranges->get (i);
+ if (r->high == 0)
+ break;
+ ranges->append (new Range (r->low + base_address,
+ r->high + base_address));
+ }
+ }
+ }
+ 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)
+ {
+ ranges->sort (rangeCmp);
+ if (DUMP_DWARFLIB)
+ ranges->dump ("DwrCU::get_ranges:");
+ }
+ return ranges;
+}
+
+Vector<Symbol *> *
+DwrCU::get_symbols (Vector<Symbol *> *syms)
+{
+ if (syms)
+ syms->reset ();
+ Vector <Range *> *ranges = get_ranges ();
+ if (ranges)
+ {
+ syms = Symbol::find_symbols (symbols, ranges, syms);
+ Destroy (ranges);
+ }
+ if (syms)
+ {
+ Symbol *sym = Symbol::get_symbol (symbols_sorted_by_name,
+ get_linkage_name ());
+ if (sym)
+ syms->append (sym);
+ }
+ if (syms && DUMP_ELF_SYM)
+ syms->dump ("DwrCU::get_symbols:");
+ return syms;
+}
+
+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);
+ func->setDefSrc (get_source (fileno));
+}
+
+SourceFile *
+DwrCU::get_source (int fileno)
+{
+ if (fileno > 0 && fileno < VecSize (srcFiles))
+ return srcFiles->get (fileno);
+ return NULL;
+}
+
+void
+DwrCU::inherit_prop (int64_t offset, source_t *src)
+{
+ if (src->lineno == 0)
+ src->lineno = (int) Dwarf_data (DW_AT_decl_line);
+ if (src->sf == NULL)
+ src->sf = get_source ((int) Dwarf_data (DW_AT_decl_file));
+
+ int64_t old_offset = dwrTag.offset;
+ if (set_die (offset) == DW_DLV_OK)
+ {
+ if (src->lineno == 0)
+ src->lineno = (int) Dwarf_data (DW_AT_decl_line);
+ if (src->sf == NULL)
+ src->sf = get_source ((int) Dwarf_data (DW_AT_decl_file));
+
+ Dwr_Attr *dwrAttr = dwrTag.get_attr (DW_AT_specification);
+ if (dwrAttr)
+ inherit_prop (dwrAttr->u.offset, src);
+ else
+ {
+ Symbol *sym = Symbol::get_symbol (symbols_sorted_by_name,
+ get_linkage_name ());
+ if (sym)
+ update_source (sym, src);
+ }
+ }
+ set_die (old_offset);
+}
+
+void
+DwrCU::set_up_funcs (int64_t offset)
+{
+ // get symbols from DW_AT_ranges, DW_AT_low_pc, DW_AT_linkage_name
+ Vector<Symbol *> *syms = get_symbols (tmp_syms);
+ if (VecSize (syms) == 0)
+ return;
+
+ // Find previous declaration to inherit settings.
+ source_t src = {.lineno = 0, .sf = NULL};
+ inherit_prop (offset, &src);
+
+ for (int i = 0, sz = VecSize (syms); i < sz; i++)
+ {
+ Symbol *sym = syms->get (i);
+ update_source (sym, &src);
+ if (sym->alias)
+ update_source (sym->alias, &src);
+ }
+}
+
+/* Create a function if necessary.
+ * Update the source information */
+void
+DwrCU::update_source (Symbol *sym, source_t *src)
+{
+ Function *f = sym->createFunction (module);
+ f->setLineFirst (src->lineno);
+ f->setDefSrc (src->sf);
+}
+
+Symbol *
+DwrCU::find_declaration (int64_t offset, source_t *src)
+{
+ int64_t old_offset = dwrTag.offset;
+ Symbol *sym = NULL;
+ if (set_die (offset) == DW_DLV_OK)
+ {
+ if (src->lineno == 0)
+ src->lineno = (int) Dwarf_data (DW_AT_decl_line);
+ if (src->sf == NULL)
+ src->sf = get_source ((int) Dwarf_data (DW_AT_decl_file));
+
+ sym = Symbol::get_symbol (symbols_sorted_by_name, get_linkage_name ());
+ if (sym && sym->func == NULL)
+ update_source (sym, src);
+ }
+ set_die (old_offset);
+ return sym;
+}
+
Dwr_Attr *
Dwr_Tag::get_attr (Dwarf_Half attr)
{
@@ -2269,6 +2249,7 @@ DwrCU::read_data_attr (Dwarf_Half attr, int64_t *retVal)
case DW_FORM_data16:
case DW_FORM_udata:
case DW_FORM_sec_offset:
+ case DW_FORM_implicit_const:
*retVal = dwrAttr->u.val;
return DW_DLV_OK;
@@ -2357,7 +2338,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;
@@ -2502,3 +2483,69 @@ DwrInlinedSubr::dump ()
(int) level, (long long) abstract_origin, (long long) low_pc,
(long long) high_pc, (int) file, (int) line);
}
+
+
+//////////////////////////////////////////////////////////
+// class Dwr_rng_entry
+Dwr_rng_entry::Dwr_rng_entry ()
+{
+ ranges = new Vector <ExtRange *>();
+}
+
+Dwr_rng_entry::~Dwr_rng_entry ()
+{
+ delete ranges;
+}
+
+void
+Dwr_rng_entry::dump ()
+{
+ Dprintf (DUMP_DWARFLIB, "offset=0x%08llx length=0x%08llx fmt=%d version=%d "
+ "addr_size=%d seg_size=%d offset_entry_count=0x%llx\n",
+ (long long) offset, (long long) (length - offset), fmt64 ? 64 : 32,
+ (int) version, (int) address_size, (int) segment_selector_size,
+ (long long) offset_entry_count);
+ for (long i = 0, sz = VecSize (ranges); i < sz; i++)
+ {
+ ExtRange *p = ranges->get (i);
+ Dprintf (DUMP_DWARFLIB, " %8ld: 0x%08llx 0x%08llx-0x%08llx [%lld-%lld)\n",
+ i, (long long) p->offset, (long long) p->low, (long long) p->high,
+ (long long) p->low, (long long) p->high);
+ }
+}
+
+char *
+Dwr_rng_entry::rng_entry2str (int val)
+{
+ char *s;
+ switch (val)
+ {
+ CASE_S (DW_RLE_end_of_list);
+ CASE_S (DW_RLE_base_address);
+ CASE_S (DW_RLE_start_length);
+ CASE_S (DW_RLE_offset_pair);
+ CASE_S (DW_RLE_start_end);
+ CASE_S (DW_RLE_base_addressx);
+ CASE_S (DW_RLE_startx_endx);
+ CASE_S (DW_RLE_startx_length);
+ default: s = (char *) "???";
+ break;
+ }
+ return s;
+}
+
+template<> void Vector<Dwr_rng_entry *>::dump (const char *msg)
+{
+ if (!DUMP_DWARFLIB)
+ return;
+ if (msg == NULL)
+ msg = "#";
+ Dprintf (1, NTXT ("\n%s Vector<Dwr_rng_entry *> [%lld]\n"), msg, (long long) size ());
+ for (long i = 0, sz = size (); i < sz; i++)
+ {
+ Dwr_rng_entry *p = get (i);
+ Dprintf (1, " %3ld ", i);
+ p->dump ();
+ }
+}
+
diff --git a/gprofng/src/DwarfLib.h b/gprofng/src/DwarfLib.h
index 178801d..49ecb41 100644
--- a/gprofng/src/DwarfLib.h
+++ b/gprofng/src/DwarfLib.h
@@ -23,9 +23,11 @@
#include "dwarf2.h"
-class ElfReloc;
class Dwr_type;
+class Function;
+class Range;
class SourceFile;
+class Symbol;
template <class ITEM> class Vector;
template <class ITEM> class DbeArray;
@@ -73,13 +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;
uint64_t offset;
@@ -90,7 +85,6 @@ public:
int segment_selector_size; // DWARF 5
private:
- bool isCopy;
unsigned char *data;
bool bounds_violation (uint64_t sz);
};
@@ -260,6 +254,45 @@ public:
Dwr_type *put_dwr_type (Dwr_Tag *dwrTag);
};
+class ExtRange
+{
+public:
+ ExtRange (uint64_t _off, uint64_t _low, uint64_t _high)
+ {
+ offset = _off;
+ low = _low;
+ high = _high;
+ };
+
+ uint64_t offset;
+ uint64_t low;
+ uint64_t high;
+};
+
+class Dwr_rng_entry
+{
+public:
+ Dwr_rng_entry ();
+ ~Dwr_rng_entry ();
+ void dump();
+ static char *rng_entry2str(int val);
+
+ Dwarf_Half version;
+ Dwarf_Small address_size;
+ Dwarf_Small segment_selector_size;
+ int offset_entry_count;
+ uint64_t length;
+ uint64_t offset;
+ bool fmt64;
+ Vector <ExtRange *> *ranges;
+};
+
+typedef struct Source
+{
+ int lineno;
+ SourceFile *sf;
+} source_t;
+
class DwrCU
{
public:
@@ -280,6 +313,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 +322,15 @@ 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);
+ void set_up_funcs (int64_t offset);
+ void inherit_prop (int64_t offset, source_t *src);
+ void update_source (Symbol *sym, source_t *prop);
+ Symbol *find_declaration (int64_t offset, source_t *prop);
+ SourceFile *get_source (int fileno);
+ Vector<Symbol *> *get_symbols (Vector<Symbol *> *syms = NULL);
+ 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);
@@ -316,6 +359,10 @@ private:
DwrLineRegs *dwrLineReg;
DbeArray<DwrAbbrevTable> *abbrevTable;
DbeArray<Dwr_Attr> *abbrevAtForm;
+ Vector<Symbol*> *tmp_syms; // reused vector for get_symbols()
+ Dwr_rng_entry *rng_list; // entry in the .debug_rnglists section
+ bool rng_list_inited;
+ uint64_t base_address; // low_pc in compile_unit
};
#endif /* _DWARFLIB_H_ */
diff --git a/gprofng/src/Elf.cc b/gprofng/src/Elf.cc
index f0fd121..b90ad29 100644
--- a/gprofng/src/Elf.cc
+++ b/gprofng/src/Elf.cc
@@ -28,6 +28,7 @@
#include "Map.h"
#include "StringBuilder.h"
#include "DbeFile.h"
+#include "DbeSession.h"
typedef uint32_t Elf32_Word;
typedef uint32_t Elf64_Word;
@@ -83,56 +84,6 @@ struct S_Elf64_Dyn
} d_un;
};
-
-// Symbol table
-typedef struct
-{
- Elf32_Word st_name;
- Elf32_Addr st_value;
- Elf32_Word st_size;
- unsigned char st_info; /* bind, type: ELF_32_ST_... */
- unsigned char st_other;
- Elf32_Half st_shndx; /* SHN_... */
-} Elf32_Sym;
-
-typedef struct
-{
- Elf64_Word st_name;
- unsigned char st_info; /* bind, type: ELF_64_ST_... */
- unsigned char st_other;
- Elf64_Half st_shndx; /* SHN_... */
- Elf64_Addr st_value;
- Elf64_Xword st_size;
-} Elf64_Sym;
-
-
-// Relocation
-typedef struct
-{
- Elf32_Addr r_offset;
- Elf32_Word r_info; /* sym, type: ELF32_R_... */
-} Elf32_Rel;
-
-typedef struct
-{
- Elf32_Addr r_offset;
- Elf32_Word r_info; /* sym, type: ELF32_R_... */
- Elf32_Sword r_addend;
-} Elf32_Rela;
-
-typedef struct
-{
- Elf64_Addr r_offset;
- Elf64_Xword r_info; /* sym, type: ELF64_R_... */
-} Elf64_Rel;
-
-typedef struct
-{
- Elf64_Addr r_offset;
- Elf64_Xword r_info; /* sym, type: ELF64_R_... */
- Elf64_Sxword r_addend;
-} Elf64_Rela;
-
int Elf::bfd_status = -1;
void
@@ -196,23 +147,13 @@ Elf::Elf (char *filename) : DbeMessages (), Data_window (filename)
}
status = ELF_ERR_NONE;
-#if ARCH(SPARC)
- need_swap_endian = is_Intel ();
-#else
- need_swap_endian = !is_Intel ();
-#endif
-
+ need_swap_endian = DbeSession::is_bigendian () != bfd_big_endian (abfd);
analyzerInfo = 0;
- SUNW_ldynsym = 0;
- gnuLink = 0;
stab = 0;
- stabStr = 0;
stabIndex = 0;
stabIndexStr = 0;
stabExcl = 0;
stabExclStr = 0;
- symtab = 0;
- dynsym = 0;
info = 0;
plt = 0;
dwarf = false;
@@ -234,20 +175,12 @@ Elf::Elf (char *filename) : DbeMessages (), Data_window (filename)
stabExcl = sec;
else if (streq (name, NTXT (".stab.exclstr")))
stabExclStr = sec;
- else if (streq (name, NTXT (".gnu_debuglink")))
- gnuLink = sec;
else if (streq (name, NTXT (".__analyzer_info")))
analyzerInfo = sec;
else if (streq (name, NTXT (".info")))
info = true;
else if (streq (name, NTXT (".plt")))
plt = sec;
- else if (streq (name, NTXT (".SUNW_ldynsym")))
- SUNW_ldynsym = sec;
- else if (streq (name, NTXT (".dynsym")))
- dynsym = sec;
- else if (streq (name, NTXT (".symtab")))
- symtab = sec;
else if (strncmp (name, NTXT (".debug"), 6) == 0)
dwarf = true;
}
@@ -572,50 +505,6 @@ Elf::elf_getsym (unsigned int ndx, Elf_Internal_Sym *dst, bool is_dynamic)
return asym;
}
-Elf_Internal_Rela *
-Elf::elf_getrel (Elf_Data *edta, unsigned int ndx, Elf_Internal_Rela *dst)
-{
- if (dst == NULL || edta == NULL || edta->d_buf == NULL)
- return NULL;
- if (elf_getclass () == ELFCLASS32)
- {
- Elf32_Rel *rel = ((Elf32_Rel *) edta->d_buf) + ndx;
- dst->r_offset = decode (rel->r_offset);
- dst->r_info = ELF64_R_INFO (ELF32_R_SYM (decode (rel->r_info)),
- ELF32_R_TYPE (decode (rel->r_info)));
- }
- else
- {
- Elf64_Rel *rel = ((Elf64_Rel *) edta->d_buf) + ndx;
- dst->r_offset = decode (rel->r_offset);
- dst->r_info = decode (rel->r_info);
- }
- return dst;
-}
-
-Elf_Internal_Rela *
-Elf::elf_getrela (Elf_Data *edta, unsigned int ndx, Elf_Internal_Rela *dst)
-{
- if (dst == NULL || edta == NULL || edta->d_buf == NULL)
- return NULL;
- if (elf_getclass () == ELFCLASS32)
- {
- Elf32_Rela *rela = ((Elf32_Rela *) edta->d_buf) + ndx;
- dst->r_offset = decode (rela->r_offset);
- dst->r_addend = decode (rela->r_addend);
- dst->r_info = ELF64_R_INFO (ELF32_R_SYM (decode (rela->r_info)),
- ELF32_R_TYPE (decode (rela->r_info)));
- }
- else
- {
- Elf64_Rela *rela = ((Elf64_Rela *) edta->d_buf) + ndx;
- dst->r_offset = decode (rela->r_offset);
- dst->r_addend = decode (rela->r_addend);
- dst->r_info = decode (rela->r_info);
- }
- return dst;
-}
-
Elf64_Ancillary *
Elf::elf_getancillary (Elf_Data *edta, unsigned int ndx, Elf64_Ancillary *dst)
{
diff --git a/gprofng/src/Elf.h b/gprofng/src/Elf.h
index b324c39..6667670 100644
--- a/gprofng/src/Elf.h
+++ b/gprofng/src/Elf.h
@@ -35,10 +35,8 @@ class DbeFile;
template <class ITEM> class Vector;
template <typename Key_t, typename Value_t> class Map;
-#define GELF_R_SYM(info) ((info)>>32)
#define GELF_ST_TYPE(info) ((info) & 0xf)
#define GELF_ST_BIND(info) ((info) >> 4)
-#define GELF_R_TYPE(info) ((((uint64_t)(info))<<56)>>56)
#define SHF_SUNW_ABSENT 0x00200000 /* section data not present */
#define SEC_DECOMPRESSED 0x00400000 /* bfd allocated this memory */
@@ -94,8 +92,6 @@ public:
char *elf_strptr (unsigned int sec, uint64_t off);
long elf_getSymCount (bool is_dynamic);
asymbol *elf_getsym (unsigned int ndx, Elf_Internal_Sym *dst, bool is_dynamic);
- Elf_Internal_Rela *elf_getrel (Elf_Data *edta, unsigned int ndx, Elf_Internal_Rela *dst);
- Elf_Internal_Rela *elf_getrela (Elf_Data *edta, unsigned int ndx, Elf_Internal_Rela *dst);
Elf64_Ancillary *elf_getancillary (Elf_Data *edta, unsigned int ndx, Elf64_Ancillary *dst);
Elf *find_ancillary_files (char *lo_name); // read the .gnu_debuglink and .SUNW_ancillary seections
const char *get_funcname_in_plt (uint64_t pc);
@@ -132,7 +128,7 @@ public:
Elf *gnu_debug_file;
DbeFile *dbeFile;
Map<const char*, Symbol*> *elfSymbols;
- unsigned int gnuLink, analyzerInfo, SUNW_ldynsym, stab, stabStr, symtab, dynsym;
+ unsigned int analyzerInfo, stab, stabStr;
unsigned int stabIndex, stabIndexStr, stabExcl, stabExclStr, info, plt;
bool dwarf;
@@ -154,28 +150,4 @@ protected:
Vector <asymbol *> *synthsym;
};
-
-class ElfReloc
-{
-public:
- struct Sreloc
- {
- long long offset;
- long long value;
- int stt_type;
- };
-
- static ElfReloc *get_elf_reloc (Elf *elf, char *sec_name, ElfReloc *rlc);
- ElfReloc (Elf *_elf);
- ~ElfReloc ();
- long long get_reloc_addr (long long offset);
- void dump ();
- void dump_rela_debug_sec (int sec);
-
-private:
- Elf *elf;
- Vector<Sreloc *> *reloc;
- int cur_reloc_ind;
-};
-
#endif
diff --git a/gprofng/src/Experiment.cc b/gprofng/src/Experiment.cc
index 45550e8..4cbb7f6 100644
--- a/gprofng/src/Experiment.cc
+++ b/gprofng/src/Experiment.cc
@@ -541,10 +541,14 @@ Experiment::ExperimentHandler::startElement (char*, char*, char *qName, Attribut
exp->platform = RISCV;
else
exp->platform = Sparc;
- exp->need_swap_endian = (DbeSession::platform == Sparc) ?
- (exp->platform != Sparc) : (exp->platform == Sparc);
exp->architecture = xstrdup (str);
}
+ str = attrs->getValue (NTXT ("bigendian"));
+ if (str != NULL)
+ {
+ exp->bigendian = *str == '1';
+ exp->need_swap_endian = DbeSession::is_bigendian () != exp->bigendian;
+ }
str = attrs->getValue (NTXT ("pagesz"));
if (str != NULL)
exp->page_size = atoi (str);
@@ -1314,6 +1318,7 @@ Experiment::Experiment ()
exp_maj_version = 0;
exp_min_version = 0;
platform = Unknown;
+ bigendian = DbeSession::is_bigendian(); // can be changed in log.xml reading
wsize = Wnone;
page_size = 4096;
npages = 0;
diff --git a/gprofng/src/Experiment.h b/gprofng/src/Experiment.h
index 2047a15..c85aadd 100644
--- a/gprofng/src/Experiment.h
+++ b/gprofng/src/Experiment.h
@@ -135,6 +135,7 @@ public:
// for current experiment, i.e. 8 for 32bit addresses
int broken; // If SP_JCMD_RUN line not seen
int obsolete; // If pointer file experiment detected
+ bool bigendian; // the experiment was created on a big_endian machine
bool hwc_default; // True if HW counters were enabled by default
int hwc_bogus; // Count of bogus HWC packets
int hwc_lost_int; // Count of packets reflecting lost interrupt
diff --git a/gprofng/src/LoadObject.cc b/gprofng/src/LoadObject.cc
index 1ca6ab6..bf49e9d 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"
@@ -86,7 +87,6 @@ LoadObject::LoadObject (const char *loname)
size = 0;
type = SEG_UNKNOWN;
isReadStabs = false;
- need_swap_endian = false;
instHTable = new DbeInstr*[LO_InstHTableSize];
for (int i = 0; i < LO_InstHTableSize; i++)
instHTable[i] = NULL;
@@ -298,18 +298,21 @@ LoadObject::dump_functions (FILE *out)
if (fitem->alias && fitem->alias != fitem)
fprintf (out, "id %6llu, @0x%llx - %s == alias of '%s'\n",
(ull_t) fitem->id, (ull_t) fitem->img_offset,
- fitem->get_name (), fitem->alias->get_name ());
+ fitem->get_mangled_name (), fitem->alias->get_mangled_name ());
else
{
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/LoadObject.h b/gprofng/src/LoadObject.h
index 14dfe26..dd40ea0 100644
--- a/gprofng/src/LoadObject.h
+++ b/gprofng/src/LoadObject.h
@@ -167,7 +167,6 @@ public:
unsigned int flags; // SEG_FLAG_*
bool isReadStabs;
- bool need_swap_endian;
int seg_idx; // for compatibility (ADDRESS)
seg_type type;
int64_t size; // size of loadobject in bytes
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..53f7ef1 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,18 +163,6 @@ 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)
{
path = dbe_strdup (_path);
@@ -294,8 +170,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 +215,6 @@ Stabs::~Stabs ()
{
delete SymLstByName;
Destroy (SymLst);
- Destroy (RelLst);
- Destroy (RelPLTLst);
Destroy (LocalFile);
delete elfDis;
delete dwarf;
@@ -458,42 +330,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 +1542,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 +1598,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 +1678,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 +2119,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 +2126,7 @@ Stabs::openDwarf ()
{
dwarf = new Dwarf (this);
check_Symtab ();
+ dump();
}
return dwarf;
}
@@ -2363,8 +2151,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..f0e162b 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;
@@ -77,7 +76,6 @@ class Stabs {
DBGD_ERR_CHK_SUM
};
- static Stabs *NewStabs(char *_path, char *lo_name);
Stabs(char *_path, char *_lo_name);
~Stabs();
@@ -86,12 +84,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();
@@ -101,7 +99,6 @@ class Stabs {
static Function *find_func(char *fname, Vector<Function*> *functions, bool fortran, bool inner_names=false);
Module *append_Module(LoadObject *lo, char *name, int lastMod = 0);
Function *append_Function(Module *module, char *fname);
- Function *append_Function(Module *module, char *linkerName, uint64_t pc);
Function *map_PC_to_func(uint64_t pc, uint64_t &low_pc, Vector<Function*> *functions);
char *path; // path to the object file
char *lo_name; // User name of load object
@@ -135,8 +132,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..8cc578f
--- /dev/null
+++ b/gprofng/src/Symbol.cc
@@ -0,0 +1,218 @@
+/* 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,
+ Vector<Symbol *> *symbols)
+{
+ // 'syms' and 'ranges' must already be sorted.
+ // return symbols matched by 'ranges'
+ if (VecSize (syms) == 0 || VecSize (ranges) == 0)
+ return NULL;
+
+ // 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;
+ }
+ return symbols;
+}
+
+/* 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..e9e0060
--- /dev/null
+++ b/gprofng/src/Symbol.h
@@ -0,0 +1,84 @@
+/* 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. */
+
+#ifndef _Symbol_h_
+#define _Symbol_h_
+
+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, Vector<Symbol *> *symbols = NULL);
+ 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 Symbol,
+ 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;
+};
+#endif
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"