[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
This commit is contained in:
aokblast
2023-10-04 02:16:32 +08:00
committed by GitHub
parent f659ef43cd
commit b3cc4804d4
6 changed files with 1014 additions and 7 deletions

View File

@@ -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