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 /// The classic linker does not use a shared thread pool.
281 void setThreadPool(ThreadPoolInterface *Pool) override {}
282
283 /// Add kind of accelerator tables to be generated.
284 void addAccelTableKind(AccelTableKind Kind) override {
285 assert(!llvm::is_contained(Options.AccelTables, Kind));
286 Options.AccelTables.emplace_back(Kind);
287 }
288
289 /// Set prepend path for clang modules.
290 void setPrependPath(StringRef Ppath) override { Options.PrependPath = Ppath; }
291
292 /// Set estimated objects files amount, for preliminary data allocation.
293 void setEstimatedObjfilesAmount(unsigned ObjFilesNum) override {
294 ObjectContexts.reserve(ObjFilesNum);
295 }
296
297 /// Set verification handler which would be used to report verification
298 /// errors.
299 void
301 Options.InputVerificationHandler = Handler;
302 }
303
304 /// Set map for Swift interfaces.
306 Options.ParseableSwiftInterfaces = Map;
307 }
308
309 /// Set prefix map for objects.
311 Options.ObjectPrefixMap = Map;
312 }
313
314 /// Set target DWARF version.
315 Error setTargetDWARFVersion(uint16_t TargetDWARFVersion) override {
316 if ((TargetDWARFVersion < 1) || (TargetDWARFVersion > 5))
317 return createStringError(std::errc::invalid_argument,
318 "unsupported DWARF version: %d",
319 TargetDWARFVersion);
320
321 Options.TargetDWARFVersion = TargetDWARFVersion;
322 return Error::success();
323 }
324
325private:
326 /// Flags passed to DwarfLinker::lookForDIEsToKeep
327 enum TraversalFlags {
328 TF_Keep = 1 << 0, ///< Mark the traversed DIEs as kept.
329 TF_InFunctionScope = 1 << 1, ///< Current scope is a function scope.
330 TF_DependencyWalk = 1 << 2, ///< Walking the dependencies of a kept DIE.
331 TF_ParentWalk = 1 << 3, ///< Walking up the parents of a kept DIE.
332 TF_ODR = 1 << 4, ///< Use the ODR while keeping dependents.
333 TF_SkipPC = 1 << 5, ///< Skip all location attributes.
334 };
335
336 /// The distinct types of work performed by the work loop.
337 enum class WorklistItemType {
338 /// Given a DIE, look for DIEs to be kept.
339 LookForDIEsToKeep,
340 /// Given a DIE, look for children of this DIE to be kept.
341 LookForChildDIEsToKeep,
342 /// Given a DIE, look for DIEs referencing this DIE to be kept.
343 LookForRefDIEsToKeep,
344 /// Given a DIE, look for parent DIEs to be kept.
345 LookForParentDIEsToKeep,
346 /// Given a DIE, update its incompleteness based on whether its children are
347 /// incomplete.
348 UpdateChildIncompleteness,
349 /// Given a DIE, update its incompleteness based on whether the DIEs it
350 /// references are incomplete.
351 UpdateRefIncompleteness,
352 /// Given a DIE, mark it as ODR Canonical if applicable.
353 MarkODRCanonicalDie,
354 };
355
356 /// This class represents an item in the work list. The type defines what kind
357 /// of work needs to be performed when processing the current item. The flags
358 /// and info fields are optional based on the type.
359 struct WorklistItem {
360 DWARFDie Die;
361 WorklistItemType Type;
363 unsigned Flags;
364 union {
365 const unsigned AncestorIdx;
366 CompileUnit::DIEInfo *OtherInfo;
367 };
368
369 WorklistItem(DWARFDie Die, CompileUnit &CU, unsigned Flags,
370 WorklistItemType T = WorklistItemType::LookForDIEsToKeep)
371 : Die(Die), Type(T), CU(CU), Flags(Flags), AncestorIdx(0) {}
372
373 WorklistItem(DWARFDie Die, CompileUnit &CU, WorklistItemType T,
374 CompileUnit::DIEInfo *OtherInfo = nullptr)
375 : Die(Die), Type(T), CU(CU), Flags(0), OtherInfo(OtherInfo) {}
376
377 WorklistItem(unsigned AncestorIdx, CompileUnit &CU, unsigned Flags)
378 : Type(WorklistItemType::LookForParentDIEsToKeep), CU(CU), Flags(Flags),
379 AncestorIdx(AncestorIdx) {}
380 };
381
382 /// Verify the given DWARF file.
383 void verifyInput(const DWARFFile &File);
384
385 /// returns true if we need to translate strings.
386 bool needToTranslateStrings() { return StringsTranslator != nullptr; }
387
388 void reportWarning(const Twine &Warning, const DWARFFile &File,
389 const DWARFDie *DIE = nullptr) const {
390 if (WarningHandler != nullptr)
391 WarningHandler(Warning, File.FileName, DIE);
392 }
393
394 void reportError(const Twine &Warning, const DWARFFile &File,
395 const DWARFDie *DIE = nullptr) const {
396 if (ErrorHandler != nullptr)
397 ErrorHandler(Warning, File.FileName, DIE);
398 }
399
400 void copyInvariantDebugSection(DWARFContext &Dwarf);
401
402 /// Keep information for referenced clang module: already loaded DWARF info
403 /// of the clang module and a CompileUnit of the module.
404 struct RefModuleUnit {
405 RefModuleUnit(DWARFFile &File, std::unique_ptr<CompileUnit> Unit)
406 : File(File), Unit(std::move(Unit)) {}
407 RefModuleUnit(RefModuleUnit &&Other)
408 : File(Other.File), Unit(std::move(Other.Unit)) {}
409 RefModuleUnit(const RefModuleUnit &) = delete;
410
411 DWARFFile &File;
412 std::unique_ptr<CompileUnit> Unit;
413 };
414 using ModuleUnitListTy = std::vector<RefModuleUnit>;
415
416 /// Keeps track of data associated with one object during linking.
417 struct LinkContext {
418 DWARFFile &File;
419 UnitListTy CompileUnits;
420 ModuleUnitListTy ModuleUnits;
421 bool Skip = false;
422
423 LinkContext(DWARFFile &File) : File(File) {}
424
425 /// Clear part of the context that's no longer needed when we're done with
426 /// the debug object.
427 void clear() {
428 CompileUnits.clear();
429 ModuleUnits.clear();
430 File.unload();
431 }
432 };
433
434 /// Called before emitting object data
435 void cleanupAuxiliarryData(LinkContext &Context);
436
437 /// Look at the parent of the given DIE and decide whether they should be
438 /// kept.
439 void lookForParentDIEsToKeep(unsigned AncestorIdx, CompileUnit &CU,
440 unsigned Flags,
441 SmallVectorImpl<WorklistItem> &Worklist);
442
443 /// Look at the children of the given DIE and decide whether they should be
444 /// kept.
445 void lookForChildDIEsToKeep(const DWARFDie &Die, CompileUnit &CU,
446 unsigned Flags,
447 SmallVectorImpl<WorklistItem> &Worklist);
448
449 /// Look at DIEs referenced by the given DIE and decide whether they should be
450 /// kept. All DIEs referenced though attributes should be kept.
451 void lookForRefDIEsToKeep(const DWARFDie &Die, CompileUnit &CU,
452 unsigned Flags, const UnitListTy &Units,
453 const DWARFFile &File,
454 SmallVectorImpl<WorklistItem> &Worklist);
455
456 /// Mark context corresponding to the specified \p Die as having canonical
457 /// die, if applicable.
458 void markODRCanonicalDie(const DWARFDie &Die, CompileUnit &CU);
459
460 /// \defgroup FindRootDIEs Find DIEs corresponding to Address map entries.
461 ///
462 /// @{
463 /// Recursively walk the \p DIE tree and look for DIEs to
464 /// keep. Store that information in \p CU's DIEInfo.
465 ///
466 /// The return value indicates whether the DIE is incomplete.
467 void lookForDIEsToKeep(AddressesMap &RelocMgr, const UnitListTy &Units,
468 const DWARFDie &DIE, const DWARFFile &File,
469 CompileUnit &CU, unsigned Flags);
470
471 /// Check whether specified \p CUDie is a Clang module reference.
472 /// if \p Quiet is false then display error messages.
473 /// \return first == true if CUDie is a Clang module reference.
474 /// second == true if module is already loaded.
475 std::pair<bool, bool> isClangModuleRef(const DWARFDie &CUDie,
476 std::string &PCMFile,
477 LinkContext &Context, unsigned Indent,
478 bool Quiet);
479
480 /// If this compile unit is really a skeleton CU that points to a
481 /// clang module, register it in ClangModules and return true.
482 ///
483 /// A skeleton CU is a CU without children, a DW_AT_gnu_dwo_name
484 /// pointing to the module, and a DW_AT_gnu_dwo_id with the module
485 /// hash.
486 bool registerModuleReference(const DWARFDie &CUDie, LinkContext &Context,
487 ObjFileLoaderTy Loader,
488 CompileUnitHandlerTy OnCUDieLoaded,
489 unsigned Indent = 0);
490
491 /// Recursively add the debug info in this clang module .pcm
492 /// file (and all the modules imported by it in a bottom-up fashion)
493 /// to ModuleUnits.
494 Error loadClangModule(ObjFileLoaderTy Loader, const DWARFDie &CUDie,
495 const std::string &PCMFile, LinkContext &Context,
496 CompileUnitHandlerTy OnCUDieLoaded,
497 unsigned Indent = 0);
498
499 /// Clone specified Clang module unit \p Unit.
500 Error cloneModuleUnit(LinkContext &Context, RefModuleUnit &Unit,
501 DeclContextTree &ODRContexts,
502 OffsetsStringPool &DebugStrPool,
503 OffsetsStringPool &DebugLineStrPool,
504 DebugDieValuePool &StringOffsetPool,
505 unsigned Indent = 0);
506
507 unsigned shouldKeepDIE(AddressesMap &RelocMgr, const DWARFDie &DIE,
508 const DWARFFile &File, CompileUnit &Unit,
509 CompileUnit::DIEInfo &MyInfo, unsigned Flags);
510
511 /// This function checks whether variable has DWARF expression containing
512 /// operation referencing live address(f.e. DW_OP_addr, DW_OP_addrx...).
513 /// \returns first is true if the expression has an operation referencing an
514 /// address.
515 /// second is the relocation adjustment value if the live address is
516 /// referenced.
517 std::pair<bool, std::optional<int64_t>>
518 getVariableRelocAdjustment(AddressesMap &RelocMgr, const DWARFDie &DIE);
519
520 /// Check if a variable describing DIE should be kept.
521 /// \returns updated TraversalFlags.
522 unsigned shouldKeepVariableDIE(AddressesMap &RelocMgr, const DWARFDie &DIE,
523 CompileUnit::DIEInfo &MyInfo, unsigned Flags);
524
525 unsigned shouldKeepSubprogramDIE(AddressesMap &RelocMgr, const DWARFDie &DIE,
526 const DWARFFile &File, CompileUnit &Unit,
527 CompileUnit::DIEInfo &MyInfo,
528 unsigned Flags);
529
530 /// Resolve the DIE attribute reference that has been extracted in \p
531 /// RefValue. The resulting DIE might be in another CompileUnit which is
532 /// stored into \p ReferencedCU. \returns null if resolving fails for any
533 /// reason.
534 DWARFDie resolveDIEReference(const DWARFFile &File, const UnitListTy &Units,
535 const DWARFFormValue &RefValue,
536 const DWARFDie &DIE, CompileUnit *&RefCU);
537
538 /// @}
539
540 /// \defgroup Methods used to link the debug information
541 ///
542 /// @{
543
544 struct DWARFLinkerOptions;
545
546 class DIECloner {
547 DWARFLinker &Linker;
548 DwarfEmitter *Emitter;
549 DWARFFile &ObjFile;
550 OffsetsStringPool &DebugStrPool;
551 OffsetsStringPool &DebugLineStrPool;
552 DebugDieValuePool &StringOffsetPool;
553 DebugDieValuePool AddrPool;
554
555 /// Allocator used for all the DIEValue objects.
556 BumpPtrAllocator &DIEAlloc;
557
558 std::vector<std::unique_ptr<CompileUnit>> &CompileUnits;
559
560 /// Keeps mapping from offset of the macro table to corresponding
561 /// compile unit.
562 Offset2UnitMap UnitMacroMap;
563
564 bool Update;
565
566 public:
567 DIECloner(DWARFLinker &Linker, DwarfEmitter *Emitter, DWARFFile &ObjFile,
568 BumpPtrAllocator &DIEAlloc,
569 std::vector<std::unique_ptr<CompileUnit>> &CompileUnits,
570 bool Update, OffsetsStringPool &DebugStrPool,
571 OffsetsStringPool &DebugLineStrPool,
572 DebugDieValuePool &StringOffsetPool)
573 : Linker(Linker), Emitter(Emitter), ObjFile(ObjFile),
574 DebugStrPool(DebugStrPool), DebugLineStrPool(DebugLineStrPool),
575 StringOffsetPool(StringOffsetPool), DIEAlloc(DIEAlloc),
576 CompileUnits(CompileUnits), Update(Update) {}
577
578 /// Recursively clone \p InputDIE into an tree of DIE objects
579 /// where useless (as decided by lookForDIEsToKeep()) bits have been
580 /// stripped out and addresses have been rewritten according to the
581 /// address map.
582 ///
583 /// \param OutOffset is the offset the cloned DIE in the output
584 /// compile unit.
585 /// \param PCOffset (while cloning a function scope) is the offset
586 /// applied to the entry point of the function to get the linked address.
587 /// \param Die the output DIE to use, pass NULL to create one.
588 /// \returns the root of the cloned tree or null if nothing was selected.
589 LLVM_ABI DIE *cloneDIE(const DWARFDie &InputDIE, const DWARFFile &File,
590 CompileUnit &U, int64_t PCOffset, uint32_t OutOffset,
591 unsigned Flags, bool IsLittleEndian,
592 DIE *Die = nullptr);
593
594 /// Construct the output DIE tree by cloning the DIEs we
595 /// chose to keep above. If there are no valid relocs, then there's
596 /// nothing to clone/emit.
597 LLVM_ABI Expected<uint64_t> cloneAllCompileUnits(DWARFContext &DwarfContext,
598 const DWARFFile &File,
599 bool IsLittleEndian);
600
601 /// Emit the .debug_addr section for the \p Unit.
602 LLVM_ABI Error emitDebugAddrSection(CompileUnit &Unit,
603 const uint16_t DwarfVersion) const;
604
605 using ExpressionHandlerRef = function_ref<void(
606 SmallVectorImpl<uint8_t> &, SmallVectorImpl<uint8_t> &,
607 int64_t AddrRelocAdjustment)>;
608
609 /// Compute and emit debug locations (.debug_loc, .debug_loclists)
610 /// for \p Unit, patch the attributes referencing it.
611 LLVM_ABI Error generateUnitLocations(CompileUnit &Unit,
612 const DWARFFile &File,
613 ExpressionHandlerRef ExprHandler);
614
615 private:
616 using AttributeSpec = DWARFAbbreviationDeclaration::AttributeSpec;
617
618 /// Information gathered and exchanged between the various
619 /// clone*Attributes helpers about the attributes of a particular DIE.
620 struct AttributesInfo {
621 /// Names.
622 DwarfStringPoolEntryRef Name, MangledName, NameWithoutTemplate;
623
624 /// Offsets in the string pool.
625 uint32_t NameOffset = 0;
626 uint32_t MangledNameOffset = 0;
627
628 /// Offset to apply to PC addresses inside a function.
629 int64_t PCOffset = 0;
630
631 /// Does the DIE have a low_pc attribute?
632 bool HasLowPc = false;
633
634 /// Does the DIE have a ranges attribute?
635 bool HasRanges = false;
636
637 /// Is this DIE only a declaration?
638 bool IsDeclaration = false;
639
640 /// Is there a DW_AT_str_offsets_base in the CU?
641 bool AttrStrOffsetBaseSeen = false;
642
643 /// Is there a DW_AT_APPLE_origin in the CU?
644 bool HasAppleOrigin = false;
645
646 AttributesInfo() = default;
647 };
648
649 /// Helper for cloneDIE.
650 unsigned cloneAttribute(DIE &Die, const DWARFDie &InputDIE,
651 const DWARFFile &File, CompileUnit &U,
652 const DWARFFormValue &Val,
653 const AttributeSpec AttrSpec, unsigned AttrSize,
654 AttributesInfo &AttrInfo, bool IsLittleEndian);
655
656 /// Clone a string attribute described by \p AttrSpec and add
657 /// it to \p Die.
658 /// \returns the size of the new attribute.
659 unsigned cloneStringAttribute(DIE &Die, AttributeSpec AttrSpec,
660 const DWARFFormValue &Val, const DWARFUnit &U,
661 AttributesInfo &Info);
662
663 /// Clone an attribute referencing another DIE and add
664 /// it to \p Die.
665 /// \returns the size of the new attribute.
666 unsigned cloneDieReferenceAttribute(DIE &Die, const DWARFDie &InputDIE,
667 AttributeSpec AttrSpec,
668 unsigned AttrSize,
669 const DWARFFormValue &Val,
670 const DWARFFile &File,
671 CompileUnit &Unit);
672
673 /// Clone a DWARF expression that may be referencing another DIE.
674 void cloneExpression(DataExtractor &Data, DWARFExpression Expression,
675 const DWARFFile &File, CompileUnit &Unit,
676 SmallVectorImpl<uint8_t> &OutputBuffer,
677 int64_t AddrRelocAdjustment, bool IsLittleEndian);
678
679 /// Clone an attribute referencing another DIE and add
680 /// it to \p Die.
681 /// \returns the size of the new attribute.
682 unsigned cloneBlockAttribute(DIE &Die, const DWARFDie &InputDIE,
683 const DWARFFile &File, CompileUnit &Unit,
684 AttributeSpec AttrSpec,
685 const DWARFFormValue &Val,
686 bool IsLittleEndian);
687
688 /// Clone an attribute referencing another DIE and add
689 /// it to \p Die.
690 /// \returns the size of the new attribute.
691 unsigned cloneAddressAttribute(DIE &Die, const DWARFDie &InputDIE,
692 AttributeSpec AttrSpec, unsigned AttrSize,
693 const DWARFFormValue &Val,
694 const CompileUnit &Unit,
695 AttributesInfo &Info);
696
697 /// Clone a scalar attribute and add it to \p Die.
698 /// \returns the size of the new attribute.
699 unsigned cloneScalarAttribute(DIE &Die, const DWARFDie &InputDIE,
700 const DWARFFile &File, CompileUnit &U,
701 AttributeSpec AttrSpec,
702 const DWARFFormValue &Val, unsigned AttrSize,
703 AttributesInfo &Info);
704
705 /// Get the potential name and mangled name for the entity
706 /// described by \p Die and store them in \Info if they are not
707 /// already there.
708 /// \returns is a name was found.
709 bool getDIENames(const DWARFDie &Die, AttributesInfo &Info,
710 OffsetsStringPool &StringPool, const DWARFFile &File,
711 CompileUnit &Unit, bool StripTemplate = false);
712
713 llvm::StringRef getCanonicalDIEName(DWARFDie Die, const DWARFFile &File,
714 CompileUnit *Unit);
715
716 uint32_t hashFullyQualifiedName(DWARFDie DIE, CompileUnit &U,
717 const DWARFFile &File,
718 int RecurseDepth = 0);
719
720 /// Helper for cloneDIE.
721 void addObjCAccelerator(CompileUnit &Unit, const DIE *Die,
722 DwarfStringPoolEntryRef Name,
723 OffsetsStringPool &StringPool, bool SkipPubSection);
724
725 void rememberUnitForMacroOffset(CompileUnit &Unit);
726
727 /// Clone and emit the line table for the specified \p Unit.
728 /// Translate directories and file names if necessary.
729 /// Relocate address ranges.
730 Error generateLineTableForUnit(CompileUnit &Unit);
731 };
732
733 /// Assign an abbreviation number to \p Abbrev
734 void assignAbbrev(DIEAbbrev &Abbrev);
735
736 /// Compute and emit debug ranges(.debug_aranges, .debug_ranges,
737 /// .debug_rnglists) for \p Unit, patch the attributes referencing it.
738 Error generateUnitRanges(CompileUnit &Unit, const DWARFFile &File,
739 DebugDieValuePool &AddrPool) const;
740
741 /// Emit the accelerator entries for \p Unit.
742 void emitAcceleratorEntriesForUnit(CompileUnit &Unit);
743
744 /// Patch the frame info for an object file and emit it.
745 void patchFrameInfoForObject(LinkContext &Context);
746
747 /// FoldingSet that uniques the abbreviations.
748 FoldingSet<DIEAbbrev> AbbreviationsSet;
749
750 /// Storage for the unique Abbreviations.
751 /// This is passed to AsmPrinter::emitDwarfAbbrevs(), thus it cannot be
752 /// changed to a vector of unique_ptrs.
753 std::vector<std::unique_ptr<DIEAbbrev>> Abbreviations;
754
755 /// DIELoc objects that need to be destructed (but not freed!).
756 std::vector<DIELoc *> DIELocs;
757
758 /// DIEBlock objects that need to be destructed (but not freed!).
759 std::vector<DIEBlock *> DIEBlocks;
760
761 /// Allocator used for all the DIEValue objects.
762 BumpPtrAllocator DIEAlloc;
763 /// @}
764
765 DwarfEmitter *TheDwarfEmitter = nullptr;
766 std::vector<LinkContext> ObjectContexts;
767
768 /// The CIEs that have been emitted in the output section. The actual CIE
769 /// data serves a the key to this StringMap, this takes care of comparing the
770 /// semantics of CIEs defined in different object files.
771 StringMap<uint32_t> EmittedCIEs;
772
773 /// Offset of the last CIE that has been emitted in the output
774 /// .debug_frame section.
775 uint32_t LastCIEOffset = 0;
776
777 /// Apple accelerator tables.
778 DWARF5AccelTable DebugNames;
779 AccelTable<AppleAccelTableStaticOffsetData> AppleNames;
780 AccelTable<AppleAccelTableStaticOffsetData> AppleNamespaces;
781 AccelTable<AppleAccelTableStaticOffsetData> AppleObjc;
782 AccelTable<AppleAccelTableStaticTypeData> AppleTypes;
783
784 /// Mapping the PCM filename to the DwoId.
785 StringMap<uint64_t> ClangModules;
786
787 std::function<StringRef(StringRef)> StringsTranslator = nullptr;
788
789 /// A unique ID that identifies each compile unit.
790 unsigned UniqueUnitID = 0;
791
792 // error handler
794
795 // warning handler
796 MessageHandlerTy WarningHandler = nullptr;
797
798 /// linking options
799 struct DWARFLinkerOptions {
800 /// DWARF version for the output.
801 uint16_t TargetDWARFVersion = 0;
802
803 /// Generate processing log to the standard output.
804 bool Verbose = false;
805
806 /// Print statistics.
807 bool Statistics = false;
808
809 /// Verify the input DWARF.
810 bool VerifyInputDWARF = false;
811
812 /// Do not unique types according to ODR
813 bool NoODR = false;
814
815 /// Update
816 bool Update = false;
817
818 /// Whether we want a static variable to force us to keep its enclosing
819 /// function.
820 bool KeepFunctionForStatic = false;
821
822 /// Number of threads.
823 unsigned Threads = 1;
824
825 /// The accelerator table kinds
826 SmallVector<AccelTableKind, 1> AccelTables;
827
828 /// Prepend path for the clang modules.
829 std::string PrependPath;
830
831 // input verification handler
832 InputVerificationHandlerTy InputVerificationHandler = nullptr;
833
834 /// A list of all .swiftinterface files referenced by the debug
835 /// info, mapping Module name to path on disk. The entries need to
836 /// be uniqued and sorted and there are only few entries expected
837 /// per compile unit, which is why this is a std::map.
838 /// this is dsymutil specific fag.
839 SwiftInterfacesMapTy *ParseableSwiftInterfaces = nullptr;
840
841 /// A list of remappings to apply to file paths.
842 ObjectPrefixMapTy *ObjectPrefixMap = nullptr;
843 } Options;
844};
845
846} // end of namespace classic
847} // end of namespace dwarf_linker
848} // end of namespace llvm
849
850#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:215
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.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
This defines the abstract base interface for a ThreadPool allowing asynchronous parallel execution on...
Definition ThreadPool.h:51
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.
void setThreadPool(ThreadPoolInterface *Pool) override
The classic linker does not use a shared thread pool.
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:1917
StrongType< NonRelocatableStringpool, OffsetsTag > OffsetsStringPool
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1947
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:397
std::vector< DWARFLocationExpression > DWARFLocationExpressionsVector
Represents a set of absolute location expressions.
Information gathered about a DIE in the object file.