Skip to content

Commit

Permalink
Several fixes related to supplemental dwarf files and the redhat issues
Browse files Browse the repository at this point in the history
- Do not create modules from DW_TAG_compile_unit;
- Append compilation offset to compilation name if name is <artificial>;
- Initialize decode of DW_OP_entry_value, DW_OP_GNU_entry_value DW_OP_GNU_convert, DW_OP_GNU_implicit_pointer;
- Disable dwarf_parse_aranges to prevent duplicates;
- Clear error after call to Symtab::getLastSymtabError();
- Change dwarf_hasattr to dwarf_hasattr_integrate, and dwarf_attr to dwarf_attr_integrate;
- Check return of parseRangeTypes() and setFunctionFromRange() in DwarfWalker::parseSubprogram;
- Ignore abstract origin in DwarfWalker::handleAbstractOrigin() if it's in a supplemental file;
- Retrieve DIE from a GNU extension DW_FORM_GNU_ref_alt reference;
  • Loading branch information
Sasha (fedora33) committed Dec 15, 2020
1 parent 3927921 commit c6e088d
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 76 deletions.
16 changes: 16 additions & 0 deletions dwarf/src/dwarfExprParser.C
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,23 @@ bool decodeDwarfExpression(Dwarf_Op * expr,
// the value is at the top of the stack
continue;

case DW_OP_entry_value:
case DW_OP_GNU_entry_value:
dwarf_printf("\t\t skipping GNU_entry_value\n", locations[i].number);
return false;

case DW_OP_convert:
case DW_OP_GNU_convert:
dwarf_printf("\t\t skipping GNU_convert\n", locations[i].number);
return false;

case DW_OP_implicit_pointer:
case DW_OP_GNU_implicit_pointer:
dwarf_printf("\t\t skipping GNU_implicit_pointer\n", locations[i].number);
return false;

default:
dwarf_printf("\t\t error: unrecognized dwarf operation 0x%llx\n", locations[i].atom);
return false;
} /* end operand switch */
} /* end iteration over Dwarf_Op entries. */
Expand Down
69 changes: 50 additions & 19 deletions symtabAPI/src/Object-elf.C
Original file line number Diff line number Diff line change
Expand Up @@ -2404,7 +2404,7 @@ bool Object::dwarf_parse_aranges(Dwarf *dbg, std::set<Dwarf_Off> &dies_seen) {
size_t num_ranges;
int status = dwarf_getaranges(dbg, &ranges, &num_ranges);
if (status != 0) return false;
// cout << "Processing " << num_ranges << "DWARF ranges" << endl;
dwarf_printf("dwarf_parse_aranges: Processing %zu DWARF ranges\n", num_ranges);
for (size_t i = 0; i < num_ranges; i++) {
Dwarf_Arange *range = dwarf_onearange(ranges, i);
if (!range) continue;
Expand All @@ -2420,7 +2420,7 @@ bool Object::dwarf_parse_aranges(Dwarf *dbg, std::set<Dwarf_Off> &dies_seen) {
cu_die_off_p = dwarf_addrdie(dbg, start, &cu_die);
assert(cu_die_off_p != NULL);
auto off_die = dwarf_dieoffset(&cu_die);
if (dies_seen.find(off_die) != dies_seen.end()) continue;
//if (dies_seen.find(off_die) != dies_seen.end()) continue;

std::string modname;
if (!DwarfWalker::findDieName(dbg, cu_die, modname)) {
Expand All @@ -2433,40 +2433,48 @@ bool Object::dwarf_parse_aranges(Dwarf *dbg, std::set<Dwarf_Off> &dies_seen) {
Module *m = associated_symtab->getOrCreateModule(modname, actual_start);
m->addRange(actual_start, actual_end);
m->addDebugInfo(cu_die);
cerr << "File in module " << modname << ", DIE CU " << hex << off_die << dec << endl;
DwarfWalker::buildSrcFiles(dbg, cu_die, m->getStrings());
dies_seen.insert(off_die);
//dies_seen.insert(off_die);
}
dwarf_printf("end of dwarf_parse_aranges\n");
return true;
}

bool Object::fix_global_symbol_modules_static_dwarf() {
/* Initialize libdwarf. */

Dwarf **dbg_ptr = dwarf->type_dbg();
if (!dbg_ptr) return false;

if (!dbg_ptr)
return false;
dwarf_printf("At fix_global_symbol_modules_static_dwarf\n");
Dwarf *dbg = *dbg_ptr;
std::set<Dwarf_Off> dies_seen;
if (!dwarf_parse_aranges(dbg, dies_seen)) {
/*if (!dwarf_parse_aranges(dbg, dies_seen)) {
return false;
}
}*/

std::vector<Dwarf_Die> dies;
size_t cu_header_size;
for (Dwarf_Off cu_off = 0, next_cu_off;
dwarf_nextcu(dbg, cu_off, &next_cu_off, &cu_header_size,
NULL, NULL, NULL) == 0;
cu_off = next_cu_off) {
cu_off = next_cu_off)
{
Dwarf_Off cu_die_off = cu_off + cu_header_size;
Dwarf_Die cu_die, *cu_die_p;
cu_die_p = dwarf_offdie(dbg, cu_die_off, &cu_die);

Dwarf_Half moduleTag = dwarf_tag(&cu_die);
if (moduleTag != DW_TAG_compile_unit) {
continue;
}

if (cu_die_p == NULL) continue;
//if(dies_seen.find(cu_die_off) != dies_seen.end()) continue;

dies.push_back(cu_die);
}
dwarf_printf("Number of CU DIEs seen %zu\n", dies.size());

/* Iterate over the compilation-unit headers. */
for (size_t i = 0; i < dies.size(); i++) {
Expand All @@ -2476,6 +2484,14 @@ bool Object::fix_global_symbol_modules_static_dwarf() {
if (!DwarfWalker::findDieName(dbg, cu_die, modname)) {
modname = associated_symtab->file(); // default module
}
if(modname=="<artificial>")
{
auto off_die = dwarf_dieoffset(&cu_die);
std::stringstream suffix;
suffix << std::hex << off_die;
modname = "<artificial>" + suffix.str();
}

//cerr << "Processing CU DIE for " << modname << " offset: " << next_cu_off << endl;
Address tempModLow;
Address modLow = 0;
Expand All @@ -2487,23 +2503,27 @@ bool Object::fix_global_symbol_modules_static_dwarf() {
Module *m;
#pragma omp critical
m = associated_symtab->getOrCreateModule(modname, modLow);
for (auto r = mod_ranges.begin();
r != mod_ranges.end(); ++r) {
for (auto r = mod_ranges.begin(); r != mod_ranges.end(); ++r)
{
m->addRange(r->first, r->second);
}
if (!m->hasRanges()) {
if (!m->hasRanges())
{
// cout << "No ranges for module " << modname << ", need to extract from statements\n";
Dwarf_Lines *lines;
size_t num_lines;
if (dwarf_getsrclines(&cu_die, &lines, &num_lines) == 0) {
if (dwarf_getsrclines(&cu_die, &lines, &num_lines) == 0)
{
Dwarf_Addr low;
for (size_t i = 0; i < num_lines; ++i) {
Dwarf_Line *line = dwarf_onesrcline(lines, i);
if ((dwarf_lineaddr(line, &low) == 0) && low) {
if ((dwarf_lineaddr(line, &low) == 0) && low)
{
Dwarf_Addr high = low;
int result = 0;
for (; (i < num_lines) &&
(result == 0); ++i) {
(result == 0); ++i)
{
line = dwarf_onesrcline(lines, i);
if (!line) continue;

Expand All @@ -2524,6 +2544,7 @@ bool Object::fix_global_symbol_modules_static_dwarf() {
}
#pragma omp critical
m->addDebugInfo(cu_die);
//cerr << "Files in module " << modname << endl;
DwarfWalker::buildSrcFiles(dbg, cu_die, m->getStrings());
// dies_seen.insert(cu_die_off);
}
Expand Down Expand Up @@ -3760,17 +3781,18 @@ void Object::getModuleLanguageInfo(dyn_hash_map<string, supportedLanguages> *mod
/* Only .debug_info for now, not .debug_types */
size_t cu_header_size;
for (Dwarf_Off cu_off = 0, next_cu_off;
dwarf_nextcu(dbg, cu_off, &next_cu_off, &cu_header_size,
NULL, NULL, NULL) == 0;
cu_off = next_cu_off) {
dwarf_nextcu(dbg, cu_off, &next_cu_off, &cu_header_size,
NULL, NULL, NULL) == 0;
cu_off = next_cu_off)
{
Dwarf_Off cu_die_off = cu_off + cu_header_size;
Dwarf_Die *cu_die_p;
cu_die_p = dwarf_offdie(dbg, cu_die_off, &moduleDIE);
if (cu_die_p == NULL) break;

Dwarf_Half moduleTag = dwarf_tag(&moduleDIE);
if (moduleTag != DW_TAG_compile_unit) {
break;
continue;
}

/* Extract the name of this module. */
Expand All @@ -3785,6 +3807,15 @@ void Object::getModuleLanguageInfo(dyn_hash_map<string, supportedLanguages> *mod
ptr = moduleName;

working_module = string(ptr);

if(working_module=="<artificial>")
{
auto off_die = dwarf_dieoffset(&moduleDIE);
std::stringstream suffix;
suffix << std::hex << off_die;
working_module = "<artificial>" + suffix.str();
}

auto attr_p = dwarf_attr(&moduleDIE, DW_AT_language, &languageAttribute);
if (attr_p == NULL) {
break;
Expand Down
4 changes: 2 additions & 2 deletions symtabAPI/src/Symtab-lookup.C
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,8 @@ bool Symtab::findFuncByEntryOffset(Function *&ret, const Offset entry)
dyn_c_hash_map<Offset,Function*>::const_accessor ca;
if (funcsByOffset.find(ca, entry)) {
ret = ca->second;
return true;
}
return true;
}
}
setSymtabError(No_Such_Symbol);
return false;
Expand Down
1 change: 1 addition & 0 deletions symtabAPI/src/Symtab.C
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ std::vector<Symtab *> Symtab::allSymtabs;
SymtabError Symtab::getLastSymtabError()
{
SymtabError last = serr;
serr = No_Error;
return last;
}

Expand Down

0 comments on commit c6e088d

Please sign in to comment.