https://github.com/aokblast updated https://github.com/llvm/llvm-project/pull/80785
>From 5f9eac19a45cd4b71afe48643fc0cf8b4b4ab6be Mon Sep 17 00:00:00 2001 From: aokblast <aokbl...@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 <aokbl...@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; _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits