aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.h')
-rw-r--r--contrib/llvm-project/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.h382
1 files changed, 382 insertions, 0 deletions
diff --git a/contrib/llvm-project/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.h b/contrib/llvm-project/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.h
new file mode 100644
index 000000000000..b4331df5e323
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.h
@@ -0,0 +1,382 @@
+//===- DWARFLinkerImpl.h ----------------------------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_DWARFLINKER_PARALLEL_DWARFLINKERIMPL_H
+#define LLVM_LIB_DWARFLINKER_PARALLEL_DWARFLINKERIMPL_H
+
+#include "DWARFEmitterImpl.h"
+#include "DWARFLinkerCompileUnit.h"
+#include "DWARFLinkerTypeUnit.h"
+#include "StringEntryToDwarfStringPoolEntryMap.h"
+#include "llvm/ADT/AddressRanges.h"
+#include "llvm/CodeGen/AccelTable.h"
+#include "llvm/DWARFLinker/Parallel/DWARFLinker.h"
+#include "llvm/DWARFLinker/StringPool.h"
+
+namespace llvm {
+namespace dwarf_linker {
+namespace parallel {
+
+/// This class links debug info.
+class DWARFLinkerImpl : public DWARFLinker {
+public:
+ DWARFLinkerImpl(MessageHandlerTy ErrorHandler,
+ 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
+ /// pre-loaded by \p Loader for !Update case.
+ ///
+ /// \pre NoODR, Update options should be set before call to addObjectFile.
+ void addObjectFile(
+ DWARFFile &File, ObjFileLoaderTy Loader = nullptr,
+
+ CompileUnitHandlerTy OnCUDieLoaded = [](const DWARFUnit &) {}) override;
+
+ /// Link debug info for added files.
+ Error link() override;
+
+ /// \defgroup Methods setting various linking options:
+ ///
+ /// @{
+ ///
+
+ /// Allows to generate log of linking process to the standard output.
+ void setVerbosity(bool Verbose) override {
+ GlobalData.Options.Verbose = Verbose;
+ }
+
+ /// Print statistics to standard output.
+ void setStatistics(bool Statistics) override {
+ GlobalData.Options.Statistics = Statistics;
+ }
+
+ /// Verify the input DWARF.
+ void setVerifyInputDWARF(bool Verify) override {
+ GlobalData.Options.VerifyInputDWARF = Verify;
+ }
+
+ /// Do not unique types according to ODR.
+ void setNoODR(bool NoODR) override { GlobalData.Options.NoODR = NoODR; }
+
+ /// Update index tables only(do not modify rest of DWARF).
+ void setUpdateIndexTablesOnly(bool UpdateIndexTablesOnly) override {
+ GlobalData.Options.UpdateIndexTablesOnly = UpdateIndexTablesOnly;
+ }
+
+ /// Allow generating valid, but non-deterministic output.
+ void
+ setAllowNonDeterministicOutput(bool AllowNonDeterministicOutput) override {
+ GlobalData.Options.AllowNonDeterministicOutput =
+ AllowNonDeterministicOutput;
+ }
+
+ /// Set to keep the enclosing function for a static variable.
+ void setKeepFunctionForStatic(bool KeepFunctionForStatic) override {
+ GlobalData.Options.KeepFunctionForStatic = KeepFunctionForStatic;
+ }
+
+ /// Use specified number of threads for parallel files linking.
+ void setNumThreads(unsigned NumThreads) override {
+ GlobalData.Options.Threads = NumThreads;
+ }
+
+ /// Add kind of accelerator tables to be generated.
+ void addAccelTableKind(AccelTableKind Kind) override {
+ assert(!llvm::is_contained(GlobalData.getOptions().AccelTables, Kind));
+ GlobalData.Options.AccelTables.emplace_back(Kind);
+ }
+
+ /// Set prepend path for clang modules.
+ void setPrependPath(StringRef Ppath) override {
+ GlobalData.Options.PrependPath = Ppath;
+ }
+
+ /// Set estimated objects files amount, for preliminary data allocation.
+ void setEstimatedObjfilesAmount(unsigned ObjFilesNum) override;
+
+ /// Set verification handler which would be used to report verification
+ /// errors.
+ void
+ setInputVerificationHandler(InputVerificationHandlerTy Handler) override {
+ GlobalData.Options.InputVerificationHandler = Handler;
+ }
+
+ /// Set map for Swift interfaces.
+ void setSwiftInterfacesMap(SwiftInterfacesMapTy *Map) override {
+ GlobalData.Options.ParseableSwiftInterfaces = Map;
+ }
+
+ /// Set prefix map for objects.
+ void setObjectPrefixMap(ObjectPrefixMapTy *Map) override {
+ GlobalData.Options.ObjectPrefixMap = Map;
+ }
+
+ /// Set target DWARF version.
+ Error setTargetDWARFVersion(uint16_t TargetDWARFVersion) override {
+ if ((TargetDWARFVersion < 1) || (TargetDWARFVersion > 5))
+ return createStringError(std::errc::invalid_argument,
+ "unsupported DWARF version: %d",
+ TargetDWARFVersion);
+
+ GlobalData.Options.TargetDWARFVersion = TargetDWARFVersion;
+ return Error::success();
+ }
+ /// @}
+
+protected:
+ /// Verify input DWARF file.
+ void verifyInput(const DWARFFile &File);
+
+ /// Validate specified options.
+ Error validateAndUpdateOptions();
+
+ /// Take already linked compile units and glue them into single file.
+ void glueCompileUnitsAndWriteToTheOutput();
+
+ /// Hold the input and output of the debug info size in bytes.
+ struct DebugInfoSize {
+ uint64_t Input;
+ uint64_t Output;
+ };
+
+ friend class DependencyTracker;
+ /// Keeps track of data associated with one object during linking.
+ /// i.e. source file descriptor, compilation units, output data
+ /// for compilation units common tables.
+ struct LinkContext : public OutputSections {
+ using UnitListTy = SmallVector<std::unique_ptr<CompileUnit>>;
+
+ /// Keep information for referenced clang module: already loaded DWARF info
+ /// of the clang module and a CompileUnit of the module.
+ struct RefModuleUnit {
+ RefModuleUnit(DWARFFile &File, std::unique_ptr<CompileUnit> Unit);
+ RefModuleUnit(RefModuleUnit &&Other);
+ RefModuleUnit(const RefModuleUnit &) = delete;
+
+ DWARFFile &File;
+ std::unique_ptr<CompileUnit> Unit;
+ };
+ using ModuleUnitListTy = SmallVector<RefModuleUnit>;
+
+ /// Object file descriptor.
+ DWARFFile &InputDWARFFile;
+
+ /// Set of Compilation Units(may be accessed asynchroniously for reading).
+ UnitListTy CompileUnits;
+
+ /// Set of Compile Units for modules.
+ ModuleUnitListTy ModulesCompileUnits;
+
+ /// Size of Debug info before optimizing.
+ uint64_t OriginalDebugInfoSize = 0;
+
+ /// Flag indicating that all inter-connected units are loaded
+ /// and the dwarf linking process for these units is started.
+ bool InterCUProcessingStarted = false;
+
+ 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.
+ std::atomic<bool> HasNewInterconnectedCUs = {false};
+
+ std::atomic<bool> HasNewGlobalDependency = {false};
+
+ /// Counter for compile units ID.
+ std::atomic<size_t> &UniqueUnitID;
+
+ LinkContext(LinkingGlobalData &GlobalData, DWARFFile &File,
+ StringMap<uint64_t> &ClangModules,
+ std::atomic<size_t> &UniqueUnitID,
+ std::optional<Triple> TargetTriple);
+
+ /// Check whether specified \p CUDie is a Clang module reference.
+ /// if \p Quiet is false then display error messages.
+ /// \return first == true if CUDie is a Clang module reference.
+ /// second == true if module is already loaded.
+ std::pair<bool, bool> isClangModuleRef(const DWARFDie &CUDie,
+ std::string &PCMFile,
+ unsigned Indent, bool Quiet);
+
+ /// If this compile unit is really a skeleton CU that points to a
+ /// clang module, register it in ClangModules and return true.
+ ///
+ /// A skeleton CU is a CU without children, a DW_AT_gnu_dwo_name
+ /// pointing to the module, and a DW_AT_gnu_dwo_id with the module
+ /// hash.
+ bool registerModuleReference(const DWARFDie &CUDie, ObjFileLoaderTy Loader,
+ CompileUnitHandlerTy OnCUDieLoaded,
+ unsigned Indent = 0);
+
+ /// Recursively add the debug info in this clang module .pcm
+ /// file (and all the modules imported by it in a bottom-up fashion)
+ /// to ModuleUnits.
+ Error loadClangModule(ObjFileLoaderTy Loader, const DWARFDie &CUDie,
+ const std::string &PCMFile,
+ CompileUnitHandlerTy OnCUDieLoaded,
+ unsigned Indent = 0);
+
+ /// Add Compile Unit corresponding to the module.
+ void addModulesCompileUnit(RefModuleUnit &&Unit);
+
+ /// Computes the total size of the debug info.
+ uint64_t getInputDebugInfoSize() const {
+ uint64_t Size = 0;
+
+ if (InputDWARFFile.Dwarf == nullptr)
+ return Size;
+
+ for (auto &Unit : InputDWARFFile.Dwarf->compile_units())
+ Size += Unit->getLength();
+
+ return Size;
+ }
+
+ /// Link compile units for this context.
+ Error link(TypeUnit *ArtificialTypeUnit);
+
+ /// Link specified compile unit until specified stage.
+ void linkSingleCompileUnit(
+ CompileUnit &CU, TypeUnit *ArtificialTypeUnit,
+ enum CompileUnit::Stage DoUntilStage = CompileUnit::Stage::Cleaned);
+
+ /// Emit invariant sections.
+ Error emitInvariantSections();
+
+ /// Clone and emit .debug_frame.
+ Error cloneAndEmitDebugFrame();
+
+ /// Emit FDE record.
+ void emitFDE(uint32_t CIEOffset, uint32_t AddrSize, uint64_t Address,
+ StringRef FDEBytes, SectionDescriptor &Section);
+
+ std::function<CompileUnit *(uint64_t)> getUnitForOffset =
+ [&](uint64_t Offset) -> CompileUnit * {
+ auto CU = llvm::upper_bound(
+ CompileUnits, Offset,
+ [](uint64_t LHS, const std::unique_ptr<CompileUnit> &RHS) {
+ return LHS < RHS->getOrigUnit().getNextUnitOffset();
+ });
+
+ return CU != CompileUnits.end() ? CU->get() : nullptr;
+ };
+ };
+
+ /// Enumerate all compile units and assign offsets to their sections and
+ /// strings.
+ void assignOffsets();
+
+ /// Enumerate all compile units and assign offsets to their sections.
+ void assignOffsetsToSections();
+
+ /// Enumerate all compile units and assign offsets to their strings.
+ void assignOffsetsToStrings();
+
+ /// Print statistic for processed Debug Info.
+ void printStatistic();
+
+ enum StringDestinationKind : uint8_t { DebugStr, DebugLineStr };
+
+ /// Enumerates all strings.
+ void forEachOutputString(
+ function_ref<void(StringDestinationKind, const StringEntry *)>
+ StringHandler);
+
+ /// Enumerates sections for modules, invariant for object files, compile
+ /// units.
+ void forEachObjectSectionsSet(
+ function_ref<void(OutputSections &SectionsSet)> SectionsSetHandler);
+
+ /// Enumerates all compile and type units.
+ void forEachCompileAndTypeUnit(function_ref<void(DwarfUnit *CU)> UnitHandler);
+
+ /// Enumerates all comple units.
+ void forEachCompileUnit(function_ref<void(CompileUnit *CU)> UnitHandler);
+
+ /// Enumerates all patches and update them with the correct values.
+ void patchOffsetsAndSizes();
+
+ /// Emit debug sections common for all input files.
+ void emitCommonSectionsAndWriteCompileUnitsToTheOutput();
+
+ /// Emit apple accelerator sections.
+ void emitAppleAcceleratorSections(const Triple &TargetTriple);
+
+ /// Emit .debug_names section.
+ void emitDWARFv5DebugNamesSection(const Triple &TargetTriple);
+
+ /// Emit string sections.
+ void emitStringSections();
+
+ /// Cleanup data(string pools) after output sections are generated.
+ void cleanupDataAfterDWARFOutputIsWritten();
+
+ /// Enumerate all compile units and put their data into the output stream.
+ void writeCompileUnitsToTheOutput();
+
+ /// Enumerate common sections and put their data into the output stream.
+ void writeCommonSectionsToTheOutput();
+
+ /// \defgroup Data members accessed asinchroniously.
+ ///
+ /// @{
+
+ /// Unique ID for compile unit.
+ std::atomic<size_t> UniqueUnitID;
+
+ /// Mapping the PCM filename to the DwoId.
+ StringMap<uint64_t> ClangModules;
+ std::mutex ClangModulesMutex;
+
+ /// Type unit.
+ std::unique_ptr<TypeUnit> ArtificialTypeUnit;
+ /// @}
+
+ /// \defgroup Data members accessed sequentially.
+ ///
+ /// @{
+ /// DwarfStringPoolEntries for .debug_str section.
+ StringEntryToDwarfStringPoolEntryMap DebugStrStrings;
+
+ /// DwarfStringPoolEntries for .debug_line_str section.
+ StringEntryToDwarfStringPoolEntryMap DebugLineStrStrings;
+
+ /// Keeps all linking contexts.
+ SmallVector<std::unique_ptr<LinkContext>> ObjectContexts;
+
+ /// Common sections.
+ OutputSections CommonSections;
+
+ /// The emitter of final dwarf file.
+ std::unique_ptr<DwarfEmitterImpl> TheDwarfEmitter;
+
+ /// Overall compile units number.
+ uint64_t OverallNumberOfCU = 0;
+
+ /// Data global for the whole linking process.
+ LinkingGlobalData GlobalData;
+ /// @}
+};
+
+} // end of namespace parallel
+} // end of namespace dwarf_linker
+} // end of namespace llvm
+
+#endif // LLVM_LIB_DWARFLINKER_PARALLEL_DWARFLINKERIMPL_H