mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-27 07:31:28 +00:00
[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:
parent
6f371149c1
commit
9ff4be640f
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -1,4 +1,5 @@
|
||||
add_llvm_component_library(LLVMDWARFLinker
|
||||
DWARFLinkerBase.cpp
|
||||
Utils.cpp
|
||||
|
||||
ADDITIONAL_HEADER_DIRS
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
|
64
llvm/lib/DWARFLinker/DWARFLinkerBase.cpp
Normal file
64
llvm/lib/DWARFLinker/DWARFLinkerBase.cpp
Normal 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);
|
||||
}
|
@ -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) {
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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; }
|
||||
|
@ -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}),
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user