[Lldb-commits] [lldb] [LLDB] Add FreeBSD kernel coredump matching check. (PR #80785)
via lldb-commits
lldb-commits at lists.llvm.org
Tue Feb 6 05:56:53 PST 2024
https://github.com/aokblast updated https://github.com/llvm/llvm-project/pull/80785
>From 5f9eac19a45cd4b71afe48643fc0cf8b4b4ab6be Mon Sep 17 00:00:00 2001
From: aokblast <aokblast at FreeBSD.org>
Date: Tue, 6 Feb 2024 10:18:34 +0800
Subject: [PATCH 1/2] [LLDB] Fetch UUID from note section in coredump
---
.../Plugins/ObjectFile/ELF/ObjectFileELF.cpp | 29 +++++++++++++++++++
.../Plugins/ObjectFile/ELF/ObjectFileELF.h | 3 ++
2 files changed, 32 insertions(+)
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index 0d95a1c12bde3..3b047e3d5c759 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -795,6 +795,32 @@ bool ObjectFileELF::ParseHeader() {
return m_header.Parse(m_data, &offset);
}
+UUID ObjectFileELF::GetUUIDByNoteSection() {
+ if (!ParseProgramHeaders())
+ return UUID();
+ for (const ELFProgramHeader &H : m_program_headers) {
+ if (H.p_type == llvm::ELF::PT_NOTE) {
+ const elf_off ph_offset = H.p_offset;
+ const size_t ph_size = H.p_filesz;
+
+ DataExtractor segment_data;
+ if (segment_data.SetData(m_data, ph_offset, ph_size) != ph_size) {
+ // The ELF program header contained incorrect data, probably corefile
+ // is incomplete or corrupted.
+ break;
+ }
+
+ UUID uuid;
+ ArchSpec arch;
+
+ if (RefineModuleDetailsFromNote(segment_data, arch, uuid).Success())
+ return uuid;
+ }
+ }
+
+ return UUID();
+}
+
UUID ObjectFileELF::GetUUID() {
// Need to parse the section list to get the UUIDs, so make sure that's been
// done.
@@ -809,6 +835,9 @@ UUID ObjectFileELF::GetUUID() {
if (!ParseProgramHeaders())
return UUID();
+ if ((m_uuid = GetUUIDByNoteSection()).IsValid())
+ return m_uuid;
+
core_notes_crc =
CalculateELFNotesSegmentsCRC32(m_program_headers, m_data);
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
index bc8e34981a9d8..6954bd96b753a 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
@@ -272,6 +272,9 @@ class ObjectFileELF : public lldb_private::ObjectFile {
uint32_t &gnu_debuglink_crc,
lldb_private::ArchSpec &arch_spec);
+ // Use Note Section to get uuid.
+ lldb_private::UUID GetUUIDByNoteSection();
+
/// Scans the dynamic section and locates all dependent modules (shared
/// libraries) populating m_filespec_up. This method will compute the
/// dependent module list only once. Returns the number of dependent
>From ebcee01c88b9064b1b9da8fdca0561a569bb6271 Mon Sep 17 00:00:00 2001
From: aokblast <aokblast at FreeBSD.org>
Date: Tue, 6 Feb 2024 21:56:24 +0800
Subject: [PATCH 2/2] Add match check between binary and coredump of FreeBSD
kernel
---
.../DynamicLoaderFreeBSDKernel.cpp | 38 +++++++++++++++----
.../DynamicLoaderFreeBSDKernel.h | 3 +-
2 files changed, 33 insertions(+), 8 deletions(-)
diff --git a/lldb/source/Plugins/DynamicLoader/FreeBSD-Kernel/DynamicLoaderFreeBSDKernel.cpp b/lldb/source/Plugins/DynamicLoader/FreeBSD-Kernel/DynamicLoaderFreeBSDKernel.cpp
index e504e6cbf6921..5ac629552de7c 100644
--- a/lldb/source/Plugins/DynamicLoader/FreeBSD-Kernel/DynamicLoaderFreeBSDKernel.cpp
+++ b/lldb/source/Plugins/DynamicLoader/FreeBSD-Kernel/DynamicLoaderFreeBSDKernel.cpp
@@ -153,9 +153,10 @@ addr_t DynamicLoaderFreeBSDKernel::FindKernelAtLoadAddress(
}
// Read ELF header from memry and return
+template <typename Elf_Ehdr>
bool DynamicLoaderFreeBSDKernel::ReadELFHeader(Process *process,
lldb::addr_t addr,
- llvm::ELF::Elf32_Ehdr &header,
+ Elf_Ehdr &header,
bool *read_error) {
Status error;
if (read_error)
@@ -200,8 +201,23 @@ lldb_private::UUID DynamicLoaderFreeBSDKernel::CheckForKernelImageAtAddress(
if (header.e_type != llvm::ELF::ET_EXEC)
return UUID();
- ModuleSP memory_module_sp =
- process->ReadModuleFromMemory(FileSpec("temp_freebsd_kernel"), addr);
+ ArchSpec kernel_arch(llvm::ELF::convertEMachineToArchName(header.e_machine));
+
+ // If the memory module is 64bit, we should use the Elf64_Ehdr or the e_shoff
+ // would be wrong
+ ModuleSP memory_module_sp;
+ if (header.e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS64) {
+ llvm::ELF::Elf64_Ehdr elf64_header;
+ if (!ReadELFHeader(process, addr, elf64_header)) {
+ *read_error = true;
+ return UUID();
+ }
+ memory_module_sp = process->ReadModuleFromMemory(
+ FileSpec("temp_freebsd_kernel"), addr, elf64_header.e_shoff);
+ } else {
+ memory_module_sp = process->ReadModuleFromMemory(
+ FileSpec("temp_freebsd_kernel"), addr, header.e_shoff);
+ }
if (!memory_module_sp.get()) {
*read_error = true;
@@ -218,10 +234,18 @@ lldb_private::UUID DynamicLoaderFreeBSDKernel::CheckForKernelImageAtAddress(
return UUID();
}
- // In here, I should check is_kernel for memory_module_sp
- // However, the ReadModuleFromMemory reads wrong section so that this check
- // will failed
- ArchSpec kernel_arch(llvm::ELF::convertEMachineToArchName(header.e_machine));
+ // Because the memory module is read from memory and in the memory, the type
+ // is eTypeExecutable so we have to assign the type manually
+ memory_module_sp->GetObjectFile()->SetType(ObjectFile::eTypeCoreFile);
+ UUID memory_module_uuid = memory_module_sp->GetUUID();
+ if (memory_module_uuid.IsValid() &&
+ (memory_module_uuid !=
+ process->GetTarget().GetExecutableModule()->GetUUID())) {
+ LLDB_LOGF(log, "DynamicLoaderFreeBSDKernel::CheckForKernelImageAtAddress "
+ ".note.gnu.build-id mismatched. Maybe you are using "
+ "coredump with incompatible kernel binary?");
+ return UUID();
+ }
if (!process->GetTarget().GetArchitecture().IsCompatibleMatch(kernel_arch))
process->GetTarget().SetArchitecture(kernel_arch);
diff --git a/lldb/source/Plugins/DynamicLoader/FreeBSD-Kernel/DynamicLoaderFreeBSDKernel.h b/lldb/source/Plugins/DynamicLoader/FreeBSD-Kernel/DynamicLoaderFreeBSDKernel.h
index d8656e9c49dfe..bce0837aa4df4 100644
--- a/lldb/source/Plugins/DynamicLoader/FreeBSD-Kernel/DynamicLoaderFreeBSDKernel.h
+++ b/lldb/source/Plugins/DynamicLoader/FreeBSD-Kernel/DynamicLoaderFreeBSDKernel.h
@@ -148,8 +148,9 @@ class DynamicLoaderFreeBSDKernel : public lldb_private::DynamicLoader {
static lldb::addr_t FindKernelAtLoadAddress(lldb_private::Process *process);
+ template <typename Elf_Ehdr>
static bool ReadELFHeader(lldb_private::Process *process,
- lldb::addr_t address, llvm::ELF::Elf32_Ehdr &header,
+ lldb::addr_t address, Elf_Ehdr &header,
bool *read_error = nullptr);
lldb_private::Process *m_process;
More information about the lldb-commits
mailing list