namespace llvm {
class raw_ostream;
+class DWARFObject;
struct DWARFAddressRange {
uint64_t LowPC;
DWARFAddressRange() = default;
/// Used for unit testing.
- DWARFAddressRange(uint64_t LowPC, uint64_t HighPC, uint64_t SectionIndex = 0)
+ DWARFAddressRange(
+ uint64_t LowPC, uint64_t HighPC,
+ uint64_t SectionIndex = object::SectionedAddress::UndefSection)
: LowPC(LowPC), HighPC(HighPC), SectionIndex(SectionIndex) {}
/// Returns true if LowPC is smaller or equal to HighPC. This accounts for
return LowPC < RHS.HighPC && RHS.LowPC < HighPC;
}
- void dump(raw_ostream &OS, uint32_t AddressSize,
- DIDumpOptions DumpOpts = {}) const;
+ void dump(raw_ostream &OS, uint32_t AddressSize, DIDumpOptions DumpOpts = {},
+ const DWARFObject *Obj = nullptr) const;
};
static inline bool operator<(const DWARFAddressRange &LHS,
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
-
+#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
void DWARFAddressRange::dump(raw_ostream &OS, uint32_t AddressSize,
- DIDumpOptions DumpOpts) const {
+ DIDumpOptions DumpOpts,
+ const DWARFObject *Obj) const {
OS << (DumpOpts.DisplayRawContents ? " " : "[");
OS << format("0x%*.*" PRIx64 ", ", AddressSize * 2, AddressSize * 2, LowPC)
<< format("0x%*.*" PRIx64, AddressSize * 2, AddressSize * 2, HighPC);
OS << (DumpOpts.DisplayRawContents ? "" : ")");
+
+ if (Obj)
+ DWARFFormValue::dumpAddressSection(*Obj, OS, DumpOpts, SectionIndex);
}
raw_ostream &llvm::operator<<(raw_ostream &OS, const DWARFAddressRange &R) {
dumpDebugType(".debug_types.dwo", dwo_types_section_units());
}
+ DIDumpOptions LLDumpOpts = DumpOpts;
+ if (LLDumpOpts.Verbose)
+ LLDumpOpts.DisplayRawContents = true;
+
if (const auto *Off = shouldDump(Explicit, ".debug_loc", DIDT_ID_DebugLoc,
DObj->getLocSection().Data)) {
- getDebugLoc()->dump(OS, getRegisterInfo(), DumpOpts, *Off);
+ getDebugLoc()->dump(OS, getRegisterInfo(), LLDumpOpts, *Off);
}
if (const auto *Off =
shouldDump(Explicit, ".debug_loclists", DIDT_ID_DebugLoclists,
DObj->getLoclistsSection().Data)) {
DWARFDataExtractor Data(*DObj, DObj->getLoclistsSection(), isLittleEndian(),
0);
- dumpLoclistsSection(OS, DumpOpts, Data, getRegisterInfo(), *Off);
+ dumpLoclistsSection(OS, LLDumpOpts, Data, getRegisterInfo(), *Off);
}
if (const auto *Off =
shouldDump(ExplicitDWO, ".debug_loc.dwo", DIDT_ID_DebugLoc,
uint64_t Offset = **Off;
Loc.dumpLocationList(&Offset, OS,
/*BaseAddr=*/None, getRegisterInfo(), nullptr,
- DumpOpts, /*Indent=*/0);
+ LLDumpOpts, /*Indent=*/0);
OS << "\n";
} else {
- Loc.dumpRange(0, Data.getData().size(), OS, getRegisterInfo(), DumpOpts);
+ Loc.dumpRange(0, Data.getData().size(), OS, getRegisterInfo(),
+ LLDumpOpts);
}
}
OS << format("0x%8.8" PRIx64 ": ", *Offset);
Error E = visitLocationList(Offset, [&](const DWARFLocationEntry &E) {
Expected<Optional<DWARFLocationExpression>> Loc = Interp.Interpret(E);
- if (!Loc || DumpOpts.Verbose)
+ if (!Loc || DumpOpts.DisplayRawContents)
dumpRawEntry(E, OS, Indent);
if (Loc && *Loc) {
OS << "\n";
OS.indent(Indent);
- if (DumpOpts.Verbose)
+ if (DumpOpts.DisplayRawContents)
OS << " => ";
- Loc.get()->Range->dump(OS, Data.getAddressSize(), DumpOpts);
+
+ DIDumpOptions RangeDumpOpts(DumpOpts);
+ RangeDumpOpts.DisplayRawContents = false;
+ const DWARFObject *Obj = nullptr;
+ if (U)
+ Obj = &U->getContext().getDWARFObj();
+ Loc.get()->Range->dump(OS, Data.getAddressSize(), RangeDumpOpts, Obj);
}
if (!Loc)
consumeError(Loc.takeError());
if (!DumpOpts.ShowAddresses)
return;
- ArrayRef<SectionName> SectionNames;
- if (DumpOpts.Verbose)
- SectionNames = Obj.getSectionNames();
-
for (const DWARFAddressRange &R : Ranges) {
OS << '\n';
OS.indent(Indent);
- R.dump(OS, AddressSize);
-
- DWARFFormValue::dumpAddressSection(Obj, OS, DumpOpts, R.SectionIndex);
+ R.dump(OS, AddressSize, DumpOpts, &Obj);
}
}
}
if (FormValue.isFormClass(DWARFFormValue::FC_SectionOffset)) {
- auto LLDumpOpts = DumpOpts;
- LLDumpOpts.Verbose = false;
-
uint64_t Offset = *FormValue.getAsSectionOffset();
if (FormValue.getForm() == DW_FORM_loclistx) {
return;
}
U->getLocationTable().dumpLocationList(&Offset, OS, U->getBaseAddress(),
- MRI, U, LLDumpOpts, Indent);
+ MRI, U, DumpOpts, Indent);
return;
}
; CHECK: DW_TAG_variable
; CHECK-NEXT: DW_AT_location [DW_FORM_loclistx] (indexed (0x0) loclist = 0x00000018:
-; CHECK-NEXT: [0x0000000000000000, 0x0000000000000003): DW_OP_consts +3, DW_OP_stack_value
-; CHECK-NEXT: [0x0000000000000003, 0x0000000000000004): DW_OP_consts +4, DW_OP_stack_value)
+; CHECK-NEXT: [0x0000000000000000, 0x0000000000000003) ".text._Z2f1ii": DW_OP_consts +3, DW_OP_stack_value
+; CHECK-NEXT: [0x0000000000000003, 0x0000000000000004) ".text._Z2f1ii": DW_OP_consts +4, DW_OP_stack_value)
; CHECK-NEXT: DW_AT_name {{.*}} "y"
; CHECK: DW_TAG_variable
; CHECK-NEXT: DW_AT_location [DW_FORM_loclistx] (indexed (0x1) loclist = 0x00000029:
-; CHECK-NEXT: [0x0000000000000000, 0x0000000000000003): DW_OP_consts +5, DW_OP_stack_value)
+; CHECK-NEXT: [0x0000000000000000, 0x0000000000000003) ".text._Z2f1ii": DW_OP_consts +5, DW_OP_stack_value)
; CHECK-NEXT: DW_AT_name {{.*}} "x"
; CHECK: DW_TAG_variable
-; FIXME: Use DW_FORM_loclistx to reduce relocations
; CHECK-NEXT: DW_AT_location [DW_FORM_loclistx] (indexed (0x2) loclist = 0x00000031:
-; CHECK-NEXT: [0x0000000000000003, 0x0000000000000004): DW_OP_reg0 RAX)
+; CHECK-NEXT: [0x0000000000000003, 0x0000000000000004) ".text._Z2f1ii": DW_OP_reg0 RAX)
; CHECK-NEXT: DW_AT_name {{.*}} "r"
; CHECK: .debug_loclists contents:
-; RUN: llc -filetype=obj -o - < %s | llvm-dwarfdump -v -debug-info - | FileCheck %s
+; RUN: llc -filetype=obj -o - < %s | llvm-dwarfdump -debug-info - | FileCheck %s
;
; Checks that we're omitting the first range, as it is empty, and that we're
; emitting one that spans the rest of the function. In this case, the first
;
; CHECK: DW_TAG_inlined_subroutine
; CHECK: DW_TAG_variable
-; CHECK: DW_AT_location [DW_FORM_sec_offset] ({{.*}}
+; CHECK: DW_AT_location ({{.*}}
; CHECK-NEXT: [0x00000004, 0x00000014): DW_OP_lit0, DW_OP_stack_value, DW_OP_piece 0x4)
; Created form the following test case (PR26163) with
; CHECK: DW_AT_name {{.*}}"e"
; CHECK: DW_TAG_variable
; CHECK-NEXT: DW_AT_location [DW_FORM_sec_offset] (
-; CHECK-NEXT: [0x00000028, 0x0000002c): DW_OP_reg1 AT_64
-; CHECK-NEXT: [0x0000002c, 0x00000048): DW_OP_breg29 SP_64+16)
+; CHECK-NEXT: [0x00000028, 0x0000002c) ".text": DW_OP_reg1 AT_64
+; CHECK-NEXT: [0x0000002c, 0x00000048) ".text": DW_OP_breg29 SP_64+16)
; CHECK-NEXT: DW_AT_name [DW_FORM_strp] ( .debug_str[0x0000006b] = "x")
define i32 @f0(i32 signext %a, i32 signext %b, i32 signext %c, i32 signext %d, i32 signext %e) !dbg !4 {
; CHECK: DW_TAG_variable
; CHECK-NEXT: DW_AT_location [DW_FORM_sec_offset] (
-; CHECK-NEXT: [0x00000080, 0x00000084): DW_OP_reg1 AT_64
-; CHECK-NEXT: [0x00000084, 0x00000098): DW_OP_breg29 SP_64+16)
+; CHECK-NEXT: [0x00000080, 0x00000084) ".text": DW_OP_reg1 AT_64
+; CHECK-NEXT: [0x00000084, 0x00000098) ".text": DW_OP_breg29 SP_64+16)
; CHECK-NEXT: DW_AT_name [DW_FORM_strp] ( .debug_str[0x0000006b] = "x")
define i32 @f1(i32 signext %a, i32 signext %b, i32 signext %c, i32 signext %d, i32 signext %e) !dbg !15 {
; CHECK: DW_TAG_variable
; CHECK-NEXT: DW_AT_location [DW_FORM_sec_offset] (0x00000000
; Check that the location contains only 2 ranges.
-; CHECK-NEXT: [0x{{[0-9a-f]*}}, 0x{{[0-9a-f]*}}):
-; CHECK-NEXT: [0x{{[0-9a-f]*}}, 0x{{[0-9a-f]*}}): {{.*}})
+; CHECK-NEXT: [0x{{[0-9a-f]*}}, 0x{{[0-9a-f]*}})
+; CHECK-NEXT: [0x{{[0-9a-f]*}}, 0x{{[0-9a-f]*}}){{.*}})
; CHECK-NEXT: DW_AT_name {{.*}} "x"
; CHECK-NEXT: DW_AT_decl_file
; CHECK-NEXT: DW_AT_decl_line
; RUN: llc -mtriple=x86_64-unknown-unknown -o - %s | FileCheck %s
; RUN: llc -mtriple=x86_64-unknown-unknown -filetype=obj < %s \
-; RUN: | llvm-dwarfdump -v - | FileCheck %s --check-prefix=DWARF
+; RUN: | llvm-dwarfdump - | FileCheck %s --check-prefix=DWARF
define i1 @test() !dbg !4 {
entry:
; CHECK-LABEL: test
; To get the value of the variable, we need to do [$rsp+8], i.e:
; CHECK: #DEBUG_VALUE: test:w <- [DW_OP_plus_uconst 8, DW_OP_deref] $rsp
-; DWARF: DW_AT_location [DW_FORM_sec_offset] (
+; DWARF: DW_AT_location (
; DWARF-NEXT: [{{.*}}, {{.*}}): DW_OP_breg7 RSP+8)
; Note: A previous version of this test checked for `[DW_OP_plus_uconst 8] [$rsp+0]`,
; RUN: llc < %s | FileCheck %s --check-prefix=ASM
-; RUN: llc < %s -filetype=obj | llvm-dwarfdump -v - | FileCheck %s --check-prefix=DWARF
+; RUN: llc < %s -filetype=obj | llvm-dwarfdump - | FileCheck %s --check-prefix=DWARF
; Values in registers should be clobbered by calls, which use a regmask instead
; of individual register def operands.
; argc is the first formal parameter.
; DWARF: .debug_info contents:
; DWARF: DW_TAG_formal_parameter
-; DWARF-NEXT: DW_AT_location [DW_FORM_sec_offset] ({{0x.*}}
+; DWARF-NEXT: DW_AT_location ({{0x.*}}
; DWARF-NEXT: [0x0000000000000000, 0x0000000000000013): DW_OP_reg2 RCX)
-; DWARF-NEXT: DW_AT_name [DW_FORM_strp] {{.*}} "argc"
+; DWARF-NEXT: DW_AT_name ("argc")
; ModuleID = 't.cpp'
source_filename = "test/DebugInfo/X86/dbg-value-regmask-clobber.ll"
; for the stack location directly instead of generating a register+offset indirection.
; RUN: llc -O2 -filetype=obj -disable-post-ra -mtriple=x86_64-unknown-linux-gnu < %s \
-; RUN: | llvm-dwarfdump -v - | FileCheck %s
+; RUN: | llvm-dwarfdump - | FileCheck %s
;
; int data = 17;
; int sum = 0;
; CHECK: DW_TAG_subprogram
; CHECK-NOT: NULL
; CHECK: DW_TAG_variable
-; CHECK: DW_AT_location [DW_FORM_sec_offset] ({{.*}}
+; CHECK: DW_AT_location ({{.*}}
; CHECK-NEXT: [{{0x.*}}, {{0x.*}}): DW_OP_reg0 RAX
;
; Note: This is a location, so we don't want an extra DW_OP_deref at the end.
; ... [rsp+4] DW_OP_deref
;
; CHECK-NEXT: [{{0x.*}}, {{0x.*}}): DW_OP_breg7 RSP+4)
-; CHECK-NEXT: DW_AT_name {{.*}}"val"
+; CHECK-NEXT: DW_AT_name ("val")
; ModuleID = 'frame.c'
source_filename = "frame.c"
# CHECK: DW_TAG_formal_parameter
# CHECK-NOT: DW_TAG
# CHECK: DW_AT_location [DW_FORM_sec_offset] ({{.*}}
-# CHECK-NEXT: [0x00000029, 0x00000037): DW_OP_breg0 EAX+0, DW_OP_deref
-# CHECK-NEXT: [0x00000037, 0x00000063): DW_OP_breg5 EBP-8, DW_OP_deref, DW_OP_deref
+# CHECK-NEXT: [0x00000029, 0x00000037) ".text": DW_OP_breg0 EAX+0, DW_OP_deref
+# CHECK-NEXT: [0x00000037, 0x00000063) ".text": DW_OP_breg5 EBP-8, DW_OP_deref, DW_OP_deref
# CHECK-NEXT: DW_AT_name [DW_FORM_strp]{{.*}}"a"
#
# CHECK: DW_TAG_variable
# CHECK: DW_TAG_formal_parameter
# CHECK-NOT: DW_TAG
# CHECK: DW_AT_location [DW_FORM_sec_offset] ({{.*}}
-# CHECK-NEXT: [0x00000000, 0x0000000a): DW_OP_consts +0, DW_OP_stack_value
-# CHECK-NEXT: [0x0000000a, 0x00000017): DW_OP_consts +1, DW_OP_stack_value)
+# CHECK-NEXT: [0x00000000, 0x0000000a) ".text": DW_OP_consts +0, DW_OP_stack_value
+# CHECK-NEXT: [0x0000000a, 0x00000017) ".text": DW_OP_consts +1, DW_OP_stack_value)
# CHECK-NEXT: DW_AT_name [DW_FORM_strp]{{.*}}"b"
#
# CHECK: .debug_loc contents: