https://github.com/Nerixyz updated https://github.com/llvm/llvm-project/pull/140139
>From d81a2def0f2b66b42f0e2569b3871fc682aa085c Mon Sep 17 00:00:00 2001 From: Nerixyz <[email protected]> Date: Thu, 15 May 2025 22:43:49 +0200 Subject: [PATCH 1/2] [lldb] Limit formatter-section extractor range --- lldb/source/DataFormatters/FormatterSection.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lldb/source/DataFormatters/FormatterSection.cpp b/lldb/source/DataFormatters/FormatterSection.cpp index 1de633f4998e0..72979ac1923e8 100644 --- a/lldb/source/DataFormatters/FormatterSection.cpp +++ b/lldb/source/DataFormatters/FormatterSection.cpp @@ -57,11 +57,15 @@ static void ForEachFormatterInModule( cursor.seek(cursor.tell() - 1); break; } + if (!cursor || cursor.tell() >= section_size) + break; + uint64_t version = section.getULEB128(cursor); uint64_t record_size = section.getULEB128(cursor); if (version == 1) { - llvm::DataExtractor record(section.getData().drop_front(cursor.tell()), - le, addr_size); + llvm::DataExtractor record( + section.getData().drop_front(cursor.tell()).take_front(record_size), + le, addr_size); llvm::DataExtractor::Cursor cursor(0); uint64_t type_size = record.getULEB128(cursor); llvm::StringRef type_name = record.getBytes(cursor, type_size); >From 95636b5d80232e980a18047155562ba672f4e2d2 Mon Sep 17 00:00:00 2001 From: Nerixyz <[email protected]> Date: Wed, 28 Jan 2026 20:57:50 +0100 Subject: [PATCH 2/2] Add test --- lldb/unittests/DataFormatter/CMakeLists.txt | 6 + .../DataFormatter/FormatterSectionTest.cpp | 143 ++++++++++++++++++ 2 files changed, 149 insertions(+) create mode 100644 lldb/unittests/DataFormatter/FormatterSectionTest.cpp diff --git a/lldb/unittests/DataFormatter/CMakeLists.txt b/lldb/unittests/DataFormatter/CMakeLists.txt index 3126a285ab5ac..df9a04bb8773f 100644 --- a/lldb/unittests/DataFormatter/CMakeLists.txt +++ b/lldb/unittests/DataFormatter/CMakeLists.txt @@ -2,6 +2,7 @@ add_lldb_unittest(LLDBFormatterTests FormatManagerTests.cpp FormattersContainerTest.cpp FormatterBytecodeTest.cpp + FormatterSectionTest.cpp StringPrinterTests.cpp LINK_COMPONENTS @@ -9,7 +10,12 @@ add_lldb_unittest(LLDBFormatterTests LINK_LIBS lldbCore lldbInterpreter + lldbPluginObjectFileELF + lldbPluginPlatformLinux + lldbPluginSymbolFileSymtab lldbSymbol lldbTarget lldbUtility + lldbUtilityHelpers + LLVMTestingSupport ) diff --git a/lldb/unittests/DataFormatter/FormatterSectionTest.cpp b/lldb/unittests/DataFormatter/FormatterSectionTest.cpp new file mode 100644 index 0000000000000..4b088fef184f3 --- /dev/null +++ b/lldb/unittests/DataFormatter/FormatterSectionTest.cpp @@ -0,0 +1,143 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/DataFormatters/FormatterSection.h" +#include "Plugins/ObjectFile/ELF/ObjectFileELF.h" +#include "Plugins/Platform/Linux/PlatformLinux.h" +#include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h" +#include "TestingSupport/SubsystemRAII.h" +#include "TestingSupport/TestUtilities.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Core/Module.h" +#include "lldb/DataFormatters/DataVisualization.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Target/Platform.h" +#include "lldb/ValueObject/ValueObjectConstResult.h" +#include "gtest/gtest.h" + +using namespace lldb; +using namespace lldb_private; + +namespace { + +struct MockProcess : Process { + MockProcess(TargetSP target_sp, ListenerSP listener_sp) + : Process(target_sp, listener_sp) {} + + llvm::StringRef GetPluginName() override { return "mock process"; } + + bool CanDebug(TargetSP target, bool plugin_specified_by_name) override { + return false; + }; + + Status DoDestroy() override { return {}; } + + void RefreshStateAfterStop() override {} + + bool DoUpdateThreadList(ThreadList &old_thread_list, + ThreadList &new_thread_list) override { + return false; + }; + + size_t DoReadMemory(addr_t vm_addr, void *buf, size_t size, + Status &error) override { + return 0; + } +}; + +class FormatterSectionTest : public ::testing::Test { +public: + void SetUp() override { + ArchSpec arch("x86_64-pc-linux"); + Platform::SetHostPlatform( + platform_linux::PlatformLinux::CreateInstance(true, &arch)); + m_debugger_sp = Debugger::CreateInstance(); + ASSERT_TRUE(m_debugger_sp); + m_debugger_sp->GetTargetList().CreateTarget(*m_debugger_sp, "", arch, + eLoadDependentsNo, + m_platform_sp, m_target_sp); + ASSERT_TRUE(m_target_sp); + ASSERT_TRUE(m_target_sp->GetArchitecture().IsValid()); + ASSERT_TRUE(m_platform_sp); + m_listener_sp = Listener::MakeListener("dummy"); + m_process_sp = std::make_shared<MockProcess>(m_target_sp, m_listener_sp); + ASSERT_TRUE(m_process_sp); + m_exe_ctx = ExecutionContext(m_process_sp); + } + + ExecutionContext m_exe_ctx; + TypeSystemClang *m_type_system; + lldb::TargetSP m_target_sp; + +private: + SubsystemRAII<FileSystem, HostInfo, ObjectFileELF, + platform_linux::PlatformLinux, SymbolFileSymtab> + m_subsystems; + + lldb::DebuggerSP m_debugger_sp; + lldb::PlatformSP m_platform_sp; + lldb::ListenerSP m_listener_sp; + lldb::ProcessSP m_process_sp; +}; + +} // namespace + +/// Test that multiple formatters can be loaded +TEST_F(FormatterSectionTest, LoadFormattersForModule) { + auto ExpectedFile = TestFile::fromYaml(R"( +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .lldbformatters + Type: SHT_PROGBITS + Flags: [ ] + Address: 0x2010 + AddressAlign: 0x10 + # Two summaries for "Point" and "Rect" that return "AAAAA" and "BBBBB" respectively + Content: 011205506F696E74000009012205414141414113000000000111045265637400000901220542424242421300000000 + Size: 256 +... +)"); + ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded()); + + auto module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec()); + + LoadFormattersForModule(module_sp); + + TypeCategoryImplSP category; + DataVisualization::Categories::GetCategory(ConstString("default"), category); + ASSERT_TRUE(category != nullptr); + + ASSERT_EQ(category->GetCount(), 2); + + TypeSummaryImplSP point_summary_sp = + category->GetSummaryForType(std::make_shared<TypeNameSpecifierImpl>( + "Point", lldb::eFormatterMatchExact)); + ASSERT_TRUE(point_summary_sp != nullptr); + + TypeSummaryImplSP rect_summary_sp = + category->GetSummaryForType(std::make_shared<TypeNameSpecifierImpl>( + "Rect", lldb::eFormatterMatchExact)); + ASSERT_TRUE(rect_summary_sp != nullptr); + + std::string dest; + ValueObjectSP valobj = ValueObjectConstResult::CreateValueObjectFromBool( + m_target_sp, false, "mock"); + ASSERT_TRUE( + point_summary_sp->FormatObject(valobj.get(), dest, TypeSummaryOptions())); + ASSERT_EQ(dest, "AAAAA"); + dest.clear(); + ASSERT_TRUE( + rect_summary_sp->FormatObject(valobj.get(), dest, TypeSummaryOptions())); + ASSERT_EQ(dest, "BBBBB"); +} _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
