Create a helper wrapper / abstraction for managing srcfiles lists

This commit is contained in:
Jeremy Rifkin 2025-02-17 01:02:28 -06:00
parent 0f990f05a1
commit 62548497a8
No known key found for this signature in database
GPG Key ID: 19AA8270105E8EB4
2 changed files with 56 additions and 21 deletions

View File

@ -531,6 +531,56 @@ namespace libdwarf {
} }
} }
}; };
class srcfiles {
Dwarf_Debug dbg = nullptr;
char** dw_srcfiles = nullptr;
Dwarf_Unsigned dw_filecount = 0;
public:
srcfiles(Dwarf_Debug dbg, char** dw_srcfiles, Dwarf_Signed filecount)
: dbg(dbg), dw_srcfiles(dw_srcfiles), dw_filecount(static_cast<Dwarf_Unsigned>(filecount))
{
if(filecount < 0) {
throw internal_error(microfmt::format("Unexpected dw_filecount {}", filecount));
}
}
~srcfiles() {
if(dw_srcfiles) {
for(unsigned i = 0; i < dw_filecount; i++) {
dwarf_dealloc(dbg, dw_srcfiles[i], DW_DLA_STRING);
dw_srcfiles[i] = nullptr;
}
dwarf_dealloc(dbg, dw_srcfiles, DW_DLA_LIST);
}
}
srcfiles(const srcfiles&) = delete;
srcfiles(srcfiles&& other) {
std::swap(dbg, other.dbg);
std::swap(dw_srcfiles, other.dw_srcfiles);
std::swap(dw_filecount, other.dw_filecount);
}
srcfiles& operator=(const srcfiles&) = delete;
srcfiles& operator=(srcfiles&& other) {
std::swap(dbg, other.dbg);
std::swap(dw_srcfiles, other.dw_srcfiles);
std::swap(dw_filecount, other.dw_filecount);
return *this;
}
// note: dwarf uses 1-indexing
const char* get(Dwarf_Unsigned file_i) const {
if(file_i >= dw_filecount) {
throw internal_error(microfmt::format(
"Error while accessing the srcfiles list, requested index {} is out of bounds (count = {})",
file_i,
dw_filecount
));
}
return dw_srcfiles[file_i];
}
Dwarf_Unsigned count() const {
return dw_filecount;
}
};
} }
} }
} }

View File

@ -93,7 +93,7 @@ namespace libdwarf {
std::vector<cu_entry> cu_cache; std::vector<cu_entry> cu_cache;
bool generated_cu_cache = false; bool generated_cu_cache = false;
// Map from CU -> {srcfiles, count} // Map from CU -> {srcfiles, count}
std::unordered_map<Dwarf_Off, std::pair<char**, Dwarf_Signed>> srcfiles_cache; std::unordered_map<Dwarf_Off, srcfiles> srcfiles_cache;
// Map from CU -> split full cu resolver // Map from CU -> split full cu resolver
std::unordered_map<Dwarf_Off, std::unique_ptr<dwarf_resolver>> split_full_cu_resolvers; std::unordered_map<Dwarf_Off, std::unique_ptr<dwarf_resolver>> split_full_cu_resolvers;
// info for resolving a dwo object // info for resolving a dwo object
@ -205,15 +205,6 @@ namespace libdwarf {
for(auto& entry : line_tables) { for(auto& entry : line_tables) {
dwarf_srclines_dealloc_b(entry.second.line_context); dwarf_srclines_dealloc_b(entry.second.line_context);
} }
for(auto& entry : srcfiles_cache) {
auto srcfiles = entry.second.first;
auto count = entry.second.second;
for(int i = 0; i < count; i++) {
dwarf_dealloc(dbg, srcfiles[i], DW_DLA_STRING);
srcfiles[i] = nullptr;
}
dwarf_dealloc(dbg, srcfiles, DW_DLA_LIST);
}
// subprograms_cache needs to be destroyed before dbg otherwise there will be another use after free // subprograms_cache needs to be destroyed before dbg otherwise there will be another use after free
subprograms_cache.clear(); subprograms_cache.clear();
split_full_cu_resolvers.clear(); split_full_cu_resolvers.clear();
@ -354,15 +345,11 @@ namespace libdwarf {
char** dw_srcfiles; char** dw_srcfiles;
Dwarf_Signed dw_filecount; Dwarf_Signed dw_filecount;
VERIFY(wrap(dwarf_srcfiles, cu_die.get(), &dw_srcfiles, &dw_filecount) == DW_DLV_OK); VERIFY(wrap(dwarf_srcfiles, cu_die.get(), &dw_srcfiles, &dw_filecount) == DW_DLV_OK);
srcfiles srcfiles(cu_die.dbg, dw_srcfiles, dw_filecount);
if(Dwarf_Signed(file_i) < dw_filecount) { if(Dwarf_Signed(file_i) < dw_filecount) {
// dwarf is using 1-indexing // dwarf is using 1-indexing
filename = dw_srcfiles[file_i]; filename = srcfiles.get(file_i);
} }
for(int i = 0; i < dw_filecount; i++) {
dwarf_dealloc(cu_die.dbg, dw_srcfiles[i], DW_DLA_STRING);
dw_srcfiles[i] = nullptr;
}
dwarf_dealloc(cu_die.dbg, dw_srcfiles, DW_DLA_LIST);
} else { } else {
auto off = cu_die.get_global_offset(); auto off = cu_die.get_global_offset();
auto it = srcfiles_cache.find(off); auto it = srcfiles_cache.find(off);
@ -370,13 +357,11 @@ namespace libdwarf {
char** dw_srcfiles; char** dw_srcfiles;
Dwarf_Signed dw_filecount; Dwarf_Signed dw_filecount;
VERIFY(wrap(dwarf_srcfiles, cu_die.get(), &dw_srcfiles, &dw_filecount) == DW_DLV_OK); VERIFY(wrap(dwarf_srcfiles, cu_die.get(), &dw_srcfiles, &dw_filecount) == DW_DLV_OK);
it = srcfiles_cache.insert(it, {off, {dw_srcfiles, dw_filecount}}); it = srcfiles_cache.insert(it, {off, srcfiles{cu_die.dbg, dw_srcfiles, dw_filecount}});
} }
char** dw_srcfiles = it->second.first; if(file_i < it->second.count()) {
Dwarf_Signed dw_filecount = it->second.second;
if(Dwarf_Signed(file_i) < dw_filecount) {
// dwarf is using 1-indexing // dwarf is using 1-indexing
filename = dw_srcfiles[file_i]; filename = it->second.get(file_i);
} }
} }
return filename; return filename;