diff options
| author | Evgenii Stepanov <eugenis@google.com> | 2019-11-26 17:34:04 -0800 |
|---|---|---|
| committer | Evgenii Stepanov <eugenis@google.com> | 2019-12-20 10:36:14 -0800 |
| commit | b538a2aa071485a1fc13a8ef583d31db3381fec0 (patch) | |
| tree | 61353c81333dd6a6f10c01f0d380441bde109072 /llvm/lib/DebugInfo | |
| parent | 02a6b0bc3b54571f890a531e8c16b4c1173c55d0 (diff) | |
| download | bcm5719-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.cpp | 44 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFDie.cpp | 14 |
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{ |

