[AMDGPU] Test codegen'ing True16 additions.
[llvm-project.git] / llvm / tools / dsymutil / DwarfLinkerForBinary.h
blob230f569a6988c32c49bfbdc3ef340758297f6fe8
1 //===- tools/dsymutil/DwarfLinkerForBinary.h --------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_TOOLS_DSYMUTIL_DWARFLINKER_H
10 #define LLVM_TOOLS_DSYMUTIL_DWARFLINKER_H
12 #include "BinaryHolder.h"
13 #include "DebugMap.h"
14 #include "LinkUtils.h"
15 #include "MachOUtils.h"
16 #include "llvm/DWARFLinker/DWARFLinker.h"
17 #include "llvm/DWARFLinker/DWARFLinkerCompileUnit.h"
18 #include "llvm/DWARFLinker/DWARFLinkerDeclContext.h"
19 #include "llvm/DWARFLinker/DWARFStreamer.h"
20 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
21 #include "llvm/Remarks/RemarkFormat.h"
22 #include "llvm/Remarks/RemarkLinker.h"
23 #include <mutex>
25 namespace llvm {
26 namespace dsymutil {
28 /// The core of the Dsymutil Dwarf linking logic.
29 ///
30 /// The link of the dwarf information from the object files will be
31 /// driven by DWARFLinker. DwarfLinkerForBinary reads DebugMap objects
32 /// and pass information to the DWARFLinker. DWARFLinker
33 /// optimizes DWARF taking into account valid relocations.
34 /// Finally, optimized DWARF is passed to DwarfLinkerForBinary through
35 /// DWARFEmitter interface.
36 class DwarfLinkerForBinary {
37 public:
38 DwarfLinkerForBinary(raw_fd_ostream &OutFile, BinaryHolder &BinHolder,
39 LinkOptions Options, std::mutex &ErrorHandlerMutex)
40 : OutFile(OutFile), BinHolder(BinHolder), Options(std::move(Options)),
41 ErrorHandlerMutex(ErrorHandlerMutex) {}
43 /// Link the contents of the DebugMap.
44 bool link(const DebugMap &);
46 void reportWarning(Twine Warning, Twine Context = {},
47 const DWARFDie *DIE = nullptr) const;
48 void reportError(Twine Error, Twine Context = {},
49 const DWARFDie *DIE = nullptr) const;
51 /// Returns true if input verification is enabled and verification errors were
52 /// found.
53 bool InputVerificationFailed() const { return HasVerificationErrors; }
55 /// Flags passed to DwarfLinker::lookForDIEsToKeep
56 enum TraversalFlags {
57 TF_Keep = 1 << 0, ///< Mark the traversed DIEs as kept.
58 TF_InFunctionScope = 1 << 1, ///< Current scope is a function scope.
59 TF_DependencyWalk = 1 << 2, ///< Walking the dependencies of a kept DIE.
60 TF_ParentWalk = 1 << 3, ///< Walking up the parents of a kept DIE.
61 TF_ODR = 1 << 4, ///< Use the ODR while keeping dependents.
62 TF_SkipPC = 1 << 5, ///< Skip all location attributes.
65 private:
67 /// Keeps track of relocations.
68 template <typename AddressesMapBase>
69 class AddressManager : public AddressesMapBase {
70 struct ValidReloc {
71 uint64_t Offset;
72 uint32_t Size;
73 uint64_t Addend;
74 const DebugMapObject::DebugMapEntry *Mapping;
76 ValidReloc(uint64_t Offset, uint32_t Size, uint64_t Addend,
77 const DebugMapObject::DebugMapEntry *Mapping)
78 : Offset(Offset), Size(Size), Addend(Addend), Mapping(Mapping) {}
80 bool operator<(const ValidReloc &RHS) const {
81 return Offset < RHS.Offset;
83 bool operator<(uint64_t RHS) const { return Offset < RHS; }
86 const DwarfLinkerForBinary &Linker;
88 /// The valid relocations for the current DebugMapObject.
89 /// This vector is sorted by relocation offset.
90 /// {
91 std::vector<ValidReloc> ValidDebugInfoRelocs;
92 std::vector<ValidReloc> ValidDebugAddrRelocs;
93 /// }
95 StringRef SrcFileName;
97 /// Returns list of valid relocations from \p Relocs,
98 /// between \p StartOffset and \p NextOffset.
99 ///
100 /// \returns true if any relocation is found.
101 std::vector<ValidReloc>
102 getRelocations(const std::vector<ValidReloc> &Relocs, uint64_t StartPos,
103 uint64_t EndPos);
105 /// Resolve specified relocation \p Reloc.
107 /// \returns resolved value.
108 uint64_t relocate(const ValidReloc &Reloc) const;
110 /// \returns value for the specified \p Reloc.
111 int64_t getRelocValue(const ValidReloc &Reloc);
113 /// Print contents of debug map entry for the specified \p Reloc.
114 void printReloc(const ValidReloc &Reloc);
116 public:
117 AddressManager(DwarfLinkerForBinary &Linker, const object::ObjectFile &Obj,
118 const DebugMapObject &DMO)
119 : Linker(Linker), SrcFileName(DMO.getObjectFilename()) {
120 findValidRelocsInDebugSections(Obj, DMO);
122 ~AddressManager() override { clear(); }
124 bool hasValidRelocs() override {
125 return !ValidDebugInfoRelocs.empty() || !ValidDebugAddrRelocs.empty();
128 /// \defgroup FindValidRelocations Translate debug map into a list
129 /// of relevant relocations
131 /// @{
132 bool findValidRelocsInDebugSections(const object::ObjectFile &Obj,
133 const DebugMapObject &DMO);
135 bool findValidRelocs(const object::SectionRef &Section,
136 const object::ObjectFile &Obj,
137 const DebugMapObject &DMO,
138 std::vector<ValidReloc> &ValidRelocs);
140 void findValidRelocsMachO(const object::SectionRef &Section,
141 const object::MachOObjectFile &Obj,
142 const DebugMapObject &DMO,
143 std::vector<ValidReloc> &ValidRelocs);
144 /// @}
146 /// Checks that there is a relocation in the \p Relocs array against a
147 /// debug map entry between \p StartOffset and \p NextOffset.
149 /// \returns relocation value if relocation exist, otherwise std::nullopt.
150 std::optional<int64_t>
151 hasValidRelocationAt(const std::vector<ValidReloc> &Relocs,
152 uint64_t StartOffset, uint64_t EndOffset);
154 std::optional<int64_t> getExprOpAddressRelocAdjustment(
155 DWARFUnit &U, const DWARFExpression::Operation &Op,
156 uint64_t StartOffset, uint64_t EndOffset) override;
158 std::optional<int64_t>
159 getSubprogramRelocAdjustment(const DWARFDie &DIE) override;
161 bool applyValidRelocs(MutableArrayRef<char> Data, uint64_t BaseOffset,
162 bool IsLittleEndian) override;
164 void clear() override {
165 ValidDebugInfoRelocs.clear();
166 ValidDebugAddrRelocs.clear();
170 private:
171 /// \defgroup Helpers Various helper methods.
173 /// @{
174 template <typename OutStreamer>
175 bool createStreamer(const Triple &TheTriple,
176 typename OutStreamer::OutputFileType FileType,
177 std::unique_ptr<OutStreamer> &Streamer,
178 raw_fd_ostream &OutFile);
180 /// Attempt to load a debug object from disk.
181 ErrorOr<const object::ObjectFile &> loadObject(const DebugMapObject &Obj,
182 const Triple &triple);
184 template <typename OutDWARFFile, typename AddressesMap>
185 ErrorOr<std::unique_ptr<OutDWARFFile>> loadObject(const DebugMapObject &Obj,
186 const DebugMap &DebugMap,
187 remarks::RemarkLinker &RL);
189 void collectRelocationsToApplyToSwiftReflectionSections(
190 const object::SectionRef &Section, StringRef &Contents,
191 const llvm::object::MachOObjectFile *MO,
192 const std::vector<uint64_t> &SectionToOffsetInDwarf,
193 const llvm::dsymutil::DebugMapObject *Obj,
194 std::vector<MachOUtils::DwarfRelocationApplicationInfo>
195 &RelocationsToApply) const;
197 Error copySwiftInterfaces(StringRef Architecture) const;
199 template <typename OutStreamer>
200 void copySwiftReflectionMetadata(
201 const llvm::dsymutil::DebugMapObject *Obj, OutStreamer *Streamer,
202 std::vector<uint64_t> &SectionToOffsetInDwarf,
203 std::vector<MachOUtils::DwarfRelocationApplicationInfo>
204 &RelocationsToApply);
206 template <typename Linker, typename OutDwarfFile, typename AddressMapBase>
207 bool linkImpl(const DebugMap &Map,
208 typename Linker::OutputFileType ObjectType);
210 raw_fd_ostream &OutFile;
211 BinaryHolder &BinHolder;
212 LinkOptions Options;
213 std::mutex &ErrorHandlerMutex;
215 std::vector<std::string> EmptyWarnings;
217 /// A list of all .swiftinterface files referenced by the debug
218 /// info, mapping Module name to path on disk. The entries need to
219 /// be uniqued and sorted and there are only few entries expected
220 /// per compile unit, which is why this is a std::map.
221 std::map<std::string, std::string> ParseableSwiftInterfaces;
223 bool ModuleCacheHintDisplayed = false;
224 bool ArchiveHintDisplayed = false;
225 bool HasVerificationErrors = false;
228 } // end namespace dsymutil
229 } // end namespace llvm
231 #endif // LLVM_TOOLS_DSYMUTIL_DWARFLINKER_H