[DWARFVerifier] Use the new location list api

Summary:
Instead of going to the debug_loc section directly, use new
DWARFDie::getLocations instead. This means that the code will now
automatically support debug_loclists sections.

This is the last usage of the old debug_loc methods, and they can now be
removed.

Reviewers: dblaikie, JDevlieghere, aprantl, SouraVX

Subscribers: hiraditya, probinson, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D70534
This commit is contained in:
Pavel Labath 2019-11-08 15:33:54 +01:00
parent a4cc895aee
commit 01bb3b07c3
5 changed files with 32 additions and 87 deletions

View File

@ -101,18 +101,10 @@ public:
void dump(raw_ostream &OS, const MCRegisterInfo *RegInfo, DIDumpOptions DumpOpts,
Optional<uint64_t> Offset) const;
/// Parse the debug_loc section.
void parse();
/// Return the location list at the given offset or nullptr.
LocationList const *getLocationListAtOffset(uint64_t Offset) const;
Error visitLocationList(
uint64_t *Offset,
function_ref<bool(const DWARFLocationEntry &)> Callback) const override;
Expected<LocationList> parseOneLocationList(uint64_t *Offset);
protected:
void dumpRawEntry(const DWARFLocationEntry &Entry, raw_ostream &OS,
unsigned Indent) const override;

View File

@ -746,7 +746,6 @@ const DWARFDebugLoc *DWARFContext::getDebugLoc() {
getUnitAtIndex(0)->getAddressByteSize())
: DWARFDataExtractor("", isLittleEndian(), 0);
Loc.reset(new DWARFDebugLoc(std::move(LocData)));
Loc->parse();
return Loc.get();
}

View File

@ -166,15 +166,6 @@ Error DWARFLocationTable::visitAbsoluteLocationList(
});
}
DWARFDebugLoc::LocationList const *
DWARFDebugLoc::getLocationListAtOffset(uint64_t Offset) const {
auto It = partition_point(
Locations, [=](const LocationList &L) { return L.Offset < Offset; });
if (It != Locations.end() && It->Offset == Offset)
return &(*It);
return nullptr;
}
void DWARFDebugLoc::dump(raw_ostream &OS, const MCRegisterInfo *MRI,
DIDumpOptions DumpOpts,
Optional<uint64_t> DumpOffset) const {
@ -235,32 +226,6 @@ Error DWARFDebugLoc::visitLocationList(
return Error::success();
}
Expected<DWARFDebugLoc::LocationList>
DWARFDebugLoc::parseOneLocationList(uint64_t *Offset) {
LocationList LL;
LL.Offset = *Offset;
Error E = visitLocationList(Offset, [&](const DWARFLocationEntry &E) {
LL.Entries.push_back(E);
return true;
});
if (E)
return std::move(E);
return std::move(LL);
}
void DWARFDebugLoc::parse() {
uint64_t Offset = 0;
while (Offset < Data.getData().size()) {
if (auto LL = parseOneLocationList(&Offset))
Locations.push_back(std::move(*LL));
else {
logAllUnhandledErrors(LL.takeError(), WithColor::error());
break;
}
}
}
void DWARFDebugLoc::dumpRawEntry(const DWARFLocationEntry &Entry,
raw_ostream &OS, unsigned Indent) const {
uint64_t Value0, Value1;

View File

@ -468,27 +468,21 @@ unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die,
ReportError("DIE has invalid DW_AT_stmt_list encoding:");
break;
case DW_AT_location: {
auto VerifyLocationExpr = [&](ArrayRef<uint8_t> D) {
if (Expected<std::vector<DWARFLocationExpression>> Loc =
Die.getLocations(DW_AT_location)) {
DWARFUnit *U = Die.getDwarfUnit();
DataExtractor Data(toStringRef(D), DCtx.isLittleEndian(), 0);
DWARFExpression Expression(Data, U->getVersion(),
U->getAddressByteSize());
bool Error = llvm::any_of(Expression, [](DWARFExpression::Operation &Op) {
return Op.isError();
});
if (Error || !Expression.verify(U))
ReportError("DIE contains invalid DWARF expression:");
};
if (Optional<ArrayRef<uint8_t>> Expr = AttrValue.Value.getAsBlock()) {
// Verify inlined location.
VerifyLocationExpr(*Expr);
} else if (auto LocOffset = AttrValue.Value.getAsSectionOffset()) {
// Verify location list.
if (auto DebugLoc = DCtx.getDebugLoc())
if (auto LocList = DebugLoc->getLocationListAtOffset(*LocOffset))
for (const auto &Entry : LocList->Entries)
VerifyLocationExpr(Entry.Loc);
}
for (const auto &Entry : *Loc) {
DataExtractor Data(toStringRef(Entry.Expr), DCtx.isLittleEndian(), 0);
DWARFExpression Expression(Data, U->getVersion(),
U->getAddressByteSize());
bool Error = any_of(Expression, [](DWARFExpression::Operation &Op) {
return Op.isError();
});
if (Error || !Expression.verify(U))
ReportError("DIE contains invalid DWARF expression:");
}
} else
ReportError(toString(Loc.takeError()));
break;
}
case DW_AT_specification:
@ -1278,36 +1272,24 @@ unsigned DWARFVerifier::verifyNameIndexEntries(
}
static bool isVariableIndexable(const DWARFDie &Die, DWARFContext &DCtx) {
Optional<DWARFFormValue> Location = Die.findRecursively(DW_AT_location);
if (!Location)
Expected<std::vector<DWARFLocationExpression>> Loc =
Die.getLocations(DW_AT_location);
if (!Loc) {
consumeError(Loc.takeError());
return false;
auto ContainsInterestingOperators = [&](ArrayRef<uint8_t> D) {
DWARFUnit *U = Die.getDwarfUnit();
DataExtractor Data(toStringRef(D), DCtx.isLittleEndian(), U->getAddressByteSize());
}
DWARFUnit *U = Die.getDwarfUnit();
for (const auto &Entry : *Loc) {
DataExtractor Data(toStringRef(Entry.Expr), DCtx.isLittleEndian(),
U->getAddressByteSize());
DWARFExpression Expression(Data, U->getVersion(), U->getAddressByteSize());
return any_of(Expression, [](DWARFExpression::Operation &Op) {
bool IsInteresting = any_of(Expression, [](DWARFExpression::Operation &Op) {
return !Op.isError() && (Op.getCode() == DW_OP_addr ||
Op.getCode() == DW_OP_form_tls_address ||
Op.getCode() == DW_OP_GNU_push_tls_address);
});
};
if (Optional<ArrayRef<uint8_t>> Expr = Location->getAsBlock()) {
// Inlined location.
if (ContainsInterestingOperators(*Expr))
if (IsInteresting)
return true;
} else if (Optional<uint64_t> Offset = Location->getAsSectionOffset()) {
// Location list.
if (const DWARFDebugLoc *DebugLoc = DCtx.getDebugLoc()) {
if (const DWARFDebugLoc::LocationList *LocList =
DebugLoc->getLocationListAtOffset(*Offset)) {
if (any_of(LocList->Entries, [&](const DWARFLocationEntry &E) {
return ContainsInterestingOperators(E.Loc);
}))
return true;
}
}
}
return false;
}

View File

@ -29,6 +29,10 @@
.byte 1 # DW_CHILDREN_yes
.byte 37 # DW_AT_producer
.byte 8 # DW_FORM_string
.byte 17 # DW_AT_low_pc
.byte 1 # DW_FORM_addr
.byte 18 # DW_AT_high_pc
.byte 6 # DW_FORM_data4
.byte 0 # EOM(1)
.byte 0 # EOM(2)
@ -102,6 +106,7 @@
.byte 0 # EOM(3)
.section .debug_info,"",@progbits
.Lcu_begin0:
.long .Lcu_end0-.Lcu_start0 # Length of Unit
.Lcu_start0:
@ -110,6 +115,8 @@
.byte 8 # Address Size (in bytes)
.byte 1 # Abbrev [1] DW_TAG_compile_unit
.asciz "hand-written DWARF" # DW_AT_producer
.quad 0x0 # DW_AT_low_pc
.long 0x100 # DW_AT_high_pc
.byte 4 # Abbrev [4] DW_TAG_namespace
.asciz "namesp" # DW_AT_name