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