forked from OSchip/llvm-project
[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:
parent
a4cc895aee
commit
01bb3b07c3
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue