aadsm updated this revision to Diff 202651.
aadsm added a comment.
Rebase
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D62501/new/
https://reviews.llvm.org/D62501
Files:
lldb/include/lldb/Host/common/NativeProcessProtocol.h
lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
Index: lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
===================================================================
--- lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
+++ lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
@@ -131,11 +131,14 @@
protected:
llvm::Expected<llvm::ArrayRef<uint8_t>>
GetSoftwareBreakpointTrapOpcode(size_t size_hint) override;
+ template <typename ELF_EHDR, typename ELF_PHDR, typename ELF_DYN>
+ lldb::addr_t GetELFImageInfoAddress();
private:
MainLoop::SignalHandleUP m_sigchld_handle;
ArchSpec m_arch;
std::unique_ptr<AuxVector> m_aux_vector;
+ lldb::addr_t m_elf_image_info_addr = LLDB_INVALID_ADDRESS;
LazyBool m_supports_mem_region = eLazyBoolCalculate;
std::vector<std::pair<MemoryRegionInfo, FileSpec>> m_mem_region_cache;
Index: lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
===================================================================
--- lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -38,6 +38,7 @@
#include "lldb/Utility/State.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StringExtractor.h"
+#include "llvm/BinaryFormat/ELF.h"
#include "llvm/Support/Errno.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Threading.h"
@@ -1390,8 +1391,12 @@
}
lldb::addr_t NativeProcessLinux::GetSharedLibraryInfoAddress() {
- // punt on this for now
- return LLDB_INVALID_ADDRESS;
+ if (GetAddressByteSize() == 8)
+ return GetELFImageInfoAddress<llvm::ELF::Elf64_Ehdr, llvm::ELF::Elf64_Phdr,
+ llvm::ELF::Elf64_Dyn>();
+ else
+ return GetELFImageInfoAddress<llvm::ELF::Elf32_Ehdr, llvm::ELF::Elf32_Phdr,
+ llvm::ELF::Elf32_Dyn>();
}
size_t NativeProcessLinux::UpdateThreads() {
@@ -2097,3 +2102,77 @@
return m_aux_vector->GetAuxValue(type);
}
+
+template <typename ELF_EHDR, typename ELF_PHDR, typename ELF_DYN>
+lldb::addr_t NativeProcessLinux::GetELFImageInfoAddress() {
+ if (m_elf_image_info_addr != LLDB_INVALID_ADDRESS)
+ return m_elf_image_info_addr;
+
+ llvm::Optional<uint64_t> maybe_phdr_addr =
+ GetAuxValue(AuxVector::AUXV_AT_PHDR);
+ llvm::Optional<uint64_t> maybe_phdr_entry_size =
+ GetAuxValue(AuxVector::AUXV_AT_PHENT);
+ llvm::Optional<uint64_t> maybe_phdr_num_entries =
+ GetAuxValue(AuxVector::AUXV_AT_PHNUM);
+ if (!maybe_phdr_addr || !maybe_phdr_entry_size || !maybe_phdr_num_entries)
+ return LLDB_INVALID_ADDRESS;
+ lldb::addr_t phdr_addr = *maybe_phdr_addr;
+ size_t phdr_entry_size = *maybe_phdr_entry_size;
+ size_t phdr_num_entries = *maybe_phdr_num_entries;
+ lldb::addr_t load_base = phdr_addr - sizeof(ELF_EHDR);
+
+ // Find the PT_DYNAMIC segment (.dynamic section) in the program header and
+ // what the ELF believes to be the load base.
+ lldb::addr_t elf_load_base = 0;
+ bool found_elf_load_base = false;
+ lldb::addr_t dynamic_section_addr = 0;
+ uint64_t dynamic_section_size = 0;
+ bool found_dynamic_section = false;
+ ELF_PHDR phdr_entry;
+ for (size_t i = 0; i < phdr_num_entries; i++) {
+ size_t bytes_read;
+ auto error = ReadMemory(phdr_addr + i * phdr_entry_size, &phdr_entry,
+ sizeof(phdr_entry), bytes_read);
+ if (!error.Success())
+ return LLDB_INVALID_ADDRESS;
+
+ if ((!found_elf_load_base || phdr_entry.p_vaddr < elf_load_base) &&
+ phdr_entry.p_type == llvm::ELF::PT_LOAD) {
+ elf_load_base = phdr_entry.p_vaddr;
+ found_elf_load_base = true;
+ }
+
+ if (phdr_entry.p_type == llvm::ELF::PT_DYNAMIC) {
+ dynamic_section_addr = phdr_entry.p_vaddr;
+ dynamic_section_size = phdr_entry.p_memsz;
+ found_dynamic_section = true;
+ }
+ }
+
+ if (!found_elf_load_base || !found_dynamic_section)
+ return LLDB_INVALID_ADDRESS;
+
+ // Find the DT_DEBUG entry in the .dynamic section
+ // The load base we got from the auxiliary vector is the source of truth. If
+ // we got a different load base from the ELF then we need to correct the
+ // .dynamic section address with the difference we found.
+ dynamic_section_addr += (load_base - elf_load_base);
+ ELF_DYN dynamic_entry;
+ size_t dynamic_num_entries = dynamic_section_size / sizeof(dynamic_entry);
+ for (size_t i = 0; i < dynamic_num_entries; i++) {
+ size_t bytes_read;
+ auto error = ReadMemory(dynamic_section_addr + i * sizeof(dynamic_entry),
+ &dynamic_entry, sizeof(dynamic_entry), bytes_read);
+ if (!error.Success())
+ return LLDB_INVALID_ADDRESS;
+ // Return the &DT_DEBUG->d_ptr which points to r_debug which contains the
+ // link_map.
+ if (dynamic_entry.d_tag == llvm::ELF::DT_DEBUG) {
+ m_elf_image_info_addr = dynamic_section_addr + i * sizeof(dynamic_entry) +
+ sizeof(dynamic_entry.d_tag);
+ return m_elf_image_info_addr;
+ }
+ }
+
+ return LLDB_INVALID_ADDRESS;
+}
Index: lldb/include/lldb/Host/common/NativeProcessProtocol.h
===================================================================
--- lldb/include/lldb/Host/common/NativeProcessProtocol.h
+++ lldb/include/lldb/Host/common/NativeProcessProtocol.h
@@ -427,6 +427,8 @@
NativeThreadProtocol *GetThreadByIDUnlocked(lldb::tid_t tid);
+ lldb::addr_t GetELFImageInfoAddress();
+
private:
void SynchronouslyNotifyProcessStateChanged(lldb::StateType state);
llvm::Expected<SoftwareBreakpoint>
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits