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