diff --git a/llvm/include/llvm/DWARFLinker/DWARFLinker.h b/llvm/include/llvm/DWARFLinker/DWARFLinker.h --- a/llvm/include/llvm/DWARFLinker/DWARFLinker.h +++ b/llvm/include/llvm/DWARFLinker/DWARFLinker.h @@ -140,10 +140,9 @@ virtual MCSymbol *emitDwarfDebugRangeListHeader(const CompileUnit &Unit) = 0; /// Emit debug ranges (.debug_ranges, .debug_rnglists) fragment. - virtual void - emitDwarfDebugRangeListFragment(const CompileUnit &Unit, - const AddressRanges &LinkedRanges, - PatchLocation Patch) = 0; + virtual void emitDwarfDebugRangeListFragment( + const CompileUnit &Unit, const AddressRanges &LinkedRanges, + PatchLocation Patch, DebugAddrPool &AddrPool) = 0; /// Emit debug ranges (.debug_ranges, .debug_rnglists) footer. virtual void emitDwarfDebugRangeListFooter(const CompileUnit &Unit, @@ -825,7 +824,8 @@ /// Compute and emit debug ranges(.debug_aranges, .debug_ranges, /// .debug_rnglists) for \p Unit, patch the attributes referencing it. - void generateUnitRanges(CompileUnit &Unit, const DWARFFile &File) const; + void generateUnitRanges(CompileUnit &Unit, const DWARFFile &File, + DebugAddrPool &AddrPool) const; /// Emit the accelerator entries for \p Unit. void emitAcceleratorEntriesForUnit(CompileUnit &Unit); diff --git a/llvm/include/llvm/DWARFLinker/DWARFStreamer.h b/llvm/include/llvm/DWARFLinker/DWARFStreamer.h --- a/llvm/include/llvm/DWARFLinker/DWARFStreamer.h +++ b/llvm/include/llvm/DWARFLinker/DWARFStreamer.h @@ -98,7 +98,8 @@ /// Emit debug ranges(.debug_ranges, .debug_rnglists) fragment. void emitDwarfDebugRangeListFragment(const CompileUnit &Unit, const AddressRanges &LinkedRanges, - PatchLocation Patch) override; + PatchLocation Patch, + DebugAddrPool &AddrPool) override; /// Emit debug ranges(.debug_ranges, .debug_rnglists) footer. void emitDwarfDebugRangeListFooter(const CompileUnit &Unit, @@ -220,7 +221,8 @@ /// Emit piece of .debug_rnglists for \p LinkedRanges. void emitDwarfDebugRngListsTableFragment(const CompileUnit &Unit, const AddressRanges &LinkedRanges, - PatchLocation Patch); + PatchLocation Patch, + DebugAddrPool &AddrPool); /// Emit piece of .debug_loc for \p LinkedRanges. void emitDwarfDebugLocTableFragment( diff --git a/llvm/lib/DWARFLinker/DWARFLinker.cpp b/llvm/lib/DWARFLinker/DWARFLinker.cpp --- a/llvm/lib/DWARFLinker/DWARFLinker.cpp +++ b/llvm/lib/DWARFLinker/DWARFLinker.cpp @@ -1868,8 +1868,8 @@ /// Patch the input object file relevant debug_ranges or debug_rnglists /// entries and emit them in the output file. Update the relevant attributes /// to point at the new entries. -void DWARFLinker::generateUnitRanges(CompileUnit &Unit, - const DWARFFile &File) const { +void DWARFLinker::generateUnitRanges(CompileUnit &Unit, const DWARFFile &File, + DebugAddrPool &AddrPool) const { if (LLVM_UNLIKELY(Options.Update)) return; @@ -1922,14 +1922,14 @@ } // Emit linked ranges. - TheDwarfEmitter->emitDwarfDebugRangeListFragment(Unit, LinkedRanges, - AttributePatch); + TheDwarfEmitter->emitDwarfDebugRangeListFragment( + Unit, LinkedRanges, AttributePatch, AddrPool); } // Emit ranges for Unit AT_ranges attribute. if (UnitRngListAttribute.has_value()) TheDwarfEmitter->emitDwarfDebugRangeListFragment( - Unit, LinkedFunctionRanges, *UnitRngListAttribute); + Unit, LinkedFunctionRanges, *UnitRngListAttribute, AddrPool); // Emit ranges footer. TheDwarfEmitter->emitDwarfDebugRangeListFooter(Unit, EndLabel); @@ -2571,7 +2571,7 @@ if (LLVM_UNLIKELY(Linker.Options.Update)) continue; - Linker.generateUnitRanges(*CurrentUnit, File); + Linker.generateUnitRanges(*CurrentUnit, File, AddrPool); auto ProcessExpr = [&](SmallVectorImpl &SrcBytes, SmallVectorImpl &OutBytes, diff --git a/llvm/lib/DWARFLinker/DWARFStreamer.cpp b/llvm/lib/DWARFLinker/DWARFStreamer.cpp --- a/llvm/lib/DWARFLinker/DWARFStreamer.cpp +++ b/llvm/lib/DWARFLinker/DWARFStreamer.cpp @@ -455,13 +455,13 @@ void DwarfStreamer::emitDwarfDebugRangeListFragment( const CompileUnit &Unit, const AddressRanges &LinkedRanges, - PatchLocation Patch) { + PatchLocation Patch, DebugAddrPool &AddrPool) { if (Unit.getOrigUnit().getVersion() < 5) { emitDwarfDebugRangesTableFragment(Unit, LinkedRanges, Patch); return; } - emitDwarfDebugRngListsTableFragment(Unit, LinkedRanges, Patch); + emitDwarfDebugRngListsTableFragment(Unit, LinkedRanges, Patch, AddrPool); } void DwarfStreamer::emitDwarfDebugRangeListFooter(const CompileUnit &Unit, @@ -478,25 +478,35 @@ void DwarfStreamer::emitDwarfDebugRngListsTableFragment( const CompileUnit &Unit, const AddressRanges &LinkedRanges, - PatchLocation Patch) { + PatchLocation Patch, DebugAddrPool &AddrPool) { Patch.set(RngListsSectionSize); // Make .debug_rnglists to be current section. MS->switchSection(MC->getObjectFileInfo()->getDwarfRnglistsSection()); - - unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize(); + std::optional BaseAddress; for (const AddressRange &Range : LinkedRanges) { + + if (!BaseAddress) { + BaseAddress = Range.start(); + + // Emit base address. + MS->emitInt8(dwarf::DW_RLE_base_addressx); + RngListsSectionSize += 1; + RngListsSectionSize += + MS->emitULEB128IntValue(AddrPool.getAddrIndex(*BaseAddress)); + } + // Emit type of entry. - MS->emitInt8(dwarf::DW_RLE_start_length); + MS->emitInt8(dwarf::DW_RLE_offset_pair); RngListsSectionSize += 1; - // Emit start address. - MS->emitIntValue(Range.start(), AddressSize); - RngListsSectionSize += AddressSize; + // Emit start offset relative to base address. + RngListsSectionSize += + MS->emitULEB128IntValue(Range.start() - *BaseAddress); - // Emit length of the range. - RngListsSectionSize += MS->emitULEB128IntValue(Range.end() - Range.start()); + // Emit end offset relative to base address. + RngListsSectionSize += MS->emitULEB128IntValue(Range.end() - *BaseAddress); } // Emit the terminator entry. diff --git a/llvm/test/tools/dsymutil/ARM/dwarf5-dwarf4-combination-macho.test b/llvm/test/tools/dsymutil/ARM/dwarf5-dwarf4-combination-macho.test --- a/llvm/test/tools/dsymutil/ARM/dwarf5-dwarf4-combination-macho.test +++ b/llvm/test/tools/dsymutil/ARM/dwarf5-dwarf4-combination-macho.test @@ -146,9 +146,11 @@ CHECK-NEXT: 00000000 [[#sub(RANGE_START,RANGE_LOWPC)]] [[#sub(RANGE_END,RANGE_LOWPC)]] CHECK: .debug_rnglists contents: -CHECK-NEXT: 0x00000000: range list header: length = 0x00000013, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000 +CHECK-NEXT: 0x00000000: range list header: length = 0x0000000e, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000 CHECK-NEXT: ranges: -CHECK-NEXT: [[RANGELIST_OFFSET]]: [DW_RLE_start_length]: {{.*}}[0x[[RANGELIST_OFFSET_START]], 0x[[RANGELIST_OFFSET_END]]) +CHECK-NEXT: [[RANGELIST_OFFSET]]: [DW_RLE_base_addressx]: 0x0000000000000000 +CHECK-NEXT: 0x0000000e: [DW_RLE_offset_pair ]: {{.*}}[0x[[RANGELIST_OFFSET_START]], 0x[[RANGELIST_OFFSET_END]]) +CHECK-NEXT: 0x00000011: [DW_RLE_end_of_list ] CHECK: .debug_names contents: CHECK-NEXT: Name Index @ 0x0 { diff --git a/llvm/test/tools/dsymutil/ARM/dwarf5-macho.test b/llvm/test/tools/dsymutil/ARM/dwarf5-macho.test --- a/llvm/test/tools/dsymutil/ARM/dwarf5-macho.test +++ b/llvm/test/tools/dsymutil/ARM/dwarf5-macho.test @@ -84,9 +84,11 @@ CHECK-NEXT: 0x00000029: "a.cpp" CHECK: .debug_rnglists contents: -CHECK-NEXT: 0x00000000: range list header: length = 0x00000013, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000 +CHECK-NEXT: 0x00000000: range list header: length = 0x0000000e, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000 CHECK-NEXT: ranges: -CHECK-NEXT: [[RANGELIST_OFFSET]]: [DW_RLE_start_length]: {{.*}}[0x[[RANGELIST_OFFSET_START]], 0x[[RANGELIST_OFFSET_END]]) +CHECK-NEXT: [[RANGELIST_OFFSET]]: [DW_RLE_base_addressx]: 0x0000000000000000 +CHECK-NEXT: 0x0000000e: [DW_RLE_offset_pair ]: {{.*}}[0x[[RANGELIST_OFFSET_START]], 0x[[RANGELIST_OFFSET_END]]) +CHECK-NEXT: 0x00000011: [DW_RLE_end_of_list ] CHECK: .debug_names contents: CHECK-NEX:T Name Index @ 0x0 { diff --git a/llvm/test/tools/dsymutil/X86/dwarf5-rnglists.test b/llvm/test/tools/dsymutil/X86/dwarf5-rnglists.test --- a/llvm/test/tools/dsymutil/X86/dwarf5-rnglists.test +++ b/llvm/test/tools/dsymutil/X86/dwarf5-rnglists.test @@ -46,11 +46,12 @@ #DWARF-CHECK: [0x0000000100000f79, 0x0000000100000f96) #DWARF-CHECK: [0x0000000100000fad, 0x0000000100000fb4)) #DWARF-CHECK: .debug_rnglists contents: -#DWARF-CHECK: 0x00000000: range list header: length = 0x0000001d, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000 +#DWARF-CHECK: 0x00000000: range list header: length = 0x00000011, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000 #DWARF-CHECK: ranges: -#DWARF-CHECK: 0x0000000c: [DW_RLE_start_length]: 0x0000000100000f79, 0x000000000000001d => [0x0000000100000f79, 0x0000000100000f96) -#DWARF-CHECK: 0x00000016: [DW_RLE_start_length]: 0x0000000100000fad, 0x0000000000000007 => [0x0000000100000fad, 0x0000000100000fb4) -#DWARF-CHECK: 0x00000020: [DW_RLE_end_of_list ] +#DWARF-CHECK: 0x0000000c: [DW_RLE_base_addressx]: 0x0000000000000003 +#DWARF-CHECK: 0x0000000e: [DW_RLE_offset_pair ]: 0x0000000000000000, 0x000000000000001d => [0x0000000100000f79, 0x0000000100000f96) +#DWARF-CHECK: 0x00000011: [DW_RLE_offset_pair ]: 0x0000000000000034, 0x000000000000003b => [0x0000000100000fad, 0x0000000100000fb4) +#DWARF-CHECK: 0x00000014: [DW_RLE_end_of_list ] # #UPD-DWARF-CHECK: DW_TAG_compile_unit #UPD-DWARF-CHECK: DW_AT_addr_base [DW_FORM_sec_offset] (0x00000008) diff --git a/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-rnglists.test b/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-rnglists.test --- a/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-rnglists.test +++ b/llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-rnglists.test @@ -63,18 +63,23 @@ #DWARF-CHECK: 0x0000000000001160 #DWARF-CHECK: ] #DWARF-CHECK: .debug_rnglists contents: -#DWARF-CHECK: 0x00000000: range list header: length = 0x0000003f, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000 +#DWARF-CHECK: 0x00000000: range list header: length = 0x00000026, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000 #DWARF-CHECK: ranges: -#DWARF-CHECK: 0x[[F1RANGE_OFF]]: [DW_RLE_start_length]: 0x0000000000001130, 0x0000000000000010 => [0x0000000000001130, 0x0000000000001140) -#DWARF-CHECK: {{.*}} [DW_RLE_end_of_list ] -#DWARF-CHECK: 0x[[F2RANGE_OFF]]: [DW_RLE_start_length]: 0x0000000000001140, 0x0000000000000010 => [0x0000000000001140, 0x0000000000001150) -#DWARF-CHECK: {{.*}} [DW_RLE_end_of_list ] -#DWARF-CHECK: 0x[[F3RANGE_OFF]]: [DW_RLE_start_length]: 0x0000000000001150, 0x0000000000000010 => [0x0000000000001150, 0x0000000000001160) -#DWARF-CHECK: {{.*}} [DW_RLE_end_of_list ] -#DWARF-CHECK: 0x[[F4RANGE_OFF]]: [DW_RLE_start_length]: 0x0000000000001160, 0x0000000000000010 => [0x0000000000001160, 0x0000000000001170) -#DWARF-CHECK: {{.*}} [DW_RLE_end_of_list ] -#DWARF-CHECK: 0x[[CURANGE_OFF]]: [DW_RLE_start_length]: 0x0000000000001130, 0x0000000000000040 => [0x0000000000001130, 0x0000000000001170) -#DWARF-CHECK: {{.*}} [DW_RLE_end_of_list ] +#DWARF-CHECK: 0x[[F1RANGE_OFF]]: [DW_RLE_base_addressx]: 0x0000000000000000 +#DWARF-CHECK: {{.}}: [DW_RLE_offset_pair ]: 0x0000000000000000, 0x0000000000000010 => [0x0000000000001130, 0x0000000000001140) +#DWARF-CHECK: {{.}}: [DW_RLE_end_of_list ] +#DWARF-CHECK: 0x[[F2RANGE_OFF]]: [DW_RLE_base_addressx]: 0x0000000000000001 +#DWARF-CHECK: {{.}}: [DW_RLE_offset_pair ]: 0x0000000000000000, 0x0000000000000010 => [0x0000000000001140, 0x0000000000001150) +#DWARF-CHECK: {{.}}: [DW_RLE_end_of_list ] +#DWARF-CHECK: 0x[[F3RANGE_OFF]]: [DW_RLE_base_addressx]: 0x0000000000000002 +#DWARF-CHECK: {{.}}: [DW_RLE_offset_pair ]: 0x0000000000000000, 0x0000000000000010 => [0x0000000000001150, 0x0000000000001160) +#DWARF-CHECK: {{.}}: [DW_RLE_end_of_list ] +#DWARF-CHECK: 0x[[F4RANGE_OFF]]: [DW_RLE_base_addressx]: 0x0000000000000003 +#DWARF-CHECK: {{.}}: [DW_RLE_offset_pair ]: 0x0000000000000000, 0x0000000000000010 => [0x0000000000001160, 0x0000000000001170) +#DWARF-CHECK: {{.}}: [DW_RLE_end_of_list ] +#DWARF-CHECK 0x[[CURANGE_OFF]]: [DW_RLE_base_addressx]: 0x0000000000000000 +#DWARF-CHECK: {{.}}: [DW_RLE_offset_pair ]: 0x0000000000000000, 0x0000000000000040 => [0x0000000000001130, 0x0000000000001170) +#DWARF-CHECK: {{.}}: [DW_RLE_end_of_list ] #UPD-DWARF-CHECK: DW_TAG_compile_unit #UPD-DWARF-CHECK: DW_AT_name {{.*}}"CU1"