[dwarfdump] Pretty print location expressions and location lists
Summary:
Based on Fred's patch here: https://reviews.llvm.org/D6771
I can't seem to commandeer the old review, so I'm creating a new one.
With that change the locations exrpessions are pretty printed inline in the
DIE tree. The output looks like this for debug_loc entries:
DW_AT_location [DW_FORM_data4] (0x00000000
0x0000000000000001 - 0x000000000000000b: DW_OP_consts +3
0x000000000000000b - 0x0000000000000012: DW_OP_consts +7
0x0000000000000012 - 0x000000000000001b: DW_OP_reg0 RAX, DW_OP_piece 0x4
0x000000000000001b - 0x0000000000000024: DW_OP_breg5 RDI+0)
And like this for debug_loc.dwo entries:
DW_AT_location [DW_FORM_sec_offset] (0x00000000
Addr idx 2 (w/ length 190): DW_OP_consts +0, DW_OP_stack_value
Addr idx 3 (w/ length 23): DW_OP_reg0 RAX, DW_OP_piece 0x4)
Simple locations without ranges are printed inline:
DW_AT_location [DW_FORM_block1] (DW_OP_reg4 RSI, DW_OP_piece 0x4, DW_OP_bit_piece 0x20 0x0)
The debug_loc(.dwo) dumping in changed accordingly to factor the code.
Reviewers: dblaikie, aprantl, friss
Subscribers: mgorny, javed.absar, hiraditya, llvm-commits, JDevlieghere
Differential Revision: https://reviews.llvm.org/D37123
llvm-svn: 312042
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
index 9ad4b52..261a5ca 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -16,6 +16,7 @@
#include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
+#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
#include "llvm/Object/ObjectFile.h"
@@ -81,6 +82,47 @@
}
}
+static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue,
+ DWARFUnit *U, unsigned Indent) {
+ DWARFContext &Ctx = U->getContext();
+ const DWARFObject &Obj = Ctx.getDWARFObj();
+ const MCRegisterInfo *MRI = Ctx.getRegisterInfo();
+ if (FormValue.isFormClass(DWARFFormValue::FC_Block) ||
+ FormValue.isFormClass(DWARFFormValue::FC_Exprloc)) {
+ ArrayRef<uint8_t> Expr = *FormValue.getAsBlock();
+ DataExtractor Data(StringRef((const char *)Expr.data(), Expr.size()),
+ Ctx.isLittleEndian(), 0);
+ DWARFExpression(Data, U->getVersion(), U->getAddressByteSize())
+ .print(OS, MRI);
+ return;
+ }
+
+ FormValue.dump(OS);
+ if (FormValue.isFormClass(DWARFFormValue::FC_SectionOffset)) {
+ const DWARFSection &LocSection = Obj.getLocSection();
+ const DWARFSection &LocDWOSection = Obj.getLocDWOSection();
+ uint32_t Offset = *FormValue.getAsSectionOffset();
+
+ if (!LocSection.Data.empty()) {
+ DWARFDebugLoc DebugLoc;
+ DWARFDataExtractor Data(Obj, LocSection, Ctx.isLittleEndian(),
+ Obj.getAddressSize());
+ auto LL = DebugLoc.parseOneLocationList(Data, &Offset);
+ if (LL)
+ LL->dump(OS, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI, Indent);
+ else
+ OS << "error extracting location list.";
+ } else if (!LocDWOSection.Data.empty()) {
+ DataExtractor Data(LocDWOSection.Data, Ctx.isLittleEndian(), 0);
+ auto LL = DWARFDebugLocDWO::parseOneLocationList(Data, &Offset);
+ if (LL)
+ LL->dump(OS, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI, Indent);
+ else
+ OS << "error extracting location list.";
+ }
+ }
+}
+
static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
uint32_t *OffsetPtr, dwarf::Attribute Attr,
dwarf::Form Form, unsigned Indent,
@@ -129,6 +171,9 @@
WithColor(OS, Color) << Name;
else if (Attr == DW_AT_decl_line || Attr == DW_AT_call_line)
OS << *formValue.getAsUnsignedConstant();
+ else if (Attr == DW_AT_location || Attr == DW_AT_frame_base ||
+ Attr == DW_AT_data_member_location)
+ dumpLocation(OS, formValue, U, sizeof(BaseIndent) + Indent + 4);
else
formValue.dump(OS, DumpOpts);