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