diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h @@ -122,6 +122,10 @@ 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/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp b/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp @@ -387,6 +387,27 @@ 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("; + prettyPrintDWARFExpr(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) { uint64_t DwarfRegNum = Opcode - dwarf::DW_OP_reg0; diff --git a/llvm/test/tools/llvm-objdump/ARM/debug-vars-entry-value.s b/llvm/test/tools/llvm-objdump/ARM/debug-vars-entry-value.s new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-objdump/ARM/debug-vars-entry-value.s @@ -0,0 +1,241 @@ +# RUN: llvm-mc --triple armv8a--none-eabi < %s --filetype=obj | \ +# RUN: llvm-objdump - -d --debug-vars --no-show-raw-insn | \ +# RUN: FileCheck %s + +## Check that the --debug-vars option works for the DW_OP_entry_value opcode, +## which also requires the DW_OP_stack_value opcode. + +## Generated with this compile command and source code: +## arm-none-eabi-gcc -march=armv7-a -c debug.c -O1 -g -S -o - -gno-as-locview-support + +## int foo(int a, int b) { +## return a + b; +## } + +# CHECK: 00000000 foo: +# CHECK-NEXT: ┠─ a = R0 +# CHECK-NEXT: ┃ ┌─ a = entry(R0) +# CHECK-NEXT: ┃ │ ┠─ b = R1 +# CHECK-NEXT: 0: add r0, r0, r1 ┻ ╈ ┃ +# CHECK-NEXT: 4: bx lr ┻ ┻ + + .arch armv7-a + .eabi_attribute 20, 1 + .eabi_attribute 21, 1 + .eabi_attribute 23, 3 + .eabi_attribute 24, 1 + .eabi_attribute 25, 1 + .eabi_attribute 26, 1 + .eabi_attribute 30, 1 + .eabi_attribute 34, 1 + .eabi_attribute 18, 4 + .file "debug.c" + .text +.Ltext0: + .cfi_sections .debug_frame + .align 2 + .global foo + .syntax unified + .arm + .fpu softvfp + .type foo, %function +foo: +.LFB0: + .file 1 "debug.c" + .loc 1 1 23 + .cfi_startproc + @ args = 0, pretend = 0, frame = 0 + @ frame_needed = 0, uses_anonymous_args = 0 + @ link register save eliminated. +.LVL0: + .loc 1 2 3 + .loc 1 3 1 is_stmt 0 + add r0, r0, r1 +.LVL1: + bx lr + .cfi_endproc +.LFE0: + .size foo, .-foo +.Letext0: + .section .debug_info,"",%progbits +.Ldebug_info0: + .4byte 0x5e + .2byte 0x4 + .4byte .Ldebug_abbrev0 + .byte 0x4 + .uleb128 0x1 + .4byte .LASF0 + .byte 0xc + .4byte .LASF1 + .4byte .LASF2 + .4byte .Ltext0 + .4byte .Letext0-.Ltext0 + .4byte .Ldebug_line0 + .uleb128 0x2 + .ascii "foo\000" + .byte 0x1 + .byte 0x1 + .byte 0x5 + .4byte 0x5a + .4byte .LFB0 + .4byte .LFE0-.LFB0 + .uleb128 0x1 + .byte 0x9c + .4byte 0x5a + .uleb128 0x3 + .ascii "a\000" + .byte 0x1 + .byte 0x1 + .byte 0xd + .4byte 0x5a + .4byte .LLST0 + .uleb128 0x4 + .ascii "b\000" + .byte 0x1 + .byte 0x1 + .byte 0x14 + .4byte 0x5a + .uleb128 0x1 + .byte 0x51 + .byte 0 + .uleb128 0x5 + .byte 0x4 + .byte 0x5 + .ascii "int\000" + .byte 0 + .section .debug_abbrev,"",%progbits +.Ldebug_abbrev0: + .uleb128 0x1 + .uleb128 0x11 + .byte 0x1 + .uleb128 0x25 + .uleb128 0xe + .uleb128 0x13 + .uleb128 0xb + .uleb128 0x3 + .uleb128 0xe + .uleb128 0x1b + .uleb128 0xe + .uleb128 0x11 + .uleb128 0x1 + .uleb128 0x12 + .uleb128 0x6 + .uleb128 0x10 + .uleb128 0x17 + .byte 0 + .byte 0 + .uleb128 0x2 + .uleb128 0x2e + .byte 0x1 + .uleb128 0x3f + .uleb128 0x19 + .uleb128 0x3 + .uleb128 0x8 + .uleb128 0x3a + .uleb128 0xb + .uleb128 0x3b + .uleb128 0xb + .uleb128 0x39 + .uleb128 0xb + .uleb128 0x27 + .uleb128 0x19 + .uleb128 0x49 + .uleb128 0x13 + .uleb128 0x11 + .uleb128 0x1 + .uleb128 0x12 + .uleb128 0x6 + .uleb128 0x40 + .uleb128 0x18 + .uleb128 0x2117 + .uleb128 0x19 + .uleb128 0x1 + .uleb128 0x13 + .byte 0 + .byte 0 + .uleb128 0x3 + .uleb128 0x5 + .byte 0 + .uleb128 0x3 + .uleb128 0x8 + .uleb128 0x3a + .uleb128 0xb + .uleb128 0x3b + .uleb128 0xb + .uleb128 0x39 + .uleb128 0xb + .uleb128 0x49 + .uleb128 0x13 + .uleb128 0x2 + .uleb128 0x17 + .byte 0 + .byte 0 + .uleb128 0x4 + .uleb128 0x5 + .byte 0 + .uleb128 0x3 + .uleb128 0x8 + .uleb128 0x3a + .uleb128 0xb + .uleb128 0x3b + .uleb128 0xb + .uleb128 0x39 + .uleb128 0xb + .uleb128 0x49 + .uleb128 0x13 + .uleb128 0x2 + .uleb128 0x18 + .byte 0 + .byte 0 + .uleb128 0x5 + .uleb128 0x24 + .byte 0 + .uleb128 0xb + .uleb128 0xb + .uleb128 0x3e + .uleb128 0xb + .uleb128 0x3 + .uleb128 0x8 + .byte 0 + .byte 0 + .byte 0 + .section .debug_loc,"",%progbits +.Ldebug_loc0: +.LLST0: + .4byte .LVL0-.Ltext0 + .4byte .LVL1-.Ltext0 + .2byte 0x1 + .byte 0x50 + .4byte .LVL1-.Ltext0 + .4byte .LFE0-.Ltext0 + .2byte 0x4 + .byte 0xf3 + .uleb128 0x1 + .byte 0x50 + .byte 0x9f + .4byte 0 + .4byte 0 + .section .debug_aranges,"",%progbits + .4byte 0x1c + .2byte 0x2 + .4byte .Ldebug_info0 + .byte 0x4 + .byte 0 + .2byte 0 + .2byte 0 + .4byte .Ltext0 + .4byte .Letext0-.Ltext0 + .4byte 0 + .4byte 0 + .section .debug_line,"",%progbits +.Ldebug_line0: + .section .debug_str,"MS",%progbits,1 +.LASF0: + .ascii "GNU C17 10.0.0 20190731 (experimental) -mfloat-abi=" + .ascii "soft -marm -march=armv7-a -g -gno-as-locview-suppor" + .ascii "t -O1\000" +.LASF2: + .ascii "/work/scratch\000" +.LASF1: + .ascii "debug.c\000" + .ident "GCC: (fsf-trunk.1961) 10.0.0 20190731 (experimental)"