[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:
Pavel Labath 2019-11-22 10:53:09 +01:00
parent d34927e7db
commit a3af3ac393
2 changed files with 128 additions and 33 deletions

View File

@ -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:

View File

@ -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: