diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h --- a/llvm/include/llvm/CodeGen/AsmPrinter.h +++ b/llvm/include/llvm/CodeGen/AsmPrinter.h @@ -645,8 +645,9 @@ /// Emit a unit length field. The actual format, DWARF32 or DWARF64, is chosen /// according to the settings. - void emitDwarfUnitLength(const MCSymbol *Hi, const MCSymbol *Lo, - const Twine &Comment) const; + /// Return the end symbol generated inside, the caller needs to emit it. + MCSymbol *emitDwarfUnitLength(const Twine &Prefix, + const Twine &Comment) const; /// Emit reference to a call site with a specified encoding void emitCallSiteOffset(const MCSymbol *Hi, const MCSymbol *Lo, diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h --- a/llvm/include/llvm/MC/MCStreamer.h +++ b/llvm/include/llvm/MC/MCStreamer.h @@ -1089,8 +1089,9 @@ /// Emit a unit length field. The actual format, DWARF32 or DWARF64, is chosen /// according to the settings. - virtual void emitDwarfUnitLength(const MCSymbol *Hi, const MCSymbol *Lo, - const Twine &Comment); + /// Return the end symbol generated inside, the caller needs to emit it. + virtual MCSymbol *emitDwarfUnitLength(const Twine &Prefix, + const Twine &Comment); }; /// Create a dummy machine code streamer, which does nothing. This is useful for diff --git a/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp b/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp --- a/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp @@ -205,7 +205,7 @@ : CompUnitCount(CompUnitCount), BucketCount(BucketCount), NameCount(NameCount) {} - void emit(const Dwarf5AccelTableWriter &Ctx) const; + void emit(Dwarf5AccelTableWriter &Ctx); }; struct AttributeEncoding { dwarf::Index Index; @@ -216,8 +216,7 @@ DenseMap> Abbreviations; ArrayRef CompUnits; llvm::function_ref getCUIndexForEntry; - MCSymbol *ContributionStart = Asm->createTempSymbol("names_start"); - MCSymbol *ContributionEnd = Asm->createTempSymbol("names_end"); + MCSymbol *ContributionEnd = nullptr; MCSymbol *AbbrevStart = Asm->createTempSymbol("names_abbrev_start"); MCSymbol *AbbrevEnd = Asm->createTempSymbol("names_abbrev_end"); MCSymbol *EntryPool = Asm->createTempSymbol("names_entries"); @@ -240,7 +239,7 @@ ArrayRef CompUnits, llvm::function_ref GetCUIndexForEntry); - void emit() const; + void emit(); }; } // namespace @@ -361,14 +360,12 @@ } template -void Dwarf5AccelTableWriter::Header::emit( - const Dwarf5AccelTableWriter &Ctx) const { +void Dwarf5AccelTableWriter::Header::emit(Dwarf5AccelTableWriter &Ctx) { assert(CompUnitCount > 0 && "Index must have at least one CU."); AsmPrinter *Asm = Ctx.Asm; - Asm->emitDwarfUnitLength(Ctx.ContributionEnd, Ctx.ContributionStart, - "Header: unit length"); - Asm->OutStreamer->emitLabel(Ctx.ContributionStart); + Ctx.ContributionEnd = + Asm->emitDwarfUnitLength("names", "Header: unit length"); Asm->OutStreamer->AddComment("Header: version"); Asm->emitInt16(Version); Asm->OutStreamer->AddComment("Header: padding"); @@ -526,7 +523,7 @@ Abbreviations.try_emplace(Tag, UniformAttributes); } -template void Dwarf5AccelTableWriter::emit() const { +template void Dwarf5AccelTableWriter::emit() { Header.emit(*this); emitCUList(); emitBuckets(); diff --git a/llvm/lib/CodeGen/AsmPrinter/AddressPool.cpp b/llvm/lib/CodeGen/AsmPrinter/AddressPool.cpp --- a/llvm/lib/CodeGen/AsmPrinter/AddressPool.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AddressPool.cpp @@ -25,12 +25,9 @@ MCSymbol *AddressPool::emitHeader(AsmPrinter &Asm, MCSection *Section) { static const uint8_t AddrSize = Asm.getDataLayout().getPointerSize(); - StringRef Prefix = "debug_addr_"; - MCSymbol *BeginLabel = Asm.createTempSymbol(Prefix + "start"); - MCSymbol *EndLabel = Asm.createTempSymbol(Prefix + "end"); - Asm.emitDwarfUnitLength(EndLabel, BeginLabel, "Length of contribution"); - Asm.OutStreamer->emitLabel(BeginLabel); + MCSymbol *EndLabel = + Asm.emitDwarfUnitLength("debug_addr", "Length of contribution"); Asm.OutStreamer->AddComment("DWARF version number"); Asm.emitInt16(Asm.getDwarfVersion()); Asm.OutStreamer->AddComment("Address size"); diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp @@ -203,9 +203,9 @@ OutStreamer->emitDwarfUnitLength(Length, Comment); } -void AsmPrinter::emitDwarfUnitLength(const MCSymbol *Hi, const MCSymbol *Lo, - const Twine &Comment) const { - OutStreamer->emitDwarfUnitLength(Hi, Lo, Comment); +MCSymbol *AsmPrinter::emitDwarfUnitLength(const Twine &Prefix, + const Twine &Comment) const { + return OutStreamer->emitDwarfUnitLength(Prefix, Comment); } void AsmPrinter::emitCallSiteOffset(const MCSymbol *Hi, const MCSymbol *Lo, diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -2374,12 +2374,8 @@ TheU = Skeleton; // Emit the header. - MCSymbol *BeginLabel = Asm->createTempSymbol("pub" + Name + "_begin"); - MCSymbol *EndLabel = Asm->createTempSymbol("pub" + Name + "_end"); - Asm->emitDwarfUnitLength(EndLabel, BeginLabel, - "Length of Public " + Name + " Info"); - - Asm->OutStreamer->emitLabel(BeginLabel); + MCSymbol *EndLabel = Asm->emitDwarfUnitLength( + "pub" + Name, "Length of Public " + Name + " Info"); Asm->OutStreamer->AddComment("DWARF Version"); Asm->emitInt16(dwarf::DW_PUBNAMES_VERSION); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -1701,13 +1701,10 @@ void DwarfUnit::emitCommonHeader(bool UseOffsets, dwarf::UnitType UT) { // Emit size of content not including length itself - if (!DD->useSectionsAsReferences()) { - StringRef Prefix = isDwoUnit() ? "debug_info_dwo_" : "debug_info_"; - MCSymbol *BeginLabel = Asm->createTempSymbol(Prefix + "start"); - EndLabel = Asm->createTempSymbol(Prefix + "end"); - Asm->emitDwarfUnitLength(EndLabel, BeginLabel, "Length of Unit"); - Asm->OutStreamer->emitLabel(BeginLabel); - } else + if (!DD->useSectionsAsReferences()) + EndLabel = Asm->emitDwarfUnitLength( + isDwoUnit() ? "debug_info_dwo" : "debug_info", "Length of Unit"); + else Asm->emitDwarfUnitLength(getHeaderSize() + getUnitDie().getSize(), "Length of Unit"); diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp --- a/llvm/lib/MC/MCStreamer.cpp +++ b/llvm/lib/MC/MCStreamer.cpp @@ -1006,12 +1006,19 @@ emitIntValue(Length, dwarf::getDwarfOffsetByteSize(Context.getDwarfFormat())); } -void MCStreamer::emitDwarfUnitLength(const MCSymbol *Hi, const MCSymbol *Lo, - const Twine &Comment) { +MCSymbol *MCStreamer::emitDwarfUnitLength(const Twine &Prefix, + const Twine &Comment) { maybeEmitDwarf64Mark(); AddComment(Comment); + MCSymbol *Lo = Context.createTempSymbol(Prefix + "_start"); + MCSymbol *Hi = Context.createTempSymbol(Prefix + "_end"); + emitAbsoluteSymbolDiff( Hi, Lo, dwarf::getDwarfOffsetByteSize(Context.getDwarfFormat())); + // emit the begin symbol after we generate the length field. + emitLabel(Lo); + // Return the Hi symbol to the caller. + return Hi; } void MCStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) { diff --git a/llvm/test/DebugInfo/X86/dwarf-pubnames-split.ll b/llvm/test/DebugInfo/X86/dwarf-pubnames-split.ll --- a/llvm/test/DebugInfo/X86/dwarf-pubnames-split.ll +++ b/llvm/test/DebugInfo/X86/dwarf-pubnames-split.ll @@ -7,7 +7,7 @@ ; Check that we get a symbol off of the debug_info section when using split dwarf and pubnames. -; CHECK: .LpubTypes_begin0: +; CHECK: .LpubTypes_start0: ; CHECK-NEXT: .short 2 # DWARF Version ; CHECK-NEXT: .long .Lcu_begin0 # Offset of Compilation Unit Info diff --git a/llvm/unittests/CodeGen/AsmPrinterDwarfTest.cpp b/llvm/unittests/CodeGen/AsmPrinterDwarfTest.cpp --- a/llvm/unittests/CodeGen/AsmPrinterDwarfTest.cpp +++ b/llvm/unittests/CodeGen/AsmPrinterDwarfTest.cpp @@ -50,19 +50,21 @@ if (!AsmPrinterFixtureBase::init(TripleStr, DwarfVersion, DwarfFormat)) return false; - // Create a symbol which will be emitted in the tests and associate it - // with a section because that is required in some code paths. + // AsmPrinter::emitDwarfSymbolReference(Label, true) gets the associated + // section from `Label` to find its BeginSymbol. + // Prepare the test symbol `Val` accordingly. Val = TestPrinter->getCtx().createTempSymbol(); - Sec = TestPrinter->getCtx().getELFSection(".tst", ELF::SHT_PROGBITS, 0); + MCSection *Sec = + TestPrinter->getCtx().getELFSection(".tst", ELF::SHT_PROGBITS, 0); SecBeginSymbol = Sec->getBeginSymbol(); TestPrinter->getMS().SwitchSection(Sec); - TestPrinter->getMS().emitLabel(Val); + Val->setFragment(&Sec->getDummyFragment()); + return true; } MCSymbol *Val = nullptr; - MCSection *Sec = nullptr; MCSymbol *SecBeginSymbol = nullptr; }; @@ -326,21 +328,28 @@ if (!AsmPrinterFixtureBase::init(TripleStr, DwarfVersion, DwarfFormat)) return false; - Hi = TestPrinter->getCtx().createTempSymbol(); - Lo = TestPrinter->getCtx().createTempSymbol(); return true; } - - MCSymbol *Hi = nullptr; - MCSymbol *Lo = nullptr; }; TEST_F(AsmPrinterEmitDwarfUnitLengthAsHiLoDiffTest, DWARF32) { if (!init("x86_64-pc-linux", /*DwarfVersion=*/4, dwarf::DWARF32)) return; - EXPECT_CALL(TestPrinter->getMS(), emitAbsoluteSymbolDiff(Hi, Lo, 4)); - TestPrinter->getAP()->emitDwarfUnitLength(Hi, Lo, ""); + InSequence S; + const MCSymbol *Hi = nullptr; + const MCSymbol *Lo = nullptr; + EXPECT_CALL(TestPrinter->getMS(), emitAbsoluteSymbolDiff(_, _, 4)) + .WillOnce(DoAll(SaveArg<0>(&Hi), SaveArg<1>(&Lo))); + MCSymbol *LTmp = nullptr; + EXPECT_CALL(TestPrinter->getMS(), emitLabel(_, _)) + .WillOnce(SaveArg<0>(<mp)); + + MCSymbol *HTmp = TestPrinter->getAP()->emitDwarfUnitLength("", ""); + EXPECT_NE(Lo, nullptr); + EXPECT_EQ(Lo, LTmp); + EXPECT_NE(Hi, nullptr); + EXPECT_EQ(Hi, HTmp); } TEST_F(AsmPrinterEmitDwarfUnitLengthAsHiLoDiffTest, DWARF64) { @@ -348,10 +357,20 @@ return; InSequence S; + const MCSymbol *Hi = nullptr; + const MCSymbol *Lo = nullptr; EXPECT_CALL(TestPrinter->getMS(), emitIntValue(dwarf::DW_LENGTH_DWARF64, 4)); - EXPECT_CALL(TestPrinter->getMS(), emitAbsoluteSymbolDiff(Hi, Lo, 8)); - - TestPrinter->getAP()->emitDwarfUnitLength(Hi, Lo, ""); + EXPECT_CALL(TestPrinter->getMS(), emitAbsoluteSymbolDiff(_, _, 8)) + .WillOnce(DoAll(SaveArg<0>(&Hi), SaveArg<1>(&Lo))); + MCSymbol *LTmp = nullptr; + EXPECT_CALL(TestPrinter->getMS(), emitLabel(_, _)) + .WillOnce(SaveArg<0>(<mp)); + + MCSymbol *HTmp = TestPrinter->getAP()->emitDwarfUnitLength("", ""); + EXPECT_NE(Lo, nullptr); + EXPECT_EQ(Lo, LTmp); + EXPECT_NE(Hi, nullptr); + EXPECT_EQ(Hi, HTmp); } class AsmPrinterHandlerTest : public AsmPrinterFixtureBase { diff --git a/llvm/unittests/CodeGen/TestAsmPrinter.h b/llvm/unittests/CodeGen/TestAsmPrinter.h --- a/llvm/unittests/CodeGen/TestAsmPrinter.h +++ b/llvm/unittests/CodeGen/TestAsmPrinter.h @@ -38,6 +38,7 @@ // The following are mock methods to be used in tests. + MOCK_METHOD2(emitLabel, void(MCSymbol *Symbol, SMLoc Loc)); MOCK_METHOD2(emitIntValue, void(uint64_t Value, unsigned Size)); MOCK_METHOD3(emitValueImpl, void(const MCExpr *Value, unsigned Size, SMLoc Loc));