From bed3e0d9e68f0f35f760e5c5f93d270715a57882 Mon Sep 17 00:00:00 2001 From: Javier Lopez-Gomez Date: Mon, 12 May 2025 16:30:50 +0200 Subject: [PATCH 1/2] [llvm-debuginfo-analyzer] Fix parsing of instructions beyond section contents --- .../lib/DebugInfo/LogicalView/Readers/LVBinaryReader.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/llvm/lib/DebugInfo/LogicalView/Readers/LVBinaryReader.cpp b/llvm/lib/DebugInfo/LogicalView/Readers/LVBinaryReader.cpp index ad14baa0c9269..c1ebe0dda4a16 100644 --- a/llvm/lib/DebugInfo/LogicalView/Readers/LVBinaryReader.cpp +++ b/llvm/lib/DebugInfo/LogicalView/Readers/LVBinaryReader.cpp @@ -433,6 +433,15 @@ Error LVBinaryReader::createInstructions(LVScope *Scope, ArrayRef Bytes = arrayRefFromStringRef(*SectionContentsOrErr); uint64_t Offset = Address - SectionAddress; + if (Offset > Bytes.size()) { + LLVM_DEBUG({ + dbgs() << "offset (" << hexValue(Offset) << ") is beyond section size (" + << hexValue(Bytes.size()) << "); malformed input?\n"; + }); + return createStringError( + errc::bad_address, + "Failed to parse instructions; offset beyond section size"); + } uint8_t const *Begin = Bytes.data() + Offset; uint8_t const *End = Bytes.data() + Offset + Size; From acb83fc115cf758223ab2a9566da7dd8150eac96 Mon Sep 17 00:00:00 2001 From: Javier Lopez-Gomez Date: Mon, 12 May 2025 16:30:51 +0200 Subject: [PATCH 2/2] [llvm-debuginfo-analyzer] LVScope::addMissingElements: fix handling of unspecified parameters --- .../DebugInfo/LogicalView/Core/LVScope.cpp | 5 ++- .../DebugInfo/LogicalView/DWARFReaderTest.cpp | 39 +++++++++++++++++- .../Inputs/test-dwarf-clang-unspec-params.elf | Bin 0 -> 16800 bytes 3 files changed, 42 insertions(+), 2 deletions(-) create mode 100755 llvm/unittests/DebugInfo/LogicalView/Inputs/test-dwarf-clang-unspec-params.elf diff --git a/llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp b/llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp index 8bbaf93db0caa..f187b1a57bd45 100644 --- a/llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp +++ b/llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp @@ -330,13 +330,16 @@ void LVScope::addMissingElements(LVScope *Reference) { Symbol->setIsOptimized(); Symbol->setReference(Reference); - // The symbol can be a constant, parameter or variable. + // The symbol can be a constant, parameter, variable or unspecified + // parameters (i.e. `...`). if (Reference->getIsConstant()) Symbol->setIsConstant(); else if (Reference->getIsParameter()) Symbol->setIsParameter(); else if (Reference->getIsVariable()) Symbol->setIsVariable(); + else if (Reference->getIsUnspecified()) + Symbol->setIsUnspecified(); else llvm_unreachable("Invalid symbol kind."); } diff --git a/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp b/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp index c062c15481da9..03bf394631c99 100644 --- a/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp +++ b/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp @@ -30,6 +30,9 @@ extern const char *TestMainArgv0; namespace { const char *DwarfClang = "test-dwarf-clang.o"; +// Two compile units: one declares `extern int foo_printf(const char *, ...);` +// and another one that defines the function. +const char *DwarfClangUnspecParams = "test-dwarf-clang-unspec-params.elf"; const char *DwarfGcc = "test-dwarf-gcc.o"; // Helper function to get the first compile unit. @@ -37,7 +40,7 @@ LVScopeCompileUnit *getFirstCompileUnit(LVScopeRoot *Root) { EXPECT_NE(Root, nullptr); const LVScopes *CompileUnits = Root->getScopes(); EXPECT_NE(CompileUnits, nullptr); - EXPECT_EQ(CompileUnits->size(), 1u); + EXPECT_GT(CompileUnits->size(), 0u); LVScopes::const_iterator Iter = CompileUnits->begin(); EXPECT_NE(Iter, nullptr); @@ -124,6 +127,36 @@ void checkElementProperties(LVReader *Reader) { ASSERT_EQ(Lines->size(), 0x12u); } +// Check proper handling of DW_AT_unspecified_parameters in +// LVScope::addMissingElements(). +void checkUnspecifiedParameters(LVReader *Reader) { + LVScopeRoot *Root = Reader->getScopesRoot(); + LVScopeCompileUnit *CompileUnit = getFirstCompileUnit(Root); + + EXPECT_EQ(Root->getFileFormatName(), "elf64-x86-64"); + EXPECT_EQ(Root->getName(), DwarfClangUnspecParams); + + const LVPublicNames &PublicNames = CompileUnit->getPublicNames(); + ASSERT_EQ(PublicNames.size(), 1u); + + LVPublicNames::const_iterator IterNames = PublicNames.cbegin(); + LVScope *Function = (*IterNames).first; + EXPECT_EQ(Function->getName(), "foo_printf"); + const LVElements *Elements = Function->getChildren(); + ASSERT_NE(Elements, nullptr); + // foo_printf is a variadic function whose prototype is + // `int foo_printf(const char *, ...)`, where the '...' is represented by a + // DW_TAG_unspecified_parameters, i.e. we expect to find at least one child + // for which getIsUnspecified() returns true. + EXPECT_EQ(std::any_of( + Elements->begin(), Elements->end(), + [](const LVElement *elt) { + return elt->getIsSymbol() && + static_cast(elt)->getIsUnspecified(); + }), + true); +} + // Check the logical elements selection. void checkElementSelection(LVReader *Reader) { LVScopeRoot *Root = Reader->getScopesRoot(); @@ -253,6 +286,7 @@ void elementProperties(SmallString<128> &InputsDir) { ReaderOptions.setAttributePublics(); ReaderOptions.setAttributeRange(); ReaderOptions.setAttributeLocation(); + ReaderOptions.setAttributeInserted(); ReaderOptions.setPrintAll(); ReaderOptions.resolveDependencies(); @@ -264,6 +298,9 @@ void elementProperties(SmallString<128> &InputsDir) { std::unique_ptr Reader = createReader(ReaderHandler, InputsDir, DwarfClang); checkElementProperties(Reader.get()); + + Reader = createReader(ReaderHandler, InputsDir, DwarfClangUnspecParams); + checkUnspecifiedParameters(Reader.get()); } // Logical elements selection. diff --git a/llvm/unittests/DebugInfo/LogicalView/Inputs/test-dwarf-clang-unspec-params.elf b/llvm/unittests/DebugInfo/LogicalView/Inputs/test-dwarf-clang-unspec-params.elf new file mode 100755 index 0000000000000000000000000000000000000000..67c6e71fbf7b93f456b519d2b75f72a7d6b64fb7 GIT binary patch literal 16800 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 literal 0 HcmV?d00001