LLVM  12.0.0git
DWARFLinker.h
Go to the documentation of this file.
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 
17 #include "llvm/MC/MCDwarf.h"
18 #include <map>
19 
20 namespace llvm {
21 
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.
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 
41  ObjFileAddressRange(uint64_t EndPC, int64_t Offset)
42  : HighPC(EndPC), Offset(Offset) {}
43 
44  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,
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,
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:
208  const std::vector<std::string> &Warnings)
209  : FileName(Name), Dwarf(Dwarf), Addresses(Addresses), Warnings(Warnings) {
210  }
211 
212  /// object file name.
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)>
225 typedef std::function<ErrorOr<DwarfFile &>(StringRef ContainerName,
226  StringRef Path)>
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:
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.
261  void setVerbosity(bool Verbose) { Options.Verbose = Verbose; }
262 
263  /// Print statistics to standard output.
264  void setStatistics(bool Statistics) { Options.Statistics = Statistics; }
265 
266  /// Do not emit linked dwarf info.
267  void setNoOutput(bool NoOut) { Options.NoOutput = NoOut; }
268 
269  /// Do not unique types according to ODR.
270  void setNoODR(bool NoODR) { Options.NoODR = NoODR; }
271 
272  /// update existing DWARF info(for the linked binary).
273  void setUpdate(bool Update) { Options.Update = Update; }
274 
275  /// Use specified number of threads for parallel files linking.
276  void setNumThreads(unsigned NumThreads) { Options.Threads = NumThreads; }
277 
278  /// Set kind of accelerator tables to be generated.
280  Options.TheAccelTableKind = Kind;
281  }
282 
283  /// Set prepend path for clang modules.
284  void setPrependPath(const std::string &Ppath) { Options.PrependPath = Ppath; }
285 
286  /// Set translator which would be used for strings.
287  void
289  this->StringsTranslator = StringsTranslator;
290  }
291 
292  /// Set estimated objects files amount, for preliminary data allocation.
293  void setEstimatedObjfilesAmount(unsigned ObjFilesNum) {
294  ObjectContexts.reserve(ObjFilesNum);
295  }
296 
297  /// Set warning handler which would be used to report warnings.
299  Options.WarningHandler = Handler;
300  }
301 
302  /// Set error handler which would be used to report errors.
304  Options.ErrorHandler = Handler;
305  }
306 
307  /// Set object files loader which would be used to load
308  /// additional objects for splitted dwarf.
310  Options.ObjFileLoader = Loader;
311  }
312 
313  /// Set map for Swift interfaces.
314  void setSwiftInterfacesMap(swiftInterfacesMap *Map) {
315  Options.ParseableSwiftInterfaces = Map;
316  }
317 
318  /// Set prefix map for objects.
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  WorklistItemType Type;
357  DWARFDie Die;
358  CompileUnit &CU;
359  unsigned Flags;
360  unsigned AncestorIdx = 0;
361  CompileUnit::DIEInfo *OtherInfo = nullptr;
362 
363  WorklistItem(DWARFDie Die, CompileUnit &CU, unsigned Flags,
364  WorklistItemType T = WorklistItemType::LookForDIEsToKeep)
365  : Type(T), Die(Die), CU(CU), Flags(Flags) {}
366 
367  WorklistItem(DWARFDie Die, CompileUnit &CU, WorklistItemType T,
368  CompileUnit::DIEInfo *OtherInfo = nullptr)
369  : Type(T), Die(Die), CU(CU), OtherInfo(OtherInfo) {}
370 
371  WorklistItem(unsigned AncestorIdx, CompileUnit &CU, unsigned Flags)
372  : Type(WorklistItemType::LookForParentDIEsToKeep), CU(CU), Flags(Flags),
373  AncestorIdx(AncestorIdx) {}
374  };
375 
376  /// returns true if we need to translate strings.
377  bool needToTranslateStrings() { return StringsTranslator != nullptr; }
378 
379  void reportWarning(const Twine &Warning, const DwarfFile &File,
380  const DWARFDie *DIE = nullptr) const {
381  if (Options.WarningHandler != nullptr)
382  Options.WarningHandler(Warning, File.FileName, DIE);
383  }
384 
385  void reportError(const Twine &Warning, const DwarfFile &File,
386  const DWARFDie *DIE = nullptr) const {
387  if (Options.ErrorHandler != nullptr)
388  Options.ErrorHandler(Warning, File.FileName, DIE);
389  }
390 
391  /// Remembers the oldest and newest DWARF version we've seen in a unit.
392  void updateDwarfVersion(unsigned Version) {
393  MaxDwarfVersion = std::max(MaxDwarfVersion, Version);
394  MinDwarfVersion = std::min(MinDwarfVersion, Version);
395  }
396 
397  /// Remembers the kinds of accelerator tables we've seen in a unit.
398  void updateAccelKind(DWARFContext &Dwarf);
399 
400  /// Emit warnings as Dwarf compile units to leave a trail after linking.
401  bool emitPaperTrailWarnings(const DwarfFile &File,
402  OffsetsStringPool &StringPool);
403 
404  void copyInvariantDebugSection(DWARFContext &Dwarf);
405 
406  /// Keeps track of data associated with one object during linking.
407  struct LinkContext {
408  DwarfFile &File;
409  UnitListTy CompileUnits;
410  bool Skip = false;
411 
412  LinkContext(DwarfFile &File) : File(File) {}
413 
414  /// Clear part of the context that's no longer needed when we're done with
415  /// the debug object.
416  void clear() {
417  CompileUnits.clear();
418  File.Addresses->clear();
419  }
420  };
421 
422  /// Called before emitting object data
423  void cleanupAuxiliarryData(LinkContext &Context);
424 
425  /// Look at the parent of the given DIE and decide whether they should be
426  /// kept.
427  void lookForParentDIEsToKeep(unsigned AncestorIdx, CompileUnit &CU,
428  unsigned Flags,
430 
431  /// Look at the children of the given DIE and decide whether they should be
432  /// kept.
433  void lookForChildDIEsToKeep(const DWARFDie &Die, CompileUnit &CU,
434  unsigned Flags,
436 
437  /// Look at DIEs referenced by the given DIE and decide whether they should be
438  /// kept. All DIEs referenced though attributes should be kept.
439  void lookForRefDIEsToKeep(const DWARFDie &Die, CompileUnit &CU,
440  unsigned Flags, const UnitListTy &Units,
441  const DwarfFile &File,
443 
444  /// \defgroup FindRootDIEs Find DIEs corresponding to Address map entries.
445  ///
446  /// @{
447  /// Recursively walk the \p DIE tree and look for DIEs to
448  /// keep. Store that information in \p CU's DIEInfo.
449  ///
450  /// The return value indicates whether the DIE is incomplete.
451  void lookForDIEsToKeep(AddressesMap &RelocMgr, RangesTy &Ranges,
452  const UnitListTy &Units, const DWARFDie &DIE,
453  const DwarfFile &File, CompileUnit &CU,
454  unsigned Flags);
455 
456  /// If this compile unit is really a skeleton CU that points to a
457  /// clang module, register it in ClangModules and return true.
458  ///
459  /// A skeleton CU is a CU without children, a DW_AT_gnu_dwo_name
460  /// pointing to the module, and a DW_AT_gnu_dwo_id with the module
461  /// hash.
462  bool registerModuleReference(DWARFDie CUDie, const DWARFUnit &Unit,
463  const DwarfFile &File,
465  UniquingStringPool &UniquingStringPoolStringPool,
466  DeclContextTree &ODRContexts,
467  uint64_t ModulesEndOffset, unsigned &UnitID,
468  bool IsLittleEndian, unsigned Indent = 0,
469  bool Quiet = false);
470 
471  /// Recursively add the debug info in this clang module .pcm
472  /// file (and all the modules imported by it in a bottom-up fashion)
473  /// to Units.
474  Error loadClangModule(DWARFDie CUDie, StringRef FilePath,
475  StringRef ModuleName, uint64_t DwoId,
476  const DwarfFile &File,
477  OffsetsStringPool &OffsetsStringPool,
479  DeclContextTree &ODRContexts, uint64_t ModulesEndOffset,
480  unsigned &UnitID, bool IsLittleEndian,
481  unsigned Indent = 0, bool Quiet = false);
482 
483  /// Mark the passed DIE as well as all the ones it depends on as kept.
484  void keepDIEAndDependencies(AddressesMap &RelocMgr, RangesTy &Ranges,
485  const UnitListTy &Units, const DWARFDie &DIE,
486  CompileUnit::DIEInfo &MyInfo,
487  const DwarfFile &File, CompileUnit &CU,
488  bool UseODR);
489 
490  unsigned shouldKeepDIE(AddressesMap &RelocMgr, RangesTy &Ranges,
491  const DWARFDie &DIE, const DwarfFile &File,
492  CompileUnit &Unit, CompileUnit::DIEInfo &MyInfo,
493  unsigned Flags);
494 
495  /// Check if a variable describing DIE should be kept.
496  /// \returns updated TraversalFlags.
497  unsigned shouldKeepVariableDIE(AddressesMap &RelocMgr, const DWARFDie &DIE,
498  CompileUnit &Unit,
499  CompileUnit::DIEInfo &MyInfo, unsigned Flags);
500 
501  unsigned shouldKeepSubprogramDIE(AddressesMap &RelocMgr, RangesTy &Ranges,
502  const DWARFDie &DIE, const DwarfFile &File,
503  CompileUnit &Unit,
504  CompileUnit::DIEInfo &MyInfo,
505  unsigned Flags);
506 
507  /// Resolve the DIE attribute reference that has been extracted in \p
508  /// RefValue. The resulting DIE might be in another CompileUnit which is
509  /// stored into \p ReferencedCU. \returns null if resolving fails for any
510  /// reason.
511  DWARFDie resolveDIEReference(const DwarfFile &File, const UnitListTy &Units,
512  const DWARFFormValue &RefValue,
513  const DWARFDie &DIE, CompileUnit *&RefCU);
514 
515  /// @}
516 
517  /// \defgroup Methods used to link the debug information
518  ///
519  /// @{
520 
521  struct DWARFLinkerOptions;
522 
523  class DIECloner {
525  DwarfEmitter *Emitter;
526  DwarfFile &ObjFile;
527 
528  /// Allocator used for all the DIEValue objects.
529  BumpPtrAllocator &DIEAlloc;
530 
531  std::vector<std::unique_ptr<CompileUnit>> &CompileUnits;
532 
533  bool Update;
534 
535  public:
536  DIECloner(DWARFLinker &Linker, DwarfEmitter *Emitter, DwarfFile &ObjFile,
537  BumpPtrAllocator &DIEAlloc,
538  std::vector<std::unique_ptr<CompileUnit>> &CompileUnits,
539  bool Update)
540  : Linker(Linker), Emitter(Emitter), ObjFile(ObjFile),
541  DIEAlloc(DIEAlloc), CompileUnits(CompileUnits), Update(Update) {}
542 
543  /// Recursively clone \p InputDIE into an tree of DIE objects
544  /// where useless (as decided by lookForDIEsToKeep()) bits have been
545  /// stripped out and addresses have been rewritten according to the
546  /// address map.
547  ///
548  /// \param OutOffset is the offset the cloned DIE in the output
549  /// compile unit.
550  /// \param PCOffset (while cloning a function scope) is the offset
551  /// applied to the entry point of the function to get the linked address.
552  /// \param Die the output DIE to use, pass NULL to create one.
553  /// \returns the root of the cloned tree or null if nothing was selected.
554  DIE *cloneDIE(const DWARFDie &InputDIE, const DwarfFile &File,
555  CompileUnit &U, OffsetsStringPool &StringPool,
556  int64_t PCOffset, uint32_t OutOffset, unsigned Flags,
557  bool IsLittleEndian, DIE *Die = nullptr);
558 
559  /// Construct the output DIE tree by cloning the DIEs we
560  /// chose to keep above. If there are no valid relocs, then there's
561  /// nothing to clone/emit.
562  uint64_t cloneAllCompileUnits(DWARFContext &DwarfContext,
563  const DwarfFile &File,
564  OffsetsStringPool &StringPool,
565  bool IsLittleEndian);
566 
567  private:
568  using AttributeSpec = DWARFAbbreviationDeclaration::AttributeSpec;
569 
570  /// Information gathered and exchanged between the various
571  /// clone*Attributes helpers about the attributes of a particular DIE.
572  struct AttributesInfo {
573  /// Names.
574  DwarfStringPoolEntryRef Name, MangledName, NameWithoutTemplate;
575 
576  /// Offsets in the string pool.
577  uint32_t NameOffset = 0;
578  uint32_t MangledNameOffset = 0;
579 
580  /// Value of AT_low_pc in the input DIE
581  uint64_t OrigLowPc = std::numeric_limits<uint64_t>::max();
582 
583  /// Value of AT_high_pc in the input DIE
584  uint64_t OrigHighPc = 0;
585 
586  /// Value of DW_AT_call_return_pc in the input DIE
587  uint64_t OrigCallReturnPc = 0;
588 
589  /// Value of DW_AT_call_pc in the input DIE
590  uint64_t OrigCallPc = 0;
591 
592  /// Offset to apply to PC addresses inside a function.
593  int64_t PCOffset = 0;
594 
595  /// Does the DIE have a low_pc attribute?
596  bool HasLowPc = false;
597 
598  /// Does the DIE have a ranges attribute?
599  bool HasRanges = false;
600 
601  /// Is this DIE only a declaration?
602  bool IsDeclaration = false;
603 
604  AttributesInfo() = default;
605  };
606 
607  /// Helper for cloneDIE.
608  unsigned cloneAttribute(DIE &Die, const DWARFDie &InputDIE,
609  const DwarfFile &File, CompileUnit &U,
610  OffsetsStringPool &StringPool,
611  const DWARFFormValue &Val,
612  const AttributeSpec AttrSpec, unsigned AttrSize,
613  AttributesInfo &AttrInfo, bool IsLittleEndian);
614 
615  /// Clone a string attribute described by \p AttrSpec and add
616  /// it to \p Die.
617  /// \returns the size of the new attribute.
618  unsigned cloneStringAttribute(DIE &Die, AttributeSpec AttrSpec,
619  const DWARFFormValue &Val, const DWARFUnit &U,
620  OffsetsStringPool &StringPool,
621  AttributesInfo &Info);
622 
623  /// Clone an attribute referencing another DIE and add
624  /// it to \p Die.
625  /// \returns the size of the new attribute.
626  unsigned cloneDieReferenceAttribute(DIE &Die, const DWARFDie &InputDIE,
627  AttributeSpec AttrSpec,
628  unsigned AttrSize,
629  const DWARFFormValue &Val,
630  const DwarfFile &File,
631  CompileUnit &Unit);
632 
633  /// Clone a DWARF expression that may be referencing another DIE.
634  void cloneExpression(DataExtractor &Data, DWARFExpression Expression,
635  const DwarfFile &File, CompileUnit &Unit,
636  SmallVectorImpl<uint8_t> &OutputBuffer);
637 
638  /// Clone an attribute referencing another DIE and add
639  /// it to \p Die.
640  /// \returns the size of the new attribute.
641  unsigned cloneBlockAttribute(DIE &Die, const DwarfFile &File,
642  CompileUnit &Unit, AttributeSpec AttrSpec,
643  const DWARFFormValue &Val, unsigned AttrSize,
644  bool IsLittleEndian);
645 
646  /// Clone an attribute referencing another DIE and add
647  /// it to \p Die.
648  /// \returns the size of the new attribute.
649  unsigned cloneAddressAttribute(DIE &Die, AttributeSpec AttrSpec,
650  const DWARFFormValue &Val,
651  const CompileUnit &Unit,
652  AttributesInfo &Info);
653 
654  /// Clone a scalar attribute and add it to \p Die.
655  /// \returns the size of the new attribute.
656  unsigned cloneScalarAttribute(DIE &Die, const DWARFDie &InputDIE,
657  const DwarfFile &File, CompileUnit &U,
658  AttributeSpec AttrSpec,
659  const DWARFFormValue &Val, unsigned AttrSize,
660  AttributesInfo &Info);
661 
662  /// Get the potential name and mangled name for the entity
663  /// described by \p Die and store them in \Info if they are not
664  /// already there.
665  /// \returns is a name was found.
666  bool getDIENames(const DWARFDie &Die, AttributesInfo &Info,
667  OffsetsStringPool &StringPool, bool StripTemplate = false);
668 
669  /// Create a copy of abbreviation Abbrev.
670  void copyAbbrev(const DWARFAbbreviationDeclaration &Abbrev, bool hasODR);
671 
672  uint32_t hashFullyQualifiedName(DWARFDie DIE, CompileUnit &U,
673  const DwarfFile &File,
674  int RecurseDepth = 0);
675 
676  /// Helper for cloneDIE.
677  void addObjCAccelerator(CompileUnit &Unit, const DIE *Die,
679  OffsetsStringPool &StringPool, bool SkipPubSection);
680  };
681 
682  /// Assign an abbreviation number to \p Abbrev
683  void assignAbbrev(DIEAbbrev &Abbrev);
684 
685  /// Compute and emit debug_ranges section for \p Unit, and
686  /// patch the attributes referencing it.
687  void patchRangesForUnit(const CompileUnit &Unit, DWARFContext &Dwarf,
688  const DwarfFile &File) const;
689 
690  /// Generate and emit the DW_AT_ranges attribute for a compile_unit if it had
691  /// one.
692  void generateUnitRanges(CompileUnit &Unit) const;
693 
694  /// Extract the line tables from the original dwarf, extract the relevant
695  /// parts according to the linked function ranges and emit the result in the
696  /// debug_line section.
697  void patchLineTableForUnit(CompileUnit &Unit, DWARFContext &OrigDwarf,
698  const DwarfFile &File);
699 
700  /// Emit the accelerator entries for \p Unit.
701  void emitAcceleratorEntriesForUnit(CompileUnit &Unit);
702  void emitDwarfAcceleratorEntriesForUnit(CompileUnit &Unit);
703  void emitAppleAcceleratorEntriesForUnit(CompileUnit &Unit);
704 
705  /// Patch the frame info for an object file and emit it.
706  void patchFrameInfoForObject(const DwarfFile &, RangesTy &Ranges,
707  DWARFContext &, unsigned AddressSize);
708 
709  /// FoldingSet that uniques the abbreviations.
710  FoldingSet<DIEAbbrev> AbbreviationsSet;
711 
712  /// Storage for the unique Abbreviations.
713  /// This is passed to AsmPrinter::emitDwarfAbbrevs(), thus it cannot be
714  /// changed to a vector of unique_ptrs.
715  std::vector<std::unique_ptr<DIEAbbrev>> Abbreviations;
716 
717  /// DIELoc objects that need to be destructed (but not freed!).
718  std::vector<DIELoc *> DIELocs;
719 
720  /// DIEBlock objects that need to be destructed (but not freed!).
721  std::vector<DIEBlock *> DIEBlocks;
722 
723  /// Allocator used for all the DIEValue objects.
724  BumpPtrAllocator DIEAlloc;
725  /// @}
726 
727  DwarfEmitter *TheDwarfEmitter;
728  std::vector<LinkContext> ObjectContexts;
729 
730  unsigned MaxDwarfVersion = 0;
731  unsigned MinDwarfVersion = std::numeric_limits<unsigned>::max();
732 
733  bool AtLeastOneAppleAccelTable = false;
734  bool AtLeastOneDwarfAccelTable = false;
735 
736  /// The CIEs that have been emitted in the output section. The actual CIE
737  /// data serves a the key to this StringMap, this takes care of comparing the
738  /// semantics of CIEs defined in different object files.
739  StringMap<uint32_t> EmittedCIEs;
740 
741  /// Offset of the last CIE that has been emitted in the output
742  /// debug_frame section.
743  uint32_t LastCIEOffset = 0;
744 
745  /// Apple accelerator tables.
751 
752  /// Mapping the PCM filename to the DwoId.
753  StringMap<uint64_t> ClangModules;
754 
755  DwarfLinkerClient DwarfLinkerClientID;
756 
757  std::function<StringRef(StringRef)> StringsTranslator = nullptr;
758 
759  /// linking options
760  struct DWARFLinkerOptions {
761  /// Generate processing log to the standard output.
762  bool Verbose = false;
763 
764  /// Print statistics.
765  bool Statistics = false;
766 
767  /// Skip emitting output
768  bool NoOutput = false;
769 
770  /// Do not unique types according to ODR
771  bool NoODR = false;
772 
773  /// Update
774  bool Update = false;
775 
776  /// Number of threads.
777  unsigned Threads = 1;
778 
779  /// The accelerator table kind
780  AccelTableKind TheAccelTableKind = AccelTableKind::Default;
781 
782  /// Prepend path for the clang modules.
783  std::string PrependPath;
784 
785  // warning handler
786  messageHandler WarningHandler = nullptr;
787 
788  // error handler
789  messageHandler ErrorHandler = nullptr;
790 
791  objFileLoader ObjFileLoader = nullptr;
792 
793  /// A list of all .swiftinterface files referenced by the debug
794  /// info, mapping Module name to path on disk. The entries need to
795  /// be uniqued and sorted and there are only few entries expected
796  /// per compile unit, which is why this is a std::map.
797  /// this is dsymutil specific fag.
798  swiftInterfacesMap *ParseableSwiftInterfaces = nullptr;
799 
800  /// A list of remappings to apply to file paths.
801  objectPrefixMap *ObjectPrefixMap = nullptr;
802  } Options;
803 };
804 
805 } // end namespace llvm
806 
807 #endif // LLVM_DWARFLINKER_DWARFLINKER_H
DWARFLinker(DwarfEmitter *Emitter, DwarfLinkerClient ClientID=DwarfLinkerClient::General)
Definition: DWARFLinker.h:247
void setVerbosity(bool Verbose)
A number of methods setting various linking options:
Definition: DWARFLinker.h:261
LLVMContext & Context
uint64_t HighPC
Function HighPC.
Definition: DWARFLinker.h:36
This class represents lattice values for constants.
Definition: AllocatorList.h:23
DEBUG_TYPE to vector
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
Stores all information relating to a compile unit, be it in its original instance in the object file ...
DWARF v5 .debug_names.
This class holds an abstract representation of an Accelerator Table, consisting of a sequence of buck...
Definition: AccelTable.h:196
std::vector< std::unique_ptr< CompileUnit > > UnitListTy
Definition: DWARFLinker.h:201
void setNoOutput(bool NoOut)
Do not emit linked dwarf info.
Definition: DWARFLinker.h:267
The core of the Dwarf linking logic.
Definition: DWARFLinker.h:245
AddressesMap represents information about valid addresses used by debug information.
Definition: DWARFLinker.h:54
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:80
std::function< ErrorOr< DwarfFile & >StringRef ContainerName, StringRef Path)> objFileLoader
Definition: DWARFLinker.h:227
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:43
void setUpdate(bool Update)
update existing DWARF info(for the linked binary).
Definition: DWARFLinker.h:273
std::function< void(const Twine &Warning, StringRef Context, const DWARFDie *DIE)> messageHandler
Definition: DWARFLinker.h:224
void setErrorHandler(messageHandler Handler)
Set error handler which would be used to report errors.
Definition: DWARFLinker.h:303
AccelTableKind
The kind of accelerator tables we should emit.
Definition: DWARFLinker.h:25
void setNoODR(bool NoODR)
Do not unique types according to ODR.
Definition: DWARFLinker.h:270
This class gives a tree-like API to the DenseMap that stores the DeclContext objects.
static fatal_error_handler_t ErrorHandler
Helper for making strong types.
void setObjectPrefixMap(objectPrefixMap *Map)
Set prefix map for objects.
Definition: DWARFLinker.h:319
This class provides the core functionality of linking in LLVM.
Definition: Linker.h:24
.apple_names, .apple_namespaces, .apple_types, .apple_objc.
void setAccelTableKind(AccelTableKind Kind)
Set kind of accelerator tables to be generated.
Definition: DWARFLinker.h:279
Analysis containing CSE Info
Definition: CSEInfo.cpp:25
void setWarningHandler(messageHandler Handler)
Set warning handler which would be used to report warnings.
Definition: DWARFLinker.h:298
std::map< std::string, std::string > objectPrefixMap
Definition: DWARFLinker.h:229
DwarfFile(StringRef Name, DWARFContext *Dwarf, AddressesMap *Addresses, const std::vector< std::string > &Warnings)
Definition: DWARFLinker.h:207
Utility class that carries the DWARF compile/type unit and the debug info entry in an object...
Definition: DWARFDie.h:43
int64_t Offset
Offset to apply to the linked address.
Definition: DWARFLinker.h:39
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition: ArrayRef.h:298
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:67
Instrumentation for Order File
A structured debug information entry.
Definition: DIE.h:723
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:305
void setEstimatedObjfilesAmount(unsigned ObjFilesNum)
Set estimated objects files amount, for preliminary data allocation.
Definition: DWARFLinker.h:293
ObjFileAddressRange(uint64_t EndPC, int64_t Offset)
Definition: DWARFLinker.h:41
void setPrependPath(const std::string &Ppath)
Set prepend path for clang modules.
Definition: DWARFLinker.h:284
FoldingSet - This template class is used to instantiate a specialized implementation of the folding s...
Definition: FoldingSet.h:493
std::map< std::string, std::string > swiftInterfacesMap
Definition: DWARFLinker.h:228
DwarfLinkerClient
Definition: DWARFLinker.h:22
static Error reportError(StringRef Message)
Align max(MaybeAlign Lhs, Align Rhs)
Definition: Alignment.h:350
void setNumThreads(unsigned NumThreads)
Use specified number of threads for parallel files linking.
Definition: DWARFLinker.h:276
DWARFContext This data structure is the top level entity that deals with dwarf debug information pars...
Definition: DWARFContext.h:53
AddressesMap * Addresses
helpful address information(list of valid address ranges, relocations).
Definition: DWARFLinker.h:217
Partial address range.
Definition: DWARFLinker.h:34
static void clear(coro::Shape &Shape)
Definition: Coroutines.cpp:225
String pool entry reference.
Dwarf for DWARF5 or later, Apple otherwise.
Dwarf abbreviation, describes the organization of a debug information object.
Definition: DIE.h:79
void setStringsTranslator(std::function< StringRef(StringRef)> StringsTranslator)
Set translator which would be used for strings.
Definition: DWARFLinker.h:288
virtual void clear()=0
Erases all data.
void setObjFileLoader(objFileLoader Loader)
Set object files loader which would be used to load additional objects for splitted dwarf...
Definition: DWARFLinker.h:309
std::map< uint64_t, ObjFileAddressRange > RangesTy
Map LowPC to ObjFileAddressRange.
Definition: DWARFLinker.h:48
void setStatistics(bool Statistics)
Print statistics to standard output.
Definition: DWARFLinker.h:264
void setSwiftInterfacesMap(swiftInterfacesMap *Map)
Set map for Swift interfaces.
Definition: DWARFLinker.h:314
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
A string table that doesn&#39;t need relocations.
print Print MemDeps of function
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
Class representing an expression and its matching format.
this class represents DWARF information for source file and it`s address map.
Definition: DWARFLinker.h:205
Information gathered about a DIE in the object file.
const uint64_t Version
Definition: InstrProf.h:996
const std::vector< std::string > & Warnings
warnings for object file.
Definition: DWARFLinker.h:219
StringRef FileName
object file name.
Definition: DWARFLinker.h:213
DwarfEmitter presents interface to generate all debug info tables.
Definition: DWARFLinker.h:94