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