[DWARFLinker][NFC] Decrease DWARFLinker dependence on DwarfStreamer. (#77932)

This patch is extracted from #74725.

The DwarfStreamer interface looks overcomplicated and has unnecessary
dependencies. This patch avoids creation of DwarfStreamer by DWARFLinker and
simplifies interface.
This commit is contained in:
Alexey Lapshin 2024-01-19 16:57:09 +03:00 committed by GitHub
parent 6f371149c1
commit 9ff4be640f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 419 additions and 423 deletions

View File

@ -42,7 +42,8 @@ public:
virtual ~DwarfEmitter() = default;
/// Emit section named SecName with data SecData.
virtual void emitSectionContents(StringRef SecData, StringRef SecName) = 0;
virtual void emitSectionContents(StringRef SecData,
DebugSectionKind SecKind) = 0;
/// Emit the abbreviation table \p Abbrevs to the .debug_abbrev section.
virtual void
@ -188,17 +189,6 @@ public:
/// Dump the file to the disk.
virtual void finish() = 0;
/// Emit the swift_ast section stored in \p Buffer.
virtual void emitSwiftAST(StringRef Buffer) = 0;
/// Emit the swift reflection section stored in \p Buffer.
virtual void emitSwiftReflectionSection(
llvm::binaryformat::Swift5ReflectionSectionKind ReflSectionKind,
StringRef Buffer, uint32_t Alignment, uint32_t Size) = 0;
/// Returns underlying AsmPrinter.
virtual AsmPrinter &getAsmPrinter() const = 0;
};
class DwarfStreamer;
@ -232,10 +222,10 @@ public:
StringsTranslator);
}
Error createEmitter(const Triple &TheTriple, OutputFileType FileType,
raw_pwrite_stream &OutFile);
DwarfEmitter *getEmitter();
/// Set output DWARF emitter.
void setOutputDWARFEmitter(DwarfEmitter *Emitter) {
TheDwarfEmitter = Emitter;
}
/// Add object file to be linked. Pre-load compile unit die. Call
/// \p OnCUDieLoaded for each compile unit die. If specified \p File
@ -762,7 +752,7 @@ private:
BumpPtrAllocator DIEAlloc;
/// @}
std::unique_ptr<DwarfStreamer> TheDwarfEmitter;
DwarfEmitter *TheDwarfEmitter = nullptr;
std::vector<LinkContext> ObjectContexts;
/// The CIEs that have been emitted in the output section. The actual CIE

View File

@ -45,18 +45,23 @@ class DwarfStreamer : public DwarfEmitter {
public:
DwarfStreamer(DWARFLinkerBase::OutputFileType OutFileType,
raw_pwrite_stream &OutFile,
std::function<StringRef(StringRef Input)> Translator,
DWARFLinkerBase::TranslatorFuncTy Translator,
DWARFLinkerBase::MessageHandlerTy Warning)
: OutFile(OutFile), OutFileType(OutFileType), Translator(Translator),
WarningHandler(Warning) {}
virtual ~DwarfStreamer() = default;
static Expected<std::unique_ptr<DwarfStreamer>> createStreamer(
const Triple &TheTriple, DWARFLinkerBase::OutputFileType FileType,
raw_pwrite_stream &OutFile, DWARFLinkerBase::TranslatorFuncTy Translator,
DWARFLinkerBase::MessageHandlerTy Warning);
Error init(Triple TheTriple, StringRef Swift5ReflectionSegmentName);
/// Dump the file to the disk.
void finish() override;
AsmPrinter &getAsmPrinter() const override { return *Asm; }
AsmPrinter &getAsmPrinter() const { return *Asm; }
/// Set the current output section to debug_info and change
/// the MC Dwarf version to \p DwarfVersion.
@ -77,7 +82,8 @@ public:
unsigned DwarfVersion) override;
/// Emit contents of section SecName From Obj.
void emitSectionContents(StringRef SecData, StringRef SecName) override;
void emitSectionContents(StringRef SecData,
DebugSectionKind SecKind) override;
/// Emit the string table described by \p Pool into .debug_str table.
void emitStrings(const NonRelocatableStringpool &Pool) override;
@ -91,12 +97,12 @@ public:
void emitLineStrings(const NonRelocatableStringpool &Pool) override;
/// Emit the swift_ast section stored in \p Buffer.
void emitSwiftAST(StringRef Buffer) override;
void emitSwiftAST(StringRef Buffer);
/// Emit the swift reflection section stored in \p Buffer.
void emitSwiftReflectionSection(
llvm::binaryformat::Swift5ReflectionSectionKind ReflSectionKind,
StringRef Buffer, uint32_t Alignment, uint32_t Size) override;
StringRef Buffer, uint32_t Alignment, uint32_t Size);
/// Emit debug ranges(.debug_ranges, .debug_rnglists) header.
MCSymbol *emitDwarfDebugRangeListHeader(const CompileUnit &Unit) override;
@ -215,6 +221,8 @@ private:
WarningHandler(Warning, Context, nullptr);
}
MCSection *getMCSection(DebugSectionKind SecKind);
void emitMacroTableImpl(const DWARFDebugMacro *MacroTable,
const Offset2UnitMap &UnitMacroMap,
OffsetsStringPool &StringPool, uint64_t &OutOffset);

View File

@ -23,6 +23,53 @@ class DWARFUnit;
namespace dwarf_linker {
/// List of tracked debug tables.
enum class DebugSectionKind : uint8_t {
DebugInfo = 0,
DebugLine,
DebugFrame,
DebugRange,
DebugRngLists,
DebugLoc,
DebugLocLists,
DebugARanges,
DebugAbbrev,
DebugMacinfo,
DebugMacro,
DebugAddr,
DebugStr,
DebugLineStr,
DebugStrOffsets,
DebugPubNames,
DebugPubTypes,
DebugNames,
AppleNames,
AppleNamespaces,
AppleObjC,
AppleTypes,
NumberOfEnumEntries // must be last
};
static constexpr size_t SectionKindsNum =
static_cast<size_t>(DebugSectionKind::NumberOfEnumEntries);
static constexpr StringLiteral SectionNames[SectionKindsNum] = {
"debug_info", "debug_line", "debug_frame", "debug_ranges",
"debug_rnglists", "debug_loc", "debug_loclists", "debug_aranges",
"debug_abbrev", "debug_macinfo", "debug_macro", "debug_addr",
"debug_str", "debug_line_str", "debug_str_offsets", "debug_pubnames",
"debug_pubtypes", "debug_names", "apple_names", "apple_namespac",
"apple_objc", "apple_types"};
/// Return the name of the section.
static constexpr const StringLiteral &
getSectionName(DebugSectionKind SectionKind) {
return SectionNames[static_cast<uint8_t>(SectionKind)];
}
/// Recognise the table name and match it with the DebugSectionKind.
std::optional<DebugSectionKind> parseDebugTableName(StringRef Name);
/// The base interface for DWARFLinker implementations.
class DWARFLinkerBase {
public:

View File

@ -89,30 +89,34 @@ namespace llvm {
namespace dwarf_linker {
namespace parallel {
/// ExtraDwarfEmitter allows adding extra data to the DWARFLinker output.
/// The finish() method should be called after all extra data are emitted.
class ExtraDwarfEmitter {
public:
virtual ~ExtraDwarfEmitter() = default;
/// This structure keeps data of the concrete section.
struct SectionDescriptorBase {
SectionDescriptorBase(DebugSectionKind SectionKind, dwarf::FormParams Format,
llvm::endianness Endianess)
: SectionKind(SectionKind), Format(Format), Endianess(Endianess) {}
virtual ~SectionDescriptorBase() = default;
/// Returns section content.
virtual StringRef getContents() = 0;
/// Returns section kind.
DebugSectionKind getKind() { return SectionKind; }
/// Returns section name.
const StringLiteral &getName() const { return getSectionName(SectionKind); }
/// Returns endianess used by section.
llvm::endianness getEndianess() const { return Endianess; }
/// Returns FormParams used by section.
dwarf::FormParams getFormParams() const { return Format; }
/// Dump the file to the disk.
virtual void finish() = 0;
/// Emit section named SecName with data SecData.
virtual void emitSectionContents(StringRef SecData, StringRef SecName) = 0;
/// Emit the swift_ast section stored in \p Buffer.
virtual void emitSwiftAST(StringRef Buffer) = 0;
/// Emit the swift reflection section stored in \p Buffer.
virtual void emitSwiftReflectionSection(
llvm::binaryformat::Swift5ReflectionSectionKind ReflSectionKind,
StringRef Buffer, uint32_t Alignment, uint32_t Size) = 0;
/// Returns underlying AsmPrinter.
virtual AsmPrinter &getAsmPrinter() const = 0;
protected:
/// The section kind.
DebugSectionKind SectionKind = DebugSectionKind::NumberOfEnumEntries;
/// Output format.
dwarf::FormParams Format = {4, 4, dwarf::DWARF32};
llvm::endianness Endianess = llvm::endianness::little;
};
using SectionHandlerTy =
std::function<void(std::shared_ptr<SectionDescriptorBase> Section)>;
class DWARFLinker : public DWARFLinkerBase {
public:
virtual ~DWARFLinker() = default;
@ -122,12 +126,11 @@ public:
createLinker(MessageHandlerTy ErrorHandler, MessageHandlerTy WarningHandler,
TranslatorFuncTy StringsTranslator = nullptr);
/// Creates emitter for output dwarf.
virtual Error createEmitter(const Triple &TheTriple, OutputFileType FileType,
raw_pwrite_stream &OutFile) = 0;
/// Returns previously created dwarf emitter. May be nullptr.
virtual ExtraDwarfEmitter *getEmitter() = 0;
/// Set output DWARF handler. Result of linking DWARF is set of sections
/// containing final debug info. DWARFLinkerBase::link() pass generated
/// sections using specified \p SectionHandler.
virtual void setOutputDWARFHandler(const Triple &TargetTriple,
SectionHandlerTy SectionHandler) = 0;
};
} // end of namespace parallel

View File

@ -1,4 +1,5 @@
add_llvm_component_library(LLVMDWARFLinker
DWARFLinkerBase.cpp
Utils.cpp
ADDITIONAL_HEADER_DIRS

View File

@ -2644,19 +2644,22 @@ uint64_t DWARFLinker::DIECloner::cloneAllCompileUnits(
void DWARFLinker::copyInvariantDebugSection(DWARFContext &Dwarf) {
TheDwarfEmitter->emitSectionContents(Dwarf.getDWARFObj().getLocSection().Data,
"debug_loc");
DebugSectionKind::DebugLoc);
TheDwarfEmitter->emitSectionContents(
Dwarf.getDWARFObj().getRangesSection().Data, "debug_ranges");
Dwarf.getDWARFObj().getRangesSection().Data,
DebugSectionKind::DebugRange);
TheDwarfEmitter->emitSectionContents(
Dwarf.getDWARFObj().getFrameSection().Data, "debug_frame");
Dwarf.getDWARFObj().getFrameSection().Data, DebugSectionKind::DebugFrame);
TheDwarfEmitter->emitSectionContents(Dwarf.getDWARFObj().getArangesSection(),
"debug_aranges");
DebugSectionKind::DebugARanges);
TheDwarfEmitter->emitSectionContents(
Dwarf.getDWARFObj().getAddrSection().Data, "debug_addr");
Dwarf.getDWARFObj().getAddrSection().Data, DebugSectionKind::DebugAddr);
TheDwarfEmitter->emitSectionContents(
Dwarf.getDWARFObj().getRnglistsSection().Data, "debug_rnglists");
Dwarf.getDWARFObj().getRnglistsSection().Data,
DebugSectionKind::DebugRngLists);
TheDwarfEmitter->emitSectionContents(
Dwarf.getDWARFObj().getLoclistsSection().Data, "debug_loclists");
Dwarf.getDWARFObj().getLoclistsSection().Data,
DebugSectionKind::DebugLocLists);
}
void DWARFLinker::addObjectFile(DWARFFile &File, ObjFileLoaderTy Loader,
@ -2848,7 +2851,7 @@ Error DWARFLinker::link() {
SizeByObject[OptContext.File.FileName].Input =
getDebugInfoSize(*OptContext.File.Dwarf);
SizeByObject[OptContext.File.FileName].Output =
DIECloner(*this, TheDwarfEmitter.get(), OptContext.File, DIEAlloc,
DIECloner(*this, TheDwarfEmitter, OptContext.File, DIEAlloc,
OptContext.CompileUnits, Options.Update, DebugStrPool,
DebugLineStrPool, StringOffsetPool)
.cloneAllCompileUnits(*OptContext.File.Dwarf, OptContext.File,
@ -3011,7 +3014,7 @@ Error DWARFLinker::cloneModuleUnit(LinkContext &Context, RefModuleUnit &Unit,
UnitListTy CompileUnits;
CompileUnits.emplace_back(std::move(Unit.Unit));
assert(TheDwarfEmitter);
DIECloner(*this, TheDwarfEmitter.get(), Unit.File, DIEAlloc, CompileUnits,
DIECloner(*this, TheDwarfEmitter, Unit.File, DIEAlloc, CompileUnits,
Options.Update, DebugStrPool, DebugLineStrPool, StringOffsetPool)
.cloneAllCompileUnits(*Unit.File.Dwarf, Unit.File,
Unit.File.Dwarf->isLittleEndian());
@ -3030,16 +3033,4 @@ void DWARFLinker::verifyInput(const DWARFFile &File) {
}
}
Error DWARFLinker::createEmitter(const Triple &TheTriple,
OutputFileType FileType,
raw_pwrite_stream &OutFile) {
TheDwarfEmitter = std::make_unique<DwarfStreamer>(
FileType, OutFile, StringsTranslator, WarningHandler);
return TheDwarfEmitter->init(TheTriple, "__DWARF");
}
DwarfEmitter *DWARFLinker::getEmitter() { return TheDwarfEmitter.get(); }
} // namespace llvm

View File

@ -30,6 +30,18 @@ using namespace llvm;
using namespace dwarf_linker;
using namespace dwarf_linker::classic;
Expected<std::unique_ptr<DwarfStreamer>> DwarfStreamer::createStreamer(
const Triple &TheTriple, DWARFLinkerBase::OutputFileType FileType,
raw_pwrite_stream &OutFile, DWARFLinkerBase::TranslatorFuncTy Translator,
DWARFLinkerBase::MessageHandlerTy Warning) {
std::unique_ptr<DwarfStreamer> Streamer =
std::make_unique<DwarfStreamer>(FileType, OutFile, Translator, Warning);
if (Error Err = Streamer->init(TheTriple, "__DWARF"))
return std::move(Err);
return std::move(Streamer);
}
Error DwarfStreamer::init(Triple TheTriple,
StringRef Swift5ReflectionSegmentName) {
std::string ErrorStr;
@ -212,30 +224,72 @@ void DwarfStreamer::emitDIE(DIE &Die) {
}
/// Emit contents of section SecName From Obj.
void DwarfStreamer::emitSectionContents(StringRef SecData, StringRef SecName) {
MCSection *Section =
StringSwitch<MCSection *>(SecName)
.Case("debug_line", MC->getObjectFileInfo()->getDwarfLineSection())
.Case("debug_loc", MC->getObjectFileInfo()->getDwarfLocSection())
.Case("debug_ranges",
MC->getObjectFileInfo()->getDwarfRangesSection())
.Case("debug_frame", MC->getObjectFileInfo()->getDwarfFrameSection())
.Case("debug_aranges",
MC->getObjectFileInfo()->getDwarfARangesSection())
.Case("debug_addr", MC->getObjectFileInfo()->getDwarfAddrSection())
.Case("debug_rnglists",
MC->getObjectFileInfo()->getDwarfRnglistsSection())
.Case("debug_loclists",
MC->getObjectFileInfo()->getDwarfLoclistsSection())
.Default(nullptr);
void DwarfStreamer::emitSectionContents(StringRef SecData,
DebugSectionKind SecKind) {
if (SecData.empty())
return;
if (Section) {
if (MCSection *Section = getMCSection(SecKind)) {
MS->switchSection(Section);
MS->emitBytes(SecData);
}
}
MCSection *DwarfStreamer::getMCSection(DebugSectionKind SecKind) {
switch (SecKind) {
case DebugSectionKind::DebugInfo:
return MC->getObjectFileInfo()->getDwarfInfoSection();
case DebugSectionKind::DebugLine:
return MC->getObjectFileInfo()->getDwarfLineSection();
case DebugSectionKind::DebugFrame:
return MC->getObjectFileInfo()->getDwarfFrameSection();
case DebugSectionKind::DebugRange:
return MC->getObjectFileInfo()->getDwarfRangesSection();
case DebugSectionKind::DebugRngLists:
return MC->getObjectFileInfo()->getDwarfRnglistsSection();
case DebugSectionKind::DebugLoc:
return MC->getObjectFileInfo()->getDwarfLocSection();
case DebugSectionKind::DebugLocLists:
return MC->getObjectFileInfo()->getDwarfLoclistsSection();
case DebugSectionKind::DebugARanges:
return MC->getObjectFileInfo()->getDwarfARangesSection();
case DebugSectionKind::DebugAbbrev:
return MC->getObjectFileInfo()->getDwarfAbbrevSection();
case DebugSectionKind::DebugMacinfo:
return MC->getObjectFileInfo()->getDwarfMacinfoSection();
case DebugSectionKind::DebugMacro:
return MC->getObjectFileInfo()->getDwarfMacroSection();
case DebugSectionKind::DebugAddr:
return MC->getObjectFileInfo()->getDwarfAddrSection();
case DebugSectionKind::DebugStr:
return MC->getObjectFileInfo()->getDwarfStrSection();
case DebugSectionKind::DebugLineStr:
return MC->getObjectFileInfo()->getDwarfLineStrSection();
case DebugSectionKind::DebugStrOffsets:
return MC->getObjectFileInfo()->getDwarfStrOffSection();
case DebugSectionKind::DebugPubNames:
return MC->getObjectFileInfo()->getDwarfPubNamesSection();
case DebugSectionKind::DebugPubTypes:
return MC->getObjectFileInfo()->getDwarfPubTypesSection();
case DebugSectionKind::DebugNames:
return MC->getObjectFileInfo()->getDwarfDebugNamesSection();
case DebugSectionKind::AppleNames:
return MC->getObjectFileInfo()->getDwarfAccelNamesSection();
case DebugSectionKind::AppleNamespaces:
return MC->getObjectFileInfo()->getDwarfAccelNamespaceSection();
case DebugSectionKind::AppleObjC:
return MC->getObjectFileInfo()->getDwarfAccelObjCSection();
case DebugSectionKind::AppleTypes:
return MC->getObjectFileInfo()->getDwarfAccelTypesSection();
case DebugSectionKind::NumberOfEnumEntries:
llvm_unreachable("Unknown DebugSectionKind value");
break;
}
return nullptr;
}
/// Emit the debug_str section stored in \p Pool.
void DwarfStreamer::emitStrings(const NonRelocatableStringpool &Pool) {
Asm->OutStreamer->switchSection(MOFI->getDwarfStrSection());

View File

@ -0,0 +1,64 @@
//=== DWARFLinkerBase.cpp -------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm/DWARFLinker/DWARFLinkerBase.h"
#include "llvm/ADT/StringSwitch.h"
using namespace llvm;
using namespace llvm::dwarf_linker;
std::optional<DebugSectionKind>
llvm::dwarf_linker::parseDebugTableName(llvm::StringRef SecName) {
return llvm::StringSwitch<std::optional<DebugSectionKind>>(
SecName.substr(SecName.find_first_not_of("._")))
.Case(getSectionName(DebugSectionKind::DebugInfo),
DebugSectionKind::DebugInfo)
.Case(getSectionName(DebugSectionKind::DebugLine),
DebugSectionKind::DebugLine)
.Case(getSectionName(DebugSectionKind::DebugFrame),
DebugSectionKind::DebugFrame)
.Case(getSectionName(DebugSectionKind::DebugRange),
DebugSectionKind::DebugRange)
.Case(getSectionName(DebugSectionKind::DebugRngLists),
DebugSectionKind::DebugRngLists)
.Case(getSectionName(DebugSectionKind::DebugLoc),
DebugSectionKind::DebugLoc)
.Case(getSectionName(DebugSectionKind::DebugLocLists),
DebugSectionKind::DebugLocLists)
.Case(getSectionName(DebugSectionKind::DebugARanges),
DebugSectionKind::DebugARanges)
.Case(getSectionName(DebugSectionKind::DebugAbbrev),
DebugSectionKind::DebugAbbrev)
.Case(getSectionName(DebugSectionKind::DebugMacinfo),
DebugSectionKind::DebugMacinfo)
.Case(getSectionName(DebugSectionKind::DebugMacro),
DebugSectionKind::DebugMacro)
.Case(getSectionName(DebugSectionKind::DebugAddr),
DebugSectionKind::DebugAddr)
.Case(getSectionName(DebugSectionKind::DebugStr),
DebugSectionKind::DebugStr)
.Case(getSectionName(DebugSectionKind::DebugLineStr),
DebugSectionKind::DebugLineStr)
.Case(getSectionName(DebugSectionKind::DebugStrOffsets),
DebugSectionKind::DebugStrOffsets)
.Case(getSectionName(DebugSectionKind::DebugPubNames),
DebugSectionKind::DebugPubNames)
.Case(getSectionName(DebugSectionKind::DebugPubTypes),
DebugSectionKind::DebugPubTypes)
.Case(getSectionName(DebugSectionKind::DebugNames),
DebugSectionKind::DebugNames)
.Case(getSectionName(DebugSectionKind::AppleNames),
DebugSectionKind::AppleNames)
.Case(getSectionName(DebugSectionKind::AppleNamespaces),
DebugSectionKind::AppleNamespaces)
.Case(getSectionName(DebugSectionKind::AppleObjC),
DebugSectionKind::AppleObjC)
.Case(getSectionName(DebugSectionKind::AppleTypes),
DebugSectionKind::AppleTypes)
.Default(std::nullopt);
}

View File

@ -120,72 +120,6 @@ Error DwarfEmitterImpl::init(Triple TheTriple,
return Error::success();
}
void DwarfEmitterImpl::emitSwiftAST(StringRef Buffer) {
MCSection *SwiftASTSection = MOFI->getDwarfSwiftASTSection();
SwiftASTSection->setAlignment(Align(32));
MS->switchSection(SwiftASTSection);
MS->emitBytes(Buffer);
}
/// Emit the swift reflection section stored in \p Buffer.
void DwarfEmitterImpl::emitSwiftReflectionSection(
llvm::binaryformat::Swift5ReflectionSectionKind ReflSectionKind,
StringRef Buffer, uint32_t Alignment, uint32_t) {
MCSection *ReflectionSection =
MOFI->getSwift5ReflectionSection(ReflSectionKind);
if (ReflectionSection == nullptr)
return;
ReflectionSection->setAlignment(Align(Alignment));
MS->switchSection(ReflectionSection);
MS->emitBytes(Buffer);
}
void DwarfEmitterImpl::emitSectionContents(StringRef SecData,
StringRef SecName) {
if (SecData.empty())
return;
if (MCSection *Section = switchSection(SecName)) {
MS->switchSection(Section);
MS->emitBytes(SecData);
}
}
MCSection *DwarfEmitterImpl::switchSection(StringRef SecName) {
return StringSwitch<MCSection *>(SecName)
.Case("debug_info", MC->getObjectFileInfo()->getDwarfInfoSection())
.Case("debug_abbrev", MC->getObjectFileInfo()->getDwarfAbbrevSection())
.Case("debug_line", MC->getObjectFileInfo()->getDwarfLineSection())
.Case("debug_loc", MC->getObjectFileInfo()->getDwarfLocSection())
.Case("debug_ranges", MC->getObjectFileInfo()->getDwarfRangesSection())
.Case("debug_frame", MC->getObjectFileInfo()->getDwarfFrameSection())
.Case("debug_aranges", MC->getObjectFileInfo()->getDwarfARangesSection())
.Case("debug_rnglists",
MC->getObjectFileInfo()->getDwarfRnglistsSection())
.Case("debug_loclists",
MC->getObjectFileInfo()->getDwarfLoclistsSection())
.Case("debug_macro", MC->getObjectFileInfo()->getDwarfMacroSection())
.Case("debug_macinfo", MC->getObjectFileInfo()->getDwarfMacinfoSection())
.Case("debug_addr", MC->getObjectFileInfo()->getDwarfAddrSection())
.Case("debug_str", MC->getObjectFileInfo()->getDwarfStrSection())
.Case("debug_line_str", MC->getObjectFileInfo()->getDwarfLineStrSection())
.Case("debug_str_offsets",
MC->getObjectFileInfo()->getDwarfStrOffSection())
.Case("debug_pubnames",
MC->getObjectFileInfo()->getDwarfPubNamesSection())
.Case("debug_pubtypes",
MC->getObjectFileInfo()->getDwarfPubTypesSection())
.Case("debug_names", MC->getObjectFileInfo()->getDwarfDebugNamesSection())
.Case("apple_names", MC->getObjectFileInfo()->getDwarfAccelNamesSection())
.Case("apple_namespac",
MC->getObjectFileInfo()->getDwarfAccelNamespaceSection())
.Case("apple_objc", MC->getObjectFileInfo()->getDwarfAccelObjCSection())
.Case("apple_types", MC->getObjectFileInfo()->getDwarfAccelTypesSection())
.Default(nullptr);
}
void DwarfEmitterImpl::emitAbbrevs(
const SmallVector<std::unique_ptr<DIEAbbrev>> &Abbrevs,
unsigned DwarfVersion) {

View File

@ -45,7 +45,7 @@ using CompUnitIDToIdx = DenseMap<unsigned, unsigned>;
/// This class emits DWARF data to the output stream. It emits already
/// generated section data and specific data, which could not be generated
/// by CompileUnit.
class DwarfEmitterImpl : public ExtraDwarfEmitter {
class DwarfEmitterImpl {
public:
DwarfEmitterImpl(DWARFLinker::OutputFileType OutFileType,
raw_pwrite_stream &OutFile)
@ -58,21 +58,7 @@ public:
const Triple &getTargetTriple() { return MC->getTargetTriple(); }
/// Dump the file to the disk.
void finish() override { MS->finish(); }
/// Returns AsmPrinter.
AsmPrinter &getAsmPrinter() const override { return *Asm; }
/// Emit the swift_ast section stored in \p Buffer.
void emitSwiftAST(StringRef Buffer) override;
/// Emit the swift reflection section stored in \p Buffer.
void emitSwiftReflectionSection(
llvm::binaryformat::Swift5ReflectionSectionKind ReflSectionKind,
StringRef Buffer, uint32_t Alignment, uint32_t) override;
/// Emit specified section data.
void emitSectionContents(StringRef SecData, StringRef SecName) override;
void finish() { MS->finish(); }
/// Emit abbreviations.
void emitAbbrevs(const SmallVector<std::unique_ptr<DIEAbbrev>> &Abbrevs,
@ -115,8 +101,6 @@ private:
const StringEntryToDwarfStringPoolEntryMap &Strings,
uint64_t &NextOffset, MCSection *OutSection);
MCSection *switchSection(StringRef SecName);
/// \defgroup MCObjects MC layer objects constructed by the streamer
/// @{
std::unique_ptr<MCRegisterInfo> MRI;
@ -135,7 +119,8 @@ private:
/// The output file we stream the linked Dwarf to.
raw_pwrite_stream &OutFile;
DWARFLinker::OutputFileType OutFileType = DWARFLinker::OutputFileType::Object;
DWARFLinkerBase::OutputFileType OutFileType =
DWARFLinkerBase::OutputFileType::Object;
uint64_t DebugInfoSectionSize = 0;
};

View File

@ -1229,8 +1229,9 @@ void CompileUnit::cloneDieAttrExpression(
}
}
Error CompileUnit::cloneAndEmit(std::optional<Triple> TargetTriple,
TypeUnit *ArtificialTypeUnit) {
Error CompileUnit::cloneAndEmit(
std::optional<std::reference_wrapper<const Triple>> TargetTriple,
TypeUnit *ArtificialTypeUnit) {
BumpPtrAllocator Allocator;
DWARFDie OrigUnitDIE = getOrigUnit().getUnitDIE();
@ -1247,18 +1248,17 @@ Error CompileUnit::cloneAndEmit(std::optional<Triple> TargetTriple,
std::nullopt, std::nullopt, Allocator, ArtificialTypeUnit);
setOutUnitDIE(OutCUDie.first);
if (getGlobalData().getOptions().NoOutput || (OutCUDie.first == nullptr))
if (!TargetTriple.has_value() || (OutCUDie.first == nullptr))
return Error::success();
assert(TargetTriple.has_value());
if (Error Err = cloneAndEmitLineTable(*TargetTriple))
if (Error Err = cloneAndEmitLineTable((*TargetTriple).get()))
return Err;
if (Error Err = cloneAndEmitDebugMacro())
return Err;
getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);
if (Error Err = emitDebugInfo(*TargetTriple))
if (Error Err = emitDebugInfo((*TargetTriple).get()))
return Err;
// ASSUMPTION: .debug_info section should already be emitted at this point.
@ -1514,7 +1514,7 @@ TypeEntry *CompileUnit::createTypeDIEandCloneAttributes(
return Entry;
}
Error CompileUnit::cloneAndEmitLineTable(Triple &TargetTriple) {
Error CompileUnit::cloneAndEmitLineTable(const Triple &TargetTriple) {
const DWARFDebugLine::LineTable *InputLineTable =
getContaingFile().Dwarf->getLineTableForUnit(&getOrigUnit());
if (InputLineTable == nullptr) {

View File

@ -401,8 +401,9 @@ public:
const RangesTy &getFunctionRanges() const { return Ranges; }
/// Clone and emit this compilation unit.
Error cloneAndEmit(std::optional<Triple> TargetTriple,
TypeUnit *ArtificialTypeUnit);
Error
cloneAndEmit(std::optional<std::reference_wrapper<const Triple>> TargetTriple,
TypeUnit *ArtificialTypeUnit);
/// Clone and emit debug locations(.debug_loc/.debug_loclists).
Error cloneAndEmitDebugLocations();
@ -422,7 +423,7 @@ public:
BumpPtrAllocator &Allocator, TypeUnit *ArtificialTypeUnit);
// Clone and emit line table.
Error cloneAndEmitLineTable(Triple &TargetTriple);
Error cloneAndEmitLineTable(const Triple &TargetTriple);
/// Clone attribute location axpression.
void cloneDieAttrExpression(const DWARFExpression &InputExpression,

View File

@ -39,9 +39,6 @@ struct DWARFLinkerOptions {
/// Verify the input DWARF.
bool VerifyInputDWARF = false;
/// Do not emit output.
bool NoOutput = false;
/// Do not unique types according to ODR
bool NoODR = false;
@ -59,13 +56,14 @@ struct DWARFLinkerOptions {
unsigned Threads = 1;
/// The accelerator table kinds
SmallVector<DWARFLinker::AccelTableKind, 1> AccelTables;
SmallVector<DWARFLinkerBase::AccelTableKind, 1> AccelTables;
/// Prepend path for the clang modules.
std::string PrependPath;
/// input verification handler(it might be called asynchronously).
DWARFLinker::InputVerificationHandlerTy InputVerificationHandler = nullptr;
DWARFLinkerBase::InputVerificationHandlerTy InputVerificationHandler =
nullptr;
/// A list of all .swiftinterface files referenced by the debug
/// info, mapping Module name to path on disk. The entries need to
@ -74,12 +72,12 @@ struct DWARFLinkerOptions {
/// this is dsymutil specific fag.
///
/// (it might be called asynchronously).
DWARFLinker::SwiftInterfacesMapTy *ParseableSwiftInterfaces = nullptr;
DWARFLinkerBase::SwiftInterfacesMapTy *ParseableSwiftInterfaces = nullptr;
/// A list of remappings to apply to file paths.
///
/// (it might be called asynchronously).
DWARFLinker::ObjectPrefixMapTy *ObjectPrefixMap = nullptr;
DWARFLinkerBase::ObjectPrefixMapTy *ObjectPrefixMap = nullptr;
};
class DWARFLinkerImpl;
@ -147,6 +145,19 @@ public:
});
}
/// Set target triple.
void setTargetTriple(const Triple &TargetTriple) {
this->TargetTriple = TargetTriple;
}
/// Optionally return target triple.
std::optional<std::reference_wrapper<const Triple>> getTargetTriple() {
if (TargetTriple)
return std::cref(*TargetTriple);
return std::nullopt;
}
protected:
llvm::parallel::PerThreadBumpPtrAllocator Allocator;
StringPool Strings;
@ -154,6 +165,10 @@ protected:
DWARFLinkerOptions Options;
MessageHandlerTy WarningHandler;
MessageHandlerTy ErrorHandler;
/// Triple for output data. May be not set if generation of output
/// data is not requested.
std::optional<Triple> TargetTriple;
};
} // end of namespace parallel

View File

@ -32,11 +32,9 @@ DWARFLinkerImpl::DWARFLinkerImpl(MessageHandlerTy ErrorHandler,
DWARFLinkerImpl::LinkContext::LinkContext(LinkingGlobalData &GlobalData,
DWARFFile &File,
StringMap<uint64_t> &ClangModules,
std::atomic<size_t> &UniqueUnitID,
std::optional<Triple> TargetTriple)
std::atomic<size_t> &UniqueUnitID)
: OutputSections(GlobalData), InputDWARFFile(File),
ClangModules(ClangModules), TargetTriple(TargetTriple),
UniqueUnitID(UniqueUnitID) {
ClangModules(ClangModules), UniqueUnitID(UniqueUnitID) {
if (File.Dwarf) {
if (!File.Dwarf->compile_units().empty())
@ -63,25 +61,10 @@ void DWARFLinkerImpl::LinkContext::addModulesCompileUnit(
ModulesCompileUnits.emplace_back(std::move(Unit));
}
Error DWARFLinkerImpl::createEmitter(const Triple &TheTriple,
OutputFileType FileType,
raw_pwrite_stream &OutFile) {
TheDwarfEmitter = std::make_unique<DwarfEmitterImpl>(FileType, OutFile);
return TheDwarfEmitter->init(TheTriple, "__DWARF");
}
ExtraDwarfEmitter *DWARFLinkerImpl::getEmitter() {
return TheDwarfEmitter.get();
}
void DWARFLinkerImpl::addObjectFile(DWARFFile &File, ObjFileLoaderTy Loader,
CompileUnitHandlerTy OnCUDieLoaded) {
ObjectContexts.emplace_back(std::make_unique<LinkContext>(
GlobalData, File, ClangModules, UniqueUnitID,
(TheDwarfEmitter.get() == nullptr ? std::optional<Triple>(std::nullopt)
: TheDwarfEmitter->getTargetTriple())));
GlobalData, File, ClangModules, UniqueUnitID));
if (ObjectContexts.back()->InputDWARFFile.Dwarf) {
for (const std::unique_ptr<DWARFUnit> &CU :
@ -117,8 +100,9 @@ Error DWARFLinkerImpl::link() {
0, dwarf::DwarfFormat::DWARF32};
llvm::endianness GlobalEndianness = llvm::endianness::native;
if (TheDwarfEmitter) {
GlobalEndianness = TheDwarfEmitter->getTargetTriple().isLittleEndian()
if (std::optional<std::reference_wrapper<const Triple>> CurTriple =
GlobalData.getTargetTriple()) {
GlobalEndianness = (*CurTriple).get().isLittleEndian()
? llvm::endianness::little
: llvm::endianness::big;
}
@ -147,7 +131,7 @@ Error DWARFLinkerImpl::link() {
if (GlobalData.getOptions().VerifyInputDWARF)
verifyInput(Context->InputDWARFFile);
if (!TheDwarfEmitter)
if (!GlobalData.getTargetTriple())
GlobalEndianness = Context->getEndianness();
GlobalFormat.AddrSize =
std::max(GlobalFormat.AddrSize, Context->getFormParams().AddrSize);
@ -173,9 +157,9 @@ Error DWARFLinkerImpl::link() {
}
if (GlobalFormat.AddrSize == 0) {
if (TheDwarfEmitter)
GlobalFormat.AddrSize =
TheDwarfEmitter->getTargetTriple().isArch32Bit() ? 4 : 8;
if (std::optional<std::reference_wrapper<const Triple>> TargetTriple =
GlobalData.getTargetTriple())
GlobalFormat.AddrSize = (*TargetTriple).get().isArch32Bit() ? 4 : 8;
else
GlobalFormat.AddrSize = 8;
}
@ -225,12 +209,10 @@ Error DWARFLinkerImpl::link() {
->getValue()
.load()
->Children.empty()) {
std::optional<Triple> OutTriple = TheDwarfEmitter.get() == nullptr
? std::optional<Triple>(std::nullopt)
: TheDwarfEmitter->getTargetTriple();
if (Error Err = ArtificialTypeUnit.get()->finishCloningAndEmit(OutTriple))
return Err;
if (GlobalData.getTargetTriple().has_value())
if (Error Err = ArtificialTypeUnit.get()->finishCloningAndEmit(
(*GlobalData.getTargetTriple()).get()))
return Err;
}
// At this stage each compile units are cloned to their own set of debug
@ -258,8 +240,6 @@ Error DWARFLinkerImpl::validateAndUpdateOptions() {
return createStringError(std::errc::invalid_argument,
"target DWARF version is not set");
GlobalData.Options.NoOutput = TheDwarfEmitter.get() == nullptr;
if (GlobalData.getOptions().Verbose && GlobalData.getOptions().Threads != 1) {
GlobalData.Options.Threads = 1;
GlobalData.warn(
@ -690,7 +670,8 @@ void DWARFLinkerImpl::LinkContext::linkSingleCompileUnit(
if (CU.isClangModule() ||
GlobalData.getOptions().UpdateIndexTablesOnly ||
CU.getContaingFile().Addresses->hasValidRelocs()) {
if (Error Err = CU.cloneAndEmit(TargetTriple, ArtificialTypeUnit))
if (Error Err = CU.cloneAndEmit(GlobalData.getTargetTriple(),
ArtificialTypeUnit))
return std::move(Err);
}
@ -727,7 +708,7 @@ void DWARFLinkerImpl::LinkContext::linkSingleCompileUnit(
}
Error DWARFLinkerImpl::LinkContext::emitInvariantSections() {
if (GlobalData.getOptions().NoOutput)
if (!GlobalData.getTargetTriple().has_value())
return Error::success();
getOrCreateSectionDescriptor(DebugSectionKind::DebugLoc).OS
@ -749,7 +730,7 @@ Error DWARFLinkerImpl::LinkContext::emitInvariantSections() {
}
Error DWARFLinkerImpl::LinkContext::cloneAndEmitDebugFrame() {
if (GlobalData.getOptions().NoOutput)
if (!GlobalData.getTargetTriple().has_value())
return Error::success();
if (InputDWARFFile.Dwarf.get() == nullptr)
@ -870,8 +851,9 @@ void DWARFLinkerImpl::LinkContext::emitFDE(uint32_t CIEOffset,
}
void DWARFLinkerImpl::glueCompileUnitsAndWriteToTheOutput() {
if (GlobalData.getOptions().NoOutput)
if (!GlobalData.getTargetTriple().has_value())
return;
assert(SectionHandler);
// Go through all object files, all compile units and assign
// offsets to them.
@ -1154,21 +1136,23 @@ void DWARFLinkerImpl::emitCommonSectionsAndWriteCompileUnitsToTheOutput() {
AccelTableKind::DebugNames))
CommonSections.getOrCreateSectionDescriptor(DebugSectionKind::DebugNames);
const Triple &TargetTriple = TheDwarfEmitter->getTargetTriple();
// Emit .debug_str and .debug_line_str sections.
TG.spawn([&]() { emitStringSections(); });
if (llvm::is_contained(GlobalData.Options.AccelTables,
AccelTableKind::Apple)) {
// Emit apple accelerator sections.
TG.spawn([&]() { emitAppleAcceleratorSections(TargetTriple); });
TG.spawn([&]() {
emitAppleAcceleratorSections((*GlobalData.getTargetTriple()).get());
});
}
if (llvm::is_contained(GlobalData.Options.AccelTables,
AccelTableKind::DebugNames)) {
// Emit .debug_names section.
TG.spawn([&]() { emitDWARFv5DebugNamesSection(TargetTriple); });
TG.spawn([&]() {
emitDWARFv5DebugNamesSection((*GlobalData.getTargetTriple()).get());
});
}
// Write compile units to the output file.
@ -1419,33 +1403,17 @@ void DWARFLinkerImpl::cleanupDataAfterDWARFOutputIsWritten() {
}
void DWARFLinkerImpl::writeCompileUnitsToTheOutput() {
bool HasAbbreviations = false;
// Enumerate all sections and store them into the final emitter.
forEachObjectSectionsSet([&](OutputSections &Sections) {
Sections.forEach([&](SectionDescriptor &OutSection) {
if (!HasAbbreviations && !OutSection.getContents().empty() &&
OutSection.getKind() == DebugSectionKind::DebugAbbrev)
HasAbbreviations = true;
Sections.forEach([&](std::shared_ptr<SectionDescriptor> OutSection) {
// Emit section content.
TheDwarfEmitter->emitSectionContents(OutSection.getContents(),
OutSection.getName());
OutSection.clearSectionContent();
SectionHandler(OutSection);
});
});
if (!HasAbbreviations) {
const SmallVector<std::unique_ptr<DIEAbbrev>> Abbreviations;
TheDwarfEmitter->emitAbbrevs(Abbreviations, 3);
}
}
void DWARFLinkerImpl::writeCommonSectionsToTheOutput() {
CommonSections.forEach([&](SectionDescriptor &OutSection) {
// Emit section content.
TheDwarfEmitter->emitSectionContents(OutSection.getContents(),
OutSection.getName());
OutSection.clearSectionContent();
CommonSections.forEach([&](std::shared_ptr<SectionDescriptor> OutSection) {
SectionHandler(OutSection);
});
}

View File

@ -29,12 +29,6 @@ public:
MessageHandlerTy WarningHandler,
TranslatorFuncTy StringsTranslator);
/// Create debug info emitter.
Error createEmitter(const Triple &TheTriple, OutputFileType FileType,
raw_pwrite_stream &OutFile) override;
ExtraDwarfEmitter *getEmitter() override;
/// Add object file to be linked. Pre-load compile unit die. Call
/// \p OnCUDieLoaded for each compile unit die. If specified \p File
/// has reference to the Clang module then such module would be
@ -49,6 +43,14 @@ public:
/// Link debug info for added files.
Error link() override;
/// Set output DWARF handler. May be not set if output generation is not
/// necessary.
void setOutputDWARFHandler(const Triple &TargetTriple,
SectionHandlerTy SectionHandler) override {
GlobalData.setTargetTriple(TargetTriple);
this->SectionHandler = SectionHandler;
}
/// \defgroup Methods setting various linking options:
///
/// @{
@ -190,8 +192,6 @@ protected:
StringMap<uint64_t> &ClangModules;
std::optional<Triple> TargetTriple;
/// Flag indicating that new inter-connected compilation units were
/// discovered. It is used for restarting units processing
/// if new inter-connected units were found.
@ -204,8 +204,7 @@ protected:
LinkContext(LinkingGlobalData &GlobalData, DWARFFile &File,
StringMap<uint64_t> &ClangModules,
std::atomic<size_t> &UniqueUnitID,
std::optional<Triple> TargetTriple);
std::atomic<size_t> &UniqueUnitID);
/// Check whether specified \p CUDie is a Clang module reference.
/// if \p Quiet is false then display error messages.
@ -364,8 +363,8 @@ protected:
/// Common sections.
OutputSections CommonSections;
/// The emitter of final dwarf file.
std::unique_ptr<DwarfEmitterImpl> TheDwarfEmitter;
/// Hanler for output sections.
SectionHandlerTy SectionHandler = nullptr;
/// Overall compile units number.
uint64_t OverallNumberOfCU = 0;

View File

@ -337,11 +337,11 @@ uint8_t TypeUnit::getSizeByAttrForm(dwarf::Form Form) const {
llvm_unreachable("Unsupported Attr Form");
}
Error TypeUnit::finishCloningAndEmit(std::optional<Triple> TargetTriple) {
Error TypeUnit::finishCloningAndEmit(const Triple &TargetTriple) {
BumpPtrAllocator Allocator;
createDIETree(Allocator);
if (getGlobalData().getOptions().NoOutput || (getOutUnitDIE() == nullptr))
if (getOutUnitDIE() == nullptr)
return Error::success();
// Create sections ahead so that they should not be created asynchronously
@ -360,14 +360,12 @@ Error TypeUnit::finishCloningAndEmit(std::optional<Triple> TargetTriple) {
// Add task for emitting .debug_line section.
if (!LineTable.Prologue.FileNames.empty()) {
Tasks.push_back([&]() -> Error {
assert(TargetTriple.has_value());
return emitDebugLine(*TargetTriple, LineTable);
});
Tasks.push_back(
[&]() -> Error { return emitDebugLine(TargetTriple, LineTable); });
}
// Add task for emitting .debug_info section.
Tasks.push_back([&]() -> Error { return emitDebugInfo(*TargetTriple); });
Tasks.push_back([&]() -> Error { return emitDebugInfo(TargetTriple); });
// Add task for emitting Pub accelerator sections.
if (llvm::is_contained(GlobalData.getOptions().AccelTables,

View File

@ -31,7 +31,7 @@ public:
void createDIETree(BumpPtrAllocator &Allocator);
/// Emits resulting dwarf based on information from DIE tree.
Error finishCloningAndEmit(std::optional<Triple> TargetTriple);
Error finishCloningAndEmit(const Triple &TargetTriple);
/// Returns global type pool.
TypePool &getTypePool() { return Types; }

View File

@ -15,59 +15,6 @@ using namespace llvm;
using namespace dwarf_linker;
using namespace dwarf_linker::parallel;
std::optional<DebugSectionKind>
dwarf_linker::parallel::parseDebugTableName(llvm::StringRef SecName) {
return llvm::StringSwitch<std::optional<DebugSectionKind>>(
SecName.substr(SecName.find_first_not_of("._")))
.Case(getSectionName(DebugSectionKind::DebugInfo),
DebugSectionKind::DebugInfo)
.Case(getSectionName(DebugSectionKind::DebugLine),
DebugSectionKind::DebugLine)
.Case(getSectionName(DebugSectionKind::DebugFrame),
DebugSectionKind::DebugFrame)
.Case(getSectionName(DebugSectionKind::DebugRange),
DebugSectionKind::DebugRange)
.Case(getSectionName(DebugSectionKind::DebugRngLists),
DebugSectionKind::DebugRngLists)
.Case(getSectionName(DebugSectionKind::DebugLoc),
DebugSectionKind::DebugLoc)
.Case(getSectionName(DebugSectionKind::DebugLocLists),
DebugSectionKind::DebugLocLists)
.Case(getSectionName(DebugSectionKind::DebugARanges),
DebugSectionKind::DebugARanges)
.Case(getSectionName(DebugSectionKind::DebugAbbrev),
DebugSectionKind::DebugAbbrev)
.Case(getSectionName(DebugSectionKind::DebugMacinfo),
DebugSectionKind::DebugMacinfo)
.Case(getSectionName(DebugSectionKind::DebugMacro),
DebugSectionKind::DebugMacro)
.Case(getSectionName(DebugSectionKind::DebugAddr),
DebugSectionKind::DebugAddr)
.Case(getSectionName(DebugSectionKind::DebugStr),
DebugSectionKind::DebugStr)
.Case(getSectionName(DebugSectionKind::DebugLineStr),
DebugSectionKind::DebugLineStr)
.Case(getSectionName(DebugSectionKind::DebugStrOffsets),
DebugSectionKind::DebugStrOffsets)
.Case(getSectionName(DebugSectionKind::DebugPubNames),
DebugSectionKind::DebugPubNames)
.Case(getSectionName(DebugSectionKind::DebugPubTypes),
DebugSectionKind::DebugPubTypes)
.Case(getSectionName(DebugSectionKind::DebugNames),
DebugSectionKind::DebugNames)
.Case(getSectionName(DebugSectionKind::AppleNames),
DebugSectionKind::AppleNames)
.Case(getSectionName(DebugSectionKind::AppleNamespaces),
DebugSectionKind::AppleNamespaces)
.Case(getSectionName(DebugSectionKind::AppleObjC),
DebugSectionKind::AppleObjC)
.Case(getSectionName(DebugSectionKind::AppleTypes),
DebugSectionKind::AppleTypes)
.Default(std::nullopt);
return std::nullopt;
}
DebugDieRefPatch::DebugDieRefPatch(uint64_t PatchOffset, CompileUnit *SrcCU,
CompileUnit *RefCU, uint32_t RefIdx)
: SectionPatch({PatchOffset}),

View File

@ -34,51 +34,6 @@ namespace parallel {
class TypeUnit;
/// List of tracked debug tables.
enum class DebugSectionKind : uint8_t {
DebugInfo = 0,
DebugLine,
DebugFrame,
DebugRange,
DebugRngLists,
DebugLoc,
DebugLocLists,
DebugARanges,
DebugAbbrev,
DebugMacinfo,
DebugMacro,
DebugAddr,
DebugStr,
DebugLineStr,
DebugStrOffsets,
DebugPubNames,
DebugPubTypes,
DebugNames,
AppleNames,
AppleNamespaces,
AppleObjC,
AppleTypes,
NumberOfEnumEntries // must be last
};
constexpr static size_t SectionKindsNum =
static_cast<size_t>(DebugSectionKind::NumberOfEnumEntries);
static constexpr StringLiteral SectionNames[SectionKindsNum] = {
"debug_info", "debug_line", "debug_frame", "debug_ranges",
"debug_rnglists", "debug_loc", "debug_loclists", "debug_aranges",
"debug_abbrev", "debug_macinfo", "debug_macro", "debug_addr",
"debug_str", "debug_line_str", "debug_str_offsets", "debug_pubnames",
"debug_pubtypes", "debug_names", "apple_names", "apple_namespac",
"apple_objc", "apple_types"};
static constexpr const StringLiteral &
getSectionName(DebugSectionKind SectionKind) {
return SectionNames[static_cast<uint8_t>(SectionKind)];
}
/// Recognise the table name and match it with the DebugSectionKind.
std::optional<DebugSectionKind> parseDebugTableName(StringRef Name);
/// There are fields(sizes, offsets) which should be updated after
/// sections are generated. To remember offsets and related data
/// the descendants of SectionPatch structure should be used.
@ -194,12 +149,13 @@ class OutputSections;
/// This structure is used to keep data of the concrete section.
/// Like data bits, list of patches, format.
struct SectionDescriptor {
struct SectionDescriptor : SectionDescriptorBase {
friend OutputSections;
SectionDescriptor(DebugSectionKind SectionKind, LinkingGlobalData &GlobalData,
dwarf::FormParams Format, llvm::endianness Endianess)
: OS(Contents), ListDebugStrPatch(&GlobalData.getAllocator()),
: SectionDescriptorBase(SectionKind, Format, Endianess), OS(Contents),
ListDebugStrPatch(&GlobalData.getAllocator()),
ListDebugLineStrPatch(&GlobalData.getAllocator()),
ListDebugRangePatch(&GlobalData.getAllocator()),
ListDebugLocPatch(&GlobalData.getAllocator()),
@ -211,10 +167,9 @@ struct SectionDescriptor {
ListDebugTypeStrPatch(&GlobalData.getAllocator()),
ListDebugTypeLineStrPatch(&GlobalData.getAllocator()),
ListDebugTypeDeclFilePatch(&GlobalData.getAllocator()),
GlobalData(GlobalData), SectionKind(SectionKind), Format(Format),
Endianess(Endianess) {}
GlobalData(GlobalData) {}
/// Erase whole section contents(data bits, list of patches).
/// Erase whole section content(data bits, list of patches).
void clearAllSectionData();
/// Erase only section output data bits.
@ -263,7 +218,7 @@ struct SectionDescriptor {
void setSizesForSectionCreatedByAsmPrinter();
/// Returns section content.
StringRef getContents() {
StringRef getContents() override {
if (SectionOffsetInsideAsmPrinterOutputStart == 0)
return StringRef(Contents.data(), Contents.size());
@ -311,18 +266,6 @@ struct SectionDescriptor {
/// Write specified \p Value of \p AttrForm to the \p PatchOffset.
void apply(uint64_t PatchOffset, dwarf::Form AttrForm, uint64_t Val);
/// Returns section kind.
DebugSectionKind getKind() { return SectionKind; }
/// Returns section name.
const StringLiteral &getName() const { return getSectionName(SectionKind); }
/// Returns endianess used by section.
llvm::endianness getEndianess() const { return Endianess; }
/// Returns FormParams used by section.
dwarf::FormParams getFormParams() const { return Format; }
/// Returns integer value of \p Size located by specified \p PatchOffset.
uint64_t getIntVal(uint64_t PatchOffset, unsigned Size);
@ -344,9 +287,6 @@ protected:
LinkingGlobalData &GlobalData;
/// The section kind.
DebugSectionKind SectionKind = DebugSectionKind::NumberOfEnumEntries;
/// Section data bits.
OutSectionDataTy Contents;
@ -355,10 +295,6 @@ protected:
/// real section content inside elf file.
size_t SectionOffsetInsideAsmPrinterOutputStart = 0;
size_t SectionOffsetInsideAsmPrinterOutputEnd = 0;
/// Output format.
dwarf::FormParams Format = {4, 4, dwarf::DWARF32};
llvm::endianness Endianess = llvm::endianness::little;
};
/// This class keeps contents and offsets to the debug sections. Any objects
@ -387,7 +323,7 @@ public:
.str()
.c_str());
return It->second;
return *It->second;
}
/// Returns descriptor for the specified section of \p SectionKind.
@ -402,7 +338,9 @@ public:
.str()
.c_str());
return It->second;
assert(It->second.get() != nullptr);
return *It->second;
}
/// Returns descriptor for the specified section of \p SectionKind.
@ -414,7 +352,7 @@ public:
if (It == SectionDescriptors.end())
return std::nullopt;
return &It->second;
return It->second.get();
}
/// Returns descriptor for the specified section of \p SectionKind.
@ -426,26 +364,44 @@ public:
if (It == SectionDescriptors.end())
return std::nullopt;
return &It->second;
return It->second.get();
}
/// Returns descriptor for the specified section of \p SectionKind.
/// If descriptor does not exist then creates it.
SectionDescriptor &
getOrCreateSectionDescriptor(DebugSectionKind SectionKind) {
return SectionDescriptors
.try_emplace(SectionKind, SectionKind, GlobalData, Format, Endianness)
.first->second;
SectionsSetTy::iterator It = SectionDescriptors.find(SectionKind);
if (It == SectionDescriptors.end()) {
SectionDescriptor *Section =
new SectionDescriptor(SectionKind, GlobalData, Format, Endianness);
auto Result = SectionDescriptors.try_emplace(SectionKind, Section);
assert(Result.second);
It = Result.first;
}
return *It->second;
}
/// Erases data of all sections.
void eraseSections() {
for (auto &Section : SectionDescriptors)
Section.second.clearAllSectionData();
Section.second->clearAllSectionData();
}
/// Enumerate all sections and call \p Handler for each.
void forEach(function_ref<void(SectionDescriptor &)> Handler) {
for (auto &Section : SectionDescriptors) {
assert(Section.second.get() != nullptr);
Handler(*(Section.second));
}
}
/// Enumerate all sections and call \p Handler for each.
void forEach(
function_ref<void(std::shared_ptr<SectionDescriptor> Section)> Handler) {
for (auto &Section : SectionDescriptors)
Handler(Section.second);
}
@ -456,10 +412,11 @@ public:
void assignSectionsOffsetAndAccumulateSize(
std::array<uint64_t, SectionKindsNum> &SectionSizesAccumulator) {
for (auto &Section : SectionDescriptors) {
Section.second.StartOffset = SectionSizesAccumulator[static_cast<uint8_t>(
Section.second.getKind())];
SectionSizesAccumulator[static_cast<uint8_t>(Section.second.getKind())] +=
Section.second.getContents().size();
Section.second->StartOffset =
SectionSizesAccumulator[static_cast<uint8_t>(
Section.second->getKind())];
SectionSizesAccumulator[static_cast<uint8_t>(
Section.second->getKind())] += Section.second->getContents().size();
}
}
@ -505,7 +462,8 @@ protected:
llvm::endianness Endianness = llvm::endianness::native;
/// All keeping sections.
using SectionsSetTy = std::map<DebugSectionKind, SectionDescriptor>;
using SectionsSetTy =
std::map<DebugSectionKind, std::shared_ptr<SectionDescriptor>>;
SectionsSetTy SectionDescriptors;
};

View File

@ -533,9 +533,8 @@ Error DwarfLinkerForBinary::copySwiftInterfaces(StringRef Architecture) const {
return Error::success();
}
template <typename OutStreamer>
void DwarfLinkerForBinary::copySwiftReflectionMetadata(
const llvm::dsymutil::DebugMapObject *Obj, OutStreamer *Streamer,
const llvm::dsymutil::DebugMapObject *Obj, classic::DwarfStreamer *Streamer,
std::vector<uint64_t> &SectionToOffsetInDwarf,
std::vector<MachOUtils::DwarfRelocationApplicationInfo>
&RelocationsToApply) {
@ -649,14 +648,32 @@ bool DwarfLinkerForBinary::linkImpl(
},
Options.Translator ? TranslationLambda : nullptr);
std::unique_ptr<classic::DwarfStreamer> Streamer;
if (!Options.NoOutput) {
if (Error Err = GeneralLinker->createEmitter(Map.getTriple(), ObjectType,
OutFile)) {
handleAllErrors(std::move(Err), [&](const ErrorInfoBase &EI) {
if (Expected<std::unique_ptr<classic::DwarfStreamer>> StreamerOrErr =
classic::DwarfStreamer::createStreamer(
Map.getTriple(), ObjectType, OutFile, Options.Translator,
[&](const Twine &Warning, StringRef Context,
const DWARFDie *DIE) {
reportWarning(Warning, Context, DIE);
}))
Streamer = std::move(*StreamerOrErr);
else {
handleAllErrors(StreamerOrErr.takeError(), [&](const ErrorInfoBase &EI) {
reportError(EI.message(), "dwarf streamer init");
});
return false;
}
if constexpr (std::is_same<Linker, parallel::DWARFLinker>::value) {
GeneralLinker->setOutputDWARFHandler(
Map.getTriple(),
[&](std::shared_ptr<parallel::SectionDescriptorBase> Section) {
Streamer->emitSectionContents(Section->getContents(),
Section->getKind());
});
} else
GeneralLinker->setOutputDWARFEmitter(Streamer.get());
}
remarks::RemarkLinker RL;
@ -749,7 +766,7 @@ bool DwarfLinkerForBinary::linkImpl(
auto SectionToOffsetInDwarf =
calculateStartOfStrippableReflectionSections(Map);
for (const auto &Obj : Map.objects())
copySwiftReflectionMetadata(Obj.get(), GeneralLinker->getEmitter(),
copySwiftReflectionMetadata(Obj.get(), Streamer.get(),
SectionToOffsetInDwarf, RelocationsToApply);
}
@ -796,7 +813,7 @@ bool DwarfLinkerForBinary::linkImpl(
// Copy the module into the .swift_ast section.
if (!Options.NoOutput)
GeneralLinker->getEmitter()->emitSwiftAST((*ErrorOrMem)->getBuffer());
Streamer->emitSwiftAST((*ErrorOrMem)->getBuffer());
continue;
}
@ -850,10 +867,9 @@ bool DwarfLinkerForBinary::linkImpl(
ObjectType == Linker::OutputFileType::Object)
return MachOUtils::generateDsymCompanion(
Options.VFS, Map, Options.Translator,
*GeneralLinker->getEmitter()->getAsmPrinter().OutStreamer, OutFile,
RelocationsToApply);
*Streamer->getAsmPrinter().OutStreamer, OutFile, RelocationsToApply);
GeneralLinker->getEmitter()->finish();
Streamer->finish();
return true;
}

View File

@ -253,9 +253,9 @@ private:
Error copySwiftInterfaces(StringRef Architecture) const;
template <typename OutStreamer>
void copySwiftReflectionMetadata(
const llvm::dsymutil::DebugMapObject *Obj, OutStreamer *Streamer,
const llvm::dsymutil::DebugMapObject *Obj,
classic::DwarfStreamer *Streamer,
std::vector<uint64_t> &SectionToOffsetInDwarf,
std::vector<MachOUtils::DwarfRelocationApplicationInfo>
&RelocationsToApply);

View File

@ -336,9 +336,26 @@ Error linkDebugInfoImpl(object::ObjectFile &File, const Options &Options,
Linker::createLinker(ReportErr, ReportWarn);
Triple TargetTriple = File.makeTriple();
if (Error Err = DebugInfoLinker->createEmitter(
TargetTriple, Linker::OutputFileType::Object, OutStream))
return Err;
std::unique_ptr<classic::DwarfStreamer> Streamer;
if (Expected<std::unique_ptr<classic::DwarfStreamer>> StreamerOrErr =
classic::DwarfStreamer::createStreamer(
TargetTriple, Linker::OutputFileType::Object, OutStream, nullptr,
ReportWarn))
Streamer = std::move(*StreamerOrErr);
else
return StreamerOrErr.takeError();
if constexpr (std::is_same<Linker,
dwarf_linker::parallel::DWARFLinker>::value) {
DebugInfoLinker->setOutputDWARFHandler(
TargetTriple,
[&](std::shared_ptr<dwarf_linker::parallel::SectionDescriptorBase>
Section) {
Streamer->emitSectionContents(Section->getContents(),
Section->getKind());
});
} else
DebugInfoLinker->setOutputDWARFEmitter(Streamer.get());
DebugInfoLinker->setEstimatedObjfilesAmount(1);
DebugInfoLinker->setNumThreads(Options.NumThreads);
@ -445,7 +462,7 @@ Error linkDebugInfoImpl(object::ObjectFile &File, const Options &Options,
if (Error Err = DebugInfoLinker->link())
return Err;
DebugInfoLinker->getEmitter()->finish();
Streamer->finish();
return Error::success();
}