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