Index: lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp +++ lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp @@ -33,30 +33,59 @@ return false; Offset = *offset_ptr; while (true) { - RangeListEntry entry; + RangeListEntry Entry; + Entry.SectionIndex = -1ULL; + uint32_t prev_offset = *offset_ptr; - entry.StartAddress = - data.getRelocatedAddress(offset_ptr, &entry.SectionIndex); - entry.EndAddress = data.getRelocatedAddress(offset_ptr); + Entry.StartAddress = data.getRelocatedAddress(offset_ptr); + Entry.EndAddress = + data.getRelocatedAddress(offset_ptr, &Entry.SectionIndex); // Check that both values were extracted correctly. if (*offset_ptr != prev_offset + 2 * AddressSize) { clear(); return false; } - if (entry.isEndOfListEntry()) + if (Entry.isEndOfListEntry()) break; - Entries.push_back(entry); + Entries.push_back(Entry); } return true; } void DWARFDebugRangeList::dump(raw_ostream &OS) const { + if (Entries.empty()) + return; + + if (AddressSize == 4) + OS << "Type Offset HighPC LowPC Section\n" + << "---- -------- -------- -------- --------\n"; + else + OS << "Type Offset HighPC LowPC Section\n" + << "---- -------- ---------------- ---------------- --------\n"; + + Optional BaseAddr; + uint64_t BaseSection; for (const RangeListEntry &RLE : Entries) { - const char *format_str = (AddressSize == 4 - ? "%08x %08" PRIx64 " %08" PRIx64 "\n" - : "%08x %016" PRIx64 " %016" PRIx64 "\n"); - OS << format(format_str, Offset, RLE.StartAddress, RLE.EndAddress); + // Type can be either address selection entry or regular range. + const char *Type = RLE.StartAddress == -1LL ? " AS " : " R "; + const char *format_str = + (AddressSize == 4 ? "%s %08x %08" PRIx64 " %08" PRIx64 " %u\n" + : "%s %08x %016" PRIx64 " %016" PRIx64 " %u\n"); + + uint64_t LowPC = RLE.StartAddress; + uint64_t HighPC = RLE.EndAddress; + uint64_t SectionIndex = RLE.SectionIndex; + if (RLE.StartAddress == -1LL) { + BaseAddr = RLE.EndAddress; + BaseSection = RLE.SectionIndex; + } else if (BaseAddr) { + LowPC += *BaseAddr; + HighPC += *BaseAddr; + SectionIndex = BaseSection; + } + + OS << format(format_str, Type, Offset, LowPC, HighPC, SectionIndex); } OS << format("%08x \n", Offset); } Index: test/DebugInfo/X86/dwarfdump-ranges-baseentry.s =================================================================== --- test/DebugInfo/X86/dwarfdump-ranges-baseentry.s +++ test/DebugInfo/X86/dwarfdump-ranges-baseentry.s @@ -0,0 +1,135 @@ +# RUN: llvm-mc -triple x86_64-pc-linux -filetype=obj %s -o %t +# RUN: llvm-dwarfdump %t | FileCheck %s + +# CHECK: .debug_ranges contents: +# CHECK-NEXT: Type Offset HighPC LowPC Section +# CHECK-NEXT: ---- -------- ---------------- ---------------- -------- +# CHECK-NEXT: AS 00000000 ffffffffffffffff 0000000000000008 2 +# CHECK-NEXT: R 00000000 0000000000000008 0000000000000009 2 +# CHECK-NEXT: R 00000000 000000000000000a 000000000000000b 2 +# CHECK-NEXT: 00000000 + +## Asm code for testcase is a reduced output from next invocation and source: +# clang test.cpp -g -c -mllvm -use-dwarf-ranges-base-address-specifier +# test.cpp: +# void f2() { +# } +# __attribute__((nodebug)) void f1() { +# } +# void f3() { +# } + +.text +.quad 0x0 + +.globl _Z2f2v +.type _Z2f2v,@function +_Z2f2v: +.Lfunc_begin0: +nop +.Lfunc_end0: + +.globl _Z2f1v +.type _Z2f1v,@function +_Z2f1v: +.Lfunc_begin1: +nop +.Lfunc_end1: + + +.globl bar +.type bar,@function +bar: +.Lfunc_begin2: +nop +.Lfunc_end2: + + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 14 # DW_FORM_strp + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 14 # DW_FORM_strp + .ascii "\264B" # DW_AT_GNU_pubnames + .byte 25 # DW_FORM_flag_present + .byte 17 # DW_AT_low_pc + .byte 1 # DW_FORM_addr + .byte 85 # DW_AT_ranges + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 0 # DW_CHILDREN_no + .byte 17 # DW_AT_low_pc + .byte 1 # DW_FORM_addr + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 110 # DW_AT_linkage_name + .byte 14 # DW_FORM_strp + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + + .section .debug_info,"",@progbits +.Lcu_begin0: + .long 89 # Length of Unit + .short 4 # DWARF version number + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 8 # Address Size (in bytes) + .byte 1 # Abbrev [1] 0xb:0x52 DW_TAG_compile_unit + .long 0 # DW_AT_producer + .short 4 # DW_AT_language + .long 0 # DW_AT_name + .long 0 # DW_AT_stmt_list + .long 0 # DW_AT_comp_dir + .quad 0 # DW_AT_low_pc + .long .Ldebug_ranges0 # DW_AT_ranges + .byte 2 # Abbrev [2] 0x2a:0x19 DW_TAG_subprogram + .quad .Lfunc_begin0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .long 0 # DW_AT_linkage_name + .long 0 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .byte 2 # Abbrev [2] 0x43:0x19 DW_TAG_subprogram + .quad 0 # DW_AT_low_pc + .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .long 0 # DW_AT_linkage_name + .long 0 # DW_AT_name + .byte 1 # DW_AT_decl_file + .byte 5 # DW_AT_decl_line + .byte 0 # End Of Children Mark + + .section .debug_ranges,"",@progbits +.Ldebug_ranges0: + .quad -1 + .quad .Lfunc_begin0 + .quad .Lfunc_begin0-.Lfunc_begin0 + .quad .Lfunc_end0-.Lfunc_begin0 + .quad .Lfunc_begin2-.Lfunc_begin0 + .quad .Lfunc_end2-.Lfunc_begin0 + .quad 0 + .quad 0 Index: test/DebugInfo/X86/dwarfdump-ranges-unrelocated.s =================================================================== --- test/DebugInfo/X86/dwarfdump-ranges-unrelocated.s +++ test/DebugInfo/X86/dwarfdump-ranges-unrelocated.s @@ -1,10 +1,12 @@ # RUN: llvm-mc -triple x86_64-pc-linux -filetype=obj %s -o %t # RUN: llvm-dwarfdump %t | FileCheck %s -# CHECK: .debug_ranges contents: -# CHECK: 00000000 0000000000000000 0000000000000001 -# CHECK: 00000000 0000000000000000 0000000000000002 -# CHECK: 00000000 +# CHECK: .debug_ranges contents: +# CHECK-NEXT: Type Offset HighPC LowPC Section +# CHECK-NEXT: ---- -------- ---------------- ---------------- -------- +# CHECK-NEXT: R 00000000 0000000000000000 0000000000000001 3 +# CHECK-NEXT: R 00000000 0000000000000000 0000000000000002 4 +# CHECK-NEXT: 00000000 ## Asm code for testcase is a reduced output from next invocation and source: # clang test.cpp -S -o test.s -gmlt -ffunction-sections Index: test/DebugInfo/dwarfdump-ranges.test =================================================================== --- test/DebugInfo/dwarfdump-ranges.test +++ test/DebugInfo/dwarfdump-ranges.test @@ -15,10 +15,13 @@ CHECK: .debug_ranges contents: -CHECK-NEXT: 00000000 000000000000062c 0000000000000637 -CHECK-NEXT: 00000000 0000000000000637 000000000000063d -CHECK-NEXT: 00000000 -CHECK-NEXT: 00000030 0000000000000640 000000000000064b -CHECK-NEXT: 00000030 0000000000000637 000000000000063d -CHECK-NEXT: 00000030 - +CHECK-NEXT: Type Offset HighPC LowPC Section +CHECK-NEXT: ---- -------- ---------------- ---------------- -------- +CHECK-NEXT: R 00000000 000000000000062c 0000000000000637 4294967295 +CHECK-NEXT: R 00000000 0000000000000637 000000000000063d 4294967295 +CHECK-NEXT: 00000000 +CHECK-NEXT: Type Offset HighPC LowPC Section +CHECK-NEXT: ---- -------- ---------------- ---------------- -------- +CHECK-NEXT: R 00000030 0000000000000640 000000000000064b 4294967295 +CHECK-NEXT: R 00000030 0000000000000637 000000000000063d 4294967295 +CHECK-NEXT: 00000030