Skip to content

Commit

Permalink
[DWARFLinkerParallel][Reland] Add interface files, create a skeleton …
Browse files Browse the repository at this point in the history
…implementation.

This patch creates skeleton implementation for the DWARFLinkerParallel.
It also integrates DWARFLinkerParallel into dsymutil and llvm-dwarfutil,
so that empty DWARFLinker::link() can be called. To do this new command
line option is added "--linker apple/llvm". Additionally it changes
existing DWARFLinker interfaces/implementations to be compatible:
use Error for error reporting for the DWARFStreamer, make DWARFFile to
owner of referenced resources, other small refactorings.

Differential Revision: https://reviews.llvm.org/D147952
  • Loading branch information
avl-llvm committed Jun 4, 2023
1 parent 7226162 commit 36f3510
Show file tree
Hide file tree
Showing 32 changed files with 2,157 additions and 337 deletions.
143 changes: 80 additions & 63 deletions llvm/include/llvm/DWARFLinker/DWARFLinker.h
Expand Up @@ -14,14 +14,14 @@
#include "llvm/CodeGen/AccelTable.h"
#include "llvm/CodeGen/NonRelocatableStringpool.h"
#include "llvm/DWARFLinker/DWARFLinkerCompileUnit.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
#include <map>

namespace llvm {
class DWARFContext;
class DWARFExpression;
class DWARFUnit;
class DataExtractor;
Expand All @@ -30,13 +30,6 @@ template <typename T> class SmallVectorImpl;

enum class DwarfLinkerClient { Dsymutil, LLD, General };

/// The kind of accelerator tables we should emit.
enum class DwarfLinkerAccelTableKind : uint8_t {
Apple, ///< .apple_names, .apple_namespaces, .apple_types, .apple_objc.
Pub, ///< .debug_pubnames, .debug_pubtypes
DebugNames ///< .debug_names.
};

/// AddressesMap represents information about valid addresses used
/// by debug information. Valid addresses are those which points to
/// live code sections. i.e. relocations for these addresses point
Expand Down Expand Up @@ -221,39 +214,48 @@ class DwarfEmitter {

/// Returns size of generated .debug_loclists section.
virtual uint64_t getLocListsSectionSize() const = 0;

/// 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;
using UnitListTy = std::vector<std::unique_ptr<CompileUnit>>;

/// This class represents DWARF information for source file
/// and its address map.
class DWARFFile {
public:
DWARFFile(StringRef Name, DWARFContext *Dwarf, AddressesMap *Addresses,
DWARFFile(StringRef Name, std::unique_ptr<DWARFContext> Dwarf,
std::unique_ptr<AddressesMap> Addresses,
const std::vector<std::string> &Warnings)
: FileName(Name), Dwarf(Dwarf), Addresses(Addresses), Warnings(Warnings) {
}
: FileName(Name), Dwarf(std::move(Dwarf)),
Addresses(std::move(Addresses)), Warnings(Warnings) {}

/// The object file name.
StringRef FileName;

/// The source DWARF information.
DWARFContext *Dwarf = nullptr;
std::unique_ptr<DWARFContext> Dwarf;

/// Helpful address information(list of valid address ranges, relocations).
AddressesMap *Addresses = nullptr;
std::unique_ptr<AddressesMap> Addresses;

/// Warnings for this object file.
const std::vector<std::string> &Warnings;
};

typedef std::function<void(const Twine &Warning, StringRef Context,
const DWARFDie *DIE)>
messageHandler;
typedef std::function<void(const DWARFFile &File)> inputVerificationHandler;
typedef std::function<ErrorOr<DWARFFile &>(StringRef ContainerName,
StringRef Path)>
objFileLoader;
typedef std::map<std::string, std::string> swiftInterfacesMap;
typedef std::map<std::string, std::string> objectPrefixMap;

Expand All @@ -275,9 +277,43 @@ typedef function_ref<void(const DWARFUnit &Unit)> CompileUnitHandler;
/// processing a object file.
class DWARFLinker {
public:
DWARFLinker(DwarfEmitter *Emitter,
DwarfLinkerClient ClientID = DwarfLinkerClient::General)
: TheDwarfEmitter(Emitter), DwarfLinkerClientID(ClientID) {}
typedef std::function<void(const Twine &Warning, StringRef Context,
const DWARFDie *DIE)>
messageHandler;
DWARFLinker(messageHandler ErrorHandler, messageHandler WarningHandler,
std::function<StringRef(StringRef)> StringsTranslator)
: DwarfLinkerClientID(DwarfLinkerClient::Dsymutil),
StringsTranslator(StringsTranslator), ErrorHandler(ErrorHandler),
WarningHandler(WarningHandler) {}

static std::unique_ptr<DWARFLinker> createLinker(
messageHandler ErrorHandler, messageHandler WarningHandler,
std::function<StringRef(StringRef)> StringsTranslator = nullptr) {
return std::make_unique<DWARFLinker>(ErrorHandler, WarningHandler,
StringsTranslator);
}

/// Type of output file.
enum class OutputFileType {
Object,
Assembly,
};

/// The kind of accelerator tables we should emit.
enum class AccelTableKind : uint8_t {
Apple, ///< .apple_names, .apple_namespaces, .apple_types, .apple_objc.
Pub, ///< .debug_pubnames, .debug_pubtypes
DebugNames ///< .debug_names.
};
typedef std::function<void(const DWARFFile &File)> inputVerificationHandler;
typedef std::function<ErrorOr<DWARFFile &>(StringRef ContainerName,
StringRef Path)>
objFileLoader;

Error createEmitter(const Triple &TheTriple, OutputFileType FileType,
raw_pwrite_stream &OutFile);

DwarfEmitter *getEmitter();

/// Add object file to be linked. Pre-load compile unit die. Call
/// \p OnCUDieLoaded for each compile unit die. If specified \p File
Expand All @@ -289,8 +325,7 @@ class DWARFLinker {
DWARFFile &File, objFileLoader Loader = nullptr,
CompileUnitHandler OnCUDieLoaded = [](const DWARFUnit &) {});

/// Link debug info for added objFiles. Object
/// files are linked all together.
/// Link debug info for added objFiles. Object files are linked all together.
Error link();

/// A number of methods setting various linking options:
Expand All @@ -304,14 +339,15 @@ class DWARFLinker {
/// Verify the input DWARF.
void setVerifyInputDWARF(bool Verify) { Options.VerifyInputDWARF = Verify; }

/// Do not emit linked dwarf info.
void setNoOutput(bool NoOut) { Options.NoOutput = NoOut; }

/// Do not unique types according to ODR.
void setNoODR(bool NoODR) { Options.NoODR = NoODR; }

/// update existing DWARF info(for the linked binary).
void setUpdate(bool Update) { Options.Update = Update; }
/// Update index tables only(do not modify rest of DWARF).
void setUpdateIndexTablesOnly(bool Update) { Options.Update = Update; }

/// Allow generating valid, but non-deterministic output.
void setAllowNonDeterministicOutput(bool) { /* Nothing to do. */
}

/// Set whether to keep the enclosing function for a static variable.
void setKeepFunctionForStatic(bool KeepFunctionForStatic) {
Expand All @@ -322,7 +358,7 @@ class DWARFLinker {
void setNumThreads(unsigned NumThreads) { Options.Threads = NumThreads; }

/// Add kind of accelerator tables to be generated.
void addAccelTableKind(DwarfLinkerAccelTableKind Kind) {
void addAccelTableKind(AccelTableKind Kind) {
assert(std::find(Options.AccelTables.begin(), Options.AccelTables.end(),
Kind) == Options.AccelTables.end());
Options.AccelTables.emplace_back(Kind);
Expand All @@ -331,27 +367,11 @@ class DWARFLinker {
/// Set prepend path for clang modules.
void setPrependPath(const std::string &Ppath) { Options.PrependPath = Ppath; }

/// Set translator which would be used for strings.
void
setStringsTranslator(std::function<StringRef(StringRef)> StringsTranslator) {
this->StringsTranslator = StringsTranslator;
}

/// Set estimated objects files amount, for preliminary data allocation.
void setEstimatedObjfilesAmount(unsigned ObjFilesNum) {
ObjectContexts.reserve(ObjFilesNum);
}

/// Set warning handler which would be used to report warnings.
void setWarningHandler(messageHandler Handler) {
Options.WarningHandler = Handler;
}

/// Set error handler which would be used to report errors.
void setErrorHandler(messageHandler Handler) {
Options.ErrorHandler = Handler;
}

/// Set verification handler which would be used to report verification
/// errors.
void setInputVerificationHandler(inputVerificationHandler Handler) {
Expand All @@ -370,7 +390,7 @@ class DWARFLinker {

/// Set target DWARF version.
Error setTargetDWARFVersion(uint16_t TargetDWARFVersion) {
if (TargetDWARFVersion < 1 || TargetDWARFVersion > 5)
if ((TargetDWARFVersion < 1) || (TargetDWARFVersion > 5))
return createStringError(std::errc::invalid_argument,
"unsupported DWARF version: %d",
TargetDWARFVersion);
Expand Down Expand Up @@ -444,14 +464,14 @@ class DWARFLinker {

void reportWarning(const Twine &Warning, const DWARFFile &File,
const DWARFDie *DIE = nullptr) const {
if (Options.WarningHandler != nullptr)
Options.WarningHandler(Warning, File.FileName, DIE);
if (WarningHandler != nullptr)
WarningHandler(Warning, File.FileName, DIE);
}

void reportError(const Twine &Warning, const DWARFFile &File,
const DWARFDie *DIE = nullptr) const {
if (Options.ErrorHandler != nullptr)
Options.ErrorHandler(Warning, File.FileName, DIE);
if (ErrorHandler != nullptr)
ErrorHandler(Warning, File.FileName, DIE);
}

/// Emit warnings as Dwarf compile units to leave a trail after linking.
Expand Down Expand Up @@ -799,7 +819,7 @@ class DWARFLinker {
BumpPtrAllocator DIEAlloc;
/// @}

DwarfEmitter *TheDwarfEmitter;
std::unique_ptr<DwarfStreamer> TheDwarfEmitter;
std::vector<LinkContext> ObjectContexts;

/// The CIEs that have been emitted in the output section. The actual CIE
Expand Down Expand Up @@ -828,6 +848,12 @@ class DWARFLinker {
/// A unique ID that identifies each compile unit.
unsigned UniqueUnitID = 0;

// error handler
messageHandler ErrorHandler = nullptr;

// warning handler
messageHandler WarningHandler = nullptr;

/// linking options
struct DWARFLinkerOptions {
/// DWARF version for the output.
Expand All @@ -842,9 +868,6 @@ class DWARFLinker {
/// Verify the input DWARF.
bool VerifyInputDWARF = false;

/// Skip emitting output
bool NoOutput = false;

/// Do not unique types according to ODR
bool NoODR = false;

Expand All @@ -859,17 +882,11 @@ class DWARFLinker {
unsigned Threads = 1;

/// The accelerator table kinds
SmallVector<DwarfLinkerAccelTableKind, 1> AccelTables;
SmallVector<AccelTableKind, 1> AccelTables;

/// Prepend path for the clang modules.
std::string PrependPath;

// warning handler
messageHandler WarningHandler = nullptr;

// error handler
messageHandler ErrorHandler = nullptr;

// input verification handler
inputVerificationHandler InputVerificationHandler = nullptr;

Expand Down
32 changes: 11 additions & 21 deletions llvm/include/llvm/DWARFLinker/DWARFStreamer.h
Expand Up @@ -23,11 +23,6 @@
namespace llvm {
template <typename DataT> class AccelTable;

enum class OutputFileType {
Object,
Assembly,
};

/// User of DwarfStreamer should call initialization code
/// for AsmPrinter:
///
Expand All @@ -45,18 +40,19 @@ class DWARFDebugMacro;
/// information binary representation are handled in this class.
class DwarfStreamer : public DwarfEmitter {
public:
DwarfStreamer(OutputFileType OutFileType, raw_pwrite_stream &OutFile,
DwarfStreamer(DWARFLinker::OutputFileType OutFileType,
raw_pwrite_stream &OutFile,
std::function<StringRef(StringRef Input)> Translator,
messageHandler Error, messageHandler Warning)
DWARFLinker::messageHandler Warning)
: OutFile(OutFile), OutFileType(OutFileType), Translator(Translator),
ErrorHandler(Error), WarningHandler(Warning) {}
WarningHandler(Warning) {}

bool init(Triple TheTriple, StringRef Swift5ReflectionSegmentName);
Error init(Triple TheTriple, StringRef Swift5ReflectionSegmentName);

/// Dump the file to the disk.
void finish();
void finish() override;

AsmPrinter &getAsmPrinter() const { return *Asm; }
AsmPrinter &getAsmPrinter() const override { return *Asm; }

/// Set the current output section to debug_info and change
/// the MC Dwarf version to \p DwarfVersion.
Expand Down Expand Up @@ -89,12 +85,12 @@ class DwarfStreamer : public DwarfEmitter {
void emitLineStrings(const NonRelocatableStringpool &Pool) override;

/// Emit the swift_ast section stored in \p Buffer.
void emitSwiftAST(StringRef 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 Size);
StringRef Buffer, uint32_t Alignment, uint32_t Size) override;

/// Emit debug ranges(.debug_ranges, .debug_rnglists) header.
MCSymbol *emitDwarfDebugRangeListHeader(const CompileUnit &Unit) override;
Expand Down Expand Up @@ -194,11 +190,6 @@ class DwarfStreamer : public DwarfEmitter {
OffsetsStringPool &StringPool) override;

private:
inline void error(const Twine &Error, StringRef Context = "") {
if (ErrorHandler)
ErrorHandler(Error, Context, nullptr);
}

inline void warn(const Twine &Warning, StringRef Context = "") {
if (WarningHandler)
WarningHandler(Warning, Context, nullptr);
Expand Down Expand Up @@ -274,7 +265,7 @@ class DwarfStreamer : public DwarfEmitter {

/// The output file we stream the linked Dwarf to.
raw_pwrite_stream &OutFile;
OutputFileType OutFileType = OutputFileType::Object;
DWARFLinker::OutputFileType OutFileType = DWARFLinker::OutputFileType::Object;
std::function<StringRef(StringRef Input)> Translator;

uint64_t RangesSectionSize = 0;
Expand All @@ -300,8 +291,7 @@ class DwarfStreamer : public DwarfEmitter {
const CompileUnit &Unit,
const std::vector<CompileUnit::AccelInfo> &Names);

messageHandler ErrorHandler = nullptr;
messageHandler WarningHandler = nullptr;
DWARFLinker::messageHandler WarningHandler = nullptr;
};

} // end namespace llvm
Expand Down

0 comments on commit 36f3510

Please sign in to comment.