[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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user