From 7e201bfc21c03e116c7ed1e2a4bb70838c190da6 Mon Sep 17 00:00:00 2001 From: Oliver Stannard Date: Wed, 19 Feb 2020 12:34:12 +0000 Subject: [PATCH] [llvm-objdump] Add entry_value and stack_value opcodes Add the DW_OP_entry_value and DW_OP_stack_value opcodes to the DWARF expression printer. Differential revision: https://reviews.llvm.org/D74843 --- .../llvm/DebugInfo/DWARF/DWARFExpression.h | 4 ++++ lib/DebugInfo/DWARF/DWARFExpression.cpp | 21 +++++++++++++++++++ .../DWARFExpressionCompactPrinterTest.cpp | 15 +++++++++++++ 3 files changed, 40 insertions(+) diff --git a/include/llvm/DebugInfo/DWARF/DWARFExpression.h b/include/llvm/DebugInfo/DWARF/DWARFExpression.h index 1aff2624990..edfa68d49a6 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFExpression.h +++ b/include/llvm/DebugInfo/DWARF/DWARFExpression.h @@ -126,6 +126,10 @@ public: return Op; } + iterator skipBytes(uint64_t Add) { + return iterator(Expr, Op.EndOffset + Add); + } + // Comparison operators are provided out of line. friend bool operator==(const iterator &, const iterator &); }; diff --git a/lib/DebugInfo/DWARF/DWARFExpression.cpp b/lib/DebugInfo/DWARF/DWARFExpression.cpp index ffe2ef7532b..de5e11e084f 100644 --- a/lib/DebugInfo/DWARF/DWARFExpression.cpp +++ b/lib/DebugInfo/DWARF/DWARFExpression.cpp @@ -424,6 +424,27 @@ static bool printCompactDWARFExpr(raw_ostream &OS, DWARFExpression::iterator I, S << format("%+" PRId64, Offset); break; } + case dwarf::DW_OP_entry_value: + case dwarf::DW_OP_GNU_entry_value: { + // DW_OP_entry_value contains a sub-expression which must be rendered + // separately. + uint64_t SubExprLength = Op.getRawOperand(0); + DWARFExpression::iterator SubExprEnd = I.skipBytes(SubExprLength); + ++I; + raw_svector_ostream S(Stack.emplace_back().String); + S << "entry("; + printCompactDWARFExpr(S, I, SubExprEnd, MRI); + S << ")"; + I = SubExprEnd; + continue; + } + case dwarf::DW_OP_stack_value: { + // The top stack entry should be treated as the actual value of tne + // variable, rather than the address of the variable in memory. + assert(!Stack.empty()); + Stack.back().Kind = PrintedExpr::Value; + break; + } default: if (Opcode >= dwarf::DW_OP_reg0 && Opcode <= dwarf::DW_OP_reg31) { // DW_OP_reg: A register, with the register num implied by the diff --git a/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp b/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp index 4cdd6079cdc..6fa97794218 100644 --- a/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp +++ b/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp @@ -98,3 +98,18 @@ TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_breg0_negative) { TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_bregx) { TestExprPrinter({DW_OP_bregx, 0x0d, 0x28}, "[SP+40]"); } + +TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_stack_value) { + TestExprPrinter({DW_OP_breg13, 0x04, DW_OP_stack_value}, "SP+4"); +} + +TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_entry_value) { + TestExprPrinter({DW_OP_entry_value, 0x01, DW_OP_reg0, DW_OP_stack_value}, + "entry(R0)"); +} + +TEST_F(DWARFExpressionCompactPrinterTest, Test_OP_entry_value_mem) { + TestExprPrinter( + {DW_OP_entry_value, 0x02, DW_OP_breg13, 0x10, DW_OP_stack_value}, + "entry([SP+16])"); +}