aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-12-02 21:49:08 +0000
committerDimitry Andric <dim@FreeBSD.org>2022-05-14 11:43:49 +0000
commit4824e7fd18a1223177218d4aec1b3c6c5c4a444e (patch)
tree5ca6493b1b0bf6a41f257794c0116d5e50fbf37c /contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF
parent5e801ac66d24704442eba426ed13c3effb8a34e7 (diff)
parentf65dcba83ce5035ab88a85fe17628b447eb56e1b (diff)
Diffstat (limited to 'contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF')
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp244
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h11
2 files changed, 116 insertions, 139 deletions
diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index 8e0f228a988f..96e94ef08a45 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -2687,155 +2687,131 @@ unsigned ObjectFileELF::RelocateDebugSections(const ELFSectionHeader *rel_hdr,
return 0;
}
-Symtab *ObjectFileELF::GetSymtab() {
+void ObjectFileELF::ParseSymtab(Symtab &lldb_symtab) {
ModuleSP module_sp(GetModule());
if (!module_sp)
- return nullptr;
+ return;
+
+ Progress progress(
+ llvm::formatv("Parsing symbol table for {0}",
+ m_file.GetFilename().AsCString("<Unknown>")));
+ ElapsedTime elapsed(module_sp->GetSymtabParseTime());
// We always want to use the main object file so we (hopefully) only have one
// cached copy of our symtab, dynamic sections, etc.
ObjectFile *module_obj_file = module_sp->GetObjectFile();
if (module_obj_file && module_obj_file != this)
- return module_obj_file->GetSymtab();
-
- if (m_symtab_up == nullptr) {
- Progress progress(
- llvm::formatv("Parsing symbol table for {0}",
- m_file.GetFilename().AsCString("<Unknown>")));
- ElapsedTime elapsed(module_sp->GetSymtabParseTime());
- SectionList *section_list = module_sp->GetSectionList();
- if (!section_list)
- return nullptr;
+ return module_obj_file->ParseSymtab(lldb_symtab);
- uint64_t symbol_id = 0;
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
-
- // Sharable objects and dynamic executables usually have 2 distinct symbol
- // tables, one named ".symtab", and the other ".dynsym". The dynsym is a
- // smaller version of the symtab that only contains global symbols. The
- // information found in the dynsym is therefore also found in the symtab,
- // while the reverse is not necessarily true.
- Section *symtab =
- section_list->FindSectionByType(eSectionTypeELFSymbolTable, true).get();
- if (symtab) {
- m_symtab_up = std::make_unique<Symtab>(symtab->GetObjectFile());
- symbol_id += ParseSymbolTable(m_symtab_up.get(), symbol_id, symtab);
- }
-
- // The symtab section is non-allocable and can be stripped, while the
- // .dynsym section which should always be always be there. To support the
- // minidebuginfo case we parse .dynsym when there's a .gnu_debuginfo
- // section, nomatter if .symtab was already parsed or not. This is because
- // minidebuginfo normally removes the .symtab symbols which have their
- // matching .dynsym counterparts.
- if (!symtab ||
- GetSectionList()->FindSectionByName(ConstString(".gnu_debugdata"))) {
- Section *dynsym =
- section_list->FindSectionByType(eSectionTypeELFDynamicSymbols, true)
- .get();
- if (dynsym) {
- if (!m_symtab_up)
- m_symtab_up = std::make_unique<Symtab>(dynsym->GetObjectFile());
- symbol_id += ParseSymbolTable(m_symtab_up.get(), symbol_id, dynsym);
- }
- }
+ SectionList *section_list = module_sp->GetSectionList();
+ if (!section_list)
+ return;
- // DT_JMPREL
- // If present, this entry's d_ptr member holds the address of
- // relocation
- // entries associated solely with the procedure linkage table.
- // Separating
- // these relocation entries lets the dynamic linker ignore them during
- // process initialization, if lazy binding is enabled. If this entry is
- // present, the related entries of types DT_PLTRELSZ and DT_PLTREL must
- // also be present.
- const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL);
- if (symbol) {
- // Synthesize trampoline symbols to help navigate the PLT.
- addr_t addr = symbol->d_ptr;
- Section *reloc_section =
- section_list->FindSectionContainingFileAddress(addr).get();
- if (reloc_section) {
- user_id_t reloc_id = reloc_section->GetID();
- const ELFSectionHeaderInfo *reloc_header =
- GetSectionHeaderByIndex(reloc_id);
- if (reloc_header) {
- if (m_symtab_up == nullptr)
- m_symtab_up =
- std::make_unique<Symtab>(reloc_section->GetObjectFile());
-
- ParseTrampolineSymbols(m_symtab_up.get(), symbol_id, reloc_header,
- reloc_id);
- }
- }
- }
+ uint64_t symbol_id = 0;
- if (DWARFCallFrameInfo *eh_frame =
- GetModule()->GetUnwindTable().GetEHFrameInfo()) {
- if (m_symtab_up == nullptr)
- m_symtab_up = std::make_unique<Symtab>(this);
- ParseUnwindSymbols(m_symtab_up.get(), eh_frame);
+ // Sharable objects and dynamic executables usually have 2 distinct symbol
+ // tables, one named ".symtab", and the other ".dynsym". The dynsym is a
+ // smaller version of the symtab that only contains global symbols. The
+ // information found in the dynsym is therefore also found in the symtab,
+ // while the reverse is not necessarily true.
+ Section *symtab =
+ section_list->FindSectionByType(eSectionTypeELFSymbolTable, true).get();
+ if (symtab)
+ symbol_id += ParseSymbolTable(&lldb_symtab, symbol_id, symtab);
+
+ // The symtab section is non-allocable and can be stripped, while the
+ // .dynsym section which should always be always be there. To support the
+ // minidebuginfo case we parse .dynsym when there's a .gnu_debuginfo
+ // section, nomatter if .symtab was already parsed or not. This is because
+ // minidebuginfo normally removes the .symtab symbols which have their
+ // matching .dynsym counterparts.
+ if (!symtab ||
+ GetSectionList()->FindSectionByName(ConstString(".gnu_debugdata"))) {
+ Section *dynsym =
+ section_list->FindSectionByType(eSectionTypeELFDynamicSymbols, true)
+ .get();
+ if (dynsym)
+ symbol_id += ParseSymbolTable(&lldb_symtab, symbol_id, dynsym);
+ }
+
+ // DT_JMPREL
+ // If present, this entry's d_ptr member holds the address of
+ // relocation
+ // entries associated solely with the procedure linkage table.
+ // Separating
+ // these relocation entries lets the dynamic linker ignore them during
+ // process initialization, if lazy binding is enabled. If this entry is
+ // present, the related entries of types DT_PLTRELSZ and DT_PLTREL must
+ // also be present.
+ const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL);
+ if (symbol) {
+ // Synthesize trampoline symbols to help navigate the PLT.
+ addr_t addr = symbol->d_ptr;
+ Section *reloc_section =
+ section_list->FindSectionContainingFileAddress(addr).get();
+ if (reloc_section) {
+ user_id_t reloc_id = reloc_section->GetID();
+ const ELFSectionHeaderInfo *reloc_header =
+ GetSectionHeaderByIndex(reloc_id);
+ if (reloc_header)
+ ParseTrampolineSymbols(&lldb_symtab, symbol_id, reloc_header, reloc_id);
}
+ }
- // If we still don't have any symtab then create an empty instance to avoid
- // do the section lookup next time.
- if (m_symtab_up == nullptr)
- m_symtab_up = std::make_unique<Symtab>(this);
-
- // In the event that there's no symbol entry for the entry point we'll
- // artificially create one. We delegate to the symtab object the figuring
- // out of the proper size, this will usually make it span til the next
- // symbol it finds in the section. This means that if there are missing
- // symbols the entry point might span beyond its function definition.
- // We're fine with this as it doesn't make it worse than not having a
- // symbol entry at all.
- if (CalculateType() == eTypeExecutable) {
- ArchSpec arch = GetArchitecture();
- auto entry_point_addr = GetEntryPointAddress();
- bool is_valid_entry_point =
- entry_point_addr.IsValid() && entry_point_addr.IsSectionOffset();
- addr_t entry_point_file_addr = entry_point_addr.GetFileAddress();
- if (is_valid_entry_point && !m_symtab_up->FindSymbolContainingFileAddress(
- entry_point_file_addr)) {
- uint64_t symbol_id = m_symtab_up->GetNumSymbols();
- // Don't set the name for any synthetic symbols, the Symbol
- // object will generate one if needed when the name is accessed
- // via accessors.
- SectionSP section_sp = entry_point_addr.GetSection();
- Symbol symbol(
- /*symID=*/symbol_id,
- /*name=*/llvm::StringRef(), // Name will be auto generated.
- /*type=*/eSymbolTypeCode,
- /*external=*/true,
- /*is_debug=*/false,
- /*is_trampoline=*/false,
- /*is_artificial=*/true,
- /*section_sp=*/section_sp,
- /*offset=*/0,
- /*size=*/0, // FDE can span multiple symbols so don't use its size.
- /*size_is_valid=*/false,
- /*contains_linker_annotations=*/false,
- /*flags=*/0);
- // When the entry point is arm thumb we need to explicitly set its
- // class address to reflect that. This is important because expression
- // evaluation relies on correctly setting a breakpoint at this
- // address.
- if (arch.GetMachine() == llvm::Triple::arm &&
- (entry_point_file_addr & 1)) {
- symbol.GetAddressRef().SetOffset(entry_point_addr.GetOffset() ^ 1);
- m_address_class_map[entry_point_file_addr ^ 1] =
- AddressClass::eCodeAlternateISA;
- } else {
- m_address_class_map[entry_point_file_addr] = AddressClass::eCode;
- }
- m_symtab_up->AddSymbol(symbol);
+ if (DWARFCallFrameInfo *eh_frame =
+ GetModule()->GetUnwindTable().GetEHFrameInfo()) {
+ ParseUnwindSymbols(&lldb_symtab, eh_frame);
+ }
+
+ // In the event that there's no symbol entry for the entry point we'll
+ // artificially create one. We delegate to the symtab object the figuring
+ // out of the proper size, this will usually make it span til the next
+ // symbol it finds in the section. This means that if there are missing
+ // symbols the entry point might span beyond its function definition.
+ // We're fine with this as it doesn't make it worse than not having a
+ // symbol entry at all.
+ if (CalculateType() == eTypeExecutable) {
+ ArchSpec arch = GetArchitecture();
+ auto entry_point_addr = GetEntryPointAddress();
+ bool is_valid_entry_point =
+ entry_point_addr.IsValid() && entry_point_addr.IsSectionOffset();
+ addr_t entry_point_file_addr = entry_point_addr.GetFileAddress();
+ if (is_valid_entry_point && !lldb_symtab.FindSymbolContainingFileAddress(
+ entry_point_file_addr)) {
+ uint64_t symbol_id = lldb_symtab.GetNumSymbols();
+ // Don't set the name for any synthetic symbols, the Symbol
+ // object will generate one if needed when the name is accessed
+ // via accessors.
+ SectionSP section_sp = entry_point_addr.GetSection();
+ Symbol symbol(
+ /*symID=*/symbol_id,
+ /*name=*/llvm::StringRef(), // Name will be auto generated.
+ /*type=*/eSymbolTypeCode,
+ /*external=*/true,
+ /*is_debug=*/false,
+ /*is_trampoline=*/false,
+ /*is_artificial=*/true,
+ /*section_sp=*/section_sp,
+ /*offset=*/0,
+ /*size=*/0, // FDE can span multiple symbols so don't use its size.
+ /*size_is_valid=*/false,
+ /*contains_linker_annotations=*/false,
+ /*flags=*/0);
+ // When the entry point is arm thumb we need to explicitly set its
+ // class address to reflect that. This is important because expression
+ // evaluation relies on correctly setting a breakpoint at this
+ // address.
+ if (arch.GetMachine() == llvm::Triple::arm &&
+ (entry_point_file_addr & 1)) {
+ symbol.GetAddressRef().SetOffset(entry_point_addr.GetOffset() ^ 1);
+ m_address_class_map[entry_point_file_addr ^ 1] =
+ AddressClass::eCodeAlternateISA;
+ } else {
+ m_address_class_map[entry_point_file_addr] = AddressClass::eCode;
}
+ lldb_symtab.AddSymbol(symbol);
}
-
- m_symtab_up->CalculateSymbolSizes();
}
-
- return m_symtab_up.get();
}
void ObjectFileELF::RelocateSection(lldb_private::Section *section)
diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
index 5738e5cf60d5..554f623ec8af 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
+++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
@@ -110,7 +110,7 @@ public:
lldb_private::AddressClass GetAddressClass(lldb::addr_t file_addr) override;
- lldb_private::Symtab *GetSymtab() override;
+ void ParseSymtab(lldb_private::Symtab &symtab) override;
bool IsStripped() override;
@@ -123,7 +123,7 @@ public:
lldb_private::UUID GetUUID() override;
/// Return the contents of the .gnu_debuglink section, if the object file
- /// contains it.
+ /// contains it.
llvm::Optional<lldb_private::FileSpec> GetDebugLink();
uint32_t GetDependentModules(lldb_private::FileSpecList &files) override;
@@ -278,8 +278,9 @@ private:
/// number of dynamic symbols parsed.
size_t ParseDynamicSymbols();
- /// Populates m_symtab_up will all non-dynamic linker symbols. This method
- /// will parse the symbols only once. Returns the number of symbols parsed.
+ /// Populates the symbol table with all non-dynamic linker symbols. This
+ /// method will parse the symbols only once. Returns the number of symbols
+ /// parsed.
unsigned ParseSymbolTable(lldb_private::Symtab *symbol_table,
lldb::user_id_t start_id,
lldb_private::Section *symtab);
@@ -384,7 +385,7 @@ private:
lldb_private::UUID &uuid);
bool AnySegmentHasPhysicalAddress();
-
+
/// Takes the .gnu_debugdata and returns the decompressed object file that is
/// stored within that section.
///