LLVM 23.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 /// 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(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(ObjFilesNum);
292 }
293
294 /// Set verification handler which would be used to report verification
295 /// errors.
296 void
298 Options.InputVerificationHandler = Handler;
299 }
300
301 /// Set map for Swift interfaces.
303 Options.ParseableSwiftInterfaces = Map;
304 }
305
306 /// Set prefix map for objects.
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(std::errc::invalid_argument,
315 "unsupported DWARF version: %d",
316 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;
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 LLVM_ABI DIE *cloneDIE(const DWARFDie &InputDIE, const DWARFFile &File,
587 CompileUnit &U, int64_t PCOffset, uint32_t OutOffset,
588 unsigned Flags, bool IsLittleEndian,
589 DIE *Die = nullptr);
590
591 /// Construct the output DIE tree by cloning the DIEs we
592 /// chose to keep above. If there are no valid relocs, then there's
593 /// nothing to clone/emit.
594 LLVM_ABI Expected<uint64_t> cloneAllCompileUnits(DWARFContext &DwarfContext,
595 const DWARFFile &File,
596 bool IsLittleEndian);
597
598 /// Emit the .debug_addr section for the \p Unit.
599 LLVM_ABI Error emitDebugAddrSection(CompileUnit &Unit,
600 const uint16_t DwarfVersion) const;
601
602 using ExpressionHandlerRef = function_ref<void(
603 SmallVectorImpl<uint8_t> &, SmallVectorImpl<uint8_t> &,
604 int64_t AddrRelocAdjustment)>;
605
606 /// Compute and emit debug locations (.debug_loc, .debug_loclists)
607 /// for \p Unit, patch the attributes referencing it.
608 LLVM_ABI Error generateUnitLocations(CompileUnit &Unit,
609 const DWARFFile &File,
610 ExpressionHandlerRef ExprHandler);
611
612 private:
613 using AttributeSpec = DWARFAbbreviationDeclaration::AttributeSpec;
614
615 /// Information gathered and exchanged between the various
616 /// clone*Attributes helpers about the attributes of a particular DIE.
617 struct AttributesInfo {
618 /// Names.
619 DwarfStringPoolEntryRef Name, MangledName, NameWithoutTemplate;
620
621 /// Offsets in the string pool.
622 uint32_t NameOffset = 0;
623 uint32_t MangledNameOffset = 0;
624
625 /// Offset to apply to PC addresses inside a function.
626 int64_t PCOffset = 0;
627
628 /// Does the DIE have a low_pc attribute?
629 bool HasLowPc = false;
630
631 /// Does the DIE have a ranges attribute?
632 bool HasRanges = false;
633
634 /// Is this DIE only a declaration?
635 bool IsDeclaration = false;
636
637 /// Is there a DW_AT_str_offsets_base in the CU?
638 bool AttrStrOffsetBaseSeen = false;
639
640 /// Is there a DW_AT_APPLE_origin in the CU?
641 bool HasAppleOrigin = false;
642
643 AttributesInfo() = default;
644 };
645
646 /// Helper for cloneDIE.
647 unsigned cloneAttribute(DIE &Die, const DWARFDie &InputDIE,
648 const DWARFFile &File, CompileUnit &U,
649 const DWARFFormValue &Val,
650 const AttributeSpec AttrSpec, unsigned AttrSize,
651 AttributesInfo &AttrInfo, bool IsLittleEndian);
652
653 /// Clone a string attribute described by \p AttrSpec and add
654 /// it to \p Die.
655 /// \returns the size of the new attribute.
656 unsigned cloneStringAttribute(DIE &Die, AttributeSpec AttrSpec,
657 const DWARFFormValue &Val, const DWARFUnit &U,
658 AttributesInfo &Info);
659
660 /// Clone an attribute referencing another DIE and add
661 /// it to \p Die.
662 /// \returns the size of the new attribute.
663 unsigned cloneDieReferenceAttribute(DIE &Die, const DWARFDie &InputDIE,
664 AttributeSpec AttrSpec,
665 unsigned AttrSize,
666 const DWARFFormValue &Val,
667 const DWARFFile &File,
668 CompileUnit &Unit);
669
670 /// Clone a DWARF expression that may be referencing another DIE.
671 void cloneExpression(DataExtractor &Data, DWARFExpression Expression,
672 const DWARFFile &File, CompileUnit &Unit,
673 SmallVectorImpl<uint8_t> &OutputBuffer,
674 int64_t AddrRelocAdjustment, bool IsLittleEndian);
675
676 /// Clone an attribute referencing another DIE and add
677 /// it to \p Die.
678 /// \returns the size of the new attribute.
679 unsigned cloneBlockAttribute(DIE &Die, const DWARFDie &InputDIE,
680 const DWARFFile &File, CompileUnit &Unit,
681 AttributeSpec AttrSpec,
682 const DWARFFormValue &Val,
683 bool IsLittleEndian);
684
685 /// Clone an attribute referencing another DIE and add
686 /// it to \p Die.
687 /// \returns the size of the new attribute.
688 unsigned cloneAddressAttribute(DIE &Die, const DWARFDie &InputDIE,
689 AttributeSpec AttrSpec, unsigned AttrSize,
690 const DWARFFormValue &Val,
691 const CompileUnit &Unit,
692 AttributesInfo &Info);
693
694 /// Clone a scalar attribute and add it to \p Die.
695 /// \returns the size of the new attribute.
696 unsigned cloneScalarAttribute(DIE &Die, const DWARFDie &InputDIE,
697 const DWARFFile &File, CompileUnit &U,
698 AttributeSpec AttrSpec,
699 const DWARFFormValue &Val, unsigned AttrSize,
700 AttributesInfo &Info);
701
702 /// Get the potential name and mangled name for the entity
703 /// described by \p Die and store them in \Info if they are not
704 /// already there.
705 /// \returns is a name was found.
706 bool getDIENames(const DWARFDie &Die, AttributesInfo &Info,
707 OffsetsStringPool &StringPool, const DWARFFile &File,
708 CompileUnit &Unit, bool StripTemplate = false);
709
710 llvm::StringRef getCanonicalDIEName(DWARFDie Die, const DWARFFile &File,
711 CompileUnit *Unit);
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 Error 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 Error 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)
#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:46
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 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 Error emitDwarfDebugRangeListFragment(const CompileUnit &Unit, const AddressRanges &LinkedRanges, PatchLocation Patch, DebugDieValuePool &AddrPool)=0
Emit debug ranges (.debug_ranges, .debug_rnglists) fragment.
virtual uint64_t getDebugMacroSectionSize() const =0
Returns size of generated .debug_macro section.
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 Error 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:1321
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:1916
StrongType< NonRelocatableStringpool, OffsetsTag > OffsetsStringPool
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1946
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:383
std::vector< DWARFLocationExpression > DWARFLocationExpressionsVector
Represents a set of absolute location expressions.
Information gathered about a DIE in the object file.