forked from OSchip/llvm-project
[DWARFDebugLoclists] Add support for other DW_LLE encodings
Summary: lldb's loclists parser has support for DW_LLE_start_end(x) encodings. To avoid regressing when switching the implementation to llvm's, I add parsing support for all previously unsupported location list encodings. Reviewers: dblaikie, JDevlieghere, aprantl, SouraVX Subscribers: hiraditya, probinson, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D70949
This commit is contained in:
parent
d34927e7db
commit
a3af3ac393
|
@ -57,6 +57,17 @@ DWARFLocationInterpreter::Interpret(const DWARFLocationEntry &E) {
|
|||
return createResolverError(E.Value0, E.Kind);
|
||||
return None;
|
||||
}
|
||||
case dwarf::DW_LLE_startx_endx: {
|
||||
Optional<SectionedAddress> LowPC = LookupAddr(E.Value0);
|
||||
if (!LowPC)
|
||||
return createResolverError(E.Value0, E.Kind);
|
||||
Optional<SectionedAddress> HighPC = LookupAddr(E.Value1);
|
||||
if (!HighPC)
|
||||
return createResolverError(E.Value1, E.Kind);
|
||||
return DWARFLocationExpression{
|
||||
DWARFAddressRange{LowPC->Address, HighPC->Address, LowPC->SectionIndex},
|
||||
E.Loc};
|
||||
}
|
||||
case dwarf::DW_LLE_startx_length: {
|
||||
Optional<SectionedAddress> LowPC = LookupAddr(E.Value0);
|
||||
if (!LowPC)
|
||||
|
@ -78,9 +89,14 @@ DWARFLocationInterpreter::Interpret(const DWARFLocationEntry &E) {
|
|||
Range.SectionIndex = E.SectionIndex;
|
||||
return DWARFLocationExpression{Range, E.Loc};
|
||||
}
|
||||
case dwarf::DW_LLE_default_location:
|
||||
return DWARFLocationExpression{None, E.Loc};
|
||||
case dwarf::DW_LLE_base_address:
|
||||
Base = SectionedAddress{E.Value0, E.SectionIndex};
|
||||
return None;
|
||||
case dwarf::DW_LLE_start_end:
|
||||
return DWARFLocationExpression{
|
||||
DWARFAddressRange{E.Value0, E.Value1, E.SectionIndex}, E.Loc};
|
||||
case dwarf::DW_LLE_start_length:
|
||||
return DWARFLocationExpression{
|
||||
DWARFAddressRange{E.Value0, E.Value0 + E.Value1, E.SectionIndex},
|
||||
|
@ -127,7 +143,10 @@ bool DWARFLocationTable::dumpLocationList(uint64_t *Offset, raw_ostream &OS,
|
|||
|
||||
DIDumpOptions RangeDumpOpts(DumpOpts);
|
||||
RangeDumpOpts.DisplayRawContents = false;
|
||||
Loc.get()->Range->dump(OS, Data.getAddressSize(), RangeDumpOpts, &Obj);
|
||||
if (Loc.get()->Range)
|
||||
Loc.get()->Range->dump(OS, Data.getAddressSize(), RangeDumpOpts, &Obj);
|
||||
else
|
||||
OS << "<default>";
|
||||
}
|
||||
if (!Loc)
|
||||
consumeError(Loc.takeError());
|
||||
|
@ -269,6 +288,10 @@ Error DWARFDebugLoclists::visitLocationList(
|
|||
case dwarf::DW_LLE_base_addressx:
|
||||
E.Value0 = Data.getULEB128(C);
|
||||
break;
|
||||
case dwarf::DW_LLE_startx_endx:
|
||||
E.Value0 = Data.getULEB128(C);
|
||||
E.Value1 = Data.getULEB128(C);
|
||||
break;
|
||||
case dwarf::DW_LLE_startx_length:
|
||||
E.Value0 = Data.getULEB128(C);
|
||||
// Pre-DWARF 5 has different interpretation of the length field. We have
|
||||
|
@ -283,16 +306,19 @@ Error DWARFDebugLoclists::visitLocationList(
|
|||
E.Value1 = Data.getULEB128(C);
|
||||
E.SectionIndex = SectionedAddress::UndefSection;
|
||||
break;
|
||||
case dwarf::DW_LLE_default_location:
|
||||
break;
|
||||
case dwarf::DW_LLE_base_address:
|
||||
E.Value0 = Data.getRelocatedAddress(C, &E.SectionIndex);
|
||||
break;
|
||||
case dwarf::DW_LLE_start_end:
|
||||
E.Value0 = Data.getRelocatedAddress(C, &E.SectionIndex);
|
||||
E.Value1 = Data.getRelocatedAddress(C);
|
||||
break;
|
||||
case dwarf::DW_LLE_start_length:
|
||||
E.Value0 = Data.getRelocatedAddress(C, &E.SectionIndex);
|
||||
E.Value1 = Data.getULEB128(C);
|
||||
break;
|
||||
case dwarf::DW_LLE_startx_endx:
|
||||
case dwarf::DW_LLE_default_location:
|
||||
case dwarf::DW_LLE_start_end:
|
||||
default:
|
||||
cantFail(C.takeError());
|
||||
return createStringError(errc::illegal_byte_sequence,
|
||||
|
@ -333,9 +359,14 @@ void DWARFDebugLoclists::dumpRawEntry(const DWARFLocationEntry &Entry,
|
|||
OS << format("%-*s(", MaxEncodingStringLength, EncodingString.data());
|
||||
unsigned FieldSize = 2 + 2 * Data.getAddressSize();
|
||||
switch (Entry.Kind) {
|
||||
case dwarf::DW_LLE_end_of_list:
|
||||
case dwarf::DW_LLE_default_location:
|
||||
break;
|
||||
case dwarf::DW_LLE_startx_endx:
|
||||
case dwarf::DW_LLE_startx_length:
|
||||
case dwarf::DW_LLE_start_length:
|
||||
case dwarf::DW_LLE_offset_pair:
|
||||
case dwarf::DW_LLE_start_end:
|
||||
case dwarf::DW_LLE_start_length:
|
||||
OS << format_hex(Entry.Value0, FieldSize) << ", "
|
||||
<< format_hex(Entry.Value1, FieldSize);
|
||||
break;
|
||||
|
@ -343,13 +374,12 @@ void DWARFDebugLoclists::dumpRawEntry(const DWARFLocationEntry &Entry,
|
|||
case dwarf::DW_LLE_base_address:
|
||||
OS << format_hex(Entry.Value0, FieldSize);
|
||||
break;
|
||||
case dwarf::DW_LLE_end_of_list:
|
||||
break;
|
||||
}
|
||||
OS << ')';
|
||||
switch (Entry.Kind) {
|
||||
case dwarf::DW_LLE_start_length:
|
||||
case dwarf::DW_LLE_base_address:
|
||||
case dwarf::DW_LLE_start_end:
|
||||
case dwarf::DW_LLE_start_length:
|
||||
DWARFFormValue::dumpAddressSection(Obj, OS, DumpOpts, Entry.SectionIndex);
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -16,25 +16,49 @@
|
|||
# REGULAR-NEXT: [0x0000000000000002, 0x0000000000000003): DW_OP_reg2 RCX
|
||||
# VERBOSE-NEXT: [0x0000000000000002, 0x0000000000000003) ".text": DW_OP_reg2 RCX
|
||||
|
||||
# REGULAR-NEXT: [0x0000000000000003, 0x0000000000000004): DW_OP_reg3 RBX
|
||||
# VERBOSE-NEXT: [0x0000000000000003, 0x0000000000000004) ".text": DW_OP_reg3 RBX
|
||||
# BOTH-NEXT: <default>: DW_OP_reg3 RBX
|
||||
|
||||
# BOTH-NEXT: DW_LLE_startx_length (0x000000000000dead, 0x0000000000000001): DW_OP_reg4 RSI)
|
||||
# REGULAR-NEXT: [0x0000000000000004, 0x0000000000000005): DW_OP_reg4 RSI
|
||||
# VERBOSE-NEXT: [0x0000000000000004, 0x0000000000000005) ".text": DW_OP_reg4 RSI
|
||||
|
||||
# BOTH: locations list header: length = 0x00000034, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000
|
||||
# REGULAR-NEXT: [0x0000000000000005, 0x0000000000000006): DW_OP_reg5 RDI
|
||||
# VERBOSE-NEXT: [0x0000000000000005, 0x0000000000000006) ".text": DW_OP_reg5 RDI
|
||||
|
||||
# REGULAR-NEXT: [0x0000000000000006, 0x0000000000000007): DW_OP_reg6 RBP
|
||||
# VERBOSE-NEXT: [0x0000000000000006, 0x0000000000000007) ".text": DW_OP_reg6 RBP
|
||||
|
||||
# REGULAR-NEXT: [0x0000000000000007, 0x0000000000000008): DW_OP_reg7 RSP
|
||||
# VERBOSE-NEXT: [0x0000000000000007, 0x0000000000000008) ".text": DW_OP_reg7 RSP
|
||||
|
||||
# BOTH-NEXT: DW_LLE_startx_length (0x000000000000dead, 0x0000000000000001): DW_OP_reg4 RSI)
|
||||
|
||||
# BOTH: locations list header: length = 0x00000056, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000
|
||||
# BOTH-NEXT: 0x0000000c:
|
||||
# BOTH-NEXT: DW_LLE_startx_length (0x0000000000000000, 0x0000000000000001): DW_OP_reg0 RAX
|
||||
# BOTH-NEXT: DW_LLE_offset_pair (0x0000000000000001, 0x0000000000000002): DW_OP_reg1 RDX
|
||||
# BOTH-NEXT: DW_LLE_startx_endx (0x0000000000000000, 0x0000000000000001): DW_OP_reg0 RAX
|
||||
# BOTH-NEXT: DW_LLE_startx_length (0x0000000000000001, 0x0000000000000001): DW_OP_reg1 RDX
|
||||
# BOTH-NEXT: DW_LLE_offset_pair (0x0000000000000002, 0x0000000000000003): DW_OP_reg2 RCX
|
||||
|
||||
# REGULAR-NEXT: [0x0000000000000002, 0x0000000000000003): DW_OP_reg2 RCX
|
||||
# VERBOSE-NEXT: DW_LLE_start_length (0x0000000000000002, 0x0000000000000001) ".text"
|
||||
# VERBOSE-NEXT: => [0x0000000000000002, 0x0000000000000003) ".text": DW_OP_reg2 RCX
|
||||
# REGULAR-NEXT: <default>: DW_OP_reg3 RBX
|
||||
# VERBOSE-NEXT: DW_LLE_default_location()
|
||||
# VERBOSE-NEXT: => <default>: DW_OP_reg3 RBX
|
||||
|
||||
# VERBOSE-NEXT: DW_LLE_base_address (0x0000000000000003) ".text"
|
||||
# REGULAR-NEXT: [0x0000000000000004, 0x0000000000000005): DW_OP_reg4 RSI
|
||||
# VERBOSE-NEXT: DW_LLE_start_end (0x0000000000000004, 0x0000000000000005) ".text"
|
||||
# VERBOSE-NEXT: => [0x0000000000000004, 0x0000000000000005) ".text": DW_OP_reg4 RSI
|
||||
|
||||
# REGULAR-NEXT: [0x0000000000000003, 0x0000000000000004): DW_OP_reg3 RBX
|
||||
# REGULAR-NEXT: [0x0000000000000005, 0x0000000000000006): DW_OP_reg5 RDI
|
||||
# VERBOSE-NEXT: DW_LLE_start_length (0x0000000000000005, 0x0000000000000001) ".text"
|
||||
# VERBOSE-NEXT: => [0x0000000000000005, 0x0000000000000006) ".text": DW_OP_reg5 RDI
|
||||
|
||||
# BOTH-NEXT: DW_LLE_base_addressx (0x0000000000000002)
|
||||
|
||||
# BOTH-NEXT: DW_LLE_offset_pair (0x0000000000000000, 0x0000000000000001): DW_OP_reg6 RBP
|
||||
|
||||
# VERBOSE-NEXT: DW_LLE_base_address (0x0000000000000007) ".text"
|
||||
|
||||
# REGULAR-NEXT: [0x0000000000000007, 0x0000000000000008): DW_OP_reg7 RSP
|
||||
# VERBOSE-NEXT: DW_LLE_offset_pair (0x0000000000000000, 0x0000000000000001)
|
||||
# VERBOSE-NEXT: => [0x0000000000000003, 0x0000000000000004) ".text": DW_OP_reg3 RBX
|
||||
# VERBOSE-NEXT: => [0x0000000000000007, 0x0000000000000008) ".text": DW_OP_reg7 RSP
|
||||
|
||||
# BOTH-NEXT: DW_LLE_startx_length (0x000000000000dead, 0x0000000000000001): DW_OP_reg4 RSI
|
||||
|
||||
|
@ -52,6 +76,14 @@ f: # @f
|
|||
.Lf3:
|
||||
nop
|
||||
.Lf4:
|
||||
nop
|
||||
.Lf5:
|
||||
nop
|
||||
.Lf6:
|
||||
nop
|
||||
.Lf7:
|
||||
nop
|
||||
.Lf8:
|
||||
.Lfend:
|
||||
# -- End function
|
||||
.section .debug_loclists,"",@progbits
|
||||
|
@ -63,33 +95,64 @@ f: # @f
|
|||
.long 0 # Offset entry count
|
||||
.Lloclists_table_base0:
|
||||
.Ldebug_loc0:
|
||||
.byte 3 # DW_LLE_startx_length
|
||||
.byte 2 # DW_LLE_startx_endx
|
||||
.uleb128 0 # start idx
|
||||
.uleb128 .Lf1-.Lf0 # length
|
||||
.uleb128 1 # end idx
|
||||
.byte 1 # Loc expr size
|
||||
.byte 80 # super-register DW_OP_reg0
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Lf1-.Lf0 # starting offset
|
||||
.uleb128 .Lf2-.Lf0 # ending offset
|
||||
|
||||
.byte 3 # DW_LLE_startx_length
|
||||
.uleb128 1 # start idx
|
||||
.uleb128 .Lf2-.Lf1 # length
|
||||
.byte 1 # Loc expr size
|
||||
.byte 81 # super-register DW_OP_reg1
|
||||
.byte 8 # DW_LLE_start_length
|
||||
.quad .Lf2 # starting offset
|
||||
.uleb128 .Lf3-.Lf2 # length
|
||||
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Lf2-.Lf0 # starting offset
|
||||
.uleb128 .Lf3-.Lf0 # ending offset
|
||||
.byte 1 # Loc expr size
|
||||
.byte 82 # super-register DW_OP_reg2
|
||||
.byte 6 # DW_LLE_base_address
|
||||
.quad .Lf3 # base address
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Lf3-.Lf3 # starting offset
|
||||
.uleb128 .Lf4-.Lf3 # ending offset
|
||||
|
||||
.byte 5 # DW_LLE_default_location
|
||||
.byte 1 # Loc expr size
|
||||
.byte 83 # super-register DW_OP_reg3
|
||||
|
||||
.byte 7 # DW_LLE_start_end
|
||||
.quad .Lf4 # starting offset
|
||||
.quad .Lf5 # ending offset
|
||||
.byte 1 # Loc expr size
|
||||
.byte 84 # super-register DW_OP_reg4
|
||||
|
||||
.byte 8 # DW_LLE_start_length
|
||||
.quad .Lf5 # starting offset
|
||||
.uleb128 .Lf6-.Lf5 # length
|
||||
.byte 1 # Loc expr size
|
||||
.byte 85 # super-register DW_OP_reg5
|
||||
|
||||
.byte 1 # DW_LLE_base_addressx
|
||||
.uleb128 2 # base address
|
||||
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Lf6-.Lf6 # starting offset
|
||||
.uleb128 .Lf7-.Lf6 # ending offset
|
||||
.byte 1 # Loc expr size
|
||||
.byte 86 # super-register DW_OP_reg6
|
||||
|
||||
.byte 6 # DW_LLE_base_address
|
||||
.quad .Lf7 # base address
|
||||
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Lf7-.Lf7 # starting offset
|
||||
.uleb128 .Lf8-.Lf7 # ending offset
|
||||
.byte 1 # Loc expr size
|
||||
.byte 87 # super-register DW_OP_reg7
|
||||
|
||||
.byte 3 # DW_LLE_startx_length
|
||||
.uleb128 0xdead # start idx
|
||||
.uleb128 .Lf1-.Lf0 # length
|
||||
.byte 1 # Loc expr size
|
||||
.byte 84 # super-register DW_OP_reg4
|
||||
|
||||
.byte 0 # DW_LLE_end_of_list
|
||||
.Ldebug_loclist_table_end0:
|
||||
|
||||
|
@ -154,4 +217,6 @@ f: # @f
|
|||
.byte 0 # Segment selector size
|
||||
.Laddr_table_base0:
|
||||
.quad .Lf0
|
||||
.quad .Lf1
|
||||
.quad .Lf6
|
||||
.Ldebug_addr_end0:
|
||||
|
|
Loading…
Reference in New Issue