147
|
1 //===- tools/dsymutil/DwarfLinker.h - Dwarf debug info linker ---*- 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_TOOLS_DSYMUTIL_DWARFLINKER_H
|
|
10 #define LLVM_TOOLS_DSYMUTIL_DWARFLINKER_H
|
|
11
|
|
12 #include "BinaryHolder.h"
|
|
13 #include "CompileUnit.h"
|
|
14 #include "DebugMap.h"
|
|
15 #include "DeclContext.h"
|
|
16 #include "DwarfStreamer.h"
|
|
17 #include "LinkUtils.h"
|
|
18 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
|
19
|
|
20 namespace llvm {
|
|
21 namespace dsymutil {
|
|
22
|
|
23 /// Partial address range for debug map objects. Besides an offset, only the
|
|
24 /// HighPC is stored. The structure is stored in a map where the LowPC is the
|
|
25 /// key.
|
|
26 struct DebugMapObjectRange {
|
|
27 /// Function HighPC.
|
|
28 uint64_t HighPC;
|
|
29 /// Offset to apply to the linked address.
|
|
30 int64_t Offset;
|
|
31
|
|
32 DebugMapObjectRange(uint64_t EndPC, int64_t Offset)
|
|
33 : HighPC(EndPC), Offset(Offset) {}
|
|
34
|
|
35 DebugMapObjectRange() : HighPC(0), Offset(0) {}
|
|
36 };
|
|
37
|
|
38 /// Map LowPC to DebugMapObjectRange.
|
|
39 using RangesTy = std::map<uint64_t, DebugMapObjectRange>;
|
|
40 using UnitListTy = std::vector<std::unique_ptr<CompileUnit>>;
|
|
41
|
|
42 /// The core of the Dwarf linking logic.
|
|
43 ///
|
|
44 /// The link of the dwarf information from the object files will be
|
|
45 /// driven by the selection of 'root DIEs', which are DIEs that
|
|
46 /// describe variables or functions that are present in the linked
|
|
47 /// binary (and thus have entries in the debug map). All the debug
|
|
48 /// information that will be linked (the DIEs, but also the line
|
|
49 /// tables, ranges, ...) is derived from that set of root DIEs.
|
|
50 ///
|
|
51 /// The root DIEs are identified because they contain relocations that
|
|
52 /// correspond to a debug map entry at specific places (the low_pc for
|
|
53 /// a function, the location for a variable). These relocations are
|
|
54 /// called ValidRelocs in the DwarfLinker and are gathered as a very
|
|
55 /// first step when we start processing a DebugMapObject.
|
|
56 class DwarfLinker {
|
|
57 public:
|
|
58 DwarfLinker(raw_fd_ostream &OutFile, BinaryHolder &BinHolder,
|
|
59 LinkOptions Options)
|
|
60 : OutFile(OutFile), BinHolder(BinHolder), Options(std::move(Options)) {}
|
|
61
|
|
62 /// Link the contents of the DebugMap.
|
|
63 bool link(const DebugMap &);
|
|
64
|
|
65 void reportWarning(const Twine &Warning, const DebugMapObject &DMO,
|
|
66 const DWARFDie *DIE = nullptr) const;
|
|
67
|
|
68 private:
|
|
69 /// Remembers the oldest and newest DWARF version we've seen in a unit.
|
|
70 void updateDwarfVersion(unsigned Version) {
|
|
71 MaxDwarfVersion = std::max(MaxDwarfVersion, Version);
|
|
72 MinDwarfVersion = std::min(MinDwarfVersion, Version);
|
|
73 }
|
|
74
|
|
75 /// Remembers the kinds of accelerator tables we've seen in a unit.
|
|
76 void updateAccelKind(DWARFContext &Dwarf);
|
|
77
|
|
78 /// Emit warnings as Dwarf compile units to leave a trail after linking.
|
|
79 bool emitPaperTrailWarnings(const DebugMapObject &DMO, const DebugMap &Map,
|
|
80 OffsetsStringPool &StringPool);
|
|
81
|
|
82 /// Keeps track of relocations.
|
|
83 class RelocationManager {
|
|
84 struct ValidReloc {
|
|
85 uint64_t Offset;
|
|
86 uint32_t Size;
|
|
87 uint64_t Addend;
|
|
88 const DebugMapObject::DebugMapEntry *Mapping;
|
|
89
|
|
90 ValidReloc(uint64_t Offset, uint32_t Size, uint64_t Addend,
|
|
91 const DebugMapObject::DebugMapEntry *Mapping)
|
|
92 : Offset(Offset), Size(Size), Addend(Addend), Mapping(Mapping) {}
|
|
93
|
|
94 bool operator<(const ValidReloc &RHS) const {
|
|
95 return Offset < RHS.Offset;
|
|
96 }
|
|
97 };
|
|
98
|
|
99 const DwarfLinker &Linker;
|
|
100
|
|
101 /// The valid relocations for the current DebugMapObject.
|
|
102 /// This vector is sorted by relocation offset.
|
|
103 std::vector<ValidReloc> ValidRelocs;
|
|
104
|
|
105 /// Index into ValidRelocs of the next relocation to consider. As we walk
|
|
106 /// the DIEs in acsending file offset and as ValidRelocs is sorted by file
|
|
107 /// offset, keeping this index up to date is all we have to do to have a
|
|
108 /// cheap lookup during the root DIE selection and during DIE cloning.
|
|
109 unsigned NextValidReloc = 0;
|
|
110
|
|
111 public:
|
|
112 RelocationManager(DwarfLinker &Linker) : Linker(Linker) {}
|
|
113
|
|
114 bool hasValidRelocs() const { return !ValidRelocs.empty(); }
|
|
115
|
|
116 /// Reset the NextValidReloc counter.
|
|
117 void resetValidRelocs() { NextValidReloc = 0; }
|
|
118
|
|
119 /// \defgroup FindValidRelocations Translate debug map into a list
|
|
120 /// of relevant relocations
|
|
121 ///
|
|
122 /// @{
|
|
123 bool findValidRelocsInDebugInfo(const object::ObjectFile &Obj,
|
|
124 const DebugMapObject &DMO);
|
|
125
|
|
126 bool findValidRelocs(const object::SectionRef &Section,
|
|
127 const object::ObjectFile &Obj,
|
|
128 const DebugMapObject &DMO);
|
|
129
|
|
130 void findValidRelocsMachO(const object::SectionRef &Section,
|
|
131 const object::MachOObjectFile &Obj,
|
|
132 const DebugMapObject &DMO);
|
|
133 /// @}
|
|
134
|
|
135 bool hasValidRelocation(uint64_t StartOffset, uint64_t EndOffset,
|
|
136 CompileUnit::DIEInfo &Info);
|
|
137
|
|
138 bool applyValidRelocs(MutableArrayRef<char> Data, uint64_t BaseOffset,
|
|
139 bool IsLittleEndian);
|
|
140 };
|
|
141
|
|
142 /// Keeps track of data associated with one object during linking.
|
|
143 struct LinkContext {
|
|
144 DebugMapObject &DMO;
|
|
145 const object::ObjectFile *ObjectFile;
|
|
146 RelocationManager RelocMgr;
|
|
147 std::unique_ptr<DWARFContext> DwarfContext;
|
|
148 RangesTy Ranges;
|
|
149 UnitListTy CompileUnits;
|
|
150
|
|
151 LinkContext(const DebugMap &Map, DwarfLinker &Linker, DebugMapObject &DMO)
|
|
152 : DMO(DMO), RelocMgr(Linker) {
|
|
153 // Swift ASTs are not object files.
|
|
154 if (DMO.getType() == MachO::N_AST) {
|
|
155 ObjectFile = nullptr;
|
|
156 return;
|
|
157 }
|
|
158 auto ErrOrObj = Linker.loadObject(DMO, Map);
|
|
159 ObjectFile = ErrOrObj ? &*ErrOrObj : nullptr;
|
|
160 DwarfContext = ObjectFile ? DWARFContext::create(*ObjectFile) : nullptr;
|
|
161 }
|
|
162
|
|
163 /// Clear part of the context that's no longer needed when we're done with
|
|
164 /// the debug object.
|
|
165 void Clear() {
|
|
166 DwarfContext.reset(nullptr);
|
|
167 CompileUnits.clear();
|
|
168 Ranges.clear();
|
|
169 }
|
|
170 };
|
|
171
|
|
172 /// Called at the start of a debug object link.
|
|
173 void startDebugObject(LinkContext &Context);
|
|
174
|
|
175 /// Called at the end of a debug object link.
|
|
176 void endDebugObject(LinkContext &Context);
|
|
177
|
|
178 /// \defgroup FindRootDIEs Find DIEs corresponding to debug map entries.
|
|
179 ///
|
|
180 /// @{
|
|
181 /// Recursively walk the \p DIE tree and look for DIEs to
|
|
182 /// keep. Store that information in \p CU's DIEInfo.
|
|
183 ///
|
|
184 /// The return value indicates whether the DIE is incomplete.
|
|
185 void lookForDIEsToKeep(RelocationManager &RelocMgr, RangesTy &Ranges,
|
|
186 const UnitListTy &Units, const DWARFDie &DIE,
|
|
187 const DebugMapObject &DMO, CompileUnit &CU,
|
|
188 unsigned Flags);
|
|
189
|
|
190 /// If this compile unit is really a skeleton CU that points to a
|
|
191 /// clang module, register it in ClangModules and return true.
|
|
192 ///
|
|
193 /// A skeleton CU is a CU without children, a DW_AT_gnu_dwo_name
|
|
194 /// pointing to the module, and a DW_AT_gnu_dwo_id with the module
|
|
195 /// hash.
|
|
196 bool registerModuleReference(DWARFDie CUDie, const DWARFUnit &Unit,
|
|
197 DebugMap &ModuleMap, const DebugMapObject &DMO,
|
|
198 RangesTy &Ranges,
|
|
199 OffsetsStringPool &OffsetsStringPool,
|
|
200 UniquingStringPool &UniquingStringPoolStringPool,
|
|
201 DeclContextTree &ODRContexts,
|
|
202 uint64_t ModulesEndOffset, unsigned &UnitID,
|
|
203 bool IsLittleEndian, unsigned Indent = 0,
|
|
204 bool Quiet = false);
|
|
205
|
|
206 /// Recursively add the debug info in this clang module .pcm
|
|
207 /// file (and all the modules imported by it in a bottom-up fashion)
|
|
208 /// to Units.
|
|
209 Error loadClangModule(DWARFDie CUDie, StringRef FilePath,
|
|
210 StringRef ModuleName, uint64_t DwoId,
|
|
211 DebugMap &ModuleMap, const DebugMapObject &DMO,
|
|
212 RangesTy &Ranges, OffsetsStringPool &OffsetsStringPool,
|
|
213 UniquingStringPool &UniquingStringPool,
|
|
214 DeclContextTree &ODRContexts, uint64_t ModulesEndOffset,
|
|
215 unsigned &UnitID, bool IsLittleEndian,
|
|
216 unsigned Indent = 0, bool Quiet = false);
|
|
217
|
|
218 /// Flags passed to DwarfLinker::lookForDIEsToKeep
|
|
219 enum TraversalFlags {
|
|
220 TF_Keep = 1 << 0, ///< Mark the traversed DIEs as kept.
|
|
221 TF_InFunctionScope = 1 << 1, ///< Current scope is a function scope.
|
|
222 TF_DependencyWalk = 1 << 2, ///< Walking the dependencies of a kept DIE.
|
|
223 TF_ParentWalk = 1 << 3, ///< Walking up the parents of a kept DIE.
|
|
224 TF_ODR = 1 << 4, ///< Use the ODR while keeping dependents.
|
|
225 TF_SkipPC = 1 << 5, ///< Skip all location attributes.
|
|
226 };
|
|
227
|
|
228 /// Mark the passed DIE as well as all the ones it depends on as kept.
|
|
229 void keepDIEAndDependencies(RelocationManager &RelocMgr, RangesTy &Ranges,
|
|
230 const UnitListTy &Units, const DWARFDie &DIE,
|
|
231 CompileUnit::DIEInfo &MyInfo,
|
|
232 const DebugMapObject &DMO, CompileUnit &CU,
|
|
233 bool UseODR);
|
|
234
|
|
235 unsigned shouldKeepDIE(RelocationManager &RelocMgr, RangesTy &Ranges,
|
|
236 const DWARFDie &DIE, const DebugMapObject &DMO,
|
|
237 CompileUnit &Unit, CompileUnit::DIEInfo &MyInfo,
|
|
238 unsigned Flags);
|
|
239
|
|
240 /// Check if a variable describing DIE should be kept.
|
|
241 /// \returns updated TraversalFlags.
|
|
242 unsigned shouldKeepVariableDIE(RelocationManager &RelocMgr,
|
|
243 const DWARFDie &DIE, CompileUnit &Unit,
|
|
244 CompileUnit::DIEInfo &MyInfo, unsigned Flags);
|
|
245
|
|
246 unsigned shouldKeepSubprogramDIE(RelocationManager &RelocMgr,
|
|
247 RangesTy &Ranges, const DWARFDie &DIE,
|
|
248 const DebugMapObject &DMO, CompileUnit &Unit,
|
|
249 CompileUnit::DIEInfo &MyInfo,
|
|
250 unsigned Flags);
|
|
251
|
|
252 bool hasValidRelocation(uint32_t StartOffset, uint32_t EndOffset,
|
|
253 CompileUnit::DIEInfo &Info);
|
|
254 /// @}
|
|
255
|
|
256 /// \defgroup Linking Methods used to link the debug information
|
|
257 ///
|
|
258 /// @{
|
|
259
|
|
260 class DIECloner {
|
|
261 DwarfLinker &Linker;
|
|
262 RelocationManager &RelocMgr;
|
|
263
|
|
264 /// Allocator used for all the DIEValue objects.
|
|
265 BumpPtrAllocator &DIEAlloc;
|
|
266
|
|
267 std::vector<std::unique_ptr<CompileUnit>> &CompileUnits;
|
|
268 LinkOptions Options;
|
|
269
|
|
270 public:
|
|
271 DIECloner(DwarfLinker &Linker, RelocationManager &RelocMgr,
|
|
272 BumpPtrAllocator &DIEAlloc,
|
|
273 std::vector<std::unique_ptr<CompileUnit>> &CompileUnits,
|
|
274 LinkOptions &Options)
|
|
275 : Linker(Linker), RelocMgr(RelocMgr), DIEAlloc(DIEAlloc),
|
|
276 CompileUnits(CompileUnits), Options(Options) {}
|
|
277
|
|
278 /// Recursively clone \p InputDIE into an tree of DIE objects
|
|
279 /// where useless (as decided by lookForDIEsToKeep()) bits have been
|
|
280 /// stripped out and addresses have been rewritten according to the
|
|
281 /// debug map.
|
|
282 ///
|
|
283 /// \param OutOffset is the offset the cloned DIE in the output
|
|
284 /// compile unit.
|
|
285 /// \param PCOffset (while cloning a function scope) is the offset
|
|
286 /// applied to the entry point of the function to get the linked address.
|
|
287 /// \param Die the output DIE to use, pass NULL to create one.
|
|
288 /// \returns the root of the cloned tree or null if nothing was selected.
|
|
289 DIE *cloneDIE(const DWARFDie &InputDIE, const DebugMapObject &DMO,
|
|
290 CompileUnit &U, OffsetsStringPool &StringPool,
|
|
291 int64_t PCOffset, uint32_t OutOffset, unsigned Flags,
|
|
292 bool IsLittleEndian, DIE *Die = nullptr);
|
|
293
|
|
294 /// Construct the output DIE tree by cloning the DIEs we
|
|
295 /// chose to keep above. If there are no valid relocs, then there's
|
|
296 /// nothing to clone/emit.
|
|
297 void cloneAllCompileUnits(DWARFContext &DwarfContext,
|
|
298 const DebugMapObject &DMO, RangesTy &Ranges,
|
|
299 OffsetsStringPool &StringPool,
|
|
300 bool IsLittleEndian);
|
|
301
|
|
302 private:
|
|
303 using AttributeSpec = DWARFAbbreviationDeclaration::AttributeSpec;
|
|
304
|
|
305 /// Information gathered and exchanged between the various
|
|
306 /// clone*Attributes helpers about the attributes of a particular DIE.
|
|
307 struct AttributesInfo {
|
|
308 /// Names.
|
|
309 DwarfStringPoolEntryRef Name, MangledName, NameWithoutTemplate;
|
|
310
|
|
311 /// Offsets in the string pool.
|
|
312 uint32_t NameOffset = 0;
|
|
313 uint32_t MangledNameOffset = 0;
|
|
314
|
|
315 /// Value of AT_low_pc in the input DIE
|
|
316 uint64_t OrigLowPc = std::numeric_limits<uint64_t>::max();
|
|
317
|
|
318 /// Value of AT_high_pc in the input DIE
|
|
319 uint64_t OrigHighPc = 0;
|
|
320
|
|
321 /// Offset to apply to PC addresses inside a function.
|
|
322 int64_t PCOffset = 0;
|
|
323
|
|
324 /// Does the DIE have a low_pc attribute?
|
|
325 bool HasLowPc = false;
|
|
326
|
|
327 /// Does the DIE have a ranges attribute?
|
|
328 bool HasRanges = false;
|
|
329
|
|
330 /// Is this DIE only a declaration?
|
|
331 bool IsDeclaration = false;
|
|
332
|
|
333 AttributesInfo() = default;
|
|
334 };
|
|
335
|
|
336 /// Helper for cloneDIE.
|
|
337 unsigned cloneAttribute(DIE &Die, const DWARFDie &InputDIE,
|
|
338 const DebugMapObject &DMO, CompileUnit &U,
|
|
339 OffsetsStringPool &StringPool,
|
|
340 const DWARFFormValue &Val,
|
|
341 const AttributeSpec AttrSpec, unsigned AttrSize,
|
|
342 AttributesInfo &AttrInfo, bool IsLittleEndian);
|
|
343
|
|
344 /// Clone a string attribute described by \p AttrSpec and add
|
|
345 /// it to \p Die.
|
|
346 /// \returns the size of the new attribute.
|
|
347 unsigned cloneStringAttribute(DIE &Die, AttributeSpec AttrSpec,
|
|
348 const DWARFFormValue &Val, const DWARFUnit &U,
|
|
349 OffsetsStringPool &StringPool,
|
|
350 AttributesInfo &Info);
|
|
351
|
|
352 /// Clone an attribute referencing another DIE and add
|
|
353 /// it to \p Die.
|
|
354 /// \returns the size of the new attribute.
|
|
355 unsigned cloneDieReferenceAttribute(DIE &Die, const DWARFDie &InputDIE,
|
|
356 AttributeSpec AttrSpec,
|
|
357 unsigned AttrSize,
|
|
358 const DWARFFormValue &Val,
|
|
359 const DebugMapObject &DMO,
|
|
360 CompileUnit &Unit);
|
|
361
|
|
362 /// Clone a DWARF expression that may be referencing another DIE.
|
|
363 void cloneExpression(DataExtractor &Data, DWARFExpression Expression,
|
|
364 const DebugMapObject &DMO, CompileUnit &Unit,
|
|
365 SmallVectorImpl<uint8_t> &OutputBuffer);
|
|
366
|
|
367 /// Clone an attribute referencing another DIE and add
|
|
368 /// it to \p Die.
|
|
369 /// \returns the size of the new attribute.
|
|
370 unsigned cloneBlockAttribute(DIE &Die, const DebugMapObject &DMO,
|
|
371 CompileUnit &Unit, AttributeSpec AttrSpec,
|
|
372 const DWARFFormValue &Val, unsigned AttrSize,
|
|
373 bool IsLittleEndian);
|
|
374
|
|
375 /// Clone an attribute referencing another DIE and add
|
|
376 /// it to \p Die.
|
|
377 /// \returns the size of the new attribute.
|
|
378 unsigned cloneAddressAttribute(DIE &Die, AttributeSpec AttrSpec,
|
|
379 const DWARFFormValue &Val,
|
|
380 const CompileUnit &Unit,
|
|
381 AttributesInfo &Info);
|
|
382
|
|
383 /// Clone a scalar attribute and add it to \p Die.
|
|
384 /// \returns the size of the new attribute.
|
|
385 unsigned cloneScalarAttribute(DIE &Die, const DWARFDie &InputDIE,
|
|
386 const DebugMapObject &DMO, CompileUnit &U,
|
|
387 AttributeSpec AttrSpec,
|
|
388 const DWARFFormValue &Val, unsigned AttrSize,
|
|
389 AttributesInfo &Info);
|
|
390
|
|
391 /// Get the potential name and mangled name for the entity
|
|
392 /// described by \p Die and store them in \Info if they are not
|
|
393 /// already there.
|
|
394 /// \returns is a name was found.
|
|
395 bool getDIENames(const DWARFDie &Die, AttributesInfo &Info,
|
|
396 OffsetsStringPool &StringPool, bool StripTemplate = false);
|
|
397
|
|
398 /// Create a copy of abbreviation Abbrev.
|
|
399 void copyAbbrev(const DWARFAbbreviationDeclaration &Abbrev, bool hasODR);
|
|
400
|
|
401 uint32_t hashFullyQualifiedName(DWARFDie DIE, CompileUnit &U,
|
|
402 const DebugMapObject &DMO,
|
|
403 int RecurseDepth = 0);
|
|
404
|
|
405 /// Helper for cloneDIE.
|
|
406 void addObjCAccelerator(CompileUnit &Unit, const DIE *Die,
|
|
407 DwarfStringPoolEntryRef Name,
|
|
408 OffsetsStringPool &StringPool, bool SkipPubSection);
|
|
409 };
|
|
410
|
|
411 /// Assign an abbreviation number to \p Abbrev
|
|
412 void AssignAbbrev(DIEAbbrev &Abbrev);
|
|
413
|
|
414 /// Compute and emit debug_ranges section for \p Unit, and
|
|
415 /// patch the attributes referencing it.
|
|
416 void patchRangesForUnit(const CompileUnit &Unit, DWARFContext &Dwarf,
|
|
417 const DebugMapObject &DMO) const;
|
|
418
|
|
419 /// Generate and emit the DW_AT_ranges attribute for a compile_unit if it had
|
|
420 /// one.
|
|
421 void generateUnitRanges(CompileUnit &Unit) const;
|
|
422
|
|
423 /// Extract the line tables from the original dwarf, extract the relevant
|
|
424 /// parts according to the linked function ranges and emit the result in the
|
|
425 /// debug_line section.
|
|
426 void patchLineTableForUnit(CompileUnit &Unit, DWARFContext &OrigDwarf,
|
|
427 RangesTy &Ranges, const DebugMapObject &DMO);
|
|
428
|
|
429 /// Emit the accelerator entries for \p Unit.
|
|
430 void emitAcceleratorEntriesForUnit(CompileUnit &Unit);
|
|
431 void emitDwarfAcceleratorEntriesForUnit(CompileUnit &Unit);
|
|
432 void emitAppleAcceleratorEntriesForUnit(CompileUnit &Unit);
|
|
433
|
|
434 /// Patch the frame info for an object file and emit it.
|
|
435 void patchFrameInfoForObject(const DebugMapObject &, RangesTy &Ranges,
|
|
436 DWARFContext &, unsigned AddressSize);
|
|
437
|
|
438 /// FoldingSet that uniques the abbreviations.
|
|
439 FoldingSet<DIEAbbrev> AbbreviationsSet;
|
|
440
|
|
441 /// Storage for the unique Abbreviations.
|
|
442 /// This is passed to AsmPrinter::emitDwarfAbbrevs(), thus it cannot be
|
|
443 /// changed to a vector of unique_ptrs.
|
|
444 std::vector<std::unique_ptr<DIEAbbrev>> Abbreviations;
|
|
445
|
|
446 /// DIELoc objects that need to be destructed (but not freed!).
|
|
447 std::vector<DIELoc *> DIELocs;
|
|
448
|
|
449 /// DIEBlock objects that need to be destructed (but not freed!).
|
|
450 std::vector<DIEBlock *> DIEBlocks;
|
|
451
|
|
452 /// Allocator used for all the DIEValue objects.
|
|
453 BumpPtrAllocator DIEAlloc;
|
|
454 /// @}
|
|
455
|
|
456 /// \defgroup Helpers Various helper methods.
|
|
457 ///
|
|
458 /// @{
|
|
459 bool createStreamer(const Triple &TheTriple, raw_fd_ostream &OutFile);
|
|
460
|
|
461 /// Attempt to load a debug object from disk.
|
|
462 ErrorOr<const object::ObjectFile &> loadObject(const DebugMapObject &Obj,
|
|
463 const DebugMap &Map);
|
|
464 /// @}
|
|
465
|
|
466 raw_fd_ostream &OutFile;
|
|
467 BinaryHolder &BinHolder;
|
|
468 LinkOptions Options;
|
|
469 std::unique_ptr<DwarfStreamer> Streamer;
|
|
470 uint64_t OutputDebugInfoSize;
|
|
471
|
|
472 unsigned MaxDwarfVersion = 0;
|
|
473 unsigned MinDwarfVersion = std::numeric_limits<unsigned>::max();
|
|
474
|
|
475 bool AtLeastOneAppleAccelTable = false;
|
|
476 bool AtLeastOneDwarfAccelTable = false;
|
|
477
|
|
478 /// The CIEs that have been emitted in the output section. The actual CIE
|
|
479 /// data serves a the key to this StringMap, this takes care of comparing the
|
|
480 /// semantics of CIEs defined in different object files.
|
|
481 StringMap<uint32_t> EmittedCIEs;
|
|
482
|
|
483 /// Offset of the last CIE that has been emitted in the output
|
|
484 /// debug_frame section.
|
|
485 uint32_t LastCIEOffset = 0;
|
|
486
|
|
487 /// Apple accelerator tables.
|
|
488 AccelTable<DWARF5AccelTableStaticData> DebugNames;
|
|
489 AccelTable<AppleAccelTableStaticOffsetData> AppleNames;
|
|
490 AccelTable<AppleAccelTableStaticOffsetData> AppleNamespaces;
|
|
491 AccelTable<AppleAccelTableStaticOffsetData> AppleObjc;
|
|
492 AccelTable<AppleAccelTableStaticTypeData> AppleTypes;
|
|
493
|
|
494 /// Mapping the PCM filename to the DwoId.
|
|
495 StringMap<uint64_t> ClangModules;
|
|
496
|
|
497 /// A list of all .swiftinterface files referenced by the debug
|
|
498 /// info, mapping Module name to path on disk. The entries need to
|
|
499 /// be uniqued and sorted and there are only few entries expected
|
|
500 /// per compile unit, which is why this is a std::map.
|
|
501 std::map<std::string, std::string> ParseableSwiftInterfaces;
|
|
502
|
|
503 bool ModuleCacheHintDisplayed = false;
|
|
504 bool ArchiveHintDisplayed = false;
|
|
505 };
|
|
506
|
|
507 } // end namespace dsymutil
|
|
508 } // end namespace llvm
|
|
509
|
|
510 #endif // LLVM_TOOLS_DSYMUTIL_DWARFLINKER_H
|