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