diff options
author | aokblast <aokblast@FreeBSD.org> | 2023-10-04 02:16:32 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-03 14:16:32 -0400 |
commit | b3cc4804d45d6b612ac9b3cc47ebbb0da44ebc60 (patch) | |
tree | 18e018ad08ea16de75646f38e8ff27fb923e4969 /lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp | |
parent | f659ef43cd4e72fe84a1fa50966ac78ca6675428 (diff) | |
download | llvm-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.cpp | 43 |
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 |