summaryrefslogtreecommitdiffstats
path: root/llvm/lib/DebugInfo
diff options
context:
space:
mode:
authorEvgenii Stepanov <eugenis@google.com>2019-11-26 17:34:04 -0800
committerEvgenii Stepanov <eugenis@google.com>2019-12-20 10:36:14 -0800
commitb538a2aa071485a1fc13a8ef583d31db3381fec0 (patch)
tree61353c81333dd6a6f10c01f0d380441bde109072 /llvm/lib/DebugInfo
parent02a6b0bc3b54571f890a531e8c16b4c1173c55d0 (diff)
downloadbcm5719-llvm-b538a2aa071485a1fc13a8ef583d31db3381fec0.tar.gz
bcm5719-llvm-b538a2aa071485a1fc13a8ef583d31db3381fec0.zip
llvm-symbolizer: support DW_FORM_loclistx locations.
Summary: With -gdwarf-5 local variable locations are emitted as DW_FORM_loclistx form instead of the regular DW_FORM_sec_offset. Teach DWARFDie::getLocations to understand the new format and use it in llvm-symbolizer "FRAME" command. Reviewers: pcc, jdoerfert Subscribers: srhines, aprantl, hiraditya, rupprecht, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D70756
Diffstat (limited to 'llvm/lib/DebugInfo')
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFContext.cpp44
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDie.cpp14
2 files changed, 27 insertions, 31 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index b268d2e6aef..e452c7636b1 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -1077,33 +1077,6 @@ getExpressionFrameOffset(ArrayRef<uint8_t> Expr,
return None;
}
-static Optional<int64_t>
-getLocationFrameOffset(DWARFCompileUnit *CU, DWARFFormValue &FormValue,
- Optional<unsigned> FrameBaseReg) {
- if (Optional<ArrayRef<uint8_t>> Location = FormValue.getAsBlock()) {
- return getExpressionFrameOffset(*Location, FrameBaseReg);
- } else if (FormValue.isFormClass(DWARFFormValue::FC_SectionOffset)) {
- uint64_t Offset = *FormValue.getAsSectionOffset();
- const DWARFLocationTable &LocTable = CU->getLocationTable();
- Optional<int64_t> FrameOffset;
- Error E = LocTable.visitLocationList(
- &Offset, [&](const DWARFLocationEntry &Entry) {
- if (Entry.Kind == dwarf::DW_LLE_base_address ||
- Entry.Kind == dwarf::DW_LLE_base_addressx ||
- Entry.Kind == dwarf::DW_LLE_end_of_list) {
- return true;
- }
- if ((FrameOffset = getExpressionFrameOffset(Entry.Loc, FrameBaseReg)))
- return false;
- return true;
- });
- if (E)
- return None;
- return FrameOffset;
- }
- return None;
-}
-
void DWARFContext::addLocalsForDie(DWARFCompileUnit *CU, DWARFDie Subprogram,
DWARFDie Die, std::vector<DILocal> &Result) {
if (Die.getTag() == DW_TAG_variable ||
@@ -1119,8 +1092,21 @@ void DWARFContext::addLocalsForDie(DWARFCompileUnit *CU, DWARFDie Subprogram,
(*Expr)[0] <= DW_OP_reg31) {
FrameBaseReg = (*Expr)[0] - DW_OP_reg0;
}
- if (auto LocationAttr = Die.find(DW_AT_location))
- Local.FrameOffset = getLocationFrameOffset(CU, *LocationAttr, FrameBaseReg);
+
+ if (Expected<std::vector<DWARFLocationExpression>> Loc =
+ Die.getLocations(DW_AT_location)) {
+ for (const auto &Entry : *Loc) {
+ if (Optional<int64_t> FrameOffset =
+ getExpressionFrameOffset(Entry.Expr, FrameBaseReg)) {
+ Local.FrameOffset = *FrameOffset;
+ break;
+ }
+ }
+ } else {
+ // FIXME: missing DW_AT_location is OK here, but other errors should be
+ // reported to the user.
+ consumeError(Loc.takeError());
+ }
if (auto TagOffsetAttr = Die.find(DW_AT_LLVM_tag_offset))
Local.TagOffset = TagOffsetAttr->getAsUnsignedConstant();
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
index 4b86359c04e..558d8006501 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -495,8 +495,18 @@ DWARFDie::getLocations(dwarf::Attribute Attr) const {
return createStringError(inconvertibleErrorCode(), "No %s",
dwarf::AttributeString(Attr).data());
- if (Optional<uint64_t> Off = Location->getAsSectionOffset())
- return U->findLoclistFromOffset(*Off);
+ if (Optional<uint64_t> Off = Location->getAsSectionOffset()) {
+ uint64_t Offset = *Off;
+
+ if (Location->getForm() == DW_FORM_loclistx) {
+ if (auto LoclistOffset = U->getLoclistOffset(Offset))
+ Offset = *LoclistOffset;
+ else
+ return createStringError(inconvertibleErrorCode(),
+ "Loclist table not found");
+ }
+ return U->findLoclistFromOffset(Offset);
+ }
if (Optional<ArrayRef<uint8_t>> Expr = Location->getAsBlock()) {
return DWARFLocationExpressionsVector{
OpenPOWER on IntegriCloud