[LLDB][ELF] Fix section unification to not just use names. (#90099)

Section unification cannot just use names, because it's valid for ELF
binaries to have multiple sections with the same name. We should check
other section properties too.

Fixes #88001.

rdar://124467787
This commit is contained in:
Alastair Houghton
2024-05-01 17:17:03 +01:00
committed by GitHub
parent 6e31714d24
commit 4cbe7607c7
2 changed files with 95 additions and 12 deletions

View File

@@ -1854,6 +1854,39 @@ public:
};
}
// We have to do this because ELF doesn't have section IDs, and also
// doesn't require section names to be unique. (We use the section index
// for section IDs, but that isn't guaranteed to be the same in separate
// debug images.)
static SectionSP FindMatchingSection(const SectionList &section_list,
SectionSP section) {
SectionSP sect_sp;
addr_t vm_addr = section->GetFileAddress();
ConstString name = section->GetName();
offset_t byte_size = section->GetByteSize();
bool thread_specific = section->IsThreadSpecific();
uint32_t permissions = section->GetPermissions();
uint32_t alignment = section->GetLog2Align();
for (auto sect : section_list) {
if (sect->GetName() == name &&
sect->IsThreadSpecific() == thread_specific &&
sect->GetPermissions() == permissions &&
sect->GetByteSize() == byte_size && sect->GetFileAddress() == vm_addr &&
sect->GetLog2Align() == alignment) {
sect_sp = sect;
break;
} else {
sect_sp = FindMatchingSection(sect->GetChildren(), section);
if (sect_sp)
break;
}
}
return sect_sp;
}
void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
if (m_sections_up)
return;
@@ -2067,10 +2100,12 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
SectionList *module_section_list =
module_sp ? module_sp->GetSectionList() : nullptr;
// Local cache to avoid doing a FindSectionByName for each symbol. The "const
// char*" key must came from a ConstString object so they can be compared by
// pointer
std::unordered_map<const char *, lldb::SectionSP> section_name_to_section;
// We might have debug information in a separate object, in which case
// we need to map the sections from that object to the sections in the
// main object during symbol lookup. If we had to compare the sections
// for every single symbol, that would be expensive, so this map is
// used to accelerate the process.
std::unordered_map<lldb::SectionSP, lldb::SectionSP> section_map;
unsigned i;
for (i = 0; i < num_symbols; ++i) {
@@ -2275,14 +2310,14 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
if (symbol_section_sp && module_section_list &&
module_section_list != section_list) {
ConstString sect_name = symbol_section_sp->GetName();
auto section_it = section_name_to_section.find(sect_name.GetCString());
if (section_it == section_name_to_section.end())
section_it =
section_name_to_section
.emplace(sect_name.GetCString(),
module_section_list->FindSectionByName(sect_name))
.first;
auto section_it = section_map.find(symbol_section_sp);
if (section_it == section_map.end()) {
section_it = section_map
.emplace(symbol_section_sp,
FindMatchingSection(*module_section_list,
symbol_section_sp))
.first;
}
if (section_it->second)
symbol_section_sp = section_it->second;
}