[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