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:
217 DWARFLinker(MessageHandlerTy ErrorHandler, MessageHandlerTy WarningHandler,
218 std::function<StringRef(StringRef)> StringsTranslator)
219 : StringsTranslator(StringsTranslator), ErrorHandler(ErrorHandler),
220 WarningHandler(WarningHandler) {}
221
222 static std::unique_ptr<DWARFLinker> createLinker(
223 MessageHandlerTy ErrorHandler, MessageHandlerTy WarningHandler,
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)
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))
static fatal_error_handler_t ErrorHandler
static LVOptions Options
Definition LVOptions.cpp:25
#define T
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...
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
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
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 class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:45
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
std::function< void( const Twine &Warning, StringRef Context, const DWARFDie *DIE)> MessageHandlerTy
AccelTableKind
The kind of accelerator tables to be emitted.
std::map< std::string, std::string > SwiftInterfacesMapTy
std::function< void(const DWARFFile &File, llvm::StringRef Output)> InputVerificationHandlerTy
This class stores values sequentually and assigns index to the each value.
Stores all information relating to a compile unit, be it in its original instance in the object file ...
void setStatistics(bool Statistics) override
Print statistics to standard output.
void setInputVerificationHandler(InputVerificationHandlerTy Handler) override
Set verification handler which would be used to report verification errors.
void setSwiftInterfacesMap(SwiftInterfacesMapTy *Map) override
Set map for Swift interfaces.
void setNumThreads(unsigned NumThreads) override
Use specified number of threads for parallel files linking.
void setAllowNonDeterministicOutput(bool) override
Allow generating valid, but non-deterministic output.
void setObjectPrefixMap(ObjectPrefixMapTy *Map) override
Set prefix map for objects.
void setKeepFunctionForStatic(bool KeepFunctionForStatic) override
Set whether to keep the enclosing function for a static variable.
DWARFLinker(MessageHandlerTy ErrorHandler, MessageHandlerTy WarningHandler, std::function< StringRef(StringRef)> StringsTranslator)
void setVerifyInputDWARF(bool Verify) override
Verify the input DWARF.
void addAccelTableKind(AccelTableKind Kind) override
Add kind of accelerator tables to be generated.
static std::unique_ptr< DWARFLinker > createLinker(MessageHandlerTy ErrorHandler, MessageHandlerTy WarningHandler, std::function< StringRef(StringRef)> StringsTranslator=nullptr)
void setNoODR(bool NoODR) override
Do not unique types according to ODR.
void setPrependPath(StringRef Ppath) override
Set prepend path for clang modules.
Error setTargetDWARFVersion(uint16_t TargetDWARFVersion) override
Set target DWARF version.
void setOutputDWARFEmitter(DwarfEmitter *Emitter)
Set output DWARF emitter.
void setUpdateIndexTablesOnly(bool Update) override
Update index tables only(do not modify rest of DWARF).
void setEstimatedObjfilesAmount(unsigned ObjFilesNum) override
Set estimated objects files amount, for preliminary data allocation.
void setVerbosity(bool Verbose) override
A number of methods setting various linking options:
This class gives a tree-like API to the DenseMap that stores the DeclContext objects.
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:
std::vector< std::unique_ptr< CompileUnit > > UnitListTy
IndexedValuesMap< uint64_t > DebugDieValuePool
Definition DWARFLinker.h:38
DenseMap< uint64_t, CompileUnit * > Offset2UnitMap
Definition DWARFLinker.h:37
std::function< void( const Twine &Warning, StringRef Context, const DWARFDie *DIE)> MessageHandlerTy
DebugSectionKind
List of tracked debug tables.
DWARFAbbreviationDeclaration::AttributeSpec AttributeSpec
This is an optimization pass for GlobalISel generic memory operations.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition Error.h:1305
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:1849
StrongType< NonRelocatableStringpool, OffsetsTag > OffsetsStringPool
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1879
std::vector< DWARFLocationExpression > DWARFLocationExpressionsVector
Represents a set of absolute location expressions.
Information gathered about a DIE in the object file.