aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
diff options
context:
space:
mode:
authoraokblast <aokblast@FreeBSD.org>2023-10-04 02:16:32 +0800
committerGitHub <noreply@github.com>2023-10-03 14:16:32 -0400
commitb3cc4804d45d6b612ac9b3cc47ebbb0da44ebc60 (patch)
tree18e018ad08ea16de75646f38e8ff27fb923e4969 /lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
parentf659ef43cd4e72fe84a1fa50966ac78ca6675428 (diff)
downloadllvm-b3cc4804d45d6b612ac9b3cc47ebbb0da44ebc60.zip
llvm-b3cc4804d45d6b612ac9b3cc47ebbb0da44ebc60.tar.gz
llvm-b3cc4804d45d6b612ac9b3cc47ebbb0da44ebc60.tar.bz2
[lldb][FreeBSD] Add dynamic loader handle class for FreeBSD Kernel (#67106)
The implemtation support parsing kernel module for FreeBSD Kernel and has been test on x86-64 and arm64. In summary, this class parse the linked list resides in the kernel memory that record all kernel module and load the debug symbol file to facilitate debug process
Diffstat (limited to 'lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp')
-rw-r--r--lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp43
1 files changed, 38 insertions, 5 deletions
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index 2da971d..43ab87f 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -935,6 +935,16 @@ lldb_private::Address ObjectFileELF::GetEntryPointAddress() {
}
Address ObjectFileELF::GetBaseAddress() {
+ if (GetType() == ObjectFile::eTypeObjectFile) {
+ for (SectionHeaderCollIter I = std::next(m_section_headers.begin());
+ I != m_section_headers.end(); ++I) {
+ const ELFSectionHeaderInfo &header = *I;
+ if (header.sh_flags & SHF_ALLOC)
+ return Address(GetSectionList()->FindSectionByID(SectionIndex(I)), 0);
+ }
+ return LLDB_INVALID_ADDRESS;
+ }
+
for (const auto &EnumPHdr : llvm::enumerate(ProgramHeaders())) {
const ELFProgramHeader &H = EnumPHdr.value();
if (H.p_type != PT_LOAD)
@@ -1764,7 +1774,12 @@ class VMAddressProvider {
VMRange GetVMRange(const ELFSectionHeader &H) {
addr_t Address = H.sh_addr;
addr_t Size = H.sh_flags & SHF_ALLOC ? H.sh_size : 0;
- if (ObjectType == ObjectFile::Type::eTypeObjectFile && Segments.empty() && (H.sh_flags & SHF_ALLOC)) {
+
+ // When this is a debug file for relocatable file, the address is all zero
+ // and thus needs to use accumulate method
+ if ((ObjectType == ObjectFile::Type::eTypeObjectFile ||
+ (ObjectType == ObjectFile::Type::eTypeDebugInfo && H.sh_addr == 0)) &&
+ Segments.empty() && (H.sh_flags & SHF_ALLOC)) {
NextVMAddress =
llvm::alignTo(NextVMAddress, std::max<addr_t>(H.sh_addralign, 1));
Address = NextVMAddress;
@@ -3454,10 +3469,28 @@ ObjectFile::Strata ObjectFileELF::CalculateStrata() {
case llvm::ELF::ET_EXEC:
// 2 - Executable file
- // TODO: is there any way to detect that an executable is a kernel
- // related executable by inspecting the program headers, section headers,
- // symbols, or any other flag bits???
- return eStrataUser;
+ {
+ SectionList *section_list = GetSectionList();
+ if (section_list) {
+ static ConstString loader_section_name(".interp");
+ SectionSP loader_section =
+ section_list->FindSectionByName(loader_section_name);
+ if (loader_section) {
+ char buffer[256];
+ size_t read_size =
+ ReadSectionData(loader_section.get(), 0, buffer, sizeof(buffer));
+
+ // We compare the content of .interp section
+ // It will contains \0 when counting read_size, so the size needs to
+ // decrease by one
+ llvm::StringRef loader_name(buffer, read_size - 1);
+ llvm::StringRef freebsd_kernel_loader_name("/red/herring");
+ if (loader_name.equals(freebsd_kernel_loader_name))
+ return eStrataKernel;
+ }
+ }
+ return eStrataUser;
+ }
case llvm::ELF::ET_DYN:
// 3 - Shared object file