diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp @@ -57,6 +57,17 @@ return createResolverError(E.Value0, E.Kind); return None; } + case dwarf::DW_LLE_startx_endx: { + Optional LowPC = LookupAddr(E.Value0); + if (!LowPC) + return createResolverError(E.Value0, E.Kind); + Optional 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 LowPC = LookupAddr(E.Value0); if (!LowPC) @@ -78,9 +89,14 @@ 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 @@ 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 << ""; } if (!Loc) consumeError(Loc.takeError()); @@ -269,6 +288,10 @@ 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 @@ 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 @@ 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 @@ 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: diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug_loclists.s b/llvm/test/tools/llvm-dwarfdump/X86/debug_loclists.s --- a/llvm/test/tools/llvm-dwarfdump/X86/debug_loclists.s +++ b/llvm/test/tools/llvm-dwarfdump/X86/debug_loclists.s @@ -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: : 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: : DW_OP_reg3 RBX +# VERBOSE-NEXT: DW_LLE_default_location() +# VERBOSE-NEXT: => : DW_OP_reg3 RBX -# 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: [0x0000000000000004, 0x0000000000000005): DW_OP_reg4 RSI +# VERBOSE-NEXT: DW_LLE_start_end (0x0000000000000004, 0x0000000000000005) ".text" +# VERBOSE-NEXT: => [0x0000000000000004, 0x0000000000000005) ".text": DW_OP_reg4 RSI -# VERBOSE-NEXT: DW_LLE_base_address (0x0000000000000003) ".text" +# 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 -# REGULAR-NEXT: [0x0000000000000003, 0x0000000000000004): DW_OP_reg3 RBX +# 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 @@ .Lf3: nop .Lf4: + nop +.Lf5: + nop +.Lf6: + nop +.Lf7: + nop +.Lf8: .Lfend: # -- End function .section .debug_loclists,"",@progbits @@ -63,33 +95,64 @@ .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 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 .Lf3 # base address + .quad .Lf7 # base address + .byte 4 # DW_LLE_offset_pair - .uleb128 .Lf3-.Lf3 # starting offset - .uleb128 .Lf4-.Lf3 # ending offset + .uleb128 .Lf7-.Lf7 # starting offset + .uleb128 .Lf8-.Lf7 # ending offset .byte 1 # Loc expr size - .byte 83 # super-register DW_OP_reg3 + .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 @@ .byte 0 # Segment selector size .Laddr_table_base0: .quad .Lf0 + .quad .Lf1 + .quad .Lf6 .Ldebug_addr_end0: