Skip to content

Commit f89d232

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 e09e318 commit f89d232

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
@@ -1841,6 +1841,49 @@ class VMAddressProvider {
18411841
};
18421842
}
18431843

1844+
namespace {
1845+
// We have to do this because ELF doesn't have section IDs, and also
1846+
// doesn't require section names to be unique. (We use the section index
1847+
// for section IDs, but that isn't guaranteed to be the same in separate
1848+
// debug images.)
1849+
SectionSP FindMatchingSection(const SectionList &section_list,
1850+
SectionSP section) {
1851+
SectionSP sect_sp;
1852+
1853+
addr_t vm_addr = section->GetFileAddress();
1854+
ConstString name = section->GetName();
1855+
offset_t file_size = section->GetFileSize();
1856+
offset_t byte_size = section->GetByteSize();
1857+
SectionType type = section->GetType();
1858+
bool thread_specific = section->IsThreadSpecific();
1859+
uint32_t permissions = section->GetPermissions();
1860+
uint32_t alignment = section->GetLog2Align();
1861+
1862+
for (auto sect_iter = section_list.begin();
1863+
sect_iter != section_list.end();
1864+
++sect_iter) {
1865+
if ((*sect_iter)->GetName() == name
1866+
&& (*sect_iter)->GetType() == type
1867+
&& (*sect_iter)->IsThreadSpecific() == thread_specific
1868+
&& (*sect_iter)->GetPermissions() == permissions
1869+
&& (*sect_iter)->GetFileSize() == file_size
1870+
&& (*sect_iter)->GetByteSize() == byte_size
1871+
&& (*sect_iter)->GetFileAddress() == vm_addr
1872+
&& (*sect_iter)->GetLog2Align() == alignment) {
1873+
sect_sp = *sect_iter;
1874+
break;
1875+
} else {
1876+
sect_sp = FindMatchingSection((*sect_iter)->GetChildren(),
1877+
section);
1878+
if (sect_sp)
1879+
break;
1880+
}
1881+
}
1882+
1883+
return sect_sp;
1884+
}
1885+
}
1886+
18441887
void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
18451888
if (m_sections_up)
18461889
return;
@@ -2054,10 +2097,8 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
20542097
SectionList *module_section_list =
20552098
module_sp ? module_sp->GetSectionList() : nullptr;
20562099

2057-
// Local cache to avoid doing a FindSectionByName for each symbol. The "const
2058-
// char*" key must came from a ConstString object so they can be compared by
2059-
// pointer
2060-
std::unordered_map<const char *, lldb::SectionSP> section_name_to_section;
2100+
// Cache the section mapping
2101+
std::unordered_map<lldb::SectionSP, lldb::SectionSP> section_map;
20612102

20622103
unsigned i;
20632104
for (i = 0; i < num_symbols; ++i) {
@@ -2262,14 +2303,15 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
22622303

22632304
if (symbol_section_sp && module_section_list &&
22642305
module_section_list != section_list) {
2265-
ConstString sect_name = symbol_section_sp->GetName();
2266-
auto section_it = section_name_to_section.find(sect_name.GetCString());
2267-
if (section_it == section_name_to_section.end())
2306+
auto section_it = section_map.find(symbol_section_sp);
2307+
if (section_it == section_map.end()) {
22682308
section_it =
2269-
section_name_to_section
2270-
.emplace(sect_name.GetCString(),
2271-
module_section_list->FindSectionByName(sect_name))
2272-
.first;
2309+
section_map
2310+
.emplace(symbol_section_sp,
2311+
FindMatchingSection(*module_section_list,
2312+
symbol_section_sp))
2313+
.first;
2314+
}
22732315
if (section_it->second)
22742316
symbol_section_sp = section_it->second;
22752317
}

0 commit comments

Comments
 (0)