Skip to content

Commit ce54a7f

Browse files
committed
[LLDB][ELF] Fix section unification to not just use names.
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. rdar://124467787
1 parent f5953f4 commit ce54a7f

File tree

1 file changed

+53
-11
lines changed

1 file changed

+53
-11
lines changed

lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp

Lines changed: 53 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1854,6 +1854,49 @@ class VMAddressProvider {
18541854
};
18551855
}
18561856

1857+
namespace {
1858+
// We have to do this because ELF doesn't have section IDs, and also
1859+
// doesn't require section names to be unique. (We use the section index
1860+
// for section IDs, but that isn't guaranteed to be the same in separate
1861+
// debug images.)
1862+
SectionSP FindMatchingSection(const SectionList &section_list,
1863+
SectionSP section) {
1864+
SectionSP sect_sp;
1865+
1866+
addr_t vm_addr = section->GetFileAddress();
1867+
ConstString name = section->GetName();
1868+
offset_t file_size = section->GetFileSize();
1869+
offset_t byte_size = section->GetByteSize();
1870+
SectionType type = section->GetType();
1871+
bool thread_specific = section->IsThreadSpecific();
1872+
uint32_t permissions = section->GetPermissions();
1873+
uint32_t alignment = section->GetLog2Align();
1874+
1875+
for (auto sect_iter = section_list.begin();
1876+
sect_iter != section_list.end();
1877+
++sect_iter) {
1878+
if ((*sect_iter)->GetName() == name
1879+
&& (*sect_iter)->GetType() == type
1880+
&& (*sect_iter)->IsThreadSpecific() == thread_specific
1881+
&& (*sect_iter)->GetPermissions() == permissions
1882+
&& (*sect_iter)->GetFileSize() == file_size
1883+
&& (*sect_iter)->GetByteSize() == byte_size
1884+
&& (*sect_iter)->GetFileAddress() == vm_addr
1885+
&& (*sect_iter)->GetLog2Align() == alignment) {
1886+
sect_sp = *sect_iter;
1887+
break;
1888+
} else {
1889+
sect_sp = FindMatchingSection((*sect_iter)->GetChildren(),
1890+
section);
1891+
if (sect_sp)
1892+
break;
1893+
}
1894+
}
1895+
1896+
return sect_sp;
1897+
}
1898+
}
1899+
18571900
void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
18581901
if (m_sections_up)
18591902
return;
@@ -2067,10 +2110,8 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
20672110
SectionList *module_section_list =
20682111
module_sp ? module_sp->GetSectionList() : nullptr;
20692112

2070-
// Local cache to avoid doing a FindSectionByName for each symbol. The "const
2071-
// char*" key must came from a ConstString object so they can be compared by
2072-
// pointer
2073-
std::unordered_map<const char *, lldb::SectionSP> section_name_to_section;
2113+
// Cache the section mapping
2114+
std::unordered_map<lldb::SectionSP, lldb::SectionSP> section_map;
20742115

20752116
unsigned i;
20762117
for (i = 0; i < num_symbols; ++i) {
@@ -2275,14 +2316,15 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
22752316

22762317
if (symbol_section_sp && module_section_list &&
22772318
module_section_list != section_list) {
2278-
ConstString sect_name = symbol_section_sp->GetName();
2279-
auto section_it = section_name_to_section.find(sect_name.GetCString());
2280-
if (section_it == section_name_to_section.end())
2319+
auto section_it = section_map.find(symbol_section_sp);
2320+
if (section_it == section_map.end()) {
22812321
section_it =
2282-
section_name_to_section
2283-
.emplace(sect_name.GetCString(),
2284-
module_section_list->FindSectionByName(sect_name))
2285-
.first;
2322+
section_map
2323+
.emplace(symbol_section_sp,
2324+
FindMatchingSection(*module_section_list,
2325+
symbol_section_sp))
2326+
.first;
2327+
}
22862328
if (section_it->second)
22872329
symbol_section_sp = section_it->second;
22882330
}

0 commit comments

Comments
 (0)