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