From 230cf52e6e54649bffbafeedaf053d37502223c5 Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Wed, 9 Oct 2019 21:25:28 +0000 Subject: [PATCH] llvm-dwarfdump: Support multiple debug_loclists contributions Also fixing the incorrect "offset" field being computed/printed for each location list. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@374232 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h | 2 +- lib/DebugInfo/DWARF/DWARFContext.cpp | 28 +++++++----- lib/DebugInfo/DWARF/DWARFDebugLoc.cpp | 5 +-- test/CodeGen/X86/debug-loclists.ll | 2 +- .../X86/dwarfdump-debug-loclists.test | 2 +- .../X86/debug_loclists_multiple.s | 44 +++++++++++++++++++ .../X86/debug_loclists_startx_length.s | 2 +- 7 files changed, 66 insertions(+), 19 deletions(-) create mode 100644 test/tools/llvm-dwarfdump/X86/debug_loclists_multiple.s diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h b/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h index f65a20af0cb..d06818eca9d 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h @@ -99,7 +99,7 @@ private: bool IsLittleEndian; public: - void parse(DataExtractor data, unsigned Version); + void parse(DataExtractor data, uint64_t Offset, uint64_t EndOffset, uint16_t Version); void dump(raw_ostream &OS, uint64_t BaseAddr, const MCRegisterInfo *RegInfo, Optional Offset) const; diff --git a/lib/DebugInfo/DWARF/DWARFContext.cpp b/lib/DebugInfo/DWARF/DWARFContext.cpp index 770f129753e..ed6c2b93ce6 100644 --- a/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -290,20 +290,24 @@ static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts, const MCRegisterInfo *MRI, Optional DumpOffset) { uint64_t Offset = 0; - DWARFDebugLoclists Loclists; - DWARFListTableHeader Header(".debug_loclists", "locations"); - if (Error E = Header.extract(Data, &Offset)) { - WithColor::error() << toString(std::move(E)) << '\n'; - return; - } + while (Data.isValidOffset(Offset)) { + DWARFListTableHeader Header(".debug_loclists", "locations"); + if (Error E = Header.extract(Data, &Offset)) { + WithColor::error() << toString(std::move(E)) << '\n'; + return; + } - Header.dump(OS, DumpOpts); - DataExtractor LocData(Data.getData().drop_front(Offset), - Data.isLittleEndian(), Header.getAddrSize()); + Header.dump(OS, DumpOpts); + DataExtractor LocData(Data.getData(), + Data.isLittleEndian(), Header.getAddrSize()); - Loclists.parse(LocData, Header.getVersion()); - Loclists.dump(OS, 0, MRI, DumpOffset); + DWARFDebugLoclists Loclists; + uint64_t EndOffset = Header.length() + Header.getHeaderOffset(); + Loclists.parse(LocData, Offset, EndOffset, Header.getVersion()); + Loclists.dump(OS, 0, MRI, DumpOffset); + Offset = EndOffset; + } } void DWARFContext::dump( @@ -733,7 +737,7 @@ const DWARFDebugLoclists *DWARFContext::getDebugLocDWO() { // Use version 4. DWO does not support the DWARF v5 .debug_loclists yet and // that means we are parsing the new style .debug_loc (pre-standatized version // of the .debug_loclists). - LocDWO->parse(LocData, 4 /* Version */); + LocDWO->parse(LocData, 0, LocData.getData().size(), 4 /* Version */); return LocDWO.get(); } diff --git a/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp b/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp index a243ed3a80b..bdafafc7a37 100644 --- a/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp +++ b/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp @@ -187,12 +187,11 @@ DWARFDebugLoclists::parseOneLocationList(const DataExtractor &Data, return LL; } -void DWARFDebugLoclists::parse(DataExtractor data, unsigned Version) { +void DWARFDebugLoclists::parse(DataExtractor data, uint64_t Offset, uint64_t EndOffset, uint16_t Version) { IsLittleEndian = data.isLittleEndian(); AddressSize = data.getAddressSize(); - uint64_t Offset = 0; - while (Offset < data.getData().size()) { + while (Offset < EndOffset) { if (auto LL = parseOneLocationList(data, &Offset, Version)) Locations.push_back(std::move(*LL)); else { diff --git a/test/CodeGen/X86/debug-loclists.ll b/test/CodeGen/X86/debug-loclists.ll index 0c2ab3dfad5..30cab3b01e1 100644 --- a/test/CodeGen/X86/debug-loclists.ll +++ b/test/CodeGen/X86/debug-loclists.ll @@ -12,7 +12,7 @@ ; CHECK: .debug_loclists contents: ; CHECK-NEXT: 0x00000000: locations list header: length = 0x00000015, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000 -; CHECK-NEXT: 0x00000000: +; CHECK-NEXT: 0x0000000c: ; CHECK-NEXT: [0x0000000000000000, 0x0000000000000004): DW_OP_breg5 RDI+0 ; CHECK-NEXT: [0x0000000000000004, 0x0000000000000012): DW_OP_breg3 RBX+0 diff --git a/test/DebugInfo/X86/dwarfdump-debug-loclists.test b/test/DebugInfo/X86/dwarfdump-debug-loclists.test index 32f2482b511..41893d32690 100644 --- a/test/DebugInfo/X86/dwarfdump-debug-loclists.test +++ b/test/DebugInfo/X86/dwarfdump-debug-loclists.test @@ -10,7 +10,7 @@ # CHECK: .debug_loclists contents: # CHECK-NEXT: 0x00000000: locations list header: length = 0x0000002c, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000 -# CHECK-NEXT: 0x00000000: +# CHECK-NEXT: 0x0000000c: # CHECK-NEXT: [0x0000000000000000, 0x0000000000000010): DW_OP_breg5 RDI+0 # CHECK-NEXT: [0x0000000000000530, 0x0000000000000540): DW_OP_breg6 RBP-8, DW_OP_deref # CHECK-NEXT: [0x0000000000000700, 0x0000000000000710): DW_OP_breg5 RDI+0 diff --git a/test/tools/llvm-dwarfdump/X86/debug_loclists_multiple.s b/test/tools/llvm-dwarfdump/X86/debug_loclists_multiple.s new file mode 100644 index 00000000000..4e2999dd9c6 --- /dev/null +++ b/test/tools/llvm-dwarfdump/X86/debug_loclists_multiple.s @@ -0,0 +1,44 @@ +# RUN: llvm-mc %s -filetype obj -triple x86_64-pc-linux -o %t.o +# RUN: llvm-dwarfdump -v %t.o | FileCheck %s + +# Test dumping of multiple separate debug_loclist contributions +# CHECK: .debug_loclists contents: +# CHECK: 0x00000000: locations list header: +# CHECK: 0x0000000c: +# CHECK: [0x0000000000000001, 0x0000000000000002): DW_OP_consts +7, DW_OP_stack_value +# CHECK: 0x00000014: locations list header: +# CHECK: [0x0000000000000005, 0x0000000000000007): DW_OP_consts +12, DW_OP_stack_value + + .section .debug_loclists,"",@progbits + .long .Ldebug_loclist_table_end0-.Ldebug_loclist_table_start0 # Length +.Ldebug_loclist_table_start0: + .short 5 # Version + .byte 8 # Address size + .byte 0 # Segment selector size + .long 0 # Offset entry count + + .byte 4 # DW_LLE_offset_pair + .uleb128 1 # starting offset + .uleb128 2 # ending offset + .byte 3 # Loc expr size + .byte 17 # DW_OP_consts + .byte 7 # 7 + .byte 159 # DW_OP_stack_value + .byte 0 # DW_LLE_end_of_list +.Ldebug_loclist_table_end0: + .long .Ldebug_loclist_table_end1-.Ldebug_loclist_table_start1 # Length +.Ldebug_loclist_table_start1: + .short 5 # Version + .byte 8 # Address size + .byte 0 # Segment selector size + .long 0 # Offset entry count + + .byte 4 # DW_LLE_offset_pair + .uleb128 5 # starting offset + .uleb128 7 # ending offset + .byte 3 # Loc expr size + .byte 17 # DW_OP_consts + .byte 12 # 12 + .byte 159 # DW_OP_stack_value + .byte 0 # DW_LLE_end_of_list +.Ldebug_loclist_table_end1: diff --git a/test/tools/llvm-dwarfdump/X86/debug_loclists_startx_length.s b/test/tools/llvm-dwarfdump/X86/debug_loclists_startx_length.s index 0b2ae5f8e7a..508d9566546 100644 --- a/test/tools/llvm-dwarfdump/X86/debug_loclists_startx_length.s +++ b/test/tools/llvm-dwarfdump/X86/debug_loclists_startx_length.s @@ -7,7 +7,7 @@ # CHECK: .debug_loclists contents: # CHECK-NEXT: 0x00000000: locations list header: length = 0x0000000e, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000 -# CHECK-NEXT: 0x00000000: +# CHECK-NEXT: 0x0000000c: # CHECK-NEXT: Addr idx 1 (w/ length 16): DW_OP_reg5 RDI .section .debug_loclists,"",@progbits -- 2.40.0