summaryrefslogtreecommitdiffstats
path: root/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
diff options
context:
space:
mode:
authorGeorge Rimar <grimar@accesssoftek.com>2017-10-27 10:42:04 +0000
committerGeorge Rimar <grimar@accesssoftek.com>2017-10-27 10:42:04 +0000
commit144e4c5a32007bb2fe7b18930dcc4d806ef4f92f (patch)
tree8b87dd498dd0b4639bcfd9fc4c3dd7f2f74c57ee /llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
parent7f92294e9b6a00784d75587800f409af23072983 (diff)
downloadbcm5719-llvm-144e4c5a32007bb2fe7b18930dcc4d806ef4f92f.tar.gz
bcm5719-llvm-144e4c5a32007bb2fe7b18930dcc4d806ef4f92f.zip
[llvm-dwarfdump] - Teach verifier to report broken DWARF expressions.
Patch improves next things: * Fixes assert/crash in getOpDesc when giving it a invalid expression op code. * DWARFExpression::print() called DWARFExpression::Operation::getEndOffset() which returned and used uninitialized field EndOffset. Patch fixes that. * Teaches verifier to verify DW_AT_location and error out on broken expressions. Differential revision: https://reviews.llvm.org/D39294 llvm-svn: 316756
Diffstat (limited to 'llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp')
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp64
1 files changed, 38 insertions, 26 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
index b10697c9a31..f27c849456b 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
@@ -13,9 +13,11 @@
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
+#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
#include "llvm/DebugInfo/DWARF/DWARFSection.h"
#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
+#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/raw_ostream.h"
#include <map>
#include <set>
@@ -377,45 +379,55 @@ unsigned DWARFVerifier::verifyDieRanges(const DWARFDie &Die,
unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die,
DWARFAttribute &AttrValue) {
- const DWARFObject &DObj = DCtx.getDWARFObj();
unsigned NumErrors = 0;
+ auto ReportError = [&](const Twine &TitleMsg) {
+ ++NumErrors;
+ error() << TitleMsg << '\n';
+ Die.dump(OS, 0, DumpOpts);
+ OS << "\n";
+ };
+
+ const DWARFObject &DObj = DCtx.getDWARFObj();
const auto Attr = AttrValue.Attr;
switch (Attr) {
case DW_AT_ranges:
// Make sure the offset in the DW_AT_ranges attribute is valid.
if (auto SectionOffset = AttrValue.Value.getAsSectionOffset()) {
- if (*SectionOffset >= DObj.getRangeSection().Data.size()) {
- ++NumErrors;
- error() << "DW_AT_ranges offset is beyond .debug_ranges "
- "bounds:\n";
- Die.dump(OS, 0, DumpOpts);
- OS << "\n";
- }
- } else {
- ++NumErrors;
- error() << "DIE has invalid DW_AT_ranges encoding:\n";
- Die.dump(OS, 0, DumpOpts);
- OS << "\n";
+ if (*SectionOffset >= DObj.getRangeSection().Data.size())
+ ReportError("DW_AT_ranges offset is beyond .debug_ranges bounds:");
+ break;
}
+ ReportError("DIE has invalid DW_AT_ranges encoding:");
break;
case DW_AT_stmt_list:
// Make sure the offset in the DW_AT_stmt_list attribute is valid.
if (auto SectionOffset = AttrValue.Value.getAsSectionOffset()) {
- if (*SectionOffset >= DObj.getLineSection().Data.size()) {
- ++NumErrors;
- error() << "DW_AT_stmt_list offset is beyond .debug_line "
- "bounds: "
- << format("0x%08" PRIx64, *SectionOffset) << "\n";
- Die.dump(OS, 0, DumpOpts);
- OS << "\n";
- }
- } else {
- ++NumErrors;
- error() << "DIE has invalid DW_AT_stmt_list encoding:\n";
- Die.dump(OS, 0, DumpOpts);
- OS << "\n";
+ if (*SectionOffset >= DObj.getLineSection().Data.size())
+ ReportError("DW_AT_stmt_list offset is beyond .debug_line bounds: " +
+ llvm::formatv("{0:x16}", *SectionOffset));
+ break;
}
+ ReportError("DIE has invalid DW_AT_stmt_list encoding:");
break;
+ case DW_AT_location: {
+ Optional<ArrayRef<uint8_t>> Expr = AttrValue.Value.getAsBlock();
+ if (!Expr) {
+ ReportError("DIE has invalid DW_AT_location encoding:");
+ break;
+ }
+
+ DWARFUnit *U = Die.getDwarfUnit();
+ DataExtractor Data(
+ StringRef(reinterpret_cast<const char *>(Expr->data()), Expr->size()),
+ DCtx.isLittleEndian(), 0);
+ DWARFExpression Expression(Data, U->getVersion(), U->getAddressByteSize());
+ bool Error = llvm::any_of(Expression, [](DWARFExpression::Operation &Op) {
+ return Op.isError();
+ });
+ if (Error)
+ ReportError("DIE contains invalid DWARF expression:");
+ break;
+ }
default:
break;
OpenPOWER on IntegriCloud