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