1 //===- DWARFLinker.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 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_DWARFLINKER_DWARFLINKER_H
10 #define LLVM_DWARFLINKER_DWARFLINKER_H
11 
12 #include "llvm/ADT/AddressRanges.h"
13 #include "llvm/CodeGen/AccelTable.h"
14 #include "llvm/CodeGen/NonRelocatableStringpool.h"
15 #include "llvm/DWARFLinker/DWARFLinkerCompileUnit.h"
16 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
17 #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
18 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
19 #include <map>
20 
21 namespace llvm {
22 class DWARFContext;
23 class DWARFExpression;
24 class DWARFUnit;
25 class DataExtractor;
26 class DeclContextTree;
27 struct MCDwarfLineTableParams;
28 template <typename T> class SmallVectorImpl;
29 
30 enum class DwarfLinkerClient { Dsymutil, LLD, General };
31 
32 /// The kind of accelerator tables we should emit.
33 enum class DwarfLinkerAccelTableKind : uint8_t {
34   None,
35   Apple,   ///< .apple_names, .apple_namespaces, .apple_types, .apple_objc.
36   Dwarf,   ///< DWARF v5 .debug_names.
37   Default, ///< Dwarf for DWARF5 or later, Apple otherwise.
38   Pub,     ///< .debug_pubnames, .debug_pubtypes
39 };
40 
41 /// AddressesMap represents information about valid addresses used
42 /// by debug information. Valid addresses are those which points to
43 /// live code sections. i.e. relocations for these addresses point
44 /// into sections which would be/are placed into resulting binary.
45 class AddressesMap {
46 public:
47   virtual ~AddressesMap();
48 
49   /// Checks that there are valid relocations against a .debug_info
50   /// section.
51   virtual bool hasValidRelocs() = 0;
52 
53   /// Checks that the specified variable \p DIE references live code section.
54   /// Allowed kind of input die: DW_TAG_variable, DW_TAG_constant.
55   /// \returns true and sets Info.InDebugMap if it is the case.
56   virtual bool isLiveVariable(const DWARFDie &DIE,
57                               CompileUnit::DIEInfo &Info) = 0;
58 
59   /// Checks that the specified subprogram \p DIE references live code section.
60   /// Allowed kind of input die: DW_TAG_subprogram, DW_TAG_label.
61   /// \returns true and sets Info.InDebugMap if it is the case.
62   virtual bool isLiveSubprogram(const DWARFDie &DIE,
63                                 CompileUnit::DIEInfo &Info) = 0;
64 
65   /// Apply the valid relocations to the buffer \p Data, taking into
66   /// account that Data is at \p BaseOffset in the .debug_info section.
67   ///
68   /// \returns true whether any reloc has been applied.
69   virtual bool applyValidRelocs(MutableArrayRef<char> Data, uint64_t BaseOffset,
70                                 bool IsLittleEndian) = 0;
71 
72   /// Relocate the given address offset if a valid relocation exists.
73   virtual llvm::Expected<uint64_t> relocateIndexedAddr(uint64_t StartOffset,
74                                                        uint64_t EndOffset) = 0;
75 
76   /// Returns all valid functions address ranges(i.e., those ranges
77   /// which points to sections with code).
78   virtual RangesTy &getValidAddressRanges() = 0;
79 
80   /// Erases all data.
81   virtual void clear() = 0;
82 };
83 
84 /// DwarfEmitter presents interface to generate all debug info tables.
85 class DwarfEmitter {
86 public:
87   virtual ~DwarfEmitter();
88 
89   /// Emit DIE containing warnings.
90   virtual void emitPaperTrailWarningsDie(DIE &Die) = 0;
91 
92   /// Emit section named SecName with data SecData.
93   virtual void emitSectionContents(StringRef SecData, StringRef SecName) = 0;
94 
95   /// Emit the abbreviation table \p Abbrevs to the .debug_abbrev section.
96   virtual void
97   emitAbbrevs(const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs,
98               unsigned DwarfVersion) = 0;
99 
100   /// Emit the string table described by \p Pool.
101   virtual void emitStrings(const NonRelocatableStringpool &Pool) = 0;
102 
103   /// Emit DWARF debug names.
104   virtual void
105   emitDebugNames(AccelTable<DWARF5AccelTableStaticData> &Table) = 0;
106 
107   /// Emit Apple namespaces accelerator table.
108   virtual void
109   emitAppleNamespaces(AccelTable<AppleAccelTableStaticOffsetData> &Table) = 0;
110 
111   /// Emit Apple names accelerator table.
112   virtual void
113   emitAppleNames(AccelTable<AppleAccelTableStaticOffsetData> &Table) = 0;
114 
115   /// Emit Apple Objective-C accelerator table.
116   virtual void
117   emitAppleObjc(AccelTable<AppleAccelTableStaticOffsetData> &Table) = 0;
118 
119   /// Emit Apple type accelerator table.
120   virtual void
121   emitAppleTypes(AccelTable<AppleAccelTableStaticTypeData> &Table) = 0;
122 
123   /// Emit .debug_ranges for \p FuncRange by translating the
124   /// original \p Entries.
125   virtual void emitRangesEntries(
126       int64_t UnitPcOffset, uint64_t OrigLowPc,
127       Optional<std::pair<AddressRange, int64_t>> FuncRange,
128       const std::vector<DWARFDebugRangeList::RangeListEntry> &Entries,
129       unsigned AddressSize) = 0;
130 
131   /// Emit .debug_aranges entries for \p Unit and if \p DoRangesSection is true,
132   /// also emit the .debug_ranges entries for the DW_TAG_compile_unit's
133   /// DW_AT_ranges attribute.
134   virtual void emitUnitRangesEntries(CompileUnit &Unit,
135                                      bool DoRangesSection) = 0;
136 
137   /// Copy the .debug_line over to the updated binary while unobfuscating the
138   /// file names and directories.
139   virtual void translateLineTable(DataExtractor LineData, uint64_t Offset) = 0;
140 
141   /// Emit the line table described in \p Rows into the .debug_line section.
142   virtual void emitLineTableForUnit(MCDwarfLineTableParams Params,
143                                     StringRef PrologueBytes,
144                                     unsigned MinInstLength,
145                                     std::vector<DWARFDebugLine::Row> &Rows,
146                                     unsigned AdddressSize) = 0;
147 
148   /// Emit the .debug_pubnames contribution for \p Unit.
149   virtual void emitPubNamesForUnit(const CompileUnit &Unit) = 0;
150 
151   /// Emit the .debug_pubtypes contribution for \p Unit.
152   virtual void emitPubTypesForUnit(const CompileUnit &Unit) = 0;
153 
154   /// Emit a CIE.
155   virtual void emitCIE(StringRef CIEBytes) = 0;
156 
157   /// Emit an FDE with data \p Bytes.
158   virtual void emitFDE(uint32_t CIEOffset, uint32_t AddreSize, uint32_t Address,
159                        StringRef Bytes) = 0;
160 
161   /// Emit the .debug_loc contribution for \p Unit by copying the entries from
162   /// \p Dwarf and offsetting them. Update the location attributes to point to
163   /// the new entries.
164   virtual void emitLocationsForUnit(
165       const CompileUnit &Unit, DWARFContext &Dwarf,
166       std::function<void(StringRef, SmallVectorImpl<uint8_t> &)>
167           ProcessExpr) = 0;
168 
169   /// Emit the compilation unit header for \p Unit in the
170   /// .debug_info section.
171   ///
172   /// As a side effect, this also switches the current Dwarf version
173   /// of the MC layer to the one of U.getOrigUnit().
174   virtual void emitCompileUnitHeader(CompileUnit &Unit,
175                                      unsigned DwarfVersion) = 0;
176 
177   /// Recursively emit the DIE tree rooted at \p Die.
178   virtual void emitDIE(DIE &Die) = 0;
179 
180   /// Returns size of generated .debug_line section.
181   virtual uint64_t getLineSectionSize() const = 0;
182 
183   /// Returns size of generated .debug_frame section.
184   virtual uint64_t getFrameSectionSize() const = 0;
185 
186   /// Returns size of generated .debug_ranges section.
187   virtual uint64_t getRangesSectionSize() const = 0;
188 
189   /// Returns size of generated .debug_info section.
190   virtual uint64_t getDebugInfoSectionSize() const = 0;
191 };
192 
193 using UnitListTy = std::vector<std::unique_ptr<CompileUnit>>;
194 
195 /// this class represents DWARF information for source file
196 /// and it`s address map.
197 class DWARFFile {
198 public:
DWARFFile(StringRef Name,DWARFContext * Dwarf,AddressesMap * Addresses,const std::vector<std::string> & Warnings)199   DWARFFile(StringRef Name, DWARFContext *Dwarf, AddressesMap *Addresses,
200             const std::vector<std::string> &Warnings)
201       : FileName(Name), Dwarf(Dwarf), Addresses(Addresses), Warnings(Warnings) {
202   }
203 
204   /// object file name.
205   StringRef FileName;
206   /// source DWARF information.
207   DWARFContext *Dwarf = nullptr;
208   /// helpful address information(list of valid address ranges, relocations).
209   AddressesMap *Addresses = nullptr;
210   /// warnings for object file.
211   const std::vector<std::string> &Warnings;
212 };
213 
214 typedef std::function<void(const Twine &Warning, StringRef Context,
215                            const DWARFDie *DIE)>
216     messageHandler;
217 typedef std::function<ErrorOr<DWARFFile &>(StringRef ContainerName,
218                                            StringRef Path)>
219     objFileLoader;
220 typedef std::map<std::string, std::string> swiftInterfacesMap;
221 typedef std::map<std::string, std::string> objectPrefixMap;
222 
223 /// The core of the Dwarf linking logic.
224 ///
225 /// The generation of the dwarf information from the object files will be
226 /// driven by the selection of 'root DIEs', which are DIEs that
227 /// describe variables or functions that resolves to the corresponding
228 /// code section(and thus have entries in the Addresses map). All the debug
229 /// information that will be generated(the DIEs, but also the line
230 /// tables, ranges, ...) is derived from that set of root DIEs.
231 ///
232 /// The root DIEs are identified because they contain relocations that
233 /// points to code section(the low_pc for a function, the location for
234 /// a variable). These relocations are called ValidRelocs in the
235 /// AddressesInfo and are gathered as a very first step when we start
236 /// processing a object file.
237 class DWARFLinker {
238 public:
239   DWARFLinker(DwarfEmitter *Emitter,
240               DwarfLinkerClient ClientID = DwarfLinkerClient::General)
TheDwarfEmitter(Emitter)241       : TheDwarfEmitter(Emitter), DwarfLinkerClientID(ClientID) {}
242 
243   /// Add object file to be linked.
244   void addObjectFile(DWARFFile &File);
245 
246   /// Link debug info for added objFiles. Object
247   /// files are linked all together.
248   Error link();
249 
250   /// A number of methods setting various linking options:
251 
252   /// Allows to generate log of linking process to the standard output.
setVerbosity(bool Verbose)253   void setVerbosity(bool Verbose) { Options.Verbose = Verbose; }
254 
255   /// Print statistics to standard output.
setStatistics(bool Statistics)256   void setStatistics(bool Statistics) { Options.Statistics = Statistics; }
257 
258   /// Verify the input DWARF.
setVerifyInputDWARF(bool Verify)259   void setVerifyInputDWARF(bool Verify) { Options.VerifyInputDWARF = Verify; }
260 
261   /// Do not emit linked dwarf info.
setNoOutput(bool NoOut)262   void setNoOutput(bool NoOut) { Options.NoOutput = NoOut; }
263 
264   /// Do not unique types according to ODR.
setNoODR(bool NoODR)265   void setNoODR(bool NoODR) { Options.NoODR = NoODR; }
266 
267   /// update existing DWARF info(for the linked binary).
setUpdate(bool Update)268   void setUpdate(bool Update) { Options.Update = Update; }
269 
270   /// Set whether to keep the enclosing function for a static variable.
setKeepFunctionForStatic(bool KeepFunctionForStatic)271   void setKeepFunctionForStatic(bool KeepFunctionForStatic) {
272     Options.KeepFunctionForStatic = KeepFunctionForStatic;
273   }
274 
275   /// Use specified number of threads for parallel files linking.
setNumThreads(unsigned NumThreads)276   void setNumThreads(unsigned NumThreads) { Options.Threads = NumThreads; }
277 
278   /// Set kind of accelerator tables to be generated.
setAccelTableKind(DwarfLinkerAccelTableKind Kind)279   void setAccelTableKind(DwarfLinkerAccelTableKind Kind) {
280     Options.TheAccelTableKind = Kind;
281   }
282 
283   /// Set prepend path for clang modules.
setPrependPath(const std::string & Ppath)284   void setPrependPath(const std::string &Ppath) { Options.PrependPath = Ppath; }
285 
286   /// Set translator which would be used for strings.
287   void
setStringsTranslator(std::function<StringRef (StringRef)> StringsTranslator)288   setStringsTranslator(std::function<StringRef(StringRef)> StringsTranslator) {
289     this->StringsTranslator = StringsTranslator;
290   }
291 
292   /// Set estimated objects files amount, for preliminary data allocation.
setEstimatedObjfilesAmount(unsigned ObjFilesNum)293   void setEstimatedObjfilesAmount(unsigned ObjFilesNum) {
294     ObjectContexts.reserve(ObjFilesNum);
295   }
296 
297   /// Set warning handler which would be used to report warnings.
setWarningHandler(messageHandler Handler)298   void setWarningHandler(messageHandler Handler) {
299     Options.WarningHandler = Handler;
300   }
301 
302   /// Set error handler which would be used to report errors.
setErrorHandler(messageHandler Handler)303   void setErrorHandler(messageHandler Handler) {
304     Options.ErrorHandler = Handler;
305   }
306 
307   /// Set object files loader which would be used to load
308   /// additional objects for splitted dwarf.
setObjFileLoader(objFileLoader Loader)309   void setObjFileLoader(objFileLoader Loader) {
310     Options.ObjFileLoader = Loader;
311   }
312 
313   /// Set map for Swift interfaces.
setSwiftInterfacesMap(swiftInterfacesMap * Map)314   void setSwiftInterfacesMap(swiftInterfacesMap *Map) {
315     Options.ParseableSwiftInterfaces = Map;
316   }
317 
318   /// Set prefix map for objects.
setObjectPrefixMap(objectPrefixMap * Map)319   void setObjectPrefixMap(objectPrefixMap *Map) {
320     Options.ObjectPrefixMap = Map;
321   }
322 
323 private:
324   /// Flags passed to DwarfLinker::lookForDIEsToKeep
325   enum TraversalFlags {
326     TF_Keep = 1 << 0,            ///< Mark the traversed DIEs as kept.
327     TF_InFunctionScope = 1 << 1, ///< Current scope is a function scope.
328     TF_DependencyWalk = 1 << 2,  ///< Walking the dependencies of a kept DIE.
329     TF_ParentWalk = 1 << 3,      ///< Walking up the parents of a kept DIE.
330     TF_ODR = 1 << 4,             ///< Use the ODR while keeping dependents.
331     TF_SkipPC = 1 << 5,          ///< Skip all location attributes.
332   };
333 
334   /// The  distinct types of work performed by the work loop.
335   enum class WorklistItemType {
336     /// Given a DIE, look for DIEs to be kept.
337     LookForDIEsToKeep,
338     /// Given a DIE, look for children of this DIE to be kept.
339     LookForChildDIEsToKeep,
340     /// Given a DIE, look for DIEs referencing this DIE to be kept.
341     LookForRefDIEsToKeep,
342     /// Given a DIE, look for parent DIEs to be kept.
343     LookForParentDIEsToKeep,
344     /// Given a DIE, update its incompleteness based on whether its children are
345     /// incomplete.
346     UpdateChildIncompleteness,
347     /// Given a DIE, update its incompleteness based on whether the DIEs it
348     /// references are incomplete.
349     UpdateRefIncompleteness,
350     /// Given a DIE, mark it as ODR Canonical if applicable.
351     MarkODRCanonicalDie,
352   };
353 
354   /// This class represents an item in the work list. The type defines what kind
355   /// of work needs to be performed when processing the current item. The flags
356   /// and info fields are optional based on the type.
357   struct WorklistItem {
358     DWARFDie Die;
359     WorklistItemType Type;
360     CompileUnit &CU;
361     unsigned Flags;
362     union {
363       const unsigned AncestorIdx;
364       CompileUnit::DIEInfo *OtherInfo;
365     };
366 
367     WorklistItem(DWARFDie Die, CompileUnit &CU, unsigned Flags,
368                  WorklistItemType T = WorklistItemType::LookForDIEsToKeep)
DieWorklistItem369         : Die(Die), Type(T), CU(CU), Flags(Flags), AncestorIdx(0) {}
370 
371     WorklistItem(DWARFDie Die, CompileUnit &CU, WorklistItemType T,
372                  CompileUnit::DIEInfo *OtherInfo = nullptr)
DieWorklistItem373         : Die(Die), Type(T), CU(CU), Flags(0), OtherInfo(OtherInfo) {}
374 
WorklistItemWorklistItem375     WorklistItem(unsigned AncestorIdx, CompileUnit &CU, unsigned Flags)
376         : Type(WorklistItemType::LookForParentDIEsToKeep), CU(CU), Flags(Flags),
377           AncestorIdx(AncestorIdx) {}
378   };
379 
380   /// Verify the given DWARF file.
381   bool verify(const DWARFFile &File);
382 
383   /// returns true if we need to translate strings.
needToTranslateStrings()384   bool needToTranslateStrings() { return StringsTranslator != nullptr; }
385 
386   void reportWarning(const Twine &Warning, const DWARFFile &File,
387                      const DWARFDie *DIE = nullptr) const {
388     if (Options.WarningHandler != nullptr)
389       Options.WarningHandler(Warning, File.FileName, DIE);
390   }
391 
392   void reportError(const Twine &Warning, const DWARFFile &File,
393                    const DWARFDie *DIE = nullptr) const {
394     if (Options.ErrorHandler != nullptr)
395       Options.ErrorHandler(Warning, File.FileName, DIE);
396   }
397 
398   /// Remembers the oldest and newest DWARF version we've seen in a unit.
updateDwarfVersion(unsigned Version)399   void updateDwarfVersion(unsigned Version) {
400     MaxDwarfVersion = std::max(MaxDwarfVersion, Version);
401     MinDwarfVersion = std::min(MinDwarfVersion, Version);
402   }
403 
404   /// Remembers the kinds of accelerator tables we've seen in a unit.
405   void updateAccelKind(DWARFContext &Dwarf);
406 
407   /// Emit warnings as Dwarf compile units to leave a trail after linking.
408   bool emitPaperTrailWarnings(const DWARFFile &File,
409                               OffsetsStringPool &StringPool);
410 
411   void copyInvariantDebugSection(DWARFContext &Dwarf);
412 
413   /// Keeps track of data associated with one object during linking.
414   struct LinkContext {
415     DWARFFile &File;
416     UnitListTy CompileUnits;
417     bool Skip = false;
418 
LinkContextLinkContext419     LinkContext(DWARFFile &File) : File(File) {}
420 
421     /// Clear part of the context that's no longer needed when we're done with
422     /// the debug object.
clearLinkContext423     void clear() {
424       CompileUnits.clear();
425       File.Addresses->clear();
426     }
427   };
428 
429   /// Called before emitting object data
430   void cleanupAuxiliarryData(LinkContext &Context);
431 
432   /// Look at the parent of the given DIE and decide whether they should be
433   /// kept.
434   void lookForParentDIEsToKeep(unsigned AncestorIdx, CompileUnit &CU,
435                                unsigned Flags,
436                                SmallVectorImpl<WorklistItem> &Worklist);
437 
438   /// Look at the children of the given DIE and decide whether they should be
439   /// kept.
440   void lookForChildDIEsToKeep(const DWARFDie &Die, CompileUnit &CU,
441                               unsigned Flags,
442                               SmallVectorImpl<WorklistItem> &Worklist);
443 
444   /// Look at DIEs referenced by the given DIE and decide whether they should be
445   /// kept. All DIEs referenced though attributes should be kept.
446   void lookForRefDIEsToKeep(const DWARFDie &Die, CompileUnit &CU,
447                             unsigned Flags, const UnitListTy &Units,
448                             const DWARFFile &File,
449                             SmallVectorImpl<WorklistItem> &Worklist);
450 
451   /// Mark context corresponding to the specified \p Die as having canonical
452   /// die, if applicable.
453   void markODRCanonicalDie(const DWARFDie &Die, CompileUnit &CU);
454 
455   /// \defgroup FindRootDIEs Find DIEs corresponding to Address map entries.
456   ///
457   /// @{
458   /// Recursively walk the \p DIE tree and look for DIEs to
459   /// keep. Store that information in \p CU's DIEInfo.
460   ///
461   /// The return value indicates whether the DIE is incomplete.
462   void lookForDIEsToKeep(AddressesMap &RelocMgr, RangesTy &Ranges,
463                          const UnitListTy &Units, const DWARFDie &DIE,
464                          const DWARFFile &File, CompileUnit &CU,
465                          unsigned Flags);
466 
467   /// If this compile unit is really a skeleton CU that points to a
468   /// clang module, register it in ClangModules and return true.
469   ///
470   /// A skeleton CU is a CU without children, a DW_AT_gnu_dwo_name
471   /// pointing to the module, and a DW_AT_gnu_dwo_id with the module
472   /// hash.
473   bool registerModuleReference(DWARFDie CUDie, const DWARFUnit &Unit,
474                                const DWARFFile &File,
475                                OffsetsStringPool &OffsetsStringPool,
476                                DeclContextTree &ODRContexts,
477                                uint64_t ModulesEndOffset, unsigned &UnitID,
478                                bool IsLittleEndian, unsigned Indent = 0,
479                                bool Quiet = false);
480 
481   /// Recursively add the debug info in this clang module .pcm
482   /// file (and all the modules imported by it in a bottom-up fashion)
483   /// to Units.
484   Error loadClangModule(DWARFDie CUDie, StringRef FilePath,
485                         StringRef ModuleName, uint64_t DwoId,
486                         const DWARFFile &File,
487                         OffsetsStringPool &OffsetsStringPool,
488                         DeclContextTree &ODRContexts, uint64_t ModulesEndOffset,
489                         unsigned &UnitID, bool IsLittleEndian,
490                         unsigned Indent = 0, bool Quiet = false);
491 
492   /// Mark the passed DIE as well as all the ones it depends on as kept.
493   void keepDIEAndDependencies(AddressesMap &RelocMgr, RangesTy &Ranges,
494                               const UnitListTy &Units, const DWARFDie &DIE,
495                               CompileUnit::DIEInfo &MyInfo,
496                               const DWARFFile &File, CompileUnit &CU,
497                               bool UseODR);
498 
499   unsigned shouldKeepDIE(AddressesMap &RelocMgr, RangesTy &Ranges,
500                          const DWARFDie &DIE, const DWARFFile &File,
501                          CompileUnit &Unit, CompileUnit::DIEInfo &MyInfo,
502                          unsigned Flags);
503 
504   /// Check if a variable describing DIE should be kept.
505   /// \returns updated TraversalFlags.
506   unsigned shouldKeepVariableDIE(AddressesMap &RelocMgr, const DWARFDie &DIE,
507                                  CompileUnit::DIEInfo &MyInfo, unsigned Flags);
508 
509   unsigned shouldKeepSubprogramDIE(AddressesMap &RelocMgr, RangesTy &Ranges,
510                                    const DWARFDie &DIE, const DWARFFile &File,
511                                    CompileUnit &Unit,
512                                    CompileUnit::DIEInfo &MyInfo,
513                                    unsigned Flags);
514 
515   /// Resolve the DIE attribute reference that has been extracted in \p
516   /// RefValue. The resulting DIE might be in another CompileUnit which is
517   /// stored into \p ReferencedCU. \returns null if resolving fails for any
518   /// reason.
519   DWARFDie resolveDIEReference(const DWARFFile &File, const UnitListTy &Units,
520                                const DWARFFormValue &RefValue,
521                                const DWARFDie &DIE, CompileUnit *&RefCU);
522 
523   /// @}
524 
525   /// \defgroup Methods used to link the debug information
526   ///
527   /// @{
528 
529   struct DWARFLinkerOptions;
530 
531   class DIECloner {
532     DWARFLinker &Linker;
533     DwarfEmitter *Emitter;
534     DWARFFile &ObjFile;
535 
536     /// Allocator used for all the DIEValue objects.
537     BumpPtrAllocator &DIEAlloc;
538 
539     std::vector<std::unique_ptr<CompileUnit>> &CompileUnits;
540 
541     bool Update;
542 
543   public:
DIECloner(DWARFLinker & Linker,DwarfEmitter * Emitter,DWARFFile & ObjFile,BumpPtrAllocator & DIEAlloc,std::vector<std::unique_ptr<CompileUnit>> & CompileUnits,bool Update)544     DIECloner(DWARFLinker &Linker, DwarfEmitter *Emitter, DWARFFile &ObjFile,
545               BumpPtrAllocator &DIEAlloc,
546               std::vector<std::unique_ptr<CompileUnit>> &CompileUnits,
547               bool Update)
548         : Linker(Linker), Emitter(Emitter), ObjFile(ObjFile),
549           DIEAlloc(DIEAlloc), CompileUnits(CompileUnits), Update(Update) {}
550 
551     /// Recursively clone \p InputDIE into an tree of DIE objects
552     /// where useless (as decided by lookForDIEsToKeep()) bits have been
553     /// stripped out and addresses have been rewritten according to the
554     /// address map.
555     ///
556     /// \param OutOffset is the offset the cloned DIE in the output
557     /// compile unit.
558     /// \param PCOffset (while cloning a function scope) is the offset
559     /// applied to the entry point of the function to get the linked address.
560     /// \param Die the output DIE to use, pass NULL to create one.
561     /// \returns the root of the cloned tree or null if nothing was selected.
562     DIE *cloneDIE(const DWARFDie &InputDIE, const DWARFFile &File,
563                   CompileUnit &U, OffsetsStringPool &StringPool,
564                   int64_t PCOffset, uint32_t OutOffset, unsigned Flags,
565                   bool IsLittleEndian, DIE *Die = nullptr);
566 
567     /// Construct the output DIE tree by cloning the DIEs we
568     /// chose to keep above. If there are no valid relocs, then there's
569     /// nothing to clone/emit.
570     uint64_t cloneAllCompileUnits(DWARFContext &DwarfContext,
571                                   const DWARFFile &File,
572                                   OffsetsStringPool &StringPool,
573                                   bool IsLittleEndian);
574 
575   private:
576     using AttributeSpec = DWARFAbbreviationDeclaration::AttributeSpec;
577 
578     /// Information gathered and exchanged between the various
579     /// clone*Attributes helpers about the attributes of a particular DIE.
580     struct AttributesInfo {
581       /// Names.
582       DwarfStringPoolEntryRef Name, MangledName, NameWithoutTemplate;
583 
584       /// Offsets in the string pool.
585       uint32_t NameOffset = 0;
586       uint32_t MangledNameOffset = 0;
587 
588       /// Value of AT_low_pc in the input DIE
589       uint64_t OrigLowPc = std::numeric_limits<uint64_t>::max();
590 
591       /// Value of AT_high_pc in the input DIE
592       uint64_t OrigHighPc = 0;
593 
594       /// Value of DW_AT_call_return_pc in the input DIE
595       uint64_t OrigCallReturnPc = 0;
596 
597       /// Value of DW_AT_call_pc in the input DIE
598       uint64_t OrigCallPc = 0;
599 
600       /// Offset to apply to PC addresses inside a function.
601       int64_t PCOffset = 0;
602 
603       /// Does the DIE have a low_pc attribute?
604       bool HasLowPc = false;
605 
606       /// Does the DIE have a ranges attribute?
607       bool HasRanges = false;
608 
609       /// Is this DIE only a declaration?
610       bool IsDeclaration = false;
611 
612       AttributesInfo() = default;
613     };
614 
615     /// Helper for cloneDIE.
616     unsigned cloneAttribute(DIE &Die, const DWARFDie &InputDIE,
617                             const DWARFFile &File, CompileUnit &U,
618                             OffsetsStringPool &StringPool,
619                             const DWARFFormValue &Val,
620                             const AttributeSpec AttrSpec, unsigned AttrSize,
621                             AttributesInfo &AttrInfo, bool IsLittleEndian);
622 
623     /// Clone a string attribute described by \p AttrSpec and add
624     /// it to \p Die.
625     /// \returns the size of the new attribute.
626     unsigned cloneStringAttribute(DIE &Die, AttributeSpec AttrSpec,
627                                   const DWARFFormValue &Val, const DWARFUnit &U,
628                                   OffsetsStringPool &StringPool,
629                                   AttributesInfo &Info);
630 
631     /// Clone an attribute referencing another DIE and add
632     /// it to \p Die.
633     /// \returns the size of the new attribute.
634     unsigned cloneDieReferenceAttribute(DIE &Die, const DWARFDie &InputDIE,
635                                         AttributeSpec AttrSpec,
636                                         unsigned AttrSize,
637                                         const DWARFFormValue &Val,
638                                         const DWARFFile &File,
639                                         CompileUnit &Unit);
640 
641     /// Clone a DWARF expression that may be referencing another DIE.
642     void cloneExpression(DataExtractor &Data, DWARFExpression Expression,
643                          const DWARFFile &File, CompileUnit &Unit,
644                          SmallVectorImpl<uint8_t> &OutputBuffer);
645 
646     /// Clone an attribute referencing another DIE and add
647     /// it to \p Die.
648     /// \returns the size of the new attribute.
649     unsigned cloneBlockAttribute(DIE &Die, const DWARFFile &File,
650                                  CompileUnit &Unit, AttributeSpec AttrSpec,
651                                  const DWARFFormValue &Val, unsigned AttrSize,
652                                  bool IsLittleEndian);
653 
654     /// Clone an attribute referencing another DIE and add
655     /// it to \p Die.
656     /// \returns the size of the new attribute.
657     unsigned cloneAddressAttribute(DIE &Die, AttributeSpec AttrSpec,
658                                    const DWARFFormValue &Val,
659                                    const CompileUnit &Unit,
660                                    AttributesInfo &Info);
661 
662     /// Clone a scalar attribute  and add it to \p Die.
663     /// \returns the size of the new attribute.
664     unsigned cloneScalarAttribute(DIE &Die, const DWARFDie &InputDIE,
665                                   const DWARFFile &File, CompileUnit &U,
666                                   AttributeSpec AttrSpec,
667                                   const DWARFFormValue &Val, unsigned AttrSize,
668                                   AttributesInfo &Info);
669 
670     /// Get the potential name and mangled name for the entity
671     /// described by \p Die and store them in \Info if they are not
672     /// already there.
673     /// \returns is a name was found.
674     bool getDIENames(const DWARFDie &Die, AttributesInfo &Info,
675                      OffsetsStringPool &StringPool, bool StripTemplate = false);
676 
677     uint32_t hashFullyQualifiedName(DWARFDie DIE, CompileUnit &U,
678                                     const DWARFFile &File,
679                                     int RecurseDepth = 0);
680 
681     /// Helper for cloneDIE.
682     void addObjCAccelerator(CompileUnit &Unit, const DIE *Die,
683                             DwarfStringPoolEntryRef Name,
684                             OffsetsStringPool &StringPool, bool SkipPubSection);
685   };
686 
687   /// Assign an abbreviation number to \p Abbrev
688   void assignAbbrev(DIEAbbrev &Abbrev);
689 
690   /// Compute and emit .debug_ranges section for \p Unit, and
691   /// patch the attributes referencing it.
692   void patchRangesForUnit(const CompileUnit &Unit, DWARFContext &Dwarf,
693                           const DWARFFile &File) const;
694 
695   /// Generate and emit the DW_AT_ranges attribute for a compile_unit if it had
696   /// one.
697   void generateUnitRanges(CompileUnit &Unit) const;
698 
699   /// Extract the line tables from the original dwarf, extract the relevant
700   /// parts according to the linked function ranges and emit the result in the
701   /// .debug_line section.
702   void patchLineTableForUnit(CompileUnit &Unit, DWARFContext &OrigDwarf,
703                              const DWARFFile &File);
704 
705   /// Emit the accelerator entries for \p Unit.
706   void emitAcceleratorEntriesForUnit(CompileUnit &Unit);
707   void emitDwarfAcceleratorEntriesForUnit(CompileUnit &Unit);
708   void emitAppleAcceleratorEntriesForUnit(CompileUnit &Unit);
709   void emitPubAcceleratorEntriesForUnit(CompileUnit &Unit);
710 
711   /// Patch the frame info for an object file and emit it.
712   void patchFrameInfoForObject(const DWARFFile &, RangesTy &Ranges,
713                                DWARFContext &, unsigned AddressSize);
714 
715   /// FoldingSet that uniques the abbreviations.
716   FoldingSet<DIEAbbrev> AbbreviationsSet;
717 
718   /// Storage for the unique Abbreviations.
719   /// This is passed to AsmPrinter::emitDwarfAbbrevs(), thus it cannot be
720   /// changed to a vector of unique_ptrs.
721   std::vector<std::unique_ptr<DIEAbbrev>> Abbreviations;
722 
723   /// DIELoc objects that need to be destructed (but not freed!).
724   std::vector<DIELoc *> DIELocs;
725 
726   /// DIEBlock objects that need to be destructed (but not freed!).
727   std::vector<DIEBlock *> DIEBlocks;
728 
729   /// Allocator used for all the DIEValue objects.
730   BumpPtrAllocator DIEAlloc;
731   /// @}
732 
733   DwarfEmitter *TheDwarfEmitter;
734   std::vector<LinkContext> ObjectContexts;
735 
736   unsigned MaxDwarfVersion = 0;
737   unsigned MinDwarfVersion = std::numeric_limits<unsigned>::max();
738 
739   bool AtLeastOneAppleAccelTable = false;
740   bool AtLeastOneDwarfAccelTable = false;
741 
742   /// The CIEs that have been emitted in the output section. The actual CIE
743   /// data serves a the key to this StringMap, this takes care of comparing the
744   /// semantics of CIEs defined in different object files.
745   StringMap<uint32_t> EmittedCIEs;
746 
747   /// Offset of the last CIE that has been emitted in the output
748   /// .debug_frame section.
749   uint32_t LastCIEOffset = 0;
750 
751   /// Apple accelerator tables.
752   AccelTable<DWARF5AccelTableStaticData> DebugNames;
753   AccelTable<AppleAccelTableStaticOffsetData> AppleNames;
754   AccelTable<AppleAccelTableStaticOffsetData> AppleNamespaces;
755   AccelTable<AppleAccelTableStaticOffsetData> AppleObjc;
756   AccelTable<AppleAccelTableStaticTypeData> AppleTypes;
757 
758   /// Mapping the PCM filename to the DwoId.
759   StringMap<uint64_t> ClangModules;
760 
761   DwarfLinkerClient DwarfLinkerClientID;
762 
763   std::function<StringRef(StringRef)> StringsTranslator = nullptr;
764 
765   /// linking options
766   struct DWARFLinkerOptions {
767     /// Generate processing log to the standard output.
768     bool Verbose = false;
769 
770     /// Print statistics.
771     bool Statistics = false;
772 
773     /// Verify the input DWARF.
774     bool VerifyInputDWARF = false;
775 
776     /// Skip emitting output
777     bool NoOutput = false;
778 
779     /// Do not unique types according to ODR
780     bool NoODR = false;
781 
782     /// Update
783     bool Update = false;
784 
785     /// Whether we want a static variable to force us to keep its enclosing
786     /// function.
787     bool KeepFunctionForStatic = false;
788 
789     /// Number of threads.
790     unsigned Threads = 1;
791 
792     /// The accelerator table kind
793     DwarfLinkerAccelTableKind TheAccelTableKind =
794         DwarfLinkerAccelTableKind::Default;
795 
796     /// Prepend path for the clang modules.
797     std::string PrependPath;
798 
799     // warning handler
800     messageHandler WarningHandler = nullptr;
801 
802     // error handler
803     messageHandler ErrorHandler = nullptr;
804 
805     objFileLoader ObjFileLoader = nullptr;
806 
807     /// A list of all .swiftinterface files referenced by the debug
808     /// info, mapping Module name to path on disk. The entries need to
809     /// be uniqued and sorted and there are only few entries expected
810     /// per compile unit, which is why this is a std::map.
811     /// this is dsymutil specific fag.
812     swiftInterfacesMap *ParseableSwiftInterfaces = nullptr;
813 
814     /// A list of remappings to apply to file paths.
815     objectPrefixMap *ObjectPrefixMap = nullptr;
816   } Options;
817 };
818 
819 } // end namespace llvm
820 
821 #endif // LLVM_DWARFLINKER_DWARFLINKER_H
822