Index: llvm/include/llvm/DWARFLinker/DWARFLinker.h =================================================================== --- llvm/include/llvm/DWARFLinker/DWARFLinker.h +++ llvm/include/llvm/DWARFLinker/DWARFLinker.h @@ -97,10 +97,6 @@ /// Emit the string table described by \p Pool into .debug_line_str table. virtual void emitLineStrings(const NonRelocatableStringpool &Pool) = 0; - /// Emit the address described by \p Addrs into the .debug_addr section. - virtual void emitAddrs(const SmallVector &Addrs, - uint8_t AddrSize) = 0; - /// Emit DWARF debug names. virtual void emitDebugNames(AccelTable &Table) = 0; @@ -137,9 +133,6 @@ /// Emit debug locations (.debug_loc, .debug_loclists) header. virtual MCSymbol *emitDwarfDebugLocListHeader(const CompileUnit &Unit) = 0; - /// Emit .debug_addr header. - virtual MCSymbol *emitDwarfDebugAddrHeader(const CompileUnit &Unit) = 0; - /// Emit debug locations (.debug_loc, .debug_loclists) fragment. virtual void emitDwarfDebugLocListFragment( const CompileUnit &Unit, @@ -150,9 +143,16 @@ virtual void emitDwarfDebugLocListFooter(const CompileUnit &Unit, MCSymbol *EndLabel) = 0; + /// Emit .debug_addr header. + virtual MCSymbol *emitDwarfDebugAddrsHeader(const CompileUnit &Unit) = 0; + + /// Emit the addresses described by \p Addrs into the .debug_addr section. + virtual void emitDwarfDebugAddrs(const SmallVector &Addrs, + uint8_t AddrSize) = 0; + /// Emit .debug_addr footer. - virtual void emitDwarfDebugAddrFooter(const CompileUnit &Unit, - MCSymbol *EndLabel) = 0; + virtual void emitDwarfDebugAddrsFooter(const CompileUnit &Unit, + MCSymbol *EndLabel) = 0; /// Emit .debug_aranges entries for \p Unit virtual void @@ -222,6 +222,9 @@ /// Returns size of generated .debug_loclists section. virtual uint64_t getLocListsSectionSize() const = 0; + /// Returns size of generated .debug_addr section. + virtual uint64_t getDebugAddrSectionSize() const = 0; + /// Dump the file to the disk. virtual void finish() = 0; @@ -640,15 +643,6 @@ struct DebugAddrPool { DenseMap AddrIndexMap; SmallVector Addrs; - uint64_t Index; - - DebugAddrPool() : Index(0) {} - - void clear() { - AddrIndexMap.clear(); - Addrs.clear(); - Index = 0; - } uint64_t getAddrIndex(uint64_t Addr) { DenseMap::iterator It = AddrIndexMap.find(Addr); @@ -658,6 +652,12 @@ } return It->second; } + + void clear() { + AddrIndexMap.clear(); + Addrs.clear(); + } + }; DebugAddrPool AddrPool; @@ -704,6 +704,10 @@ uint64_t cloneAllCompileUnits(DWARFContext &DwarfContext, const DWARFFile &File, bool IsLittleEndian); + /// Emit the .debug_addr section for the \p Unit. + void emitDebugAddrSection(CompileUnit &Unit, + const uint16_t DwarfVersion) const; + private: using AttributeSpec = DWARFAbbreviationDeclaration::AttributeSpec; @@ -828,9 +832,6 @@ void generateUnitLocations(CompileUnit &Unit, const DWARFFile &File, ExpressionHandlerRef ExprHandler) const; - void emitDebugAddrSection(CompileUnit &Unit, - SmallVector &Addrs) const; - /// Emit the accelerator entries for \p Unit. void emitAcceleratorEntriesForUnit(CompileUnit &Unit); Index: llvm/include/llvm/DWARFLinker/DWARFStreamer.h =================================================================== --- llvm/include/llvm/DWARFLinker/DWARFStreamer.h +++ llvm/include/llvm/DWARFLinker/DWARFStreamer.h @@ -84,9 +84,6 @@ /// Emit the string table described by \p Pool into .debug_line_str table. void emitLineStrings(const NonRelocatableStringpool &Pool) override; - /// Emit the addresses described by \p Pool into .debug_addr table. - void emitAddrs(const SmallVector &Addrs, uint8_t AddrSize) override; - /// Emit the swift_ast section stored in \p Buffer. void emitSwiftAST(StringRef Buffer) override; @@ -111,7 +108,15 @@ MCSymbol *emitDwarfDebugLocListHeader(const CompileUnit &Unit) override; /// Emit .debug_addr header. - MCSymbol *emitDwarfDebugAddrHeader(const CompileUnit &Unit) override; + MCSymbol *emitDwarfDebugAddrsHeader(const CompileUnit &Unit) override; + + /// Emit the addresses described by \p Addrs into .debug_addr table. + void emitDwarfDebugAddrs(const SmallVector &Addrs, + uint8_t AddrSize) override; + + /// Emit .debug_addr footer. + void emitDwarfDebugAddrsFooter(const CompileUnit &Unit, + MCSymbol *EndLabel) override; /// Emit debug ranges(.debug_loc, .debug_loclists) fragment. void emitDwarfDebugLocListFragment( @@ -123,10 +128,6 @@ void emitDwarfDebugLocListFooter(const CompileUnit &Unit, MCSymbol *EndLabel) override; - /// Emit .debug_addr footer. - void emitDwarfDebugAddrFooter(const CompileUnit &Unit, - MCSymbol *EndLabel) override; - /// Emit .debug_aranges entries for \p Unit void emitDwarfDebugArangesTable(const CompileUnit &Unit, const AddressRanges &LinkedRanges) override; @@ -195,6 +196,8 @@ return LocListsSectionSize; } + uint64_t getDebugAddrSectionSize() const override { return AddrSectionSize; } + void emitMacroTables(DWARFContext *Context, const Offset2UnitMap &UnitMacroMap, OffsetsStringPool &StringPool) override; Index: llvm/lib/DWARFLinker/DWARFLinker.cpp =================================================================== --- llvm/lib/DWARFLinker/DWARFLinker.cpp +++ llvm/lib/DWARFLinker/DWARFLinker.cpp @@ -1365,6 +1365,11 @@ std::optional Addr = AddrAttribute->getAsAddress(); if (!Addr) { Linker.reportWarning("Cann't read address attribute value.", ObjFile); + // If the attribute is of form addrx* and the DW_AT_addr_base is not set, do + // not emit the .debug_addr section + if (AttrSpec.Form != dwarf::DW_FORM_addr && + !AddrAttribute->getUnit()->getAddrOffsetSectionBase()) + return 0; Addr = 0; } @@ -1384,15 +1389,18 @@ *Addr += Info.PCOffset; } - Die.addValue(DIEAlloc, static_cast(AttrSpec.Attr), - AttrSpec.Form, - DIEInteger(AddrAttribute->getForm() != dwarf::DW_FORM_addr - ? AddrPool.getAddrIndex(*Addr) - : *Addr)); + if (AttrSpec.Form == dwarf::DW_FORM_addr) { + Die.addValue(DIEAlloc, static_cast(AttrSpec.Attr), + AttrSpec.Form, DIEInteger(*Addr)); + return Unit.getOrigUnit().getAddressByteSize(); + } + + auto AddrIndex = AddrPool.getAddrIndex(*Addr); - return AttrSpec.Form == dwarf::DW_FORM_addr - ? Unit.getOrigUnit().getAddressByteSize() - : AttrSize; + return Die + .addValue(DIEAlloc, static_cast(AttrSpec.Attr), + dwarf::Form::DW_FORM_addrx, DIEInteger(AddrIndex)) + ->sizeOf(Unit.getOrigUnit().getFormParams()); } unsigned DWARFLinker::DIECloner::cloneScalarAttribute( @@ -1656,8 +1664,6 @@ case dwarf::DW_AT_high_pc: case dwarf::DW_AT_ranges: return !Update && SkipPC; - case dwarf::DW_AT_addr_base: - return false; case dwarf::DW_AT_rnglists_base: // In case !Update the .debug_addr table is not generated/preserved. // Thus instead of DW_FORM_rnglistx the DW_FORM_sec_offset is used. @@ -1991,14 +1997,34 @@ TheDwarfEmitter->emitDwarfDebugLocListFooter(Unit, EndLabel); } -void DWARFLinker::emitDebugAddrSection(CompileUnit &Unit, - SmallVector &Addrs) const { - if (LLVM_UNLIKELY(Options.Update)) +static void patchAddrBase(DIE &Die, DIEInteger Offset) { + for (auto &V : Die.values()) + if (V.getAttribute() == dwarf::DW_AT_addr_base) { + V = DIEValue(V.getAttribute(), V.getForm(), Offset); + return; + } + + llvm_unreachable("Didn't find a DW_AT_addr_base in cloned DIE!"); +} + +void DWARFLinker::DIECloner::emitDebugAddrSection( + CompileUnit &Unit, + const uint16_t DwarfVersion) const { + + if (LLVM_UNLIKELY(Linker.Options.Update)) + return; + + if (DwarfVersion < 5) + return; + + if (AddrPool.Addrs.empty()) return; - MCSymbol *EndLabel = TheDwarfEmitter->emitDwarfDebugAddrHeader(Unit); - TheDwarfEmitter->emitAddrs(Addrs, Unit.getOrigUnit().getAddressByteSize()); - TheDwarfEmitter->emitDwarfDebugAddrFooter(Unit, EndLabel); + MCSymbol *EndLabel = Emitter->emitDwarfDebugAddrsHeader(Unit); + patchAddrBase(*Unit.getOutputUnitDIE(), + DIEInteger(Emitter->getDebugAddrSectionSize())); + Emitter->emitDwarfDebugAddrs(AddrPool.Addrs, Unit.getOrigUnit().getAddressByteSize()); + Emitter->emitDwarfDebugAddrsFooter(Unit, EndLabel); } /// Insert the new line info sequence \p Seq into the current @@ -2566,10 +2592,10 @@ IsLittleEndian); }; Linker.generateUnitLocations(*CurrentUnit, File, ProcessExpr); - if (DwarfVersion >= 5) - Linker.emitDebugAddrSection(*CurrentUnit, AddrPool.Addrs); - AddrPool.clear(); + if (!AddrPool.Addrs.empty()) + emitDebugAddrSection(*CurrentUnit, DwarfVersion); } + AddrPool.clear(); } if (Emitter != nullptr) { Index: llvm/lib/DWARFLinker/DWARFStreamer.cpp =================================================================== --- llvm/lib/DWARFLinker/DWARFStreamer.cpp +++ llvm/lib/DWARFLinker/DWARFStreamer.cpp @@ -270,16 +270,6 @@ } } -/// Emit the debug_addr section stored in \p Pool. -void DwarfStreamer::emitAddrs(const SmallVector &Addrs, - uint8_t AddrSize) { - Asm->OutStreamer->switchSection(MOFI->getDwarfAddrSection()); - for (auto Addr : Addrs) { - Asm->OutStreamer->emitIntValue(Addr, AddrSize); - AddrSectionSize += AddrSize; - } -} - void DwarfStreamer::emitDebugNames( AccelTable &Table) { if (EmittedUnits.empty()) @@ -550,38 +540,6 @@ return EndLabel; } -/// Emit .debug_addr header. -MCSymbol *DwarfStreamer::emitDwarfDebugAddrHeader(const CompileUnit &Unit) { - if (Unit.getOrigUnit().getVersion() < 5) - return nullptr; - - // Make .debug_addr the current section. - MS->switchSection(MC->getObjectFileInfo()->getDwarfAddrSection()); - - MCSymbol *BeginLabel = Asm->createTempSymbol("Bdebugaddr"); - MCSymbol *EndLabel = Asm->createTempSymbol("Edebugaddr"); - unsigned AddrSize = Unit.getOrigUnit().getAddressByteSize(); - - // emit length. - Asm->emitLabelDifference(EndLabel, BeginLabel, sizeof(uint32_t)); - Asm->OutStreamer->emitLabel(BeginLabel); - AddrSectionSize += sizeof(uint32_t); - - // emit version - Asm->emitInt16(5); - AddrSectionSize += 2; - - // emit address size. - Asm->emitInt8(AddrSize); - AddrSectionSize += 1; - - // emit segment size. - Asm->emitInt8(0); - AddrSectionSize += 1; - - return EndLabel; -} - /// Emit debug locations(.debug_loc, .debug_loclists) fragment. void DwarfStreamer::emitDwarfDebugLocListFragment( const CompileUnit &Unit, @@ -608,19 +566,6 @@ Asm->OutStreamer->emitLabel(EndLabel); } -/// Emit .debug_addr footer. -void DwarfStreamer::emitDwarfDebugAddrFooter(const CompileUnit &Unit, - MCSymbol *EndLabel) { - if (Unit.getOrigUnit().getVersion() < 5) - return; - - // Make .debug_addr the current section. - MS->switchSection(MC->getObjectFileInfo()->getDwarfAddrSection()); - - if (EndLabel != nullptr) - Asm->OutStreamer->emitLabel(EndLabel); -} - /// Emit piece of .debug_loc for \p LinkedLocationExpression. void DwarfStreamer::emitDwarfDebugLocTableFragment( const CompileUnit &Unit, @@ -661,6 +606,57 @@ LocSectionSize += AddressSize; } +/// Emit .debug_addr header. +MCSymbol *DwarfStreamer::emitDwarfDebugAddrsHeader(const CompileUnit &Unit) { + + // Make .debug_addr the current section. + MS->switchSection(MC->getObjectFileInfo()->getDwarfAddrSection()); + + MCSymbol *BeginLabel = Asm->createTempSymbol("Bdebugaddr"); + MCSymbol *EndLabel = Asm->createTempSymbol("Edebugaddr"); + unsigned AddrSize = Unit.getOrigUnit().getAddressByteSize(); + + // Emit length. + Asm->emitLabelDifference(EndLabel, BeginLabel, sizeof(uint32_t)); + Asm->OutStreamer->emitLabel(BeginLabel); + AddrSectionSize += sizeof(uint32_t); + + // Emit version. + Asm->emitInt16(5); + AddrSectionSize += 2; + + // Emit address size. + Asm->emitInt8(AddrSize); + AddrSectionSize += 1; + + // Emit segment size. + Asm->emitInt8(0); + AddrSectionSize += 1; + + return EndLabel; +} + +/// Emit the .debug_addr addresses stored in \p Addrs. +void DwarfStreamer::emitDwarfDebugAddrs(const SmallVector &Addrs, + uint8_t AddrSize) { + Asm->OutStreamer->switchSection(MOFI->getDwarfAddrSection()); + for (auto Addr : Addrs) { + Asm->OutStreamer->emitIntValue(Addr, AddrSize); + AddrSectionSize += AddrSize; + } +} + +/// Emit .debug_addr footer. +void DwarfStreamer::emitDwarfDebugAddrsFooter(const CompileUnit &Unit, + MCSymbol *EndLabel) { + + // Make .debug_addr the current section. + MS->switchSection(MC->getObjectFileInfo()->getDwarfAddrSection()); + + if (EndLabel != nullptr) + Asm->OutStreamer->emitLabel(EndLabel); +} + /// Emit piece of .debug_loclists for \p LinkedLocationExpression. void DwarfStreamer::emitDwarfDebugLocListsTableFragment( const CompileUnit &Unit, Index: llvm/test/tools/dsymutil/ARM/dummy-debug-map-amr64.map =================================================================== --- llvm/test/tools/dsymutil/ARM/dummy-debug-map-amr64.map +++ llvm/test/tools/dsymutil/ARM/dummy-debug-map-amr64.map @@ -14,5 +14,8 @@ - filename: 2.o symbols: - { sym: __Z3foov, objAddr: 0x0, binAddr: 0x20000, size: 0x10 } + - filename: 3.o + symbols: + - { sym: __Z3foov, objAddr: 0x0, binAddr: 0x30000, size: 0x10 } ... Index: llvm/test/tools/dsymutil/ARM/dwarf5-addr_base.test =================================================================== --- /dev/null +++ llvm/test/tools/dsymutil/ARM/dwarf5-addr_base.test @@ -0,0 +1,153 @@ +; This test checks to ensure that if three DWARFv5 object files have correct values for the DW_AT_addr_base in their compile units. + +; 1.o was produced with the source file: + +; a.cpp +; __attribute__((section("1,__text_foo"))) void foo() {} +; +; int foo2(int a) { +; return a+5; +; } +; +; int foo3(int x) { +; return x+2; +; } +; +; int main () { +; return 1; +; } + +; clang -g -c -O1 a.cpp -gdwarf-5 -o 1.o + +; 2.o was produced with the following source file: + +; b.cpp +; __attribute__((section("1,__text_foo"))) void bar() {} +; +; int bar2(int a) { +; return a+5; +; } +; +; int bar3(int x) { +; return x+2; +; } + +; clang -g -c -O1 b.cpp -gdwarf-5 -o 2.o + +; 3.o was produced with the following source file: + +; c.cpp +; +; int baz(int x) { +; return x+2; +; } + +; clang -g -c -O1 c.cpp -gdwarf-5 -o 3.o + + +RUN: rm -rf %t.dir && mkdir -p %t.dir +RUN: dsymutil -y %p/dummy-debug-map-amr64.map -oso-prepend-path=%p/../Inputs/DWARF5-addr_base -o %t.dir/dwarf5-addr_base.dSYM +RUN: llvm-dwarfdump %t.dir/dwarf5-addr_base.dSYM -a --verbose | FileCheck %s + +RUN: dsymutil --update -y %p/dummy-debug-map-amr64.map -oso-prepend-path=%p/../Inputs/DWARF5-addr_base -o %t.dir/dwarf5-addr_base.dSYM +RUN: llvm-dwarfdump %t.dir/dwarf5-addr_base.dSYM -a --verbose | FileCheck %s --check-prefix=UPD + +CHECK: .debug_info contents: +CHECK-NEXT: 0x00000000: Compile Unit: length = 0x00000061, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x0000, addr_size = 0x08 (next unit at 0x00000065) + +CHECK: 0x0000000c: DW_TAG_compile_unit [1] * +CHECK: DW_AT_addr_base [DW_FORM_sec_offset] (0x00000008) + +CHECK: 0x00000037: DW_TAG_subprogram [2] * (0x0000000c) +CHECK-NEXT: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000000) address = 0x[[ADDR1:[0-9a-f]+]]) + + +CHECK: 0x00000065: Compile Unit: length = 0x00000061, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x0000, addr_size = 0x08 (next unit at 0x000000ca) + +CHECK: 0x00000071: DW_TAG_compile_unit [1] * +CHECK: DW_AT_addr_base [DW_FORM_sec_offset] (0x00000018) + +CHECK: 0x0000009c: DW_TAG_subprogram [2] * (0x00000071) +CHECK-NEXT: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000000) address = 0x[[ADDR2:[0-9a-f]+]]) + +CHECK: 0x000000ca: Compile Unit: length = 0x0000005a, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x0000, addr_size = 0x08 (next unit at 0x00000128) + +CHECK: 0x000000d6: DW_TAG_compile_unit [5] * +CHECK: DW_AT_addr_base [DW_FORM_sec_offset] (0x00000028) + +CHECK: 0x000000fa: DW_TAG_subprogram [2] * (0x000000d6) +CHECK-NEXT: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000000) address = 0x[[ADDR3:[0-9a-f]+]]) + +CHECK: .debug_addr contents: +CHECK-NEXT: 0x00000000: Address table header: length = 0x0000000c, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00 +CHECK-NEXT: Addrs: [ +CHECK-NEXT: 0x[[ADDR1]] +CHECK-NEXT: ] +CHECK-NEXT: 0x00000010: Address table header: length = 0x0000000c, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00 +CHECK-NEXT: Addrs: [ +CHECK-NEXT: 0x[[ADDR2]] +CHECK-NEXT: ] +CHECK-NEXT: 0x00000020: Address table header: length = 0x0000000c, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00 +CHECK-NEXT: Addrs: [ +CHECK-NEXT: 0x[[ADDR3]] +CHECK-NEXT: ] + +UPD: .debug_info contents: +UPD-NEXT: 0x00000000: Compile Unit: length = 0x000000aa, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x0000, addr_size = 0x08 (next unit at 0x000000ae) + +UPD: 0x0000000c: DW_TAG_compile_unit [1] * +UPD: DW_AT_addr_base [DW_FORM_sec_offset] (0x00000008) + +UPD: 0x0000003c: DW_TAG_subprogram [2] (0x0000000c) +UPD-NEXT: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000000) address = 0x0000000000000018) + +UPD: 0x0000004e: DW_TAG_subprogram [3] * (0x0000000c) +UPD-NEXT: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000001) address = 0x0000000000000000) + +UPD: 0x00000071: DW_TAG_subprogram [3] * (0x0000000c) +UPD-NEXT: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000002) address = 0x0000000000000008) + +UPD: 0x00000094: DW_TAG_subprogram [5] (0x0000000c) +UPD-NEXT: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000003) address = 0x0000000000000010) + + +UPD: 0x000000ae: Compile Unit: length = 0x00000098, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x0000, addr_size = 0x08 (next unit at 0x0000014a) + +UPD: 0x000000ba: DW_TAG_compile_unit [1] * +UPD: DW_AT_addr_base [DW_FORM_sec_offset] (0x00000008) + +UPD: 0x000000ea: DW_TAG_subprogram [2] (0x000000ba) +UPD-NEXT: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000000) address = 0x0000000000000018) + +UPD: 0x000000fc: DW_TAG_subprogram [3] * (0x000000ba) +UPD-NEXT: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000001) address = 0x0000000000000000) + +UPD: 0x0000011f: DW_TAG_subprogram [3] * (0x000000ba) +UPD-NEXT: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000002) address = 0x0000000000000008) + +UPD: 0x0000014a: Compile Unit: length = 0x0000005b, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x0000, addr_size = 0x08 (next unit at 0x000001a9) + +UPD: 0x00000156: DW_TAG_compile_unit [7] * +UPD: DW_AT_addr_base [DW_FORM_sec_offset] (0x00000008) + +UPD: 0x0000017e: DW_TAG_subprogram [3] * (0x00000156) +UPD-NEXT: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000000) address = 0x0000000000000018) + +UPD: .debug_addr contents: +UPD-NEXT: 0x00000000: Address table header: length = 0x00000024, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00 +UPD-NEXT: Addrs: [ +UPD-NEXT: 0x0000000000000018 +UPD-NEXT: 0x0000000000000000 +UPD-NEXT: 0x0000000000000008 +UPD-NEXT: 0x0000000000000010 +UPD-NEXT: ] +UPD-NEXT: 0x00000028: Address table header: length = 0x0000001c, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00 +UPD-NEXT: Addrs: [ +UPD-NEXT: 0x0000000000000010 +UPD-NEXT: 0x0000000000000000 +UPD-NEXT: 0x0000000000000008 +UPD-NEXT: ] +UPD-NEXT: 0x00000048: Address table header: length = 0x0000000c, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00 +UPD-NEXT: Addrs: [ +UPD-NEXT: 0x0000000000000000 +UPD-NEXT: ] Index: llvm/test/tools/dsymutil/ARM/dwarf5-dwarf4-combination-macho.test =================================================================== --- llvm/test/tools/dsymutil/ARM/dwarf5-dwarf4-combination-macho.test +++ llvm/test/tools/dsymutil/ARM/dwarf5-dwarf4-combination-macho.test @@ -42,6 +42,7 @@ CHECK: 0x00000000: Compile Unit: length = 0x00000061, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x0000, addr_size = 0x08 CHECK: DW_AT_ranges [DW_FORM_sec_offset] (0x[[RANGELIST_OFFSET:[0-9a-f]+]] CHECK-NEXT: [0x[[RANGELIST_OFFSET_START:[0-9a-f]+]], 0x[[RANGELIST_OFFSET_END:[0-9a-f]+]])) +CHECK-NEXT: DW_AT_addr_base [DW_FORM_sec_offset] (0x00000008) CHECK: 0x00000037: DW_TAG_subprogram [2] * (0x0000000c) CHECK-NEXT: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000000) address = 0x[[#%.16x,LOCLIST_LOWPC:]]) CHECK: 0x0000004d: DW_TAG_formal_parameter [3] (0x00000037) Index: llvm/test/tools/dsymutil/ARM/dwarf5-macho.test =================================================================== --- llvm/test/tools/dsymutil/ARM/dwarf5-macho.test +++ llvm/test/tools/dsymutil/ARM/dwarf5-macho.test @@ -28,6 +28,7 @@ CHECK-NEXT: Compile Unit: length = 0x00000061, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x0000, addr_size = 0x08 CHECK: DW_AT_ranges [DW_FORM_sec_offset] (0x[[RANGELIST_OFFSET:[0-9a-f]+]] CHECK-NEXT: [0x[[RANGELIST_OFFSET_START:[0-9a-f]+]], 0x[[RANGELIST_OFFSET_END:[0-9a-f]+]])) +CHECK-NEXT: DW_AT_addr_base [DW_FORM_sec_offset] (0x00000008) CHECK: 0x00000037: DW_TAG_subprogram [2] * (0x0000000c) CHECK-NEXT: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000000) address = 0x[[#%.16x,LOCLIST_LOWPC:]]) CHECK: 0x0000004d: DW_TAG_formal_parameter [3] (0x00000037) Index: llvm/test/tools/dsymutil/X86/dwarf5-addrx.test =================================================================== --- llvm/test/tools/dsymutil/X86/dwarf5-addrx.test +++ llvm/test/tools/dsymutil/X86/dwarf5-addrx.test @@ -58,6 +58,7 @@ DWARF: DW_AT_name [DW_FORM_strp] {{.*}} "dwarf5-addrx.c" DWARF: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000000) address = 0x0000000100000eb0) DWARF: DW_AT_high_pc [DW_FORM_data4] (0x00000103) +DWARF: DW_AT_addr_base [DW_FORM_sec_offset] (0x00000008) DWARF: DW_TAG_subprogram DWARF: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000000) address = 0x0000000100000eb0) DWARF: DW_AT_high_pc [DW_FORM_data4] (0x00000010) Index: llvm/test/tools/dsymutil/X86/dwarf5-rnglists.test =================================================================== --- llvm/test/tools/dsymutil/X86/dwarf5-rnglists.test +++ llvm/test/tools/dsymutil/X86/dwarf5-rnglists.test @@ -40,6 +40,7 @@ #CHECK: No errors. #DWARF-CHECK: DW_TAG_compile_unit +#DWARF-CHECK: DW_AT_addr_base [DW_FORM_sec_offset] (0x00000008) #DWARF-CHECK: DW_TAG_lexical_block #DWARF-CHECK: DW_AT_ranges [DW_FORM_sec_offset] (0x0000000c #DWARF-CHECK: [0x0000000100000f79, 0x0000000100000f96) @@ -52,6 +53,7 @@ #DWARF-CHECK: 0x00000020: [DW_RLE_end_of_list ] # #UPD-DWARF-CHECK: DW_TAG_compile_unit +#UPD-DWARF-CHECK: DW_AT_addr_base [DW_FORM_sec_offset] (0x00000008) #UPD-DWARF-CHECK: DW_TAG_lexical_block #UPD-DWARF-CHECK: DW_AT_ranges [DW_FORM_rnglistx] (indexed (0x0) rangelist = 0x00000010 #UPD-DWARF-CHECK: [0x0000000000000009, 0x0000000000000026) Index: llvm/test/tools/dsymutil/dwarf5-addrbase-broken.test =================================================================== --- /dev/null +++ llvm/test/tools/dsymutil/dwarf5-addrbase-broken.test @@ -0,0 +1,284 @@ +## This test checks handling of DWARFv5 address attribute. +## It contains two compile units. One is a good one and +## should be processed correctly. Second is a bad - it +## missing DW_AT_addr_base attribute. All address attributes +## inside this unit should be skipped. + +# RUN: yaml2obj %s -o %t.o +# RUN: echo '---' > %t2.map +# RUN: echo "triple: 'x86_64-apple-darwin'" >> %t2.map +# RUN: echo 'objects:' >> %t2.map +# RUN: echo " - filename: '%t.o'" >> %t2.map +# RUN: echo ' symbols:' >> %t2.map +# RUN: echo ' - { sym: __Z3foov, objAddr: 0x0, binAddr: 0x10000, size: 0x10 }' >> %t2.map +# RUN: echo '...' >> %t2.map +# RUN: dsymutil -y %t2.map -f -o - | llvm-dwarfdump -a - | FileCheck %s + +# CHECK: file format Mach-O 64-bit x86-64 +# CHECK: .debug_info contents: +# CHECK: Compile Unit: +# CHECK: DW_TAG_compile_unit +# CHECK: DW_AT_name{{.*}}"GoodCU" +# CHECK: DW_AT_low_pc +# CHECK: DW_TAG_subprogram +# CHECK: DW_AT_name{{.*}}"foo" +# CHECK: DW_TAG_variable +# CHECK: DW_AT_name{{.*}}"var1" +# CHECK: DW_AT_location (DW_OP_addr +# CHECK: 0x0000004e: NULL +# CHECK: Compile Unit: +# CHECK: DW_TAG_compile_unit +# CHECK-NOT: DW_AT_low_pc +# CHECK: DW_AT_name{{.*}}"BadCU" +# CHECK-NOT: DW_TAG_subprogram +# CHECK-NOT: DW_TAG_variable +# CHECK: 0x0000006b: NULL + +--- !mach-o +FileHeader: + magic: 0xFEEDFACF + cputype: 0x01000007 + cpusubtype: 0x00000003 + filetype: 0x00000001 + ncmds: 2 + sizeofcmds: 472 + flags: 0x00002000 + reserved: 0x00000000 +LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 312 + segname: '' + vmaddr: 0x00 + vmsize: 0x300 + fileoff: 0x300 + filesize: 0x300 + maxprot: 7 + initprot: 7 + nsects: 3 + flags: 0 + Sections: + - sectname: __debug_abbrev + segname: __DWARF + addr: 0x000000000000000F + size: 0x60 + offset: 0x00000210 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __debug_info + segname: __DWARF + addr: 0x000000000000100 + size: 0x9e + offset: 0x00000310 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __debug_addr + segname: __DWARF + addr: 0x0000000000000200 + size: 0x30 + offset: 0x00000400 + align: 0 + reloff: 0x00000600 + nreloc: 2 + flags: 0x02000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + relocations: + - address: 0x8 + symbolnum: 1 + pcrel: true + length: 3 + extern: true + type: 0 + scattered: false + value: 0 + - address: 0x1c + symbolnum: 1 + pcrel: true + length: 3 + extern: true + type: 0 + scattered: false + value: 0 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 0x700 + nsyms: 2 + stroff: 0x720 + strsize: 10 +LinkEditData: + NameList: + - n_strx: 1 + n_type: 0x0F + n_sect: 1 + n_desc: 0 + n_value: 0 + - n_strx: 1 + n_type: 0x0F + n_sect: 1 + n_desc: 0 + n_value: 0 + StringTable: + - '' + - '__Z3foov' + - '' +DWARF: + debug_abbrev: + - Table: + - Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_producer + Form: DW_FORM_string + - Attribute: DW_AT_language + Form: DW_FORM_data2 + - Attribute: DW_AT_name + Form: DW_FORM_string + - Attribute: DW_AT_low_pc + Form: DW_FORM_addrx + - Attribute: DW_AT_high_pc + Form: DW_FORM_data8 + - Attribute: DW_AT_addr_base + Form: DW_FORM_sec_offset + - Tag: DW_TAG_subprogram + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_string + - Attribute: DW_AT_low_pc + Form: DW_FORM_addrx + - Attribute: DW_AT_high_pc + Form: DW_FORM_data8 + - Attribute: DW_AT_type + Form: DW_FORM_ref4 + - Tag: DW_TAG_base_type + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_string + - Tag: DW_TAG_variable + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_string + - Attribute: DW_AT_type + Form: DW_FORM_ref4 + - Attribute: DW_AT_location + Form: DW_FORM_exprloc + - Table: + - Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_producer + Form: DW_FORM_string + - Attribute: DW_AT_language + Form: DW_FORM_data2 + - Attribute: DW_AT_name + Form: DW_FORM_string + - Attribute: DW_AT_low_pc + Form: DW_FORM_addrx + - Attribute: DW_AT_high_pc + Form: DW_FORM_data8 + - Tag: DW_TAG_subprogram + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_string + - Attribute: DW_AT_low_pc + Form: DW_FORM_addrx + - Attribute: DW_AT_high_pc + Form: DW_FORM_data8 + - Attribute: DW_AT_type + Form: DW_FORM_ref4 + - Tag: DW_TAG_base_type + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_string + - Tag: DW_TAG_variable + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_string + - Attribute: DW_AT_type + Form: DW_FORM_ref4 + - Attribute: DW_AT_location + Form: DW_FORM_exprloc + debug_info: + - Version: 5 + UnitType: DW_UT_compile + Entries: + - AbbrCode: 1 + Values: + - CStr: by_hand + - Value: 0x04 + - CStr: GoodCU + - Value: 0x0 + - Value: 0x10 + - Value: 0x8 + - AbbrCode: 2 + Values: + - CStr: foo + - Value: 0x0 + - Value: 0x10 + - Value: 0x3e + - AbbrCode: 0 + - AbbrCode: 3 + Values: + - CStr: int + - AbbrCode: 4 + Values: + - CStr: var1 + - Value: 0x0000003e + - BlockData: + - 0xa1 + - 0x00 + - AbbrCode: 0 + - Version: 5 + UnitType: DW_UT_compile + Entries: + - AbbrCode: 1 + Values: + - CStr: by_hand + - Value: 0x04 + - CStr: BadCU + - Value: 0x0 + - Value: 0x10 + - AbbrCode: 2 + Values: + - CStr: foo1 + - Value: 0x0 + - Value: 0x10 + - Value: 0x3e + - AbbrCode: 0 + - AbbrCode: 3 + Values: + - CStr: int + - AbbrCode: 4 + Values: + - CStr: var1 + - Value: 0x0000003e + - BlockData: + - 0xa1 + - 0x00 + - AbbrCode: 0 + debug_addr: + - Version: 5 + AddressSize: 0x08 + Entries: + - Address: 0x1130 + - Version: 5 + AddressSize: 0x08 + Entries: + - Address: 0x10 +... Index: llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-addresses.test =================================================================== --- llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-addresses.test +++ llvm/test/tools/llvm-dwarfutil/ELF/X86/dwarf5-addresses.test @@ -41,15 +41,15 @@ #DWARF-CHECK: DW_AT_high_pc [DW_FORM_data8] (0x0000000000000010) #DWARF-CHECK: DW_TAG_subprogram #DWARF-CHECK: DW_AT_name [DW_FORM_strp] {{.*}} "foo4" -#DWARF-CHECK: DW_AT_low_pc [DW_FORM_addrx1] (indexed (00000003) address = 0x0000000000001160) +#DWARF-CHECK: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000003) address = 0x0000000000001160) #DWARF-CHECK: DW_AT_high_pc [DW_FORM_data8] (0x0000000000000010) #DWARF-CHECK: DW_TAG_subprogram #DWARF-CHECK: DW_AT_name [DW_FORM_strp] {{.*}} "foo5" -#DWARF-CHECK: DW_AT_low_pc [DW_FORM_addrx2] (indexed (00000004) address = 0x0000000000001170) +#DWARF-CHECK: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000004) address = 0x0000000000001170) #DWARF-CHECK: DW_AT_high_pc [DW_FORM_data8] (0x0000000000000010) #DWARF-CHECK: DW_TAG_subprogram #DWARF-CHECK: DW_AT_name [DW_FORM_strp] {{.*}} "foo6" -#DWARF-CHECK: DW_AT_low_pc [DW_FORM_addrx4] (indexed (00000005) address = 0x0000000000001180) +#DWARF-CHECK: DW_AT_low_pc [DW_FORM_addrx] (indexed (00000005) address = 0x0000000000001180) #DWARF-CHECK: DW_AT_high_pc [DW_FORM_data8] (0x0000000000000010) #DWARF-CHECK: DW_TAG_variable #DWARF-CHECK: DW_AT_name [DW_FORM_strp] {{.*}} "var1"