aboutsummaryrefslogtreecommitdiff
path: root/gprofng/src/Dwarf.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gprofng/src/Dwarf.cc')
-rw-r--r--gprofng/src/Dwarf.cc180
1 files changed, 123 insertions, 57 deletions
diff --git a/gprofng/src/Dwarf.cc b/gprofng/src/Dwarf.cc
index 23ac5b9..85891099 100644
--- a/gprofng/src/Dwarf.cc
+++ b/gprofng/src/Dwarf.cc
@@ -390,6 +390,7 @@ Dwarf::Dwarf (Stabs *_stabs)
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))
{
@@ -496,9 +497,24 @@ 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
@@ -508,58 +524,26 @@ DwrCU::parseChild (Dwarf_cnt *ctx)
if (link_name && streq (link_name, NTXT ("MAIN")))
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;
+ }
+ sym = Symbol::get_symbol (symbols_sorted_by_name,
+ get_linkage_name ());
+ if (sym != NULL)
func = append_Function (sym, ctx->name);
- break;
+ break;
}
- Dwr_Attr *dwrAttr = dwrTag.get_attr (DW_AT_specification);
- if (dwrAttr)
+ func = NULL;
+ syms = get_symbols (tmp_syms);
+ for (int i = 0, sz = VecSize (syms); i < sz; i++)
{
- // 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 = syms->get (i);
+ func = append_Function (sym, ctx->name);
+ if (Stabs::is_fortran (ctx->module->lang_code) &&
+ streq (func->get_match_name (), "MAIN"))
+ ctx->fortranMAIN = func;
}
-
- 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)
+ if (func == 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;
@@ -712,14 +696,6 @@ 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)
{
@@ -741,7 +717,6 @@ Dwarf::get_ranges (uint64_t offset)
break;
ranges->append (new Range (low_pc, high_pc));
}
- ranges->sort (rangeCmp);
return ranges;
}
@@ -1127,3 +1102,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;
+}