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