-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[llvm-debuginfo-analyzer] Fix a couple of unhandled DWARF situations leading to a crash #137221
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[llvm-debuginfo-analyzer] Fix a couple of unhandled DWARF situations leading to a crash #137221
Conversation
@llvm/pr-subscribers-llvm-binary-utilities @llvm/pr-subscribers-debuginfo Author: Javier Lopez-Gomez (jalopezg-git) ChangesThis pull request fixes a couple of unhandled situations in DWARF input leading to a crash. Specifically,
FYI, @CarlosAlbertoEnciso. I believe this patchset is ready; feel free to start review. Full diff: https://github.com/llvm/llvm-project/pull/137221.diff 4 Files Affected:
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/lib/DebugInfo/LogicalView/Readers/LVBinaryReader.cpp b/llvm/lib/DebugInfo/LogicalView/Readers/LVBinaryReader.cpp
index ad14baa0c9269..b12208c53b8e3 100644
--- a/llvm/lib/DebugInfo/LogicalView/Readers/LVBinaryReader.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Readers/LVBinaryReader.cpp
@@ -433,6 +433,13 @@ Error LVBinaryReader::createInstructions(LVScope *Scope,
ArrayRef<uint8_t> 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 Error::success();
+ }
uint8_t const *Begin = Bytes.data() + Offset;
uint8_t const *End = Bytes.data() + Offset + Size;
diff --git a/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp b/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp
index c062c15481da9..7262da634d18d 100644
--- a/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp
+++ b/llvm/unittests/DebugInfo/LogicalView/DWARFReaderTest.cpp
@@ -30,6 +30,7 @@ extern const char *TestMainArgv0;
namespace {
const char *DwarfClang = "test-dwarf-clang.o";
+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 +38,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 +125,32 @@ 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);
+ EXPECT_EQ(std::any_of(
+ Elements->begin(), Elements->end(),
+ [](const LVElement *elt) {
+ return elt->getIsSymbol() &&
+ static_cast<const LVSymbol *>(elt)->getIsUnspecified();
+ }),
+ true);
+}
+
// Check the logical elements selection.
void checkElementSelection(LVReader *Reader) {
LVScopeRoot *Root = Reader->getScopesRoot();
@@ -253,6 +280,7 @@ void elementProperties(SmallString<128> &InputsDir) {
ReaderOptions.setAttributePublics();
ReaderOptions.setAttributeRange();
ReaderOptions.setAttributeLocation();
+ ReaderOptions.setAttributeInserted();
ReaderOptions.setPrintAll();
ReaderOptions.resolveDependencies();
@@ -264,6 +292,9 @@ void elementProperties(SmallString<128> &InputsDir) {
std::unique_ptr<LVReader> 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 0000000000000..67c6e71fbf7b9
Binary files /dev/null and b/llvm/unittests/DebugInfo/LogicalView/Inputs/test-dwarf-clang-unspec-params.elf differ
|
bd673db
to
4bc3d31
Compare
Using the
|
4bc3d31
to
eef3f71
Compare
eef3f71
to
278f4ae
Compare
…f unspecified parameters
278f4ae
to
acb83fc
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
@jalopezg-git With a minor change on the commit message (removed the stack trace) I have merged your patch. Thanks for fixing those issues. |
This pull request fixes a couple of unhandled situations in DWARF input leading to a crash. Specifically,
...
translates toDW_TAG_unspecified_parameters
), which is then followed by a definition,llvm_unreachable()
is hit inLVScope::addMissingElements()
.This is only visible in Debug builds (see stack trace below), but still.
test-dwarf-clang-unspec-params.elf
triggers this condition.LVBinaryReader::createInstructions()
does not check whetherOffset
lies within theBytes
ArrayRef. A specially crafted DWARF input can lead to this condition.FYI, @CarlosAlbertoEnciso. I believe this patchset is ready; feel free to start review.