diff options
author | orivej <orivej@yandex-team.ru> | 2022-02-10 16:45:01 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:45:01 +0300 |
commit | 2d37894b1b037cf24231090eda8589bbb44fb6fc (patch) | |
tree | be835aa92c6248212e705f25388ebafcf84bc7a1 /contrib/libs/llvm12/include/llvm/DWARFLinker | |
parent | 718c552901d703c502ccbefdfc3c9028d608b947 (diff) | |
download | ydb-2d37894b1b037cf24231090eda8589bbb44fb6fc.tar.gz |
Restoring authorship annotation for <orivej@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/libs/llvm12/include/llvm/DWARFLinker')
4 files changed, 1490 insertions, 1490 deletions
diff --git a/contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFLinker.h b/contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFLinker.h index 8d4ef80c95..f6007dfbec 100644 --- a/contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFLinker.h +++ b/contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFLinker.h @@ -1,824 +1,824 @@ -#pragma once - -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-parameter" -#endif - -//===- DWARFLinker.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_DWARFLINKER_DWARFLINKER_H -#define LLVM_DWARFLINKER_DWARFLINKER_H - -#include "llvm/CodeGen/AccelTable.h" -#include "llvm/CodeGen/NonRelocatableStringpool.h" -#include "llvm/DWARFLinker/DWARFLinkerDeclContext.h" -#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h" -#include "llvm/DebugInfo/DWARF/DWARFContext.h" -#include "llvm/MC/MCDwarf.h" -#include <map> - -namespace llvm { - -enum class DwarfLinkerClient { Dsymutil, LLD, General }; - -/// The kind of accelerator tables we should emit. -enum class AccelTableKind { - Apple, ///< .apple_names, .apple_namespaces, .apple_types, .apple_objc. - Dwarf, ///< DWARF v5 .debug_names. - Default, ///< Dwarf for DWARF5 or later, Apple otherwise. -}; - -/// Partial address range. Besides an offset, only the -/// HighPC is stored. The structure is stored in a map where the LowPC is the -/// key. -struct ObjFileAddressRange { - /// Function HighPC. - uint64_t HighPC; - /// Offset to apply to the linked address. - /// should be 0 for not-linked object file. - int64_t Offset; - - ObjFileAddressRange(uint64_t EndPC, int64_t Offset) - : HighPC(EndPC), Offset(Offset) {} - - ObjFileAddressRange() : HighPC(0), Offset(0) {} -}; - -/// Map LowPC to ObjFileAddressRange. -using RangesTy = std::map<uint64_t, ObjFileAddressRange>; - -/// 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 -/// into sections which would be/are placed into resulting binary. -class AddressesMap { -public: - virtual ~AddressesMap(); - - /// Returns true if represented addresses are from linked file. - /// Returns false if represented addresses are from not-linked - /// object file. - virtual bool areRelocationsResolved() const = 0; - - /// Checks that there are valid relocations against a .debug_info - /// section. Reset current relocation pointer if neccessary. - virtual bool hasValidRelocs(bool ResetRelocsPtr = true) = 0; - +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===- DWARFLinker.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_DWARFLINKER_DWARFLINKER_H +#define LLVM_DWARFLINKER_DWARFLINKER_H + +#include "llvm/CodeGen/AccelTable.h" +#include "llvm/CodeGen/NonRelocatableStringpool.h" +#include "llvm/DWARFLinker/DWARFLinkerDeclContext.h" +#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h" +#include "llvm/DebugInfo/DWARF/DWARFContext.h" +#include "llvm/MC/MCDwarf.h" +#include <map> + +namespace llvm { + +enum class DwarfLinkerClient { Dsymutil, LLD, General }; + +/// The kind of accelerator tables we should emit. +enum class AccelTableKind { + Apple, ///< .apple_names, .apple_namespaces, .apple_types, .apple_objc. + Dwarf, ///< DWARF v5 .debug_names. + Default, ///< Dwarf for DWARF5 or later, Apple otherwise. +}; + +/// Partial address range. Besides an offset, only the +/// HighPC is stored. The structure is stored in a map where the LowPC is the +/// key. +struct ObjFileAddressRange { + /// Function HighPC. + uint64_t HighPC; + /// Offset to apply to the linked address. + /// should be 0 for not-linked object file. + int64_t Offset; + + ObjFileAddressRange(uint64_t EndPC, int64_t Offset) + : HighPC(EndPC), Offset(Offset) {} + + ObjFileAddressRange() : HighPC(0), Offset(0) {} +}; + +/// Map LowPC to ObjFileAddressRange. +using RangesTy = std::map<uint64_t, ObjFileAddressRange>; + +/// 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 +/// into sections which would be/are placed into resulting binary. +class AddressesMap { +public: + virtual ~AddressesMap(); + + /// Returns true if represented addresses are from linked file. + /// Returns false if represented addresses are from not-linked + /// object file. + virtual bool areRelocationsResolved() const = 0; + + /// Checks that there are valid relocations against a .debug_info + /// section. Reset current relocation pointer if neccessary. + virtual bool hasValidRelocs(bool ResetRelocsPtr = true) = 0; + /// Checks that the specified DIE has a DW_AT_Location attribute /// that references into a live code section. This function /// must be called with DIE offsets in strictly ascending order. virtual bool hasLiveMemoryLocation(const DWARFDie &DIE, CompileUnit::DIEInfo &Info) = 0; - + /// Checks that the specified DIE has a DW_AT_Low_pc attribute /// that references into a live code section. This function /// must be called with DIE offsets in strictly ascending order. virtual bool hasLiveAddressRange(const DWARFDie &DIE, CompileUnit::DIEInfo &Info) = 0; - /// Apply the valid relocations to the buffer \p Data, taking into - /// account that Data is at \p BaseOffset in the debug_info section. - /// - /// This function must be called with monotonic \p BaseOffset values. - /// - /// \returns true whether any reloc has been applied. - virtual bool applyValidRelocs(MutableArrayRef<char> Data, uint64_t BaseOffset, - bool IsLittleEndian) = 0; - + /// Apply the valid relocations to the buffer \p Data, taking into + /// account that Data is at \p BaseOffset in the debug_info section. + /// + /// This function must be called with monotonic \p BaseOffset values. + /// + /// \returns true whether any reloc has been applied. + virtual bool applyValidRelocs(MutableArrayRef<char> Data, uint64_t BaseOffset, + bool IsLittleEndian) = 0; + /// Relocate the given address offset if a valid relocation exists. virtual llvm::Expected<uint64_t> relocateIndexedAddr(uint64_t Offset) = 0; - /// Returns all valid functions address ranges(i.e., those ranges - /// which points to sections with code). - virtual RangesTy &getValidAddressRanges() = 0; - - /// Erases all data. - virtual void clear() = 0; -}; - -/// DwarfEmitter presents interface to generate all debug info tables. -class DwarfEmitter { -public: - virtual ~DwarfEmitter(); - - /// Emit DIE containing warnings. - virtual void emitPaperTrailWarningsDie(DIE &Die) = 0; - - /// Emit section named SecName with data SecData. - virtual void emitSectionContents(StringRef SecData, StringRef SecName) = 0; - - /// Emit the abbreviation table \p Abbrevs to the debug_abbrev section. - virtual void - emitAbbrevs(const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs, - unsigned DwarfVersion) = 0; - - /// Emit the string table described by \p Pool. - virtual void emitStrings(const NonRelocatableStringpool &Pool) = 0; - - /// Emit DWARF debug names. - virtual void - emitDebugNames(AccelTable<DWARF5AccelTableStaticData> &Table) = 0; - - /// Emit Apple namespaces accelerator table. - virtual void - emitAppleNamespaces(AccelTable<AppleAccelTableStaticOffsetData> &Table) = 0; - - /// Emit Apple names accelerator table. - virtual void - emitAppleNames(AccelTable<AppleAccelTableStaticOffsetData> &Table) = 0; - - /// Emit Apple Objective-C accelerator table. - virtual void - emitAppleObjc(AccelTable<AppleAccelTableStaticOffsetData> &Table) = 0; - - /// Emit Apple type accelerator table. - virtual void - emitAppleTypes(AccelTable<AppleAccelTableStaticTypeData> &Table) = 0; - - /// Emit debug_ranges for \p FuncRange by translating the - /// original \p Entries. - virtual void emitRangesEntries( - int64_t UnitPcOffset, uint64_t OrigLowPc, - const FunctionIntervals::const_iterator &FuncRange, - const std::vector<DWARFDebugRangeList::RangeListEntry> &Entries, - unsigned AddressSize) = 0; - - /// Emit debug_aranges entries for \p Unit and if \p DoRangesSection is true, - /// also emit the debug_ranges entries for the DW_TAG_compile_unit's - /// DW_AT_ranges attribute. - virtual void emitUnitRangesEntries(CompileUnit &Unit, - bool DoRangesSection) = 0; - - /// Copy the debug_line over to the updated binary while unobfuscating the - /// file names and directories. - virtual void translateLineTable(DataExtractor LineData, uint64_t Offset) = 0; - - /// Emit the line table described in \p Rows into the debug_line section. - virtual void emitLineTableForUnit(MCDwarfLineTableParams Params, - StringRef PrologueBytes, - unsigned MinInstLength, - std::vector<DWARFDebugLine::Row> &Rows, - unsigned AdddressSize) = 0; - - /// Emit the .debug_pubnames contribution for \p Unit. - virtual void emitPubNamesForUnit(const CompileUnit &Unit) = 0; - - /// Emit the .debug_pubtypes contribution for \p Unit. - virtual void emitPubTypesForUnit(const CompileUnit &Unit) = 0; - - /// Emit a CIE. - virtual void emitCIE(StringRef CIEBytes) = 0; - - /// Emit an FDE with data \p Bytes. - virtual void emitFDE(uint32_t CIEOffset, uint32_t AddreSize, uint32_t Address, - StringRef Bytes) = 0; - - /// Emit the debug_loc contribution for \p Unit by copying the entries from - /// \p Dwarf and offsetting them. Update the location attributes to point to - /// the new entries. - virtual void emitLocationsForUnit( - const CompileUnit &Unit, DWARFContext &Dwarf, - std::function<void(StringRef, SmallVectorImpl<uint8_t> &)> - ProcessExpr) = 0; - - /// Emit the compilation unit header for \p Unit in the - /// debug_info section. - /// - /// As a side effect, this also switches the current Dwarf version - /// of the MC layer to the one of U.getOrigUnit(). + /// Returns all valid functions address ranges(i.e., those ranges + /// which points to sections with code). + virtual RangesTy &getValidAddressRanges() = 0; + + /// Erases all data. + virtual void clear() = 0; +}; + +/// DwarfEmitter presents interface to generate all debug info tables. +class DwarfEmitter { +public: + virtual ~DwarfEmitter(); + + /// Emit DIE containing warnings. + virtual void emitPaperTrailWarningsDie(DIE &Die) = 0; + + /// Emit section named SecName with data SecData. + virtual void emitSectionContents(StringRef SecData, StringRef SecName) = 0; + + /// Emit the abbreviation table \p Abbrevs to the debug_abbrev section. + virtual void + emitAbbrevs(const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs, + unsigned DwarfVersion) = 0; + + /// Emit the string table described by \p Pool. + virtual void emitStrings(const NonRelocatableStringpool &Pool) = 0; + + /// Emit DWARF debug names. + virtual void + emitDebugNames(AccelTable<DWARF5AccelTableStaticData> &Table) = 0; + + /// Emit Apple namespaces accelerator table. + virtual void + emitAppleNamespaces(AccelTable<AppleAccelTableStaticOffsetData> &Table) = 0; + + /// Emit Apple names accelerator table. + virtual void + emitAppleNames(AccelTable<AppleAccelTableStaticOffsetData> &Table) = 0; + + /// Emit Apple Objective-C accelerator table. + virtual void + emitAppleObjc(AccelTable<AppleAccelTableStaticOffsetData> &Table) = 0; + + /// Emit Apple type accelerator table. + virtual void + emitAppleTypes(AccelTable<AppleAccelTableStaticTypeData> &Table) = 0; + + /// Emit debug_ranges for \p FuncRange by translating the + /// original \p Entries. + virtual void emitRangesEntries( + int64_t UnitPcOffset, uint64_t OrigLowPc, + const FunctionIntervals::const_iterator &FuncRange, + const std::vector<DWARFDebugRangeList::RangeListEntry> &Entries, + unsigned AddressSize) = 0; + + /// Emit debug_aranges entries for \p Unit and if \p DoRangesSection is true, + /// also emit the debug_ranges entries for the DW_TAG_compile_unit's + /// DW_AT_ranges attribute. + virtual void emitUnitRangesEntries(CompileUnit &Unit, + bool DoRangesSection) = 0; + + /// Copy the debug_line over to the updated binary while unobfuscating the + /// file names and directories. + virtual void translateLineTable(DataExtractor LineData, uint64_t Offset) = 0; + + /// Emit the line table described in \p Rows into the debug_line section. + virtual void emitLineTableForUnit(MCDwarfLineTableParams Params, + StringRef PrologueBytes, + unsigned MinInstLength, + std::vector<DWARFDebugLine::Row> &Rows, + unsigned AdddressSize) = 0; + + /// Emit the .debug_pubnames contribution for \p Unit. + virtual void emitPubNamesForUnit(const CompileUnit &Unit) = 0; + + /// Emit the .debug_pubtypes contribution for \p Unit. + virtual void emitPubTypesForUnit(const CompileUnit &Unit) = 0; + + /// Emit a CIE. + virtual void emitCIE(StringRef CIEBytes) = 0; + + /// Emit an FDE with data \p Bytes. + virtual void emitFDE(uint32_t CIEOffset, uint32_t AddreSize, uint32_t Address, + StringRef Bytes) = 0; + + /// Emit the debug_loc contribution for \p Unit by copying the entries from + /// \p Dwarf and offsetting them. Update the location attributes to point to + /// the new entries. + virtual void emitLocationsForUnit( + const CompileUnit &Unit, DWARFContext &Dwarf, + std::function<void(StringRef, SmallVectorImpl<uint8_t> &)> + ProcessExpr) = 0; + + /// Emit the compilation unit header for \p Unit in the + /// debug_info section. + /// + /// As a side effect, this also switches the current Dwarf version + /// of the MC layer to the one of U.getOrigUnit(). virtual void emitCompileUnitHeader(CompileUnit &Unit, unsigned DwarfVersion) = 0; - - /// Recursively emit the DIE tree rooted at \p Die. - virtual void emitDIE(DIE &Die) = 0; - - /// Returns size of generated .debug_line section. - virtual uint64_t getLineSectionSize() const = 0; - - /// Returns size of generated .debug_frame section. - virtual uint64_t getFrameSectionSize() const = 0; - - /// Returns size of generated .debug_ranges section. - virtual uint64_t getRangesSectionSize() const = 0; - - /// Returns size of generated .debug_info section. - virtual uint64_t getDebugInfoSectionSize() const = 0; -}; - -using UnitListTy = std::vector<std::unique_ptr<CompileUnit>>; - -/// this class represents DWARF information for source file -/// and it`s address map. + + /// Recursively emit the DIE tree rooted at \p Die. + virtual void emitDIE(DIE &Die) = 0; + + /// Returns size of generated .debug_line section. + virtual uint64_t getLineSectionSize() const = 0; + + /// Returns size of generated .debug_frame section. + virtual uint64_t getFrameSectionSize() const = 0; + + /// Returns size of generated .debug_ranges section. + virtual uint64_t getRangesSectionSize() const = 0; + + /// Returns size of generated .debug_info section. + virtual uint64_t getDebugInfoSectionSize() const = 0; +}; + +using UnitListTy = std::vector<std::unique_ptr<CompileUnit>>; + +/// this class represents DWARF information for source file +/// and it`s address map. class DWARFFile { -public: +public: DWARFFile(StringRef Name, DWARFContext *Dwarf, AddressesMap *Addresses, - const std::vector<std::string> &Warnings) - : FileName(Name), Dwarf(Dwarf), Addresses(Addresses), Warnings(Warnings) { - } - - /// object file name. - StringRef FileName; - /// source DWARF information. - DWARFContext *Dwarf = nullptr; - /// helpful address information(list of valid address ranges, relocations). - AddressesMap *Addresses = nullptr; - /// warnings for object file. - const std::vector<std::string> &Warnings; -}; - -typedef std::function<void(const Twine &Warning, StringRef Context, - const DWARFDie *DIE)> - messageHandler; + const std::vector<std::string> &Warnings) + : FileName(Name), Dwarf(Dwarf), Addresses(Addresses), Warnings(Warnings) { + } + + /// object file name. + StringRef FileName; + /// source DWARF information. + DWARFContext *Dwarf = nullptr; + /// helpful address information(list of valid address ranges, relocations). + AddressesMap *Addresses = nullptr; + /// warnings for object file. + const std::vector<std::string> &Warnings; +}; + +typedef std::function<void(const Twine &Warning, StringRef Context, + const DWARFDie *DIE)> + messageHandler; 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; - -/// The core of the Dwarf linking logic. -/// -/// The generation of the dwarf information from the object files will be -/// driven by the selection of 'root DIEs', which are DIEs that -/// describe variables or functions that resolves to the corresponding -/// code section(and thus have entries in the Addresses map). All the debug -/// information that will be generated(the DIEs, but also the line -/// tables, ranges, ...) is derived from that set of root DIEs. -/// -/// The root DIEs are identified because they contain relocations that -/// points to code section(the low_pc for a function, the location for -/// a variable). These relocations are called ValidRelocs in the -/// AddressesInfo and are gathered as a very first step when we start -/// processing a object file. -class DWARFLinker { -public: - DWARFLinker(DwarfEmitter *Emitter, - DwarfLinkerClient ClientID = DwarfLinkerClient::General) - : TheDwarfEmitter(Emitter), DwarfLinkerClientID(ClientID) {} - - /// Add object file to be linked. + StringRef Path)> + objFileLoader; +typedef std::map<std::string, std::string> swiftInterfacesMap; +typedef std::map<std::string, std::string> objectPrefixMap; + +/// The core of the Dwarf linking logic. +/// +/// The generation of the dwarf information from the object files will be +/// driven by the selection of 'root DIEs', which are DIEs that +/// describe variables or functions that resolves to the corresponding +/// code section(and thus have entries in the Addresses map). All the debug +/// information that will be generated(the DIEs, but also the line +/// tables, ranges, ...) is derived from that set of root DIEs. +/// +/// The root DIEs are identified because they contain relocations that +/// points to code section(the low_pc for a function, the location for +/// a variable). These relocations are called ValidRelocs in the +/// AddressesInfo and are gathered as a very first step when we start +/// processing a object file. +class DWARFLinker { +public: + DWARFLinker(DwarfEmitter *Emitter, + DwarfLinkerClient ClientID = DwarfLinkerClient::General) + : TheDwarfEmitter(Emitter), DwarfLinkerClientID(ClientID) {} + + /// Add object file to be linked. void addObjectFile(DWARFFile &File); - - /// Link debug info for added objFiles. Object - /// files are linked all together. - bool link(); - - /// A number of methods setting various linking options: - - /// Allows to generate log of linking process to the standard output. - void setVerbosity(bool Verbose) { Options.Verbose = Verbose; } - - /// Print statistics to standard output. - void setStatistics(bool Statistics) { Options.Statistics = Statistics; } - - /// 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; } - - /// Use specified number of threads for parallel files linking. - void setNumThreads(unsigned NumThreads) { Options.Threads = NumThreads; } - - /// Set kind of accelerator tables to be generated. - void setAccelTableKind(AccelTableKind Kind) { - Options.TheAccelTableKind = Kind; - } - - /// 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 object files loader which would be used to load - /// additional objects for splitted dwarf. - void setObjFileLoader(objFileLoader Loader) { - Options.ObjFileLoader = Loader; - } - - /// Set map for Swift interfaces. - void setSwiftInterfacesMap(swiftInterfacesMap *Map) { - Options.ParseableSwiftInterfaces = Map; - } - - /// Set prefix map for objects. - void setObjectPrefixMap(objectPrefixMap *Map) { - Options.ObjectPrefixMap = Map; - } - -private: - /// Flags passed to DwarfLinker::lookForDIEsToKeep - enum TraversalFlags { - TF_Keep = 1 << 0, ///< Mark the traversed DIEs as kept. - TF_InFunctionScope = 1 << 1, ///< Current scope is a function scope. - TF_DependencyWalk = 1 << 2, ///< Walking the dependencies of a kept DIE. - TF_ParentWalk = 1 << 3, ///< Walking up the parents of a kept DIE. - TF_ODR = 1 << 4, ///< Use the ODR while keeping dependents. - TF_SkipPC = 1 << 5, ///< Skip all location attributes. - }; - - /// The distinct types of work performed by the work loop. - enum class WorklistItemType { - /// Given a DIE, look for DIEs to be kept. - LookForDIEsToKeep, - /// Given a DIE, look for children of this DIE to be kept. - LookForChildDIEsToKeep, - /// Given a DIE, look for DIEs referencing this DIE to be kept. - LookForRefDIEsToKeep, - /// Given a DIE, look for parent DIEs to be kept. - LookForParentDIEsToKeep, - /// Given a DIE, update its incompleteness based on whether its children are - /// incomplete. - UpdateChildIncompleteness, - /// Given a DIE, update its incompleteness based on whether the DIEs it - /// references are incomplete. - UpdateRefIncompleteness, - }; - - /// This class represents an item in the work list. The type defines what kind - /// of work needs to be performed when processing the current item. The flags - /// and info fields are optional based on the type. - struct WorklistItem { + + /// Link debug info for added objFiles. Object + /// files are linked all together. + bool link(); + + /// A number of methods setting various linking options: + + /// Allows to generate log of linking process to the standard output. + void setVerbosity(bool Verbose) { Options.Verbose = Verbose; } + + /// Print statistics to standard output. + void setStatistics(bool Statistics) { Options.Statistics = Statistics; } + + /// 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; } + + /// Use specified number of threads for parallel files linking. + void setNumThreads(unsigned NumThreads) { Options.Threads = NumThreads; } + + /// Set kind of accelerator tables to be generated. + void setAccelTableKind(AccelTableKind Kind) { + Options.TheAccelTableKind = Kind; + } + + /// 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 object files loader which would be used to load + /// additional objects for splitted dwarf. + void setObjFileLoader(objFileLoader Loader) { + Options.ObjFileLoader = Loader; + } + + /// Set map for Swift interfaces. + void setSwiftInterfacesMap(swiftInterfacesMap *Map) { + Options.ParseableSwiftInterfaces = Map; + } + + /// Set prefix map for objects. + void setObjectPrefixMap(objectPrefixMap *Map) { + Options.ObjectPrefixMap = Map; + } + +private: + /// Flags passed to DwarfLinker::lookForDIEsToKeep + enum TraversalFlags { + TF_Keep = 1 << 0, ///< Mark the traversed DIEs as kept. + TF_InFunctionScope = 1 << 1, ///< Current scope is a function scope. + TF_DependencyWalk = 1 << 2, ///< Walking the dependencies of a kept DIE. + TF_ParentWalk = 1 << 3, ///< Walking up the parents of a kept DIE. + TF_ODR = 1 << 4, ///< Use the ODR while keeping dependents. + TF_SkipPC = 1 << 5, ///< Skip all location attributes. + }; + + /// The distinct types of work performed by the work loop. + enum class WorklistItemType { + /// Given a DIE, look for DIEs to be kept. + LookForDIEsToKeep, + /// Given a DIE, look for children of this DIE to be kept. + LookForChildDIEsToKeep, + /// Given a DIE, look for DIEs referencing this DIE to be kept. + LookForRefDIEsToKeep, + /// Given a DIE, look for parent DIEs to be kept. + LookForParentDIEsToKeep, + /// Given a DIE, update its incompleteness based on whether its children are + /// incomplete. + UpdateChildIncompleteness, + /// Given a DIE, update its incompleteness based on whether the DIEs it + /// references are incomplete. + UpdateRefIncompleteness, + }; + + /// This class represents an item in the work list. The type defines what kind + /// of work needs to be performed when processing the current item. The flags + /// and info fields are optional based on the type. + struct WorklistItem { DWARFDie Die; - WorklistItemType Type; - CompileUnit &CU; - unsigned Flags; + WorklistItemType Type; + CompileUnit &CU; + unsigned Flags; union { const unsigned AncestorIdx; CompileUnit::DIEInfo *OtherInfo; }; - - WorklistItem(DWARFDie Die, CompileUnit &CU, unsigned Flags, - WorklistItemType T = WorklistItemType::LookForDIEsToKeep) + + WorklistItem(DWARFDie Die, CompileUnit &CU, unsigned Flags, + WorklistItemType T = WorklistItemType::LookForDIEsToKeep) : Die(Die), Type(T), CU(CU), Flags(Flags), AncestorIdx(0) {} - - WorklistItem(DWARFDie Die, CompileUnit &CU, WorklistItemType T, - CompileUnit::DIEInfo *OtherInfo = nullptr) + + WorklistItem(DWARFDie Die, CompileUnit &CU, WorklistItemType T, + CompileUnit::DIEInfo *OtherInfo = nullptr) : Die(Die), Type(T), CU(CU), Flags(0), OtherInfo(OtherInfo) {} - - WorklistItem(unsigned AncestorIdx, CompileUnit &CU, unsigned Flags) + + WorklistItem(unsigned AncestorIdx, CompileUnit &CU, unsigned Flags) : Die(), Type(WorklistItemType::LookForParentDIEsToKeep), CU(CU), Flags(Flags), AncestorIdx(AncestorIdx) {} - }; - - /// returns true if we need to translate strings. - bool needToTranslateStrings() { return StringsTranslator != nullptr; } - + }; + + /// returns true if we need to translate strings. + bool needToTranslateStrings() { return StringsTranslator != nullptr; } + void reportWarning(const Twine &Warning, const DWARFFile &File, - const DWARFDie *DIE = nullptr) const { - if (Options.WarningHandler != nullptr) - Options.WarningHandler(Warning, File.FileName, DIE); - } - + const DWARFDie *DIE = nullptr) const { + if (Options.WarningHandler != nullptr) + Options.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); - } - - /// Remembers the oldest and newest DWARF version we've seen in a unit. - void updateDwarfVersion(unsigned Version) { - MaxDwarfVersion = std::max(MaxDwarfVersion, Version); - MinDwarfVersion = std::min(MinDwarfVersion, Version); - } - - /// Remembers the kinds of accelerator tables we've seen in a unit. - void updateAccelKind(DWARFContext &Dwarf); - - /// Emit warnings as Dwarf compile units to leave a trail after linking. + const DWARFDie *DIE = nullptr) const { + if (Options.ErrorHandler != nullptr) + Options.ErrorHandler(Warning, File.FileName, DIE); + } + + /// Remembers the oldest and newest DWARF version we've seen in a unit. + void updateDwarfVersion(unsigned Version) { + MaxDwarfVersion = std::max(MaxDwarfVersion, Version); + MinDwarfVersion = std::min(MinDwarfVersion, Version); + } + + /// Remembers the kinds of accelerator tables we've seen in a unit. + void updateAccelKind(DWARFContext &Dwarf); + + /// Emit warnings as Dwarf compile units to leave a trail after linking. bool emitPaperTrailWarnings(const DWARFFile &File, - OffsetsStringPool &StringPool); - - void copyInvariantDebugSection(DWARFContext &Dwarf); - - /// Keeps track of data associated with one object during linking. - struct LinkContext { + OffsetsStringPool &StringPool); + + void copyInvariantDebugSection(DWARFContext &Dwarf); + + /// Keeps track of data associated with one object during linking. + struct LinkContext { DWARFFile &File; - UnitListTy CompileUnits; - bool Skip = false; - + UnitListTy CompileUnits; + bool Skip = false; + LinkContext(DWARFFile &File) : File(File) {} - - /// Clear part of the context that's no longer needed when we're done with - /// the debug object. - void clear() { - CompileUnits.clear(); - File.Addresses->clear(); - } - }; - - /// Called before emitting object data - void cleanupAuxiliarryData(LinkContext &Context); - - /// Look at the parent of the given DIE and decide whether they should be - /// kept. - void lookForParentDIEsToKeep(unsigned AncestorIdx, CompileUnit &CU, - unsigned Flags, - SmallVectorImpl<WorklistItem> &Worklist); - - /// Look at the children of the given DIE and decide whether they should be - /// kept. - void lookForChildDIEsToKeep(const DWARFDie &Die, CompileUnit &CU, - unsigned Flags, - SmallVectorImpl<WorklistItem> &Worklist); - - /// Look at DIEs referenced by the given DIE and decide whether they should be - /// kept. All DIEs referenced though attributes should be kept. - void lookForRefDIEsToKeep(const DWARFDie &Die, CompileUnit &CU, - unsigned Flags, const UnitListTy &Units, + + /// Clear part of the context that's no longer needed when we're done with + /// the debug object. + void clear() { + CompileUnits.clear(); + File.Addresses->clear(); + } + }; + + /// Called before emitting object data + void cleanupAuxiliarryData(LinkContext &Context); + + /// Look at the parent of the given DIE and decide whether they should be + /// kept. + void lookForParentDIEsToKeep(unsigned AncestorIdx, CompileUnit &CU, + unsigned Flags, + SmallVectorImpl<WorklistItem> &Worklist); + + /// Look at the children of the given DIE and decide whether they should be + /// kept. + void lookForChildDIEsToKeep(const DWARFDie &Die, CompileUnit &CU, + unsigned Flags, + SmallVectorImpl<WorklistItem> &Worklist); + + /// Look at DIEs referenced by the given DIE and decide whether they should be + /// kept. All DIEs referenced though attributes should be kept. + void lookForRefDIEsToKeep(const DWARFDie &Die, CompileUnit &CU, + unsigned Flags, const UnitListTy &Units, const DWARFFile &File, - SmallVectorImpl<WorklistItem> &Worklist); - - /// \defgroup FindRootDIEs Find DIEs corresponding to Address map entries. - /// - /// @{ - /// Recursively walk the \p DIE tree and look for DIEs to - /// keep. Store that information in \p CU's DIEInfo. - /// - /// The return value indicates whether the DIE is incomplete. - void lookForDIEsToKeep(AddressesMap &RelocMgr, RangesTy &Ranges, - const UnitListTy &Units, const DWARFDie &DIE, + SmallVectorImpl<WorklistItem> &Worklist); + + /// \defgroup FindRootDIEs Find DIEs corresponding to Address map entries. + /// + /// @{ + /// Recursively walk the \p DIE tree and look for DIEs to + /// keep. Store that information in \p CU's DIEInfo. + /// + /// The return value indicates whether the DIE is incomplete. + void lookForDIEsToKeep(AddressesMap &RelocMgr, RangesTy &Ranges, + const UnitListTy &Units, const DWARFDie &DIE, const DWARFFile &File, CompileUnit &CU, - unsigned Flags); - - /// 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(DWARFDie CUDie, const DWARFUnit &Unit, + unsigned Flags); + + /// 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(DWARFDie CUDie, const DWARFUnit &Unit, const DWARFFile &File, - OffsetsStringPool &OffsetsStringPool, - DeclContextTree &ODRContexts, - uint64_t ModulesEndOffset, unsigned &UnitID, - bool IsLittleEndian, unsigned Indent = 0, - bool Quiet = false); - - /// Recursively add the debug info in this clang module .pcm - /// file (and all the modules imported by it in a bottom-up fashion) - /// to Units. - Error loadClangModule(DWARFDie CUDie, StringRef FilePath, - StringRef ModuleName, uint64_t DwoId, + OffsetsStringPool &OffsetsStringPool, + DeclContextTree &ODRContexts, + uint64_t ModulesEndOffset, unsigned &UnitID, + bool IsLittleEndian, unsigned Indent = 0, + bool Quiet = false); + + /// Recursively add the debug info in this clang module .pcm + /// file (and all the modules imported by it in a bottom-up fashion) + /// to Units. + Error loadClangModule(DWARFDie CUDie, StringRef FilePath, + StringRef ModuleName, uint64_t DwoId, const DWARFFile &File, - OffsetsStringPool &OffsetsStringPool, - DeclContextTree &ODRContexts, uint64_t ModulesEndOffset, - unsigned &UnitID, bool IsLittleEndian, - unsigned Indent = 0, bool Quiet = false); - - /// Mark the passed DIE as well as all the ones it depends on as kept. - void keepDIEAndDependencies(AddressesMap &RelocMgr, RangesTy &Ranges, - const UnitListTy &Units, const DWARFDie &DIE, - CompileUnit::DIEInfo &MyInfo, + OffsetsStringPool &OffsetsStringPool, + DeclContextTree &ODRContexts, uint64_t ModulesEndOffset, + unsigned &UnitID, bool IsLittleEndian, + unsigned Indent = 0, bool Quiet = false); + + /// Mark the passed DIE as well as all the ones it depends on as kept. + void keepDIEAndDependencies(AddressesMap &RelocMgr, RangesTy &Ranges, + const UnitListTy &Units, const DWARFDie &DIE, + CompileUnit::DIEInfo &MyInfo, const DWARFFile &File, CompileUnit &CU, - bool UseODR); - - unsigned shouldKeepDIE(AddressesMap &RelocMgr, RangesTy &Ranges, + bool UseODR); + + unsigned shouldKeepDIE(AddressesMap &RelocMgr, RangesTy &Ranges, const DWARFDie &DIE, const DWARFFile &File, - CompileUnit &Unit, CompileUnit::DIEInfo &MyInfo, - unsigned Flags); - - /// Check if a variable describing DIE should be kept. - /// \returns updated TraversalFlags. - unsigned shouldKeepVariableDIE(AddressesMap &RelocMgr, const DWARFDie &DIE, - CompileUnit::DIEInfo &MyInfo, unsigned Flags); - - unsigned shouldKeepSubprogramDIE(AddressesMap &RelocMgr, RangesTy &Ranges, + CompileUnit &Unit, CompileUnit::DIEInfo &MyInfo, + unsigned Flags); + + /// Check if a variable describing DIE should be kept. + /// \returns updated TraversalFlags. + unsigned shouldKeepVariableDIE(AddressesMap &RelocMgr, const DWARFDie &DIE, + CompileUnit::DIEInfo &MyInfo, unsigned Flags); + + unsigned shouldKeepSubprogramDIE(AddressesMap &RelocMgr, RangesTy &Ranges, const DWARFDie &DIE, const DWARFFile &File, - CompileUnit &Unit, - CompileUnit::DIEInfo &MyInfo, - unsigned Flags); - - /// Resolve the DIE attribute reference that has been extracted in \p - /// RefValue. The resulting DIE might be in another CompileUnit which is - /// stored into \p ReferencedCU. \returns null if resolving fails for any - /// reason. + CompileUnit &Unit, + CompileUnit::DIEInfo &MyInfo, + unsigned Flags); + + /// Resolve the DIE attribute reference that has been extracted in \p + /// RefValue. The resulting DIE might be in another CompileUnit which is + /// stored into \p ReferencedCU. \returns null if resolving fails for any + /// reason. DWARFDie resolveDIEReference(const DWARFFile &File, const UnitListTy &Units, - const DWARFFormValue &RefValue, - const DWARFDie &DIE, CompileUnit *&RefCU); - - /// @} - - /// \defgroup Methods used to link the debug information - /// - /// @{ - - struct DWARFLinkerOptions; - - class DIECloner { - DWARFLinker &Linker; - DwarfEmitter *Emitter; + const DWARFFormValue &RefValue, + const DWARFDie &DIE, CompileUnit *&RefCU); + + /// @} + + /// \defgroup Methods used to link the debug information + /// + /// @{ + + struct DWARFLinkerOptions; + + class DIECloner { + DWARFLinker &Linker; + DwarfEmitter *Emitter; DWARFFile &ObjFile; - - /// Allocator used for all the DIEValue objects. - BumpPtrAllocator &DIEAlloc; - - std::vector<std::unique_ptr<CompileUnit>> &CompileUnits; - - bool Update; - - public: + + /// Allocator used for all the DIEValue objects. + BumpPtrAllocator &DIEAlloc; + + std::vector<std::unique_ptr<CompileUnit>> &CompileUnits; + + bool Update; + + public: DIECloner(DWARFLinker &Linker, DwarfEmitter *Emitter, DWARFFile &ObjFile, - BumpPtrAllocator &DIEAlloc, - std::vector<std::unique_ptr<CompileUnit>> &CompileUnits, - bool Update) - : Linker(Linker), Emitter(Emitter), ObjFile(ObjFile), - DIEAlloc(DIEAlloc), CompileUnits(CompileUnits), Update(Update) {} - - /// Recursively clone \p InputDIE into an tree of DIE objects - /// where useless (as decided by lookForDIEsToKeep()) bits have been - /// stripped out and addresses have been rewritten according to the - /// address map. - /// - /// \param OutOffset is the offset the cloned DIE in the output - /// compile unit. - /// \param PCOffset (while cloning a function scope) is the offset - /// applied to the entry point of the function to get the linked address. - /// \param Die the output DIE to use, pass NULL to create one. - /// \returns the root of the cloned tree or null if nothing was selected. + BumpPtrAllocator &DIEAlloc, + std::vector<std::unique_ptr<CompileUnit>> &CompileUnits, + bool Update) + : Linker(Linker), Emitter(Emitter), ObjFile(ObjFile), + DIEAlloc(DIEAlloc), CompileUnits(CompileUnits), Update(Update) {} + + /// Recursively clone \p InputDIE into an tree of DIE objects + /// where useless (as decided by lookForDIEsToKeep()) bits have been + /// stripped out and addresses have been rewritten according to the + /// address map. + /// + /// \param OutOffset is the offset the cloned DIE in the output + /// compile unit. + /// \param PCOffset (while cloning a function scope) is the offset + /// applied to the entry point of the function to get the linked address. + /// \param Die the output DIE to use, pass NULL to create one. + /// \returns the root of the cloned tree or null if nothing was selected. DIE *cloneDIE(const DWARFDie &InputDIE, const DWARFFile &File, - CompileUnit &U, OffsetsStringPool &StringPool, - int64_t PCOffset, uint32_t OutOffset, unsigned Flags, - bool IsLittleEndian, DIE *Die = nullptr); - - /// Construct the output DIE tree by cloning the DIEs we - /// chose to keep above. If there are no valid relocs, then there's - /// nothing to clone/emit. - uint64_t cloneAllCompileUnits(DWARFContext &DwarfContext, + CompileUnit &U, OffsetsStringPool &StringPool, + int64_t PCOffset, uint32_t OutOffset, unsigned Flags, + bool IsLittleEndian, DIE *Die = nullptr); + + /// Construct the output DIE tree by cloning the DIEs we + /// chose to keep above. If there are no valid relocs, then there's + /// nothing to clone/emit. + uint64_t cloneAllCompileUnits(DWARFContext &DwarfContext, const DWARFFile &File, - OffsetsStringPool &StringPool, - bool IsLittleEndian); - - private: - using AttributeSpec = DWARFAbbreviationDeclaration::AttributeSpec; - - /// Information gathered and exchanged between the various - /// clone*Attributes helpers about the attributes of a particular DIE. - struct AttributesInfo { - /// Names. - DwarfStringPoolEntryRef Name, MangledName, NameWithoutTemplate; - - /// Offsets in the string pool. - uint32_t NameOffset = 0; - uint32_t MangledNameOffset = 0; - - /// Value of AT_low_pc in the input DIE - uint64_t OrigLowPc = std::numeric_limits<uint64_t>::max(); - - /// Value of AT_high_pc in the input DIE - uint64_t OrigHighPc = 0; - - /// Value of DW_AT_call_return_pc in the input DIE - uint64_t OrigCallReturnPc = 0; - - /// Value of DW_AT_call_pc in the input DIE - uint64_t OrigCallPc = 0; - - /// Offset to apply to PC addresses inside a function. - int64_t PCOffset = 0; - - /// Does the DIE have a low_pc attribute? - bool HasLowPc = false; - - /// Does the DIE have a ranges attribute? - bool HasRanges = false; - - /// Is this DIE only a declaration? - bool IsDeclaration = false; - - AttributesInfo() = default; - }; - - /// Helper for cloneDIE. - unsigned cloneAttribute(DIE &Die, const DWARFDie &InputDIE, + OffsetsStringPool &StringPool, + bool IsLittleEndian); + + private: + using AttributeSpec = DWARFAbbreviationDeclaration::AttributeSpec; + + /// Information gathered and exchanged between the various + /// clone*Attributes helpers about the attributes of a particular DIE. + struct AttributesInfo { + /// Names. + DwarfStringPoolEntryRef Name, MangledName, NameWithoutTemplate; + + /// Offsets in the string pool. + uint32_t NameOffset = 0; + uint32_t MangledNameOffset = 0; + + /// Value of AT_low_pc in the input DIE + uint64_t OrigLowPc = std::numeric_limits<uint64_t>::max(); + + /// Value of AT_high_pc in the input DIE + uint64_t OrigHighPc = 0; + + /// Value of DW_AT_call_return_pc in the input DIE + uint64_t OrigCallReturnPc = 0; + + /// Value of DW_AT_call_pc in the input DIE + uint64_t OrigCallPc = 0; + + /// Offset to apply to PC addresses inside a function. + int64_t PCOffset = 0; + + /// Does the DIE have a low_pc attribute? + bool HasLowPc = false; + + /// Does the DIE have a ranges attribute? + bool HasRanges = false; + + /// Is this DIE only a declaration? + bool IsDeclaration = false; + + AttributesInfo() = default; + }; + + /// Helper for cloneDIE. + unsigned cloneAttribute(DIE &Die, const DWARFDie &InputDIE, const DWARFFile &File, CompileUnit &U, - OffsetsStringPool &StringPool, - const DWARFFormValue &Val, - const AttributeSpec AttrSpec, unsigned AttrSize, - AttributesInfo &AttrInfo, bool IsLittleEndian); - - /// Clone a string attribute described by \p AttrSpec and add - /// it to \p Die. - /// \returns the size of the new attribute. - unsigned cloneStringAttribute(DIE &Die, AttributeSpec AttrSpec, - const DWARFFormValue &Val, const DWARFUnit &U, - OffsetsStringPool &StringPool, - AttributesInfo &Info); - - /// Clone an attribute referencing another DIE and add - /// it to \p Die. - /// \returns the size of the new attribute. - unsigned cloneDieReferenceAttribute(DIE &Die, const DWARFDie &InputDIE, - AttributeSpec AttrSpec, - unsigned AttrSize, - const DWARFFormValue &Val, + OffsetsStringPool &StringPool, + const DWARFFormValue &Val, + const AttributeSpec AttrSpec, unsigned AttrSize, + AttributesInfo &AttrInfo, bool IsLittleEndian); + + /// Clone a string attribute described by \p AttrSpec and add + /// it to \p Die. + /// \returns the size of the new attribute. + unsigned cloneStringAttribute(DIE &Die, AttributeSpec AttrSpec, + const DWARFFormValue &Val, const DWARFUnit &U, + OffsetsStringPool &StringPool, + AttributesInfo &Info); + + /// Clone an attribute referencing another DIE and add + /// it to \p Die. + /// \returns the size of the new attribute. + unsigned cloneDieReferenceAttribute(DIE &Die, const DWARFDie &InputDIE, + AttributeSpec AttrSpec, + unsigned AttrSize, + const DWARFFormValue &Val, const DWARFFile &File, - CompileUnit &Unit); - - /// Clone a DWARF expression that may be referencing another DIE. - void cloneExpression(DataExtractor &Data, DWARFExpression Expression, + CompileUnit &Unit); + + /// Clone a DWARF expression that may be referencing another DIE. + void cloneExpression(DataExtractor &Data, DWARFExpression Expression, const DWARFFile &File, CompileUnit &Unit, - SmallVectorImpl<uint8_t> &OutputBuffer); - - /// Clone an attribute referencing another DIE and add - /// it to \p Die. - /// \returns the size of the new attribute. + SmallVectorImpl<uint8_t> &OutputBuffer); + + /// Clone an attribute referencing another DIE and add + /// it to \p Die. + /// \returns the size of the new attribute. unsigned cloneBlockAttribute(DIE &Die, const DWARFFile &File, - CompileUnit &Unit, AttributeSpec AttrSpec, - const DWARFFormValue &Val, unsigned AttrSize, - bool IsLittleEndian); - - /// Clone an attribute referencing another DIE and add - /// it to \p Die. - /// \returns the size of the new attribute. - unsigned cloneAddressAttribute(DIE &Die, AttributeSpec AttrSpec, - const DWARFFormValue &Val, - const CompileUnit &Unit, - AttributesInfo &Info); - - /// Clone a scalar attribute and add it to \p Die. - /// \returns the size of the new attribute. - unsigned cloneScalarAttribute(DIE &Die, const DWARFDie &InputDIE, + CompileUnit &Unit, AttributeSpec AttrSpec, + const DWARFFormValue &Val, unsigned AttrSize, + bool IsLittleEndian); + + /// Clone an attribute referencing another DIE and add + /// it to \p Die. + /// \returns the size of the new attribute. + unsigned cloneAddressAttribute(DIE &Die, AttributeSpec AttrSpec, + const DWARFFormValue &Val, + const CompileUnit &Unit, + AttributesInfo &Info); + + /// Clone a scalar attribute and add it to \p Die. + /// \returns the size of the new attribute. + unsigned cloneScalarAttribute(DIE &Die, const DWARFDie &InputDIE, const DWARFFile &File, CompileUnit &U, - AttributeSpec AttrSpec, - const DWARFFormValue &Val, unsigned AttrSize, - AttributesInfo &Info); - - /// Get the potential name and mangled name for the entity - /// described by \p Die and store them in \Info if they are not - /// already there. - /// \returns is a name was found. - bool getDIENames(const DWARFDie &Die, AttributesInfo &Info, - OffsetsStringPool &StringPool, bool StripTemplate = false); - - /// Create a copy of abbreviation Abbrev. - void copyAbbrev(const DWARFAbbreviationDeclaration &Abbrev, bool hasODR); - - uint32_t hashFullyQualifiedName(DWARFDie DIE, CompileUnit &U, + AttributeSpec AttrSpec, + const DWARFFormValue &Val, unsigned AttrSize, + AttributesInfo &Info); + + /// Get the potential name and mangled name for the entity + /// described by \p Die and store them in \Info if they are not + /// already there. + /// \returns is a name was found. + bool getDIENames(const DWARFDie &Die, AttributesInfo &Info, + OffsetsStringPool &StringPool, bool StripTemplate = false); + + /// Create a copy of abbreviation Abbrev. + void copyAbbrev(const DWARFAbbreviationDeclaration &Abbrev, bool hasODR); + + uint32_t hashFullyQualifiedName(DWARFDie DIE, CompileUnit &U, const DWARFFile &File, - int RecurseDepth = 0); - - /// Helper for cloneDIE. - void addObjCAccelerator(CompileUnit &Unit, const DIE *Die, - DwarfStringPoolEntryRef Name, - OffsetsStringPool &StringPool, bool SkipPubSection); - }; - - /// Assign an abbreviation number to \p Abbrev - void assignAbbrev(DIEAbbrev &Abbrev); - - /// Compute and emit debug_ranges section for \p Unit, and - /// patch the attributes referencing it. - void patchRangesForUnit(const CompileUnit &Unit, DWARFContext &Dwarf, + int RecurseDepth = 0); + + /// Helper for cloneDIE. + void addObjCAccelerator(CompileUnit &Unit, const DIE *Die, + DwarfStringPoolEntryRef Name, + OffsetsStringPool &StringPool, bool SkipPubSection); + }; + + /// Assign an abbreviation number to \p Abbrev + void assignAbbrev(DIEAbbrev &Abbrev); + + /// Compute and emit debug_ranges section for \p Unit, and + /// patch the attributes referencing it. + void patchRangesForUnit(const CompileUnit &Unit, DWARFContext &Dwarf, const DWARFFile &File) const; - - /// Generate and emit the DW_AT_ranges attribute for a compile_unit if it had - /// one. - void generateUnitRanges(CompileUnit &Unit) const; - - /// Extract the line tables from the original dwarf, extract the relevant - /// parts according to the linked function ranges and emit the result in the - /// debug_line section. - void patchLineTableForUnit(CompileUnit &Unit, DWARFContext &OrigDwarf, + + /// Generate and emit the DW_AT_ranges attribute for a compile_unit if it had + /// one. + void generateUnitRanges(CompileUnit &Unit) const; + + /// Extract the line tables from the original dwarf, extract the relevant + /// parts according to the linked function ranges and emit the result in the + /// debug_line section. + void patchLineTableForUnit(CompileUnit &Unit, DWARFContext &OrigDwarf, const DWARFFile &File); - - /// Emit the accelerator entries for \p Unit. - void emitAcceleratorEntriesForUnit(CompileUnit &Unit); - void emitDwarfAcceleratorEntriesForUnit(CompileUnit &Unit); - void emitAppleAcceleratorEntriesForUnit(CompileUnit &Unit); - - /// Patch the frame info for an object file and emit it. + + /// Emit the accelerator entries for \p Unit. + void emitAcceleratorEntriesForUnit(CompileUnit &Unit); + void emitDwarfAcceleratorEntriesForUnit(CompileUnit &Unit); + void emitAppleAcceleratorEntriesForUnit(CompileUnit &Unit); + + /// Patch the frame info for an object file and emit it. void patchFrameInfoForObject(const DWARFFile &, RangesTy &Ranges, - DWARFContext &, unsigned AddressSize); - - /// FoldingSet that uniques the abbreviations. - FoldingSet<DIEAbbrev> AbbreviationsSet; - - /// Storage for the unique Abbreviations. - /// This is passed to AsmPrinter::emitDwarfAbbrevs(), thus it cannot be - /// changed to a vector of unique_ptrs. - std::vector<std::unique_ptr<DIEAbbrev>> Abbreviations; - - /// DIELoc objects that need to be destructed (but not freed!). - std::vector<DIELoc *> DIELocs; - - /// DIEBlock objects that need to be destructed (but not freed!). - std::vector<DIEBlock *> DIEBlocks; - - /// Allocator used for all the DIEValue objects. - BumpPtrAllocator DIEAlloc; - /// @} - - DwarfEmitter *TheDwarfEmitter; - std::vector<LinkContext> ObjectContexts; - - unsigned MaxDwarfVersion = 0; - unsigned MinDwarfVersion = std::numeric_limits<unsigned>::max(); - - bool AtLeastOneAppleAccelTable = false; - bool AtLeastOneDwarfAccelTable = false; - - /// The CIEs that have been emitted in the output section. The actual CIE - /// data serves a the key to this StringMap, this takes care of comparing the - /// semantics of CIEs defined in different object files. - StringMap<uint32_t> EmittedCIEs; - - /// Offset of the last CIE that has been emitted in the output - /// debug_frame section. - uint32_t LastCIEOffset = 0; - - /// Apple accelerator tables. - AccelTable<DWARF5AccelTableStaticData> DebugNames; - AccelTable<AppleAccelTableStaticOffsetData> AppleNames; - AccelTable<AppleAccelTableStaticOffsetData> AppleNamespaces; - AccelTable<AppleAccelTableStaticOffsetData> AppleObjc; - AccelTable<AppleAccelTableStaticTypeData> AppleTypes; - - /// Mapping the PCM filename to the DwoId. - StringMap<uint64_t> ClangModules; - - DwarfLinkerClient DwarfLinkerClientID; - - std::function<StringRef(StringRef)> StringsTranslator = nullptr; - - /// linking options - struct DWARFLinkerOptions { - /// Generate processing log to the standard output. - bool Verbose = false; - - /// Print statistics. - bool Statistics = false; - - /// Skip emitting output - bool NoOutput = false; - - /// Do not unique types according to ODR - bool NoODR = false; - - /// Update - bool Update = false; - - /// Number of threads. - unsigned Threads = 1; - - /// The accelerator table kind - AccelTableKind TheAccelTableKind = AccelTableKind::Default; - - /// Prepend path for the clang modules. - std::string PrependPath; - - // warning handler - messageHandler WarningHandler = nullptr; - - // error handler - messageHandler ErrorHandler = nullptr; - - objFileLoader ObjFileLoader = nullptr; - - /// A list of all .swiftinterface files referenced by the debug - /// info, mapping Module name to path on disk. The entries need to - /// be uniqued and sorted and there are only few entries expected - /// per compile unit, which is why this is a std::map. - /// this is dsymutil specific fag. - swiftInterfacesMap *ParseableSwiftInterfaces = nullptr; - - /// A list of remappings to apply to file paths. - objectPrefixMap *ObjectPrefixMap = nullptr; - } Options; -}; - -} // end namespace llvm - -#endif // LLVM_DWARFLINKER_DWARFLINKER_H - -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif + DWARFContext &, unsigned AddressSize); + + /// FoldingSet that uniques the abbreviations. + FoldingSet<DIEAbbrev> AbbreviationsSet; + + /// Storage for the unique Abbreviations. + /// This is passed to AsmPrinter::emitDwarfAbbrevs(), thus it cannot be + /// changed to a vector of unique_ptrs. + std::vector<std::unique_ptr<DIEAbbrev>> Abbreviations; + + /// DIELoc objects that need to be destructed (but not freed!). + std::vector<DIELoc *> DIELocs; + + /// DIEBlock objects that need to be destructed (but not freed!). + std::vector<DIEBlock *> DIEBlocks; + + /// Allocator used for all the DIEValue objects. + BumpPtrAllocator DIEAlloc; + /// @} + + DwarfEmitter *TheDwarfEmitter; + std::vector<LinkContext> ObjectContexts; + + unsigned MaxDwarfVersion = 0; + unsigned MinDwarfVersion = std::numeric_limits<unsigned>::max(); + + bool AtLeastOneAppleAccelTable = false; + bool AtLeastOneDwarfAccelTable = false; + + /// The CIEs that have been emitted in the output section. The actual CIE + /// data serves a the key to this StringMap, this takes care of comparing the + /// semantics of CIEs defined in different object files. + StringMap<uint32_t> EmittedCIEs; + + /// Offset of the last CIE that has been emitted in the output + /// debug_frame section. + uint32_t LastCIEOffset = 0; + + /// Apple accelerator tables. + AccelTable<DWARF5AccelTableStaticData> DebugNames; + AccelTable<AppleAccelTableStaticOffsetData> AppleNames; + AccelTable<AppleAccelTableStaticOffsetData> AppleNamespaces; + AccelTable<AppleAccelTableStaticOffsetData> AppleObjc; + AccelTable<AppleAccelTableStaticTypeData> AppleTypes; + + /// Mapping the PCM filename to the DwoId. + StringMap<uint64_t> ClangModules; + + DwarfLinkerClient DwarfLinkerClientID; + + std::function<StringRef(StringRef)> StringsTranslator = nullptr; + + /// linking options + struct DWARFLinkerOptions { + /// Generate processing log to the standard output. + bool Verbose = false; + + /// Print statistics. + bool Statistics = false; + + /// Skip emitting output + bool NoOutput = false; + + /// Do not unique types according to ODR + bool NoODR = false; + + /// Update + bool Update = false; + + /// Number of threads. + unsigned Threads = 1; + + /// The accelerator table kind + AccelTableKind TheAccelTableKind = AccelTableKind::Default; + + /// Prepend path for the clang modules. + std::string PrependPath; + + // warning handler + messageHandler WarningHandler = nullptr; + + // error handler + messageHandler ErrorHandler = nullptr; + + objFileLoader ObjFileLoader = nullptr; + + /// A list of all .swiftinterface files referenced by the debug + /// info, mapping Module name to path on disk. The entries need to + /// be uniqued and sorted and there are only few entries expected + /// per compile unit, which is why this is a std::map. + /// this is dsymutil specific fag. + swiftInterfacesMap *ParseableSwiftInterfaces = nullptr; + + /// A list of remappings to apply to file paths. + objectPrefixMap *ObjectPrefixMap = nullptr; + } Options; +}; + +} // end namespace llvm + +#endif // LLVM_DWARFLINKER_DWARFLINKER_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFLinkerCompileUnit.h b/contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFLinkerCompileUnit.h index 50a30ea6d6..3e168e217f 100644 --- a/contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFLinkerCompileUnit.h +++ b/contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFLinkerCompileUnit.h @@ -1,327 +1,327 @@ -#pragma once - -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-parameter" -#endif - -//===- DWARFLinkerCompileUnit.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_DWARFLINKER_DWARFLINKERCOMPILEUNIT_H -#define LLVM_DWARFLINKER_DWARFLINKERCOMPILEUNIT_H - -#include "llvm/ADT/IntervalMap.h" -#include "llvm/CodeGen/DIE.h" -#include "llvm/DebugInfo/DWARF/DWARFUnit.h" -#include "llvm/Support/DataExtractor.h" - -namespace llvm { - -class DeclContext; - -template <typename KeyT, typename ValT> -using HalfOpenIntervalMap = - IntervalMap<KeyT, ValT, IntervalMapImpl::NodeSizer<KeyT, ValT>::LeafSize, - IntervalMapHalfOpenInfo<KeyT>>; - -using FunctionIntervals = HalfOpenIntervalMap<uint64_t, int64_t>; - -// FIXME: Delete this structure. -struct PatchLocation { - DIE::value_iterator I; - - PatchLocation() = default; - PatchLocation(DIE::value_iterator I) : I(I) {} - - void set(uint64_t New) const { - assert(I); - const auto &Old = *I; - assert(Old.getType() == DIEValue::isInteger); - *I = DIEValue(Old.getAttribute(), Old.getForm(), DIEInteger(New)); - } - - uint64_t get() const { - assert(I); - return I->getDIEInteger().getValue(); - } -}; - -/// Stores all information relating to a compile unit, be it in its original -/// instance in the object file to its brand new cloned and generated DIE tree. -class CompileUnit { -public: - /// Information gathered about a DIE in the object file. - struct DIEInfo { - /// Address offset to apply to the described entity. - int64_t AddrAdjust; - - /// ODR Declaration context. - DeclContext *Ctxt; - - /// Cloned version of that DIE. - DIE *Clone; - - /// The index of this DIE's parent. - uint32_t ParentIdx; - - /// Is the DIE part of the linked output? - bool Keep : 1; - - /// Was this DIE's entity found in the map? - bool InDebugMap : 1; - - /// Is this a pure forward declaration we can strip? - bool Prune : 1; - - /// Does DIE transitively refer an incomplete decl? - bool Incomplete : 1; - }; - - CompileUnit(DWARFUnit &OrigUnit, unsigned ID, bool CanUseODR, - StringRef ClangModuleName) - : OrigUnit(OrigUnit), ID(ID), Ranges(RangeAlloc), - ClangModuleName(ClangModuleName) { - Info.resize(OrigUnit.getNumDIEs()); - - auto CUDie = OrigUnit.getUnitDIE(false); - if (!CUDie) { - HasODR = false; - return; - } - if (auto Lang = dwarf::toUnsigned(CUDie.find(dwarf::DW_AT_language))) - HasODR = CanUseODR && (*Lang == dwarf::DW_LANG_C_plus_plus || - *Lang == dwarf::DW_LANG_C_plus_plus_03 || - *Lang == dwarf::DW_LANG_C_plus_plus_11 || - *Lang == dwarf::DW_LANG_C_plus_plus_14 || - *Lang == dwarf::DW_LANG_ObjC_plus_plus); - else - HasODR = false; - } - - DWARFUnit &getOrigUnit() const { return OrigUnit; } - - unsigned getUniqueID() const { return ID; } - +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===- DWARFLinkerCompileUnit.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_DWARFLINKER_DWARFLINKERCOMPILEUNIT_H +#define LLVM_DWARFLINKER_DWARFLINKERCOMPILEUNIT_H + +#include "llvm/ADT/IntervalMap.h" +#include "llvm/CodeGen/DIE.h" +#include "llvm/DebugInfo/DWARF/DWARFUnit.h" +#include "llvm/Support/DataExtractor.h" + +namespace llvm { + +class DeclContext; + +template <typename KeyT, typename ValT> +using HalfOpenIntervalMap = + IntervalMap<KeyT, ValT, IntervalMapImpl::NodeSizer<KeyT, ValT>::LeafSize, + IntervalMapHalfOpenInfo<KeyT>>; + +using FunctionIntervals = HalfOpenIntervalMap<uint64_t, int64_t>; + +// FIXME: Delete this structure. +struct PatchLocation { + DIE::value_iterator I; + + PatchLocation() = default; + PatchLocation(DIE::value_iterator I) : I(I) {} + + void set(uint64_t New) const { + assert(I); + const auto &Old = *I; + assert(Old.getType() == DIEValue::isInteger); + *I = DIEValue(Old.getAttribute(), Old.getForm(), DIEInteger(New)); + } + + uint64_t get() const { + assert(I); + return I->getDIEInteger().getValue(); + } +}; + +/// Stores all information relating to a compile unit, be it in its original +/// instance in the object file to its brand new cloned and generated DIE tree. +class CompileUnit { +public: + /// Information gathered about a DIE in the object file. + struct DIEInfo { + /// Address offset to apply to the described entity. + int64_t AddrAdjust; + + /// ODR Declaration context. + DeclContext *Ctxt; + + /// Cloned version of that DIE. + DIE *Clone; + + /// The index of this DIE's parent. + uint32_t ParentIdx; + + /// Is the DIE part of the linked output? + bool Keep : 1; + + /// Was this DIE's entity found in the map? + bool InDebugMap : 1; + + /// Is this a pure forward declaration we can strip? + bool Prune : 1; + + /// Does DIE transitively refer an incomplete decl? + bool Incomplete : 1; + }; + + CompileUnit(DWARFUnit &OrigUnit, unsigned ID, bool CanUseODR, + StringRef ClangModuleName) + : OrigUnit(OrigUnit), ID(ID), Ranges(RangeAlloc), + ClangModuleName(ClangModuleName) { + Info.resize(OrigUnit.getNumDIEs()); + + auto CUDie = OrigUnit.getUnitDIE(false); + if (!CUDie) { + HasODR = false; + return; + } + if (auto Lang = dwarf::toUnsigned(CUDie.find(dwarf::DW_AT_language))) + HasODR = CanUseODR && (*Lang == dwarf::DW_LANG_C_plus_plus || + *Lang == dwarf::DW_LANG_C_plus_plus_03 || + *Lang == dwarf::DW_LANG_C_plus_plus_11 || + *Lang == dwarf::DW_LANG_C_plus_plus_14 || + *Lang == dwarf::DW_LANG_ObjC_plus_plus); + else + HasODR = false; + } + + DWARFUnit &getOrigUnit() const { return OrigUnit; } + + unsigned getUniqueID() const { return ID; } + void createOutputDIE() { NewUnit.emplace(OrigUnit.getUnitDIE().getTag()); } - - DIE *getOutputUnitDIE() const { - if (NewUnit) - return &const_cast<BasicDIEUnit &>(*NewUnit).getUnitDie(); - return nullptr; - } - - bool hasODR() const { return HasODR; } - bool isClangModule() const { return !ClangModuleName.empty(); } - uint16_t getLanguage(); - /// Return the DW_AT_LLVM_sysroot of the compile unit or an empty StringRef. - StringRef getSysRoot(); - - const std::string &getClangModuleName() const { return ClangModuleName; } - - DIEInfo &getInfo(unsigned Idx) { return Info[Idx]; } - const DIEInfo &getInfo(unsigned Idx) const { return Info[Idx]; } - + + DIE *getOutputUnitDIE() const { + if (NewUnit) + return &const_cast<BasicDIEUnit &>(*NewUnit).getUnitDie(); + return nullptr; + } + + bool hasODR() const { return HasODR; } + bool isClangModule() const { return !ClangModuleName.empty(); } + uint16_t getLanguage(); + /// Return the DW_AT_LLVM_sysroot of the compile unit or an empty StringRef. + StringRef getSysRoot(); + + const std::string &getClangModuleName() const { return ClangModuleName; } + + DIEInfo &getInfo(unsigned Idx) { return Info[Idx]; } + const DIEInfo &getInfo(unsigned Idx) const { return Info[Idx]; } + DIEInfo &getInfo(const DWARFDie &Die) { unsigned Idx = getOrigUnit().getDIEIndex(Die); return Info[Idx]; } - uint64_t getStartOffset() const { return StartOffset; } - uint64_t getNextUnitOffset() const { return NextUnitOffset; } - void setStartOffset(uint64_t DebugInfoSize) { StartOffset = DebugInfoSize; } - - uint64_t getLowPc() const { return LowPc; } - uint64_t getHighPc() const { return HighPc; } - bool hasLabelAt(uint64_t Addr) const { return Labels.count(Addr); } - - Optional<PatchLocation> getUnitRangesAttribute() const { - return UnitRangeAttribute; - } - - const FunctionIntervals &getFunctionRanges() const { return Ranges; } - - const std::vector<PatchLocation> &getRangesAttributes() const { - return RangeAttributes; - } - - const std::vector<std::pair<PatchLocation, int64_t>> & - getLocationAttributes() const { - return LocationAttributes; - } - - void setHasInterestingContent() { HasInterestingContent = true; } - bool hasInterestingContent() { return HasInterestingContent; } - - /// Mark every DIE in this unit as kept. This function also - /// marks variables as InDebugMap so that they appear in the - /// reconstructed accelerator tables. - void markEverythingAsKept(); - - /// Compute the end offset for this unit. Must be called after the CU's DIEs - /// have been cloned. \returns the next unit offset (which is also the - /// current debug_info section size). + uint64_t getStartOffset() const { return StartOffset; } + uint64_t getNextUnitOffset() const { return NextUnitOffset; } + void setStartOffset(uint64_t DebugInfoSize) { StartOffset = DebugInfoSize; } + + uint64_t getLowPc() const { return LowPc; } + uint64_t getHighPc() const { return HighPc; } + bool hasLabelAt(uint64_t Addr) const { return Labels.count(Addr); } + + Optional<PatchLocation> getUnitRangesAttribute() const { + return UnitRangeAttribute; + } + + const FunctionIntervals &getFunctionRanges() const { return Ranges; } + + const std::vector<PatchLocation> &getRangesAttributes() const { + return RangeAttributes; + } + + const std::vector<std::pair<PatchLocation, int64_t>> & + getLocationAttributes() const { + return LocationAttributes; + } + + void setHasInterestingContent() { HasInterestingContent = true; } + bool hasInterestingContent() { return HasInterestingContent; } + + /// Mark every DIE in this unit as kept. This function also + /// marks variables as InDebugMap so that they appear in the + /// reconstructed accelerator tables. + void markEverythingAsKept(); + + /// Compute the end offset for this unit. Must be called after the CU's DIEs + /// have been cloned. \returns the next unit offset (which is also the + /// current debug_info section size). uint64_t computeNextUnitOffset(uint16_t DwarfVersion); - - /// Keep track of a forward reference to DIE \p Die in \p RefUnit by \p - /// Attr. The attribute should be fixed up later to point to the absolute - /// offset of \p Die in the debug_info section or to the canonical offset of - /// \p Ctxt if it is non-null. - void noteForwardReference(DIE *Die, const CompileUnit *RefUnit, - DeclContext *Ctxt, PatchLocation Attr); - - /// Apply all fixups recorded by noteForwardReference(). - void fixupForwardReferences(); - - /// Add the low_pc of a label that is relocated by applying - /// offset \p PCOffset. - void addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset); - - /// Add a function range [\p LowPC, \p HighPC) that is relocated by applying - /// offset \p PCOffset. - void addFunctionRange(uint64_t LowPC, uint64_t HighPC, int64_t PCOffset); - - /// Keep track of a DW_AT_range attribute that we will need to patch up later. - void noteRangeAttribute(const DIE &Die, PatchLocation Attr); - - /// Keep track of a location attribute pointing to a location list in the - /// debug_loc section. - void noteLocationAttribute(PatchLocation Attr, int64_t PcOffset); - - /// Add a name accelerator entry for \a Die with \a Name. - void addNamespaceAccelerator(const DIE *Die, DwarfStringPoolEntryRef Name); - - /// Add a name accelerator entry for \a Die with \a Name. - void addNameAccelerator(const DIE *Die, DwarfStringPoolEntryRef Name, - bool SkipPubnamesSection = false); - - /// Add various accelerator entries for \p Die with \p Name which is stored - /// in the string table at \p Offset. \p Name must be an Objective-C - /// selector. - void addObjCAccelerator(const DIE *Die, DwarfStringPoolEntryRef Name, - bool SkipPubnamesSection = false); - - /// Add a type accelerator entry for \p Die with \p Name which is stored in - /// the string table at \p Offset. - void addTypeAccelerator(const DIE *Die, DwarfStringPoolEntryRef Name, - bool ObjcClassImplementation, - uint32_t QualifiedNameHash); - - struct AccelInfo { - /// Name of the entry. - DwarfStringPoolEntryRef Name; - - /// DIE this entry describes. - const DIE *Die; - - /// Hash of the fully qualified name. - uint32_t QualifiedNameHash; - - /// Emit this entry only in the apple_* sections. - bool SkipPubSection; - - /// Is this an ObjC class implementation? - bool ObjcClassImplementation; - - AccelInfo(DwarfStringPoolEntryRef Name, const DIE *Die, - bool SkipPubSection = false) - : Name(Name), Die(Die), SkipPubSection(SkipPubSection) {} - - AccelInfo(DwarfStringPoolEntryRef Name, const DIE *Die, - uint32_t QualifiedNameHash, bool ObjCClassIsImplementation) - : Name(Name), Die(Die), QualifiedNameHash(QualifiedNameHash), - SkipPubSection(false), - ObjcClassImplementation(ObjCClassIsImplementation) {} - }; - - const std::vector<AccelInfo> &getPubnames() const { return Pubnames; } - const std::vector<AccelInfo> &getPubtypes() const { return Pubtypes; } - const std::vector<AccelInfo> &getNamespaces() const { return Namespaces; } - const std::vector<AccelInfo> &getObjC() const { return ObjC; } - - MCSymbol *getLabelBegin() { return LabelBegin; } - void setLabelBegin(MCSymbol *S) { LabelBegin = S; } - -private: - DWARFUnit &OrigUnit; - unsigned ID; - std::vector<DIEInfo> Info; ///< DIE info indexed by DIE index. - Optional<BasicDIEUnit> NewUnit; - MCSymbol *LabelBegin = nullptr; - - uint64_t StartOffset; - uint64_t NextUnitOffset; - - uint64_t LowPc = std::numeric_limits<uint64_t>::max(); - uint64_t HighPc = 0; - - /// A list of attributes to fixup with the absolute offset of - /// a DIE in the debug_info section. - /// - /// The offsets for the attributes in this array couldn't be set while - /// cloning because for cross-cu forward references the target DIE's offset - /// isn't known you emit the reference attribute. - std::vector< - std::tuple<DIE *, const CompileUnit *, DeclContext *, PatchLocation>> - ForwardDIEReferences; - - FunctionIntervals::Allocator RangeAlloc; - - /// The ranges in that interval map are the PC ranges for - /// functions in this unit, associated with the PC offset to apply - /// to the addresses to get the linked address. - FunctionIntervals Ranges; - - /// The DW_AT_low_pc of each DW_TAG_label. - SmallDenseMap<uint64_t, uint64_t, 1> Labels; - - /// DW_AT_ranges attributes to patch after we have gathered - /// all the unit's function addresses. - /// @{ - std::vector<PatchLocation> RangeAttributes; - Optional<PatchLocation> UnitRangeAttribute; - /// @} - - /// Location attributes that need to be transferred from the - /// original debug_loc section to the liked one. They are stored - /// along with the PC offset that is to be applied to their - /// function's address. - std::vector<std::pair<PatchLocation, int64_t>> LocationAttributes; - - /// Accelerator entries for the unit, both for the pub* - /// sections and the apple* ones. - /// @{ - std::vector<AccelInfo> Pubnames; - std::vector<AccelInfo> Pubtypes; - std::vector<AccelInfo> Namespaces; - std::vector<AccelInfo> ObjC; - /// @} - - /// Is this unit subject to the ODR rule? - bool HasODR; - - /// Did a DIE actually contain a valid reloc? - bool HasInterestingContent; - - /// The DW_AT_language of this unit. - uint16_t Language = 0; - - /// The DW_AT_LLVM_sysroot of this unit. - std::string SysRoot; - - /// If this is a Clang module, this holds the module's name. - std::string ClangModuleName; -}; - -} // end namespace llvm - -#endif // LLVM_DWARFLINKER_DWARFLINKERCOMPILEUNIT_H - -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif + + /// Keep track of a forward reference to DIE \p Die in \p RefUnit by \p + /// Attr. The attribute should be fixed up later to point to the absolute + /// offset of \p Die in the debug_info section or to the canonical offset of + /// \p Ctxt if it is non-null. + void noteForwardReference(DIE *Die, const CompileUnit *RefUnit, + DeclContext *Ctxt, PatchLocation Attr); + + /// Apply all fixups recorded by noteForwardReference(). + void fixupForwardReferences(); + + /// Add the low_pc of a label that is relocated by applying + /// offset \p PCOffset. + void addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset); + + /// Add a function range [\p LowPC, \p HighPC) that is relocated by applying + /// offset \p PCOffset. + void addFunctionRange(uint64_t LowPC, uint64_t HighPC, int64_t PCOffset); + + /// Keep track of a DW_AT_range attribute that we will need to patch up later. + void noteRangeAttribute(const DIE &Die, PatchLocation Attr); + + /// Keep track of a location attribute pointing to a location list in the + /// debug_loc section. + void noteLocationAttribute(PatchLocation Attr, int64_t PcOffset); + + /// Add a name accelerator entry for \a Die with \a Name. + void addNamespaceAccelerator(const DIE *Die, DwarfStringPoolEntryRef Name); + + /// Add a name accelerator entry for \a Die with \a Name. + void addNameAccelerator(const DIE *Die, DwarfStringPoolEntryRef Name, + bool SkipPubnamesSection = false); + + /// Add various accelerator entries for \p Die with \p Name which is stored + /// in the string table at \p Offset. \p Name must be an Objective-C + /// selector. + void addObjCAccelerator(const DIE *Die, DwarfStringPoolEntryRef Name, + bool SkipPubnamesSection = false); + + /// Add a type accelerator entry for \p Die with \p Name which is stored in + /// the string table at \p Offset. + void addTypeAccelerator(const DIE *Die, DwarfStringPoolEntryRef Name, + bool ObjcClassImplementation, + uint32_t QualifiedNameHash); + + struct AccelInfo { + /// Name of the entry. + DwarfStringPoolEntryRef Name; + + /// DIE this entry describes. + const DIE *Die; + + /// Hash of the fully qualified name. + uint32_t QualifiedNameHash; + + /// Emit this entry only in the apple_* sections. + bool SkipPubSection; + + /// Is this an ObjC class implementation? + bool ObjcClassImplementation; + + AccelInfo(DwarfStringPoolEntryRef Name, const DIE *Die, + bool SkipPubSection = false) + : Name(Name), Die(Die), SkipPubSection(SkipPubSection) {} + + AccelInfo(DwarfStringPoolEntryRef Name, const DIE *Die, + uint32_t QualifiedNameHash, bool ObjCClassIsImplementation) + : Name(Name), Die(Die), QualifiedNameHash(QualifiedNameHash), + SkipPubSection(false), + ObjcClassImplementation(ObjCClassIsImplementation) {} + }; + + const std::vector<AccelInfo> &getPubnames() const { return Pubnames; } + const std::vector<AccelInfo> &getPubtypes() const { return Pubtypes; } + const std::vector<AccelInfo> &getNamespaces() const { return Namespaces; } + const std::vector<AccelInfo> &getObjC() const { return ObjC; } + + MCSymbol *getLabelBegin() { return LabelBegin; } + void setLabelBegin(MCSymbol *S) { LabelBegin = S; } + +private: + DWARFUnit &OrigUnit; + unsigned ID; + std::vector<DIEInfo> Info; ///< DIE info indexed by DIE index. + Optional<BasicDIEUnit> NewUnit; + MCSymbol *LabelBegin = nullptr; + + uint64_t StartOffset; + uint64_t NextUnitOffset; + + uint64_t LowPc = std::numeric_limits<uint64_t>::max(); + uint64_t HighPc = 0; + + /// A list of attributes to fixup with the absolute offset of + /// a DIE in the debug_info section. + /// + /// The offsets for the attributes in this array couldn't be set while + /// cloning because for cross-cu forward references the target DIE's offset + /// isn't known you emit the reference attribute. + std::vector< + std::tuple<DIE *, const CompileUnit *, DeclContext *, PatchLocation>> + ForwardDIEReferences; + + FunctionIntervals::Allocator RangeAlloc; + + /// The ranges in that interval map are the PC ranges for + /// functions in this unit, associated with the PC offset to apply + /// to the addresses to get the linked address. + FunctionIntervals Ranges; + + /// The DW_AT_low_pc of each DW_TAG_label. + SmallDenseMap<uint64_t, uint64_t, 1> Labels; + + /// DW_AT_ranges attributes to patch after we have gathered + /// all the unit's function addresses. + /// @{ + std::vector<PatchLocation> RangeAttributes; + Optional<PatchLocation> UnitRangeAttribute; + /// @} + + /// Location attributes that need to be transferred from the + /// original debug_loc section to the liked one. They are stored + /// along with the PC offset that is to be applied to their + /// function's address. + std::vector<std::pair<PatchLocation, int64_t>> LocationAttributes; + + /// Accelerator entries for the unit, both for the pub* + /// sections and the apple* ones. + /// @{ + std::vector<AccelInfo> Pubnames; + std::vector<AccelInfo> Pubtypes; + std::vector<AccelInfo> Namespaces; + std::vector<AccelInfo> ObjC; + /// @} + + /// Is this unit subject to the ODR rule? + bool HasODR; + + /// Did a DIE actually contain a valid reloc? + bool HasInterestingContent; + + /// The DW_AT_language of this unit. + uint16_t Language = 0; + + /// The DW_AT_LLVM_sysroot of this unit. + std::string SysRoot; + + /// If this is a Clang module, this holds the module's name. + std::string ClangModuleName; +}; + +} // end namespace llvm + +#endif // LLVM_DWARFLINKER_DWARFLINKERCOMPILEUNIT_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFLinkerDeclContext.h b/contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFLinkerDeclContext.h index a1a279a435..454d1fa7a9 100644 --- a/contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFLinkerDeclContext.h +++ b/contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFLinkerDeclContext.h @@ -1,194 +1,194 @@ -#pragma once - -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-parameter" -#endif - -//===- DWARFLinkerDeclContext.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_DWARFLINKER_DWARFLINKERDECLCONTEXT_H -#define LLVM_DWARFLINKER_DWARFLINKERDECLCONTEXT_H - -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/DenseMapInfo.h" -#include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/CodeGen/NonRelocatableStringpool.h" -#include "llvm/DWARFLinker/DWARFLinkerCompileUnit.h" +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===- DWARFLinkerDeclContext.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_DWARFLINKER_DWARFLINKERDECLCONTEXT_H +#define LLVM_DWARFLINKER_DWARFLINKERDECLCONTEXT_H + +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseMapInfo.h" +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/CodeGen/NonRelocatableStringpool.h" +#include "llvm/DWARFLinker/DWARFLinkerCompileUnit.h" #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h" -#include "llvm/DebugInfo/DWARF/DWARFDie.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/Path.h" - -namespace llvm { - -struct DeclMapInfo; - -/// Small helper that resolves and caches file paths. This helps reduce the -/// number of calls to realpath which is expensive. We assume the input are -/// files, and cache the realpath of their parent. This way we can quickly -/// resolve different files under the same path. -class CachedPathResolver { -public: - /// Resolve a path by calling realpath and cache its result. The returned - /// StringRef is interned in the given \p StringPool. +#include "llvm/DebugInfo/DWARF/DWARFDie.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" + +namespace llvm { + +struct DeclMapInfo; + +/// Small helper that resolves and caches file paths. This helps reduce the +/// number of calls to realpath which is expensive. We assume the input are +/// files, and cache the realpath of their parent. This way we can quickly +/// resolve different files under the same path. +class CachedPathResolver { +public: + /// Resolve a path by calling realpath and cache its result. The returned + /// StringRef is interned in the given \p StringPool. StringRef resolve(const std::string &Path, NonRelocatableStringpool &StringPool) { - StringRef FileName = sys::path::filename(Path); + StringRef FileName = sys::path::filename(Path); StringRef ParentPath = sys::path::parent_path(Path); - - // If the ParentPath has not yet been resolved, resolve and cache it for - // future look-ups. - if (!ResolvedPaths.count(ParentPath)) { - SmallString<256> RealPath; - sys::fs::real_path(ParentPath, RealPath); + + // If the ParentPath has not yet been resolved, resolve and cache it for + // future look-ups. + if (!ResolvedPaths.count(ParentPath)) { + SmallString<256> RealPath; + sys::fs::real_path(ParentPath, RealPath); ResolvedPaths.insert( {ParentPath, std::string(RealPath.c_str(), RealPath.size())}); - } - - // Join the file name again with the resolved path. - SmallString<256> ResolvedPath(ResolvedPaths[ParentPath]); - sys::path::append(ResolvedPath, FileName); - return StringPool.internString(ResolvedPath); - } - -private: - StringMap<std::string> ResolvedPaths; -}; - -/// A DeclContext is a named program scope that is used for ODR uniquing of -/// types. -/// -/// The set of DeclContext for the ODR-subject parts of a Dwarf link is -/// expanded (and uniqued) with each new object file processed. We need to -/// determine the context of each DIE in an linked object file to see if the -/// corresponding type has already been emitted. -/// -/// The contexts are conceptually organized as a tree (eg. a function scope is -/// contained in a namespace scope that contains other scopes), but -/// storing/accessing them in an actual tree is too inefficient: we need to be -/// able to very quickly query a context for a given child context by name. -/// Storing a StringMap in each DeclContext would be too space inefficient. -/// -/// The solution here is to give each DeclContext a link to its parent (this -/// allows to walk up the tree), but to query the existence of a specific -/// DeclContext using a separate DenseMap keyed on the hash of the fully -/// qualified name of the context. -class DeclContext { -public: - using Map = DenseSet<DeclContext *, DeclMapInfo>; - - DeclContext() : DefinedInClangModule(0), Parent(*this) {} - - DeclContext(unsigned Hash, uint32_t Line, uint32_t ByteSize, uint16_t Tag, - StringRef Name, StringRef File, const DeclContext &Parent, - DWARFDie LastSeenDIE = DWARFDie(), unsigned CUId = 0) - : QualifiedNameHash(Hash), Line(Line), ByteSize(ByteSize), Tag(Tag), - DefinedInClangModule(0), Name(Name), File(File), Parent(Parent), - LastSeenDIE(LastSeenDIE), LastSeenCompileUnitID(CUId) {} - - uint32_t getQualifiedNameHash() const { return QualifiedNameHash; } - - bool setLastSeenDIE(CompileUnit &U, const DWARFDie &Die); - - uint32_t getCanonicalDIEOffset() const { return CanonicalDIEOffset; } - void setCanonicalDIEOffset(uint32_t Offset) { CanonicalDIEOffset = Offset; } - - bool isDefinedInClangModule() const { return DefinedInClangModule; } - void setDefinedInClangModule(bool Val) { DefinedInClangModule = Val; } - - uint16_t getTag() const { return Tag; } - -private: - friend DeclMapInfo; - - unsigned QualifiedNameHash = 0; - uint32_t Line = 0; - uint32_t ByteSize = 0; - uint16_t Tag = dwarf::DW_TAG_compile_unit; - unsigned DefinedInClangModule : 1; - StringRef Name; - StringRef File; - const DeclContext &Parent; - DWARFDie LastSeenDIE; - uint32_t LastSeenCompileUnitID = 0; - uint32_t CanonicalDIEOffset = 0; -}; - -/// This class gives a tree-like API to the DenseMap that stores the -/// DeclContext objects. It holds the BumpPtrAllocator where these objects will -/// be allocated. -class DeclContextTree { -public: - /// Get the child of \a Context described by \a DIE in \a Unit. The - /// required strings will be interned in \a StringPool. - /// \returns The child DeclContext along with one bit that is set if - /// this context is invalid. - /// - /// An invalid context means it shouldn't be considered for uniquing, but its - /// not returning null, because some children of that context might be - /// uniquing candidates. - /// - /// FIXME: The invalid bit along the return value is to emulate some - /// dsymutil-classic functionality. + } + + // Join the file name again with the resolved path. + SmallString<256> ResolvedPath(ResolvedPaths[ParentPath]); + sys::path::append(ResolvedPath, FileName); + return StringPool.internString(ResolvedPath); + } + +private: + StringMap<std::string> ResolvedPaths; +}; + +/// A DeclContext is a named program scope that is used for ODR uniquing of +/// types. +/// +/// The set of DeclContext for the ODR-subject parts of a Dwarf link is +/// expanded (and uniqued) with each new object file processed. We need to +/// determine the context of each DIE in an linked object file to see if the +/// corresponding type has already been emitted. +/// +/// The contexts are conceptually organized as a tree (eg. a function scope is +/// contained in a namespace scope that contains other scopes), but +/// storing/accessing them in an actual tree is too inefficient: we need to be +/// able to very quickly query a context for a given child context by name. +/// Storing a StringMap in each DeclContext would be too space inefficient. +/// +/// The solution here is to give each DeclContext a link to its parent (this +/// allows to walk up the tree), but to query the existence of a specific +/// DeclContext using a separate DenseMap keyed on the hash of the fully +/// qualified name of the context. +class DeclContext { +public: + using Map = DenseSet<DeclContext *, DeclMapInfo>; + + DeclContext() : DefinedInClangModule(0), Parent(*this) {} + + DeclContext(unsigned Hash, uint32_t Line, uint32_t ByteSize, uint16_t Tag, + StringRef Name, StringRef File, const DeclContext &Parent, + DWARFDie LastSeenDIE = DWARFDie(), unsigned CUId = 0) + : QualifiedNameHash(Hash), Line(Line), ByteSize(ByteSize), Tag(Tag), + DefinedInClangModule(0), Name(Name), File(File), Parent(Parent), + LastSeenDIE(LastSeenDIE), LastSeenCompileUnitID(CUId) {} + + uint32_t getQualifiedNameHash() const { return QualifiedNameHash; } + + bool setLastSeenDIE(CompileUnit &U, const DWARFDie &Die); + + uint32_t getCanonicalDIEOffset() const { return CanonicalDIEOffset; } + void setCanonicalDIEOffset(uint32_t Offset) { CanonicalDIEOffset = Offset; } + + bool isDefinedInClangModule() const { return DefinedInClangModule; } + void setDefinedInClangModule(bool Val) { DefinedInClangModule = Val; } + + uint16_t getTag() const { return Tag; } + +private: + friend DeclMapInfo; + + unsigned QualifiedNameHash = 0; + uint32_t Line = 0; + uint32_t ByteSize = 0; + uint16_t Tag = dwarf::DW_TAG_compile_unit; + unsigned DefinedInClangModule : 1; + StringRef Name; + StringRef File; + const DeclContext &Parent; + DWARFDie LastSeenDIE; + uint32_t LastSeenCompileUnitID = 0; + uint32_t CanonicalDIEOffset = 0; +}; + +/// This class gives a tree-like API to the DenseMap that stores the +/// DeclContext objects. It holds the BumpPtrAllocator where these objects will +/// be allocated. +class DeclContextTree { +public: + /// Get the child of \a Context described by \a DIE in \a Unit. The + /// required strings will be interned in \a StringPool. + /// \returns The child DeclContext along with one bit that is set if + /// this context is invalid. + /// + /// An invalid context means it shouldn't be considered for uniquing, but its + /// not returning null, because some children of that context might be + /// uniquing candidates. + /// + /// FIXME: The invalid bit along the return value is to emulate some + /// dsymutil-classic functionality. PointerIntPair<DeclContext *, 1> getChildDeclContext(DeclContext &Context, const DWARFDie &DIE, CompileUnit &Unit, bool InClangModule); - - DeclContext &getRoot() { return Root; } - -private: - BumpPtrAllocator Allocator; - DeclContext Root; - DeclContext::Map Contexts; - + + DeclContext &getRoot() { return Root; } + +private: + BumpPtrAllocator Allocator; + DeclContext Root; + DeclContext::Map Contexts; + /// Cached resolved paths from the line table. /// The key is <UniqueUnitID, FileIdx>. using ResolvedPathsMap = DenseMap<std::pair<unsigned, unsigned>, StringRef>; ResolvedPathsMap ResolvedPaths; /// Helper that resolves and caches fragments of file paths. - CachedPathResolver PathResolver; + CachedPathResolver PathResolver; /// String pool keeping real path bodies. NonRelocatableStringpool StringPool; StringRef getResolvedPath(CompileUnit &CU, unsigned FileNum, const DWARFDebugLine::LineTable &LineTable); -}; - -/// Info type for the DenseMap storing the DeclContext pointers. -struct DeclMapInfo : private DenseMapInfo<DeclContext *> { - using DenseMapInfo<DeclContext *>::getEmptyKey; - using DenseMapInfo<DeclContext *>::getTombstoneKey; - - static unsigned getHashValue(const DeclContext *Ctxt) { - return Ctxt->QualifiedNameHash; - } - - static bool isEqual(const DeclContext *LHS, const DeclContext *RHS) { - if (RHS == getEmptyKey() || RHS == getTombstoneKey()) - return RHS == LHS; - return LHS->QualifiedNameHash == RHS->QualifiedNameHash && - LHS->Line == RHS->Line && LHS->ByteSize == RHS->ByteSize && - LHS->Name.data() == RHS->Name.data() && - LHS->File.data() == RHS->File.data() && - LHS->Parent.QualifiedNameHash == RHS->Parent.QualifiedNameHash; - } -}; - -} // end namespace llvm - -#endif // LLVM_DWARFLINKER_DWARFLINKERDECLCONTEXT_H - -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif +}; + +/// Info type for the DenseMap storing the DeclContext pointers. +struct DeclMapInfo : private DenseMapInfo<DeclContext *> { + using DenseMapInfo<DeclContext *>::getEmptyKey; + using DenseMapInfo<DeclContext *>::getTombstoneKey; + + static unsigned getHashValue(const DeclContext *Ctxt) { + return Ctxt->QualifiedNameHash; + } + + static bool isEqual(const DeclContext *LHS, const DeclContext *RHS) { + if (RHS == getEmptyKey() || RHS == getTombstoneKey()) + return RHS == LHS; + return LHS->QualifiedNameHash == RHS->QualifiedNameHash && + LHS->Line == RHS->Line && LHS->ByteSize == RHS->ByteSize && + LHS->Name.data() == RHS->Name.data() && + LHS->File.data() == RHS->File.data() && + LHS->Parent.QualifiedNameHash == RHS->Parent.QualifiedNameHash; + } +}; + +} // end namespace llvm + +#endif // LLVM_DWARFLINKER_DWARFLINKERDECLCONTEXT_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFStreamer.h b/contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFStreamer.h index 13a50ea8c8..ac5f5d45be 100644 --- a/contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFStreamer.h +++ b/contrib/libs/llvm12/include/llvm/DWARFLinker/DWARFStreamer.h @@ -1,230 +1,230 @@ -#pragma once - -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-parameter" -#endif - -//===- DwarfStreamer.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_DWARFLINKER_DWARFSTREAMER_H -#define LLVM_DWARFLINKER_DWARFSTREAMER_H - -#include "llvm/CodeGen/AccelTable.h" -#include "llvm/CodeGen/AsmPrinter.h" -#include "llvm/DWARFLinker/DWARFLinker.h" -#include "llvm/MC/MCAsmInfo.h" -#include "llvm/MC/MCContext.h" -#include "llvm/MC/MCInstrInfo.h" -#include "llvm/MC/MCObjectFileInfo.h" -#include "llvm/MC/MCRegisterInfo.h" -#include "llvm/Target/TargetMachine.h" - -namespace llvm { - -enum class OutputFileType { - Object, - Assembly, -}; - -/// User of DwarfStreamer should call initialization code -/// for AsmPrinter: -/// -/// InitializeAllTargetInfos(); -/// InitializeAllTargetMCs(); -/// InitializeAllTargets(); -/// InitializeAllAsmPrinters(); - -class MCCodeEmitter; - -/// The Dwarf streaming logic. -/// -/// All interactions with the MC layer that is used to build the debug -/// information binary representation are handled in this class. -class DwarfStreamer : public DwarfEmitter { -public: - DwarfStreamer(OutputFileType OutFileType, raw_pwrite_stream &OutFile, - std::function<StringRef(StringRef Input)> Translator, - bool Minimize, messageHandler Error, messageHandler Warning) - : OutFile(OutFile), OutFileType(OutFileType), Translator(Translator), - Minimize(Minimize), ErrorHandler(Error), WarningHandler(Warning) {} - - bool init(Triple TheTriple); - - /// Dump the file to the disk. - void finish(); - - AsmPrinter &getAsmPrinter() const { return *Asm; } - - /// Set the current output section to debug_info and change - /// the MC Dwarf version to \p DwarfVersion. - void switchToDebugInfoSection(unsigned DwarfVersion); - - /// Emit the compilation unit header for \p Unit in the - /// debug_info section. - /// - /// As a side effect, this also switches the current Dwarf version - /// of the MC layer to the one of U.getOrigUnit(). +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===- DwarfStreamer.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_DWARFLINKER_DWARFSTREAMER_H +#define LLVM_DWARFLINKER_DWARFSTREAMER_H + +#include "llvm/CodeGen/AccelTable.h" +#include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/DWARFLinker/DWARFLinker.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCInstrInfo.h" +#include "llvm/MC/MCObjectFileInfo.h" +#include "llvm/MC/MCRegisterInfo.h" +#include "llvm/Target/TargetMachine.h" + +namespace llvm { + +enum class OutputFileType { + Object, + Assembly, +}; + +/// User of DwarfStreamer should call initialization code +/// for AsmPrinter: +/// +/// InitializeAllTargetInfos(); +/// InitializeAllTargetMCs(); +/// InitializeAllTargets(); +/// InitializeAllAsmPrinters(); + +class MCCodeEmitter; + +/// The Dwarf streaming logic. +/// +/// All interactions with the MC layer that is used to build the debug +/// information binary representation are handled in this class. +class DwarfStreamer : public DwarfEmitter { +public: + DwarfStreamer(OutputFileType OutFileType, raw_pwrite_stream &OutFile, + std::function<StringRef(StringRef Input)> Translator, + bool Minimize, messageHandler Error, messageHandler Warning) + : OutFile(OutFile), OutFileType(OutFileType), Translator(Translator), + Minimize(Minimize), ErrorHandler(Error), WarningHandler(Warning) {} + + bool init(Triple TheTriple); + + /// Dump the file to the disk. + void finish(); + + AsmPrinter &getAsmPrinter() const { return *Asm; } + + /// Set the current output section to debug_info and change + /// the MC Dwarf version to \p DwarfVersion. + void switchToDebugInfoSection(unsigned DwarfVersion); + + /// Emit the compilation unit header for \p Unit in the + /// debug_info section. + /// + /// As a side effect, this also switches the current Dwarf version + /// of the MC layer to the one of U.getOrigUnit(). void emitCompileUnitHeader(CompileUnit &Unit, unsigned DwarfVersion) override; - - /// Recursively emit the DIE tree rooted at \p Die. - void emitDIE(DIE &Die) override; - - /// Emit the abbreviation table \p Abbrevs to the debug_abbrev section. - void emitAbbrevs(const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs, - unsigned DwarfVersion) override; - - /// Emit DIE containing warnings. - void emitPaperTrailWarningsDie(DIE &Die) override; - - /// Emit contents of section SecName From Obj. - void emitSectionContents(StringRef SecData, StringRef SecName) override; - - /// Emit the string table described by \p Pool. - void emitStrings(const NonRelocatableStringpool &Pool) override; - - /// Emit the swift_ast section stored in \p Buffer. - void emitSwiftAST(StringRef Buffer); - - /// Emit debug_ranges for \p FuncRange by translating the - /// original \p Entries. - void emitRangesEntries( - int64_t UnitPcOffset, uint64_t OrigLowPc, - const FunctionIntervals::const_iterator &FuncRange, - const std::vector<DWARFDebugRangeList::RangeListEntry> &Entries, - unsigned AddressSize) override; - - /// Emit debug_aranges entries for \p Unit and if \p DoRangesSection is true, - /// also emit the debug_ranges entries for the DW_TAG_compile_unit's - /// DW_AT_ranges attribute. - void emitUnitRangesEntries(CompileUnit &Unit, bool DoRangesSection) override; - - uint64_t getRangesSectionSize() const override { return RangesSectionSize; } - - /// Emit the debug_loc contribution for \p Unit by copying the entries from - /// \p Dwarf and offsetting them. Update the location attributes to point to - /// the new entries. - void emitLocationsForUnit( - const CompileUnit &Unit, DWARFContext &Dwarf, - std::function<void(StringRef, SmallVectorImpl<uint8_t> &)> ProcessExpr) - override; - - /// Emit the line table described in \p Rows into the debug_line section. - void emitLineTableForUnit(MCDwarfLineTableParams Params, - StringRef PrologueBytes, unsigned MinInstLength, - std::vector<DWARFDebugLine::Row> &Rows, - unsigned AdddressSize) override; - - /// Copy the debug_line over to the updated binary while unobfuscating the - /// file names and directories. - void translateLineTable(DataExtractor LineData, uint64_t Offset) override; - - uint64_t getLineSectionSize() const override { return LineSectionSize; } - - /// Emit the .debug_pubnames contribution for \p Unit. - void emitPubNamesForUnit(const CompileUnit &Unit) override; - - /// Emit the .debug_pubtypes contribution for \p Unit. - void emitPubTypesForUnit(const CompileUnit &Unit) override; - - /// Emit a CIE. - void emitCIE(StringRef CIEBytes) override; - - /// Emit an FDE with data \p Bytes. - void emitFDE(uint32_t CIEOffset, uint32_t AddreSize, uint32_t Address, - StringRef Bytes) override; - - /// Emit DWARF debug names. - void emitDebugNames(AccelTable<DWARF5AccelTableStaticData> &Table) override; - - /// Emit Apple namespaces accelerator table. - void emitAppleNamespaces( - AccelTable<AppleAccelTableStaticOffsetData> &Table) override; - - /// Emit Apple names accelerator table. - void - emitAppleNames(AccelTable<AppleAccelTableStaticOffsetData> &Table) override; - - /// Emit Apple Objective-C accelerator table. - void - emitAppleObjc(AccelTable<AppleAccelTableStaticOffsetData> &Table) override; - - /// Emit Apple type accelerator table. - void - emitAppleTypes(AccelTable<AppleAccelTableStaticTypeData> &Table) override; - - uint64_t getFrameSectionSize() const override { return FrameSectionSize; } - - uint64_t getDebugInfoSectionSize() const override { - return DebugInfoSectionSize; - } - -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); - } - - /// \defgroup MCObjects MC layer objects constructed by the streamer - /// @{ - std::unique_ptr<MCRegisterInfo> MRI; - std::unique_ptr<MCAsmInfo> MAI; - std::unique_ptr<MCObjectFileInfo> MOFI; - std::unique_ptr<MCContext> MC; - MCAsmBackend *MAB; // Owned by MCStreamer - std::unique_ptr<MCInstrInfo> MII; - std::unique_ptr<MCSubtargetInfo> MSTI; - MCInstPrinter *MIP; // Owned by AsmPrinter - MCCodeEmitter *MCE; // Owned by MCStreamer - MCStreamer *MS; // Owned by AsmPrinter - std::unique_ptr<TargetMachine> TM; - std::unique_ptr<AsmPrinter> Asm; - /// @} - - /// The output file we stream the linked Dwarf to. - raw_pwrite_stream &OutFile; - OutputFileType OutFileType = OutputFileType::Object; - std::function<StringRef(StringRef Input)> Translator; - bool Minimize = true; - - uint64_t RangesSectionSize = 0; - uint64_t LocSectionSize = 0; - uint64_t LineSectionSize = 0; - uint64_t FrameSectionSize = 0; - uint64_t DebugInfoSectionSize = 0; - - /// Keep track of emitted CUs and their Unique ID. - struct EmittedUnit { - unsigned ID; - MCSymbol *LabelBegin; - }; - std::vector<EmittedUnit> EmittedUnits; - - /// Emit the pubnames or pubtypes section contribution for \p - /// Unit into \p Sec. The data is provided in \p Names. - void emitPubSectionForUnit(MCSection *Sec, StringRef Name, - const CompileUnit &Unit, - const std::vector<CompileUnit::AccelInfo> &Names); - - messageHandler ErrorHandler = nullptr; - messageHandler WarningHandler = nullptr; -}; - -} // end namespace llvm - -#endif // LLVM_DWARFLINKER_DWARFSTREAMER_H - -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif + + /// Recursively emit the DIE tree rooted at \p Die. + void emitDIE(DIE &Die) override; + + /// Emit the abbreviation table \p Abbrevs to the debug_abbrev section. + void emitAbbrevs(const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs, + unsigned DwarfVersion) override; + + /// Emit DIE containing warnings. + void emitPaperTrailWarningsDie(DIE &Die) override; + + /// Emit contents of section SecName From Obj. + void emitSectionContents(StringRef SecData, StringRef SecName) override; + + /// Emit the string table described by \p Pool. + void emitStrings(const NonRelocatableStringpool &Pool) override; + + /// Emit the swift_ast section stored in \p Buffer. + void emitSwiftAST(StringRef Buffer); + + /// Emit debug_ranges for \p FuncRange by translating the + /// original \p Entries. + void emitRangesEntries( + int64_t UnitPcOffset, uint64_t OrigLowPc, + const FunctionIntervals::const_iterator &FuncRange, + const std::vector<DWARFDebugRangeList::RangeListEntry> &Entries, + unsigned AddressSize) override; + + /// Emit debug_aranges entries for \p Unit and if \p DoRangesSection is true, + /// also emit the debug_ranges entries for the DW_TAG_compile_unit's + /// DW_AT_ranges attribute. + void emitUnitRangesEntries(CompileUnit &Unit, bool DoRangesSection) override; + + uint64_t getRangesSectionSize() const override { return RangesSectionSize; } + + /// Emit the debug_loc contribution for \p Unit by copying the entries from + /// \p Dwarf and offsetting them. Update the location attributes to point to + /// the new entries. + void emitLocationsForUnit( + const CompileUnit &Unit, DWARFContext &Dwarf, + std::function<void(StringRef, SmallVectorImpl<uint8_t> &)> ProcessExpr) + override; + + /// Emit the line table described in \p Rows into the debug_line section. + void emitLineTableForUnit(MCDwarfLineTableParams Params, + StringRef PrologueBytes, unsigned MinInstLength, + std::vector<DWARFDebugLine::Row> &Rows, + unsigned AdddressSize) override; + + /// Copy the debug_line over to the updated binary while unobfuscating the + /// file names and directories. + void translateLineTable(DataExtractor LineData, uint64_t Offset) override; + + uint64_t getLineSectionSize() const override { return LineSectionSize; } + + /// Emit the .debug_pubnames contribution for \p Unit. + void emitPubNamesForUnit(const CompileUnit &Unit) override; + + /// Emit the .debug_pubtypes contribution for \p Unit. + void emitPubTypesForUnit(const CompileUnit &Unit) override; + + /// Emit a CIE. + void emitCIE(StringRef CIEBytes) override; + + /// Emit an FDE with data \p Bytes. + void emitFDE(uint32_t CIEOffset, uint32_t AddreSize, uint32_t Address, + StringRef Bytes) override; + + /// Emit DWARF debug names. + void emitDebugNames(AccelTable<DWARF5AccelTableStaticData> &Table) override; + + /// Emit Apple namespaces accelerator table. + void emitAppleNamespaces( + AccelTable<AppleAccelTableStaticOffsetData> &Table) override; + + /// Emit Apple names accelerator table. + void + emitAppleNames(AccelTable<AppleAccelTableStaticOffsetData> &Table) override; + + /// Emit Apple Objective-C accelerator table. + void + emitAppleObjc(AccelTable<AppleAccelTableStaticOffsetData> &Table) override; + + /// Emit Apple type accelerator table. + void + emitAppleTypes(AccelTable<AppleAccelTableStaticTypeData> &Table) override; + + uint64_t getFrameSectionSize() const override { return FrameSectionSize; } + + uint64_t getDebugInfoSectionSize() const override { + return DebugInfoSectionSize; + } + +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); + } + + /// \defgroup MCObjects MC layer objects constructed by the streamer + /// @{ + std::unique_ptr<MCRegisterInfo> MRI; + std::unique_ptr<MCAsmInfo> MAI; + std::unique_ptr<MCObjectFileInfo> MOFI; + std::unique_ptr<MCContext> MC; + MCAsmBackend *MAB; // Owned by MCStreamer + std::unique_ptr<MCInstrInfo> MII; + std::unique_ptr<MCSubtargetInfo> MSTI; + MCInstPrinter *MIP; // Owned by AsmPrinter + MCCodeEmitter *MCE; // Owned by MCStreamer + MCStreamer *MS; // Owned by AsmPrinter + std::unique_ptr<TargetMachine> TM; + std::unique_ptr<AsmPrinter> Asm; + /// @} + + /// The output file we stream the linked Dwarf to. + raw_pwrite_stream &OutFile; + OutputFileType OutFileType = OutputFileType::Object; + std::function<StringRef(StringRef Input)> Translator; + bool Minimize = true; + + uint64_t RangesSectionSize = 0; + uint64_t LocSectionSize = 0; + uint64_t LineSectionSize = 0; + uint64_t FrameSectionSize = 0; + uint64_t DebugInfoSectionSize = 0; + + /// Keep track of emitted CUs and their Unique ID. + struct EmittedUnit { + unsigned ID; + MCSymbol *LabelBegin; + }; + std::vector<EmittedUnit> EmittedUnits; + + /// Emit the pubnames or pubtypes section contribution for \p + /// Unit into \p Sec. The data is provided in \p Names. + void emitPubSectionForUnit(MCSection *Sec, StringRef Name, + const CompileUnit &Unit, + const std::vector<CompileUnit::AccelInfo> &Names); + + messageHandler ErrorHandler = nullptr; + messageHandler WarningHandler = nullptr; +}; + +} // end namespace llvm + +#endif // LLVM_DWARFLINKER_DWARFSTREAMER_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif |