[Lldb-commits] [lldb] [LLDB] Impove ObjectFileELF's .dynamic parsing and usage. (PR #101237)
Pavel Labath via lldb-commits
lldb-commits at lists.llvm.org
Wed Aug 7 04:12:11 PDT 2024
================
@@ -3704,3 +3802,88 @@ ObjectFileELF::MapFileDataWritable(const FileSpec &file, uint64_t Size,
return FileSystem::Instance().CreateWritableDataBuffer(file.GetPath(), Size,
Offset);
}
+
+std::optional<DataExtractor> ObjectFileELF::GetDynstrData() {
+ if (SectionList *section_list = GetSectionList()) {
+ // Find the SHT_DYNAMIC section.
+ if (Section *dynamic =
+ section_list
+ ->FindSectionByType(eSectionTypeELFDynamicLinkInfo, true)
+ .get()) {
+ assert(dynamic->GetObjectFile() == this);
+ if (const ELFSectionHeaderInfo *header =
+ GetSectionHeaderByIndex(dynamic->GetID())) {
+ // sh_link: section header index of string table used by entries in
+ // the section.
+ if (Section *dynstr =
+ section_list->FindSectionByID(header->sh_link).get()) {
+ DataExtractor data;
+ if (ReadSectionData(dynstr, data))
+ return data;
+ }
+ }
+ }
+ }
+
+ // Every ELF file which represents an executable or shared library has
+ // mandatory .dynamic entries. Two of these values are DT_STRTAB and DT_STRSZ
+ // and represent the dynamic symbol tables's string table. These are needed
+ // by the dynamic loader and we can read them from a process' address space.
+ //
+ // When loading and ELF file from memory, only the program headers end up
+ // being mapped into memory, and we can find these values in the PT_DYNAMIC
+ // segment.
+ const ELFDynamic *strtab = FindDynamicSymbol(DT_STRTAB);
+ const ELFDynamic *strsz = FindDynamicSymbol(DT_STRSZ);
+ if (strtab == nullptr || strsz == nullptr)
+ return std::nullopt;
+
+ if (ProcessSP process_sp = m_process_wp.lock()) {
+ if (DataBufferSP data_sp =
+ ReadMemory(process_sp, strtab->d_ptr, strsz->d_val))
+ return DataExtractor(data_sp, GetByteOrder(), GetAddressByteSize());
+ } else {
+ // We have an ELF file with no section headers or we didn't find the
+ // .dynamic section. Try and find the .dynstr section.
+ Address addr;
+ if (addr.ResolveAddressUsingFileSections(strtab->d_ptr, GetSectionList())) {
+ DataExtractor data;
+ addr.GetSection()->GetSectionData(data);
+ return DataExtractor(data,
+ strtab->d_ptr - addr.GetSection()->GetFileOffset(),
----------------
labath wrote:
```suggestion
strtab->d_ptr - addr.GetSection()->GetFileAddress(),
```
(fixes a bug I found while working on the test case, unlikely to have been caught for real object files, as their first segment always starts at zero)
https://github.com/llvm/llvm-project/pull/101237
More information about the lldb-commits
mailing list