Mercurial > hg > CbC > CbC_llvm
comparison tools/dsymutil/DwarfLinker.cpp @ 147:c2174574ed3a
LLVM 10
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 14 Aug 2019 16:55:33 +0900 |
parents | 3a76565eade5 |
children |
comparison
equal
deleted
inserted
replaced
134:3a76565eade5 | 147:c2174574ed3a |
---|---|
1 //===- tools/dsymutil/DwarfLinker.cpp - Dwarf debug info linker -----------===// | 1 //===- tools/dsymutil/DwarfLinker.cpp - Dwarf debug info linker -----------===// |
2 // | 2 // |
3 // The LLVM Linker | 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 // | 4 // See https://llvm.org/LICENSE.txt for license information. |
5 // This file is distributed under the University of Illinois Open Source | 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 // License. See LICENSE.TXT for details. | |
7 // | 6 // |
8 //===----------------------------------------------------------------------===// | 7 //===----------------------------------------------------------------------===// |
9 | 8 |
9 #include "DwarfLinker.h" | |
10 #include "BinaryHolder.h" | 10 #include "BinaryHolder.h" |
11 #include "DebugMap.h" | 11 #include "DebugMap.h" |
12 #include "DeclContext.h" | |
13 #include "DwarfStreamer.h" | |
12 #include "MachOUtils.h" | 14 #include "MachOUtils.h" |
13 #include "NonRelocatableStringpool.h" | 15 #include "NonRelocatableStringpool.h" |
14 #include "dsymutil.h" | 16 #include "dsymutil.h" |
15 #include "llvm/ADT/ArrayRef.h" | 17 #include "llvm/ADT/ArrayRef.h" |
18 #include "llvm/ADT/BitVector.h" | |
16 #include "llvm/ADT/DenseMap.h" | 19 #include "llvm/ADT/DenseMap.h" |
17 #include "llvm/ADT/DenseMapInfo.h" | 20 #include "llvm/ADT/DenseMapInfo.h" |
18 #include "llvm/ADT/DenseSet.h" | 21 #include "llvm/ADT/DenseSet.h" |
19 #include "llvm/ADT/FoldingSet.h" | 22 #include "llvm/ADT/FoldingSet.h" |
20 #include "llvm/ADT/Hashing.h" | 23 #include "llvm/ADT/Hashing.h" |
49 #include "llvm/MC/MCCodeEmitter.h" | 52 #include "llvm/MC/MCCodeEmitter.h" |
50 #include "llvm/MC/MCContext.h" | 53 #include "llvm/MC/MCContext.h" |
51 #include "llvm/MC/MCDwarf.h" | 54 #include "llvm/MC/MCDwarf.h" |
52 #include "llvm/MC/MCInstrInfo.h" | 55 #include "llvm/MC/MCInstrInfo.h" |
53 #include "llvm/MC/MCObjectFileInfo.h" | 56 #include "llvm/MC/MCObjectFileInfo.h" |
57 #include "llvm/MC/MCObjectWriter.h" | |
54 #include "llvm/MC/MCRegisterInfo.h" | 58 #include "llvm/MC/MCRegisterInfo.h" |
55 #include "llvm/MC/MCSection.h" | 59 #include "llvm/MC/MCSection.h" |
56 #include "llvm/MC/MCStreamer.h" | 60 #include "llvm/MC/MCStreamer.h" |
57 #include "llvm/MC/MCSubtargetInfo.h" | 61 #include "llvm/MC/MCSubtargetInfo.h" |
58 #include "llvm/MC/MCTargetOptions.h" | 62 #include "llvm/MC/MCTargetOptions.h" |
59 #include "llvm/MC/MCTargetOptionsCommandFlags.def" | |
60 #include "llvm/Object/MachO.h" | 63 #include "llvm/Object/MachO.h" |
61 #include "llvm/Object/ObjectFile.h" | 64 #include "llvm/Object/ObjectFile.h" |
62 #include "llvm/Object/SymbolicFile.h" | 65 #include "llvm/Object/SymbolicFile.h" |
63 #include "llvm/Support/Allocator.h" | 66 #include "llvm/Support/Allocator.h" |
64 #include "llvm/Support/Casting.h" | 67 #include "llvm/Support/Casting.h" |
73 #include "llvm/Support/LEB128.h" | 76 #include "llvm/Support/LEB128.h" |
74 #include "llvm/Support/MathExtras.h" | 77 #include "llvm/Support/MathExtras.h" |
75 #include "llvm/Support/MemoryBuffer.h" | 78 #include "llvm/Support/MemoryBuffer.h" |
76 #include "llvm/Support/Path.h" | 79 #include "llvm/Support/Path.h" |
77 #include "llvm/Support/TargetRegistry.h" | 80 #include "llvm/Support/TargetRegistry.h" |
81 #include "llvm/Support/ThreadPool.h" | |
78 #include "llvm/Support/ToolOutputFile.h" | 82 #include "llvm/Support/ToolOutputFile.h" |
83 #include "llvm/Support/WithColor.h" | |
79 #include "llvm/Support/raw_ostream.h" | 84 #include "llvm/Support/raw_ostream.h" |
80 #include "llvm/Target/TargetMachine.h" | 85 #include "llvm/Target/TargetMachine.h" |
81 #include "llvm/Target/TargetOptions.h" | 86 #include "llvm/Target/TargetOptions.h" |
82 #include <algorithm> | 87 #include <algorithm> |
83 #include <cassert> | 88 #include <cassert> |
96 #include <vector> | 101 #include <vector> |
97 | 102 |
98 namespace llvm { | 103 namespace llvm { |
99 namespace dsymutil { | 104 namespace dsymutil { |
100 | 105 |
101 namespace { | |
102 | |
103 /// Retrieve the section named \a SecName in \a Obj. | |
104 /// | |
105 /// To accommodate for platform discrepancies, the name passed should be | |
106 /// (for example) 'debug_info' to match either '__debug_info' or '.debug_info'. | |
107 /// This function will strip the initial platform-specific characters. | |
108 static Optional<object::SectionRef> | |
109 getSectionByName(const object::ObjectFile &Obj, StringRef SecName) { | |
110 for (const object::SectionRef &Section : Obj.sections()) { | |
111 StringRef SectionName; | |
112 Section.getName(SectionName); | |
113 SectionName = SectionName.substr(SectionName.find_first_not_of("._")); | |
114 if (SectionName != SecName) | |
115 continue; | |
116 return Section; | |
117 } | |
118 return None; | |
119 } | |
120 | |
121 template <typename KeyT, typename ValT> | |
122 using HalfOpenIntervalMap = | |
123 IntervalMap<KeyT, ValT, IntervalMapImpl::NodeSizer<KeyT, ValT>::LeafSize, | |
124 IntervalMapHalfOpenInfo<KeyT>>; | |
125 | |
126 using FunctionIntervals = HalfOpenIntervalMap<uint64_t, int64_t>; | |
127 | |
128 // FIXME: Delete this structure. | |
129 struct PatchLocation { | |
130 DIE::value_iterator I; | |
131 | |
132 PatchLocation() = default; | |
133 PatchLocation(DIE::value_iterator I) : I(I) {} | |
134 | |
135 void set(uint64_t New) const { | |
136 assert(I); | |
137 const auto &Old = *I; | |
138 assert(Old.getType() == DIEValue::isInteger); | |
139 *I = DIEValue(Old.getAttribute(), Old.getForm(), DIEInteger(New)); | |
140 } | |
141 | |
142 uint64_t get() const { | |
143 assert(I); | |
144 return I->getDIEInteger().getValue(); | |
145 } | |
146 }; | |
147 | |
148 class CompileUnit; | |
149 struct DeclMapInfo; | |
150 | |
151 /// A DeclContext is a named program scope that is used for ODR | |
152 /// uniquing of types. | |
153 /// The set of DeclContext for the ODR-subject parts of a Dwarf link | |
154 /// is expanded (and uniqued) with each new object file processed. We | |
155 /// need to determine the context of each DIE in an linked object file | |
156 /// to see if the corresponding type has already been emitted. | |
157 /// | |
158 /// The contexts are conceptually organised as a tree (eg. a function | |
159 /// scope is contained in a namespace scope that contains other | |
160 /// scopes), but storing/accessing them in an actual tree is too | |
161 /// inefficient: we need to be able to very quickly query a context | |
162 /// for a given child context by name. Storing a StringMap in each | |
163 /// DeclContext would be too space inefficient. | |
164 /// The solution here is to give each DeclContext a link to its parent | |
165 /// (this allows to walk up the tree), but to query the existance of a | |
166 /// specific DeclContext using a separate DenseMap keyed on the hash | |
167 /// of the fully qualified name of the context. | |
168 class DeclContext { | |
169 friend DeclMapInfo; | |
170 | |
171 unsigned QualifiedNameHash = 0; | |
172 uint32_t Line = 0; | |
173 uint32_t ByteSize = 0; | |
174 uint16_t Tag = dwarf::DW_TAG_compile_unit; | |
175 unsigned DefinedInClangModule : 1; | |
176 StringRef Name; | |
177 StringRef File; | |
178 const DeclContext &Parent; | |
179 DWARFDie LastSeenDIE; | |
180 uint32_t LastSeenCompileUnitID = 0; | |
181 uint32_t CanonicalDIEOffset = 0; | |
182 | |
183 public: | |
184 using Map = DenseSet<DeclContext *, DeclMapInfo>; | |
185 | |
186 DeclContext() : DefinedInClangModule(0), Parent(*this) {} | |
187 | |
188 DeclContext(unsigned Hash, uint32_t Line, uint32_t ByteSize, uint16_t Tag, | |
189 StringRef Name, StringRef File, const DeclContext &Parent, | |
190 DWARFDie LastSeenDIE = DWARFDie(), unsigned CUId = 0) | |
191 : QualifiedNameHash(Hash), Line(Line), ByteSize(ByteSize), Tag(Tag), | |
192 DefinedInClangModule(0), Name(Name), File(File), Parent(Parent), | |
193 LastSeenDIE(LastSeenDIE), LastSeenCompileUnitID(CUId) {} | |
194 | |
195 uint32_t getQualifiedNameHash() const { return QualifiedNameHash; } | |
196 | |
197 bool setLastSeenDIE(CompileUnit &U, const DWARFDie &Die); | |
198 | |
199 uint32_t getCanonicalDIEOffset() const { return CanonicalDIEOffset; } | |
200 void setCanonicalDIEOffset(uint32_t Offset) { CanonicalDIEOffset = Offset; } | |
201 | |
202 bool isDefinedInClangModule() const { return DefinedInClangModule; } | |
203 void setDefinedInClangModule(bool Val) { DefinedInClangModule = Val; } | |
204 | |
205 uint16_t getTag() const { return Tag; } | |
206 StringRef getName() const { return Name; } | |
207 }; | |
208 | |
209 /// Info type for the DenseMap storing the DeclContext pointers. | |
210 struct DeclMapInfo : private DenseMapInfo<DeclContext *> { | |
211 using DenseMapInfo<DeclContext *>::getEmptyKey; | |
212 using DenseMapInfo<DeclContext *>::getTombstoneKey; | |
213 | |
214 static unsigned getHashValue(const DeclContext *Ctxt) { | |
215 return Ctxt->QualifiedNameHash; | |
216 } | |
217 | |
218 static bool isEqual(const DeclContext *LHS, const DeclContext *RHS) { | |
219 if (RHS == getEmptyKey() || RHS == getTombstoneKey()) | |
220 return RHS == LHS; | |
221 return LHS->QualifiedNameHash == RHS->QualifiedNameHash && | |
222 LHS->Line == RHS->Line && LHS->ByteSize == RHS->ByteSize && | |
223 LHS->Name.data() == RHS->Name.data() && | |
224 LHS->File.data() == RHS->File.data() && | |
225 LHS->Parent.QualifiedNameHash == RHS->Parent.QualifiedNameHash; | |
226 } | |
227 }; | |
228 | |
229 /// This class gives a tree-like API to the DenseMap that stores the | |
230 /// DeclContext objects. It also holds the BumpPtrAllocator where | |
231 /// these objects will be allocated. | |
232 class DeclContextTree { | |
233 BumpPtrAllocator Allocator; | |
234 DeclContext Root; | |
235 DeclContext::Map Contexts; | |
236 | |
237 public: | |
238 /// Get the child of \a Context described by \a DIE in \a Unit. The | |
239 /// required strings will be interned in \a StringPool. | |
240 /// \returns The child DeclContext along with one bit that is set if | |
241 /// this context is invalid. | |
242 /// An invalid context means it shouldn't be considered for uniquing, but its | |
243 /// not returning null, because some children of that context might be | |
244 /// uniquing candidates. FIXME: The invalid bit along the return value is to | |
245 /// emulate some dsymutil-classic functionality. | |
246 PointerIntPair<DeclContext *, 1> | |
247 getChildDeclContext(DeclContext &Context, | |
248 const DWARFDie &DIE, CompileUnit &Unit, | |
249 NonRelocatableStringpool &StringPool, bool InClangModule); | |
250 | |
251 DeclContext &getRoot() { return Root; } | |
252 }; | |
253 | |
254 /// Stores all information relating to a compile unit, be it in its original | |
255 /// instance in the object file to its brand new cloned and linked DIE tree. | |
256 class CompileUnit { | |
257 public: | |
258 /// Information gathered about a DIE in the object file. | |
259 struct DIEInfo { | |
260 /// Address offset to apply to the described entity. | |
261 int64_t AddrAdjust; | |
262 | |
263 /// ODR Declaration context. | |
264 DeclContext *Ctxt; | |
265 | |
266 /// Cloned version of that DIE. | |
267 DIE *Clone; | |
268 | |
269 /// The index of this DIE's parent. | |
270 uint32_t ParentIdx; | |
271 | |
272 /// Is the DIE part of the linked output? | |
273 bool Keep : 1; | |
274 | |
275 /// Was this DIE's entity found in the map? | |
276 bool InDebugMap : 1; | |
277 | |
278 /// Is this a pure forward declaration we can strip? | |
279 bool Prune : 1; | |
280 | |
281 /// Does DIE transitively refer an incomplete decl? | |
282 bool Incomplete : 1; | |
283 }; | |
284 | |
285 CompileUnit(DWARFUnit &OrigUnit, unsigned ID, bool CanUseODR, | |
286 StringRef ClangModuleName) | |
287 : OrigUnit(OrigUnit), ID(ID), Ranges(RangeAlloc), | |
288 ClangModuleName(ClangModuleName) { | |
289 Info.resize(OrigUnit.getNumDIEs()); | |
290 | |
291 auto CUDie = OrigUnit.getUnitDIE(false); | |
292 if (auto Lang = dwarf::toUnsigned(CUDie.find(dwarf::DW_AT_language))) | |
293 HasODR = CanUseODR && (*Lang == dwarf::DW_LANG_C_plus_plus || | |
294 *Lang == dwarf::DW_LANG_C_plus_plus_03 || | |
295 *Lang == dwarf::DW_LANG_C_plus_plus_11 || | |
296 *Lang == dwarf::DW_LANG_C_plus_plus_14 || | |
297 *Lang == dwarf::DW_LANG_ObjC_plus_plus); | |
298 else | |
299 HasODR = false; | |
300 } | |
301 | |
302 DWARFUnit &getOrigUnit() const { return OrigUnit; } | |
303 | |
304 unsigned getUniqueID() const { return ID; } | |
305 | |
306 void createOutputDIE() { | |
307 NewUnit.emplace(OrigUnit.getVersion(), OrigUnit.getAddressByteSize(), | |
308 OrigUnit.getUnitDIE().getTag()); | |
309 } | |
310 | |
311 DIE *getOutputUnitDIE() const { | |
312 if (NewUnit) | |
313 return &const_cast<BasicDIEUnit &>(*NewUnit).getUnitDie(); | |
314 return nullptr; | |
315 } | |
316 | |
317 bool hasODR() const { return HasODR; } | |
318 bool isClangModule() const { return !ClangModuleName.empty(); } | |
319 const std::string &getClangModuleName() const { return ClangModuleName; } | |
320 | |
321 DIEInfo &getInfo(unsigned Idx) { return Info[Idx]; } | |
322 const DIEInfo &getInfo(unsigned Idx) const { return Info[Idx]; } | |
323 | |
324 uint64_t getStartOffset() const { return StartOffset; } | |
325 uint64_t getNextUnitOffset() const { return NextUnitOffset; } | |
326 void setStartOffset(uint64_t DebugInfoSize) { StartOffset = DebugInfoSize; } | |
327 | |
328 uint64_t getLowPc() const { return LowPc; } | |
329 uint64_t getHighPc() const { return HighPc; } | |
330 | |
331 Optional<PatchLocation> getUnitRangesAttribute() const { | |
332 return UnitRangeAttribute; | |
333 } | |
334 | |
335 const FunctionIntervals &getFunctionRanges() const { return Ranges; } | |
336 | |
337 const std::vector<PatchLocation> &getRangesAttributes() const { | |
338 return RangeAttributes; | |
339 } | |
340 | |
341 const std::vector<std::pair<PatchLocation, int64_t>> & | |
342 getLocationAttributes() const { | |
343 return LocationAttributes; | |
344 } | |
345 | |
346 void setHasInterestingContent() { HasInterestingContent = true; } | |
347 bool hasInterestingContent() { return HasInterestingContent; } | |
348 | |
349 /// Mark every DIE in this unit as kept. This function also | |
350 /// marks variables as InDebugMap so that they appear in the | |
351 /// reconstructed accelerator tables. | |
352 void markEverythingAsKept(); | |
353 | |
354 /// Compute the end offset for this unit. Must be called after the CU's DIEs | |
355 /// have been cloned. \returns the next unit offset (which is also the | |
356 /// current debug_info section size). | |
357 uint64_t computeNextUnitOffset(); | |
358 | |
359 /// Keep track of a forward reference to DIE \p Die in \p RefUnit by \p | |
360 /// Attr. The attribute should be fixed up later to point to the absolute | |
361 /// offset of \p Die in the debug_info section or to the canonical offset of | |
362 /// \p Ctxt if it is non-null. | |
363 void noteForwardReference(DIE *Die, const CompileUnit *RefUnit, | |
364 DeclContext *Ctxt, PatchLocation Attr); | |
365 | |
366 /// Apply all fixups recored by noteForwardReference(). | |
367 void fixupForwardReferences(); | |
368 | |
369 /// Add a function range [\p LowPC, \p HighPC) that is relocatad by applying | |
370 /// offset \p PCOffset. | |
371 void addFunctionRange(uint64_t LowPC, uint64_t HighPC, int64_t PCOffset); | |
372 | |
373 /// Keep track of a DW_AT_range attribute that we will need to patch up later. | |
374 void noteRangeAttribute(const DIE &Die, PatchLocation Attr); | |
375 | |
376 /// Keep track of a location attribute pointing to a location list in the | |
377 /// debug_loc section. | |
378 void noteLocationAttribute(PatchLocation Attr, int64_t PcOffset); | |
379 | |
380 /// Add a name accelerator entry for \a Die with \a Name. | |
381 void addNamespaceAccelerator(const DIE *Die, DwarfStringPoolEntryRef Name); | |
382 | |
383 /// Add a name accelerator entry for \a Die with \a Name. | |
384 void addNameAccelerator(const DIE *Die, DwarfStringPoolEntryRef Name, | |
385 bool SkipPubnamesSection = false); | |
386 | |
387 /// Add various accelerator entries for \p Die with \p Name which is stored | |
388 /// in the string table at \p Offset. \p Name must be an Objective-C | |
389 /// selector. | |
390 void addObjCAccelerator(const DIE *Die, DwarfStringPoolEntryRef Name, | |
391 bool SkipPubnamesSection = false); | |
392 | |
393 /// Add a type accelerator entry for \p Die with \p Name which is stored in | |
394 /// the string table at \p Offset. | |
395 void addTypeAccelerator(const DIE *Die, DwarfStringPoolEntryRef Name, | |
396 bool ObjcClassImplementation, | |
397 uint32_t QualifiedNameHash); | |
398 | |
399 struct AccelInfo { | |
400 /// Name of the entry. | |
401 DwarfStringPoolEntryRef Name; | |
402 | |
403 /// DIE this entry describes. | |
404 const DIE *Die; | |
405 | |
406 /// Hash of the fully qualified name. | |
407 uint32_t QualifiedNameHash; | |
408 | |
409 /// Emit this entry only in the apple_* sections. | |
410 bool SkipPubSection; | |
411 | |
412 /// Is this an ObjC class implem? | |
413 bool ObjcClassImplementation; | |
414 | |
415 AccelInfo(DwarfStringPoolEntryRef Name, const DIE *Die, | |
416 bool SkipPubSection = false) | |
417 : Name(Name), Die(Die), SkipPubSection(SkipPubSection) {} | |
418 | |
419 AccelInfo(DwarfStringPoolEntryRef Name, const DIE *Die, | |
420 uint32_t QualifiedNameHash, bool ObjCClassIsImplementation) | |
421 : Name(Name), Die(Die), QualifiedNameHash(QualifiedNameHash), | |
422 SkipPubSection(false), | |
423 ObjcClassImplementation(ObjCClassIsImplementation) {} | |
424 }; | |
425 | |
426 const std::vector<AccelInfo> &getPubnames() const { return Pubnames; } | |
427 const std::vector<AccelInfo> &getPubtypes() const { return Pubtypes; } | |
428 const std::vector<AccelInfo> &getNamespaces() const { return Namespaces; } | |
429 const std::vector<AccelInfo> &getObjC() const { return ObjC; } | |
430 | |
431 /// Get the full path for file \a FileNum in the line table | |
432 StringRef getResolvedPath(unsigned FileNum) { | |
433 if (FileNum >= ResolvedPaths.size()) | |
434 return StringRef(); | |
435 return ResolvedPaths[FileNum]; | |
436 } | |
437 | |
438 /// Set the fully resolved path for the line-table's file \a FileNum | |
439 /// to \a Path. | |
440 void setResolvedPath(unsigned FileNum, StringRef Path) { | |
441 if (ResolvedPaths.size() <= FileNum) | |
442 ResolvedPaths.resize(FileNum + 1); | |
443 ResolvedPaths[FileNum] = Path; | |
444 } | |
445 | |
446 private: | |
447 DWARFUnit &OrigUnit; | |
448 unsigned ID; | |
449 std::vector<DIEInfo> Info; ///< DIE info indexed by DIE index. | |
450 Optional<BasicDIEUnit> NewUnit; | |
451 | |
452 uint64_t StartOffset; | |
453 uint64_t NextUnitOffset; | |
454 | |
455 uint64_t LowPc = std::numeric_limits<uint64_t>::max(); | |
456 uint64_t HighPc = 0; | |
457 | |
458 /// A list of attributes to fixup with the absolute offset of | |
459 /// a DIE in the debug_info section. | |
460 /// | |
461 /// The offsets for the attributes in this array couldn't be set while | |
462 /// cloning because for cross-cu forward refences the target DIE's | |
463 /// offset isn't known you emit the reference attribute. | |
464 std::vector<std::tuple<DIE *, const CompileUnit *, DeclContext *, | |
465 PatchLocation>> ForwardDIEReferences; | |
466 | |
467 FunctionIntervals::Allocator RangeAlloc; | |
468 | |
469 /// The ranges in that interval map are the PC ranges for | |
470 /// functions in this unit, associated with the PC offset to apply | |
471 /// to the addresses to get the linked address. | |
472 FunctionIntervals Ranges; | |
473 | |
474 /// DW_AT_ranges attributes to patch after we have gathered | |
475 /// all the unit's function addresses. | |
476 /// @{ | |
477 std::vector<PatchLocation> RangeAttributes; | |
478 Optional<PatchLocation> UnitRangeAttribute; | |
479 /// @} | |
480 | |
481 /// Location attributes that need to be transferred from the | |
482 /// original debug_loc section to the liked one. They are stored | |
483 /// along with the PC offset that is to be applied to their | |
484 /// function's address. | |
485 std::vector<std::pair<PatchLocation, int64_t>> LocationAttributes; | |
486 | |
487 /// Accelerator entries for the unit, both for the pub* | |
488 /// sections and the apple* ones. | |
489 /// @{ | |
490 std::vector<AccelInfo> Pubnames; | |
491 std::vector<AccelInfo> Pubtypes; | |
492 std::vector<AccelInfo> Namespaces; | |
493 std::vector<AccelInfo> ObjC; | |
494 /// @} | |
495 | |
496 /// Cached resolved paths from the line table. | |
497 /// Note, the StringRefs here point in to the intern (uniquing) string pool. | |
498 /// This means that a StringRef returned here doesn't need to then be uniqued | |
499 /// for the purposes of getting a unique address for each string. | |
500 std::vector<StringRef> ResolvedPaths; | |
501 | |
502 /// Is this unit subject to the ODR rule? | |
503 bool HasODR; | |
504 | |
505 /// Did a DIE actually contain a valid reloc? | |
506 bool HasInterestingContent; | |
507 | |
508 /// If this is a Clang module, this holds the module's name. | |
509 std::string ClangModuleName; | |
510 }; | |
511 | |
512 /// Check if the DIE at \p Idx is in the scope of a function. | |
513 static bool inFunctionScope(CompileUnit &U, unsigned Idx) { | |
514 while (Idx) { | |
515 if (U.getOrigUnit().getDIEAtIndex(Idx).getTag() == dwarf::DW_TAG_subprogram) | |
516 return true; | |
517 Idx = U.getInfo(Idx).ParentIdx; | |
518 } | |
519 return false; | |
520 } | |
521 | |
522 } // end anonymous namespace | |
523 | |
524 void CompileUnit::markEverythingAsKept() { | |
525 unsigned Idx = 0; | |
526 | |
527 setHasInterestingContent(); | |
528 | |
529 for (auto &I : Info) { | |
530 // Mark everything that wasn't explicit marked for pruning. | |
531 I.Keep = !I.Prune; | |
532 auto DIE = OrigUnit.getDIEAtIndex(Idx++); | |
533 | |
534 // Try to guess which DIEs must go to the accelerator tables. We do that | |
535 // just for variables, because functions will be handled depending on | |
536 // whether they carry a DW_AT_low_pc attribute or not. | |
537 if (DIE.getTag() != dwarf::DW_TAG_variable && | |
538 DIE.getTag() != dwarf::DW_TAG_constant) | |
539 continue; | |
540 | |
541 Optional<DWARFFormValue> Value; | |
542 if (!(Value = DIE.find(dwarf::DW_AT_location))) { | |
543 if ((Value = DIE.find(dwarf::DW_AT_const_value)) && | |
544 !inFunctionScope(*this, I.ParentIdx)) | |
545 I.InDebugMap = true; | |
546 continue; | |
547 } | |
548 if (auto Block = Value->getAsBlock()) { | |
549 if (Block->size() > OrigUnit.getAddressByteSize() && | |
550 (*Block)[0] == dwarf::DW_OP_addr) | |
551 I.InDebugMap = true; | |
552 } | |
553 } | |
554 } | |
555 | |
556 uint64_t CompileUnit::computeNextUnitOffset() { | |
557 NextUnitOffset = StartOffset + 11 /* Header size */; | |
558 // The root DIE might be null, meaning that the Unit had nothing to | |
559 // contribute to the linked output. In that case, we will emit the | |
560 // unit header without any actual DIE. | |
561 if (NewUnit) | |
562 NextUnitOffset += NewUnit->getUnitDie().getSize(); | |
563 return NextUnitOffset; | |
564 } | |
565 | |
566 /// Keep track of a forward cross-cu reference from this unit | |
567 /// to \p Die that lives in \p RefUnit. | |
568 void CompileUnit::noteForwardReference(DIE *Die, const CompileUnit *RefUnit, | |
569 DeclContext *Ctxt, PatchLocation Attr) { | |
570 ForwardDIEReferences.emplace_back(Die, RefUnit, Ctxt, Attr); | |
571 } | |
572 | |
573 /// Apply all fixups recorded by noteForwardReference(). | |
574 void CompileUnit::fixupForwardReferences() { | |
575 for (const auto &Ref : ForwardDIEReferences) { | |
576 DIE *RefDie; | |
577 const CompileUnit *RefUnit; | |
578 PatchLocation Attr; | |
579 DeclContext *Ctxt; | |
580 std::tie(RefDie, RefUnit, Ctxt, Attr) = Ref; | |
581 if (Ctxt && Ctxt->getCanonicalDIEOffset()) | |
582 Attr.set(Ctxt->getCanonicalDIEOffset()); | |
583 else | |
584 Attr.set(RefDie->getOffset() + RefUnit->getStartOffset()); | |
585 } | |
586 } | |
587 | |
588 void CompileUnit::addFunctionRange(uint64_t FuncLowPc, uint64_t FuncHighPc, | |
589 int64_t PcOffset) { | |
590 Ranges.insert(FuncLowPc, FuncHighPc, PcOffset); | |
591 this->LowPc = std::min(LowPc, FuncLowPc + PcOffset); | |
592 this->HighPc = std::max(HighPc, FuncHighPc + PcOffset); | |
593 } | |
594 | |
595 void CompileUnit::noteRangeAttribute(const DIE &Die, PatchLocation Attr) { | |
596 if (Die.getTag() != dwarf::DW_TAG_compile_unit) | |
597 RangeAttributes.push_back(Attr); | |
598 else | |
599 UnitRangeAttribute = Attr; | |
600 } | |
601 | |
602 void CompileUnit::noteLocationAttribute(PatchLocation Attr, int64_t PcOffset) { | |
603 LocationAttributes.emplace_back(Attr, PcOffset); | |
604 } | |
605 | |
606 void CompileUnit::addNamespaceAccelerator(const DIE *Die, | |
607 DwarfStringPoolEntryRef Name) { | |
608 Namespaces.emplace_back(Name, Die); | |
609 } | |
610 | |
611 void CompileUnit::addObjCAccelerator(const DIE *Die, | |
612 DwarfStringPoolEntryRef Name, | |
613 bool SkipPubSection) { | |
614 ObjC.emplace_back(Name, Die, SkipPubSection); | |
615 } | |
616 | |
617 void CompileUnit::addNameAccelerator(const DIE *Die, | |
618 DwarfStringPoolEntryRef Name, | |
619 bool SkipPubSection) { | |
620 Pubnames.emplace_back(Name, Die, SkipPubSection); | |
621 } | |
622 | |
623 void CompileUnit::addTypeAccelerator(const DIE *Die, | |
624 DwarfStringPoolEntryRef Name, | |
625 bool ObjcClassImplementation, | |
626 uint32_t QualifiedNameHash) { | |
627 Pubtypes.emplace_back(Name, Die, QualifiedNameHash, ObjcClassImplementation); | |
628 } | |
629 | |
630 namespace { | |
631 | |
632 /// The Dwarf streaming logic | |
633 /// | |
634 /// All interactions with the MC layer that is used to build the debug | |
635 /// information binary representation are handled in this class. | |
636 class DwarfStreamer { | |
637 /// \defgroup MCObjects MC layer objects constructed by the streamer | |
638 /// @{ | |
639 std::unique_ptr<MCRegisterInfo> MRI; | |
640 std::unique_ptr<MCAsmInfo> MAI; | |
641 std::unique_ptr<MCObjectFileInfo> MOFI; | |
642 std::unique_ptr<MCContext> MC; | |
643 MCAsmBackend *MAB; // Owned by MCStreamer | |
644 std::unique_ptr<MCInstrInfo> MII; | |
645 std::unique_ptr<MCSubtargetInfo> MSTI; | |
646 MCCodeEmitter *MCE; // Owned by MCStreamer | |
647 MCStreamer *MS; // Owned by AsmPrinter | |
648 std::unique_ptr<TargetMachine> TM; | |
649 std::unique_ptr<AsmPrinter> Asm; | |
650 /// @} | |
651 | |
652 /// The file we stream the linked Dwarf to. | |
653 raw_fd_ostream &OutFile; | |
654 | |
655 uint32_t RangesSectionSize; | |
656 uint32_t LocSectionSize; | |
657 uint32_t LineSectionSize; | |
658 uint32_t FrameSectionSize; | |
659 | |
660 /// Emit the pubnames or pubtypes section contribution for \p | |
661 /// Unit into \p Sec. The data is provided in \p Names. | |
662 void emitPubSectionForUnit(MCSection *Sec, StringRef Name, | |
663 const CompileUnit &Unit, | |
664 const std::vector<CompileUnit::AccelInfo> &Names); | |
665 | |
666 public: | |
667 DwarfStreamer(raw_fd_ostream &OutFile) : OutFile(OutFile) {} | |
668 bool init(Triple TheTriple); | |
669 | |
670 /// Dump the file to the disk. | |
671 bool finish(const DebugMap &); | |
672 | |
673 AsmPrinter &getAsmPrinter() const { return *Asm; } | |
674 | |
675 /// Set the current output section to debug_info and change | |
676 /// the MC Dwarf version to \p DwarfVersion. | |
677 void switchToDebugInfoSection(unsigned DwarfVersion); | |
678 | |
679 /// Emit the compilation unit header for \p Unit in the | |
680 /// debug_info section. | |
681 /// | |
682 /// As a side effect, this also switches the current Dwarf version | |
683 /// of the MC layer to the one of U.getOrigUnit(). | |
684 void emitCompileUnitHeader(CompileUnit &Unit); | |
685 | |
686 /// Recursively emit the DIE tree rooted at \p Die. | |
687 void emitDIE(DIE &Die); | |
688 | |
689 /// Emit the abbreviation table \p Abbrevs to the debug_abbrev section. | |
690 void emitAbbrevs(const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs, | |
691 unsigned DwarfVersion); | |
692 | |
693 /// Emit the string table described by \p Pool. | |
694 void emitStrings(const NonRelocatableStringpool &Pool); | |
695 | |
696 /// Emit the swift_ast section stored in \p Buffer. | |
697 void emitSwiftAST(StringRef Buffer); | |
698 | |
699 /// Emit debug_ranges for \p FuncRange by translating the | |
700 /// original \p Entries. | |
701 void emitRangesEntries( | |
702 int64_t UnitPcOffset, uint64_t OrigLowPc, | |
703 const FunctionIntervals::const_iterator &FuncRange, | |
704 const std::vector<DWARFDebugRangeList::RangeListEntry> &Entries, | |
705 unsigned AddressSize); | |
706 | |
707 /// Emit debug_aranges entries for \p Unit and if \p DoRangesSection is true, | |
708 /// also emit the debug_ranges entries for the DW_TAG_compile_unit's | |
709 /// DW_AT_ranges attribute. | |
710 void emitUnitRangesEntries(CompileUnit &Unit, bool DoRangesSection); | |
711 | |
712 uint32_t getRangesSectionSize() const { return RangesSectionSize; } | |
713 | |
714 /// Emit the debug_loc contribution for \p Unit by copying the entries from \p | |
715 /// Dwarf and offseting them. Update the location attributes to point to the | |
716 /// new entries. | |
717 void emitLocationsForUnit(const CompileUnit &Unit, DWARFContext &Dwarf); | |
718 | |
719 /// Emit the line table described in \p Rows into the debug_line section. | |
720 void emitLineTableForUnit(MCDwarfLineTableParams Params, | |
721 StringRef PrologueBytes, unsigned MinInstLength, | |
722 std::vector<DWARFDebugLine::Row> &Rows, | |
723 unsigned AdddressSize); | |
724 | |
725 /// Copy over the debug sections that are not modified when updating. | |
726 void copyInvariantDebugSection(const object::ObjectFile &Obj, LinkOptions &); | |
727 | |
728 uint32_t getLineSectionSize() const { return LineSectionSize; } | |
729 | |
730 /// Emit the .debug_pubnames contribution for \p Unit. | |
731 void emitPubNamesForUnit(const CompileUnit &Unit); | |
732 | |
733 /// Emit the .debug_pubtypes contribution for \p Unit. | |
734 void emitPubTypesForUnit(const CompileUnit &Unit); | |
735 | |
736 /// Emit a CIE. | |
737 void emitCIE(StringRef CIEBytes); | |
738 | |
739 /// Emit an FDE with data \p Bytes. | |
740 void emitFDE(uint32_t CIEOffset, uint32_t AddreSize, uint32_t Address, | |
741 StringRef Bytes); | |
742 | |
743 /// Emit Apple namespaces accelerator table. | |
744 void | |
745 emitAppleNamespaces(AppleAccelTable<AppleAccelTableStaticOffsetData> &Table); | |
746 | |
747 /// Emit Apple names accelerator table. | |
748 void emitAppleNames(AppleAccelTable<AppleAccelTableStaticOffsetData> &Table); | |
749 | |
750 /// Emit Apple Objective-C accelerator table. | |
751 void emitAppleObjc(AppleAccelTable<AppleAccelTableStaticOffsetData> &Table); | |
752 | |
753 /// Emit Apple type accelerator table. | |
754 void emitAppleTypes(AppleAccelTable<AppleAccelTableStaticTypeData> &Table); | |
755 | |
756 uint32_t getFrameSectionSize() const { return FrameSectionSize; } | |
757 }; | |
758 | |
759 } // end anonymous namespace | |
760 | |
761 bool DwarfStreamer::init(Triple TheTriple) { | |
762 std::string ErrorStr; | |
763 std::string TripleName; | |
764 StringRef Context = "dwarf streamer init"; | |
765 | |
766 // Get the target. | |
767 const Target *TheTarget = | |
768 TargetRegistry::lookupTarget(TripleName, TheTriple, ErrorStr); | |
769 if (!TheTarget) | |
770 return error(ErrorStr, Context); | |
771 TripleName = TheTriple.getTriple(); | |
772 | |
773 // Create all the MC Objects. | |
774 MRI.reset(TheTarget->createMCRegInfo(TripleName)); | |
775 if (!MRI) | |
776 return error(Twine("no register info for target ") + TripleName, Context); | |
777 | |
778 MAI.reset(TheTarget->createMCAsmInfo(*MRI, TripleName)); | |
779 if (!MAI) | |
780 return error("no asm info for target " + TripleName, Context); | |
781 | |
782 MOFI.reset(new MCObjectFileInfo); | |
783 MC.reset(new MCContext(MAI.get(), MRI.get(), MOFI.get())); | |
784 MOFI->InitMCObjectFileInfo(TheTriple, /*PIC*/ false, *MC); | |
785 | |
786 MSTI.reset(TheTarget->createMCSubtargetInfo(TripleName, "", "")); | |
787 if (!MSTI) | |
788 return error("no subtarget info for target " + TripleName, Context); | |
789 | |
790 MCTargetOptions Options; | |
791 MAB = TheTarget->createMCAsmBackend(*MSTI, *MRI, Options); | |
792 if (!MAB) | |
793 return error("no asm backend for target " + TripleName, Context); | |
794 | |
795 MII.reset(TheTarget->createMCInstrInfo()); | |
796 if (!MII) | |
797 return error("no instr info info for target " + TripleName, Context); | |
798 | |
799 MCE = TheTarget->createMCCodeEmitter(*MII, *MRI, *MC); | |
800 if (!MCE) | |
801 return error("no code emitter for target " + TripleName, Context); | |
802 | |
803 MCTargetOptions MCOptions = InitMCTargetOptionsFromFlags(); | |
804 MS = TheTarget->createMCObjectStreamer( | |
805 TheTriple, *MC, std::unique_ptr<MCAsmBackend>(MAB), OutFile, | |
806 std::unique_ptr<MCCodeEmitter>(MCE), *MSTI, MCOptions.MCRelaxAll, | |
807 MCOptions.MCIncrementalLinkerCompatible, | |
808 /*DWARFMustBeAtTheEnd*/ false); | |
809 if (!MS) | |
810 return error("no object streamer for target " + TripleName, Context); | |
811 | |
812 // Finally create the AsmPrinter we'll use to emit the DIEs. | |
813 TM.reset(TheTarget->createTargetMachine(TripleName, "", "", TargetOptions(), | |
814 None)); | |
815 if (!TM) | |
816 return error("no target machine for target " + TripleName, Context); | |
817 | |
818 Asm.reset(TheTarget->createAsmPrinter(*TM, std::unique_ptr<MCStreamer>(MS))); | |
819 if (!Asm) | |
820 return error("no asm printer for target " + TripleName, Context); | |
821 | |
822 RangesSectionSize = 0; | |
823 LocSectionSize = 0; | |
824 LineSectionSize = 0; | |
825 FrameSectionSize = 0; | |
826 | |
827 return true; | |
828 } | |
829 | |
830 bool DwarfStreamer::finish(const DebugMap &DM) { | |
831 bool Result = true; | |
832 if (DM.getTriple().isOSDarwin() && !DM.getBinaryPath().empty()) | |
833 Result = MachOUtils::generateDsymCompanion(DM, *MS, OutFile); | |
834 else | |
835 MS->Finish(); | |
836 return Result; | |
837 } | |
838 | |
839 /// Set the current output section to debug_info and change | |
840 /// the MC Dwarf version to \p DwarfVersion. | |
841 void DwarfStreamer::switchToDebugInfoSection(unsigned DwarfVersion) { | |
842 MS->SwitchSection(MOFI->getDwarfInfoSection()); | |
843 MC->setDwarfVersion(DwarfVersion); | |
844 } | |
845 | |
846 /// Emit the compilation unit header for \p Unit in the debug_info section. | |
847 /// | |
848 /// A Dwarf scetion header is encoded as: | |
849 /// uint32_t Unit length (omiting this field) | |
850 /// uint16_t Version | |
851 /// uint32_t Abbreviation table offset | |
852 /// uint8_t Address size | |
853 /// | |
854 /// Leading to a total of 11 bytes. | |
855 void DwarfStreamer::emitCompileUnitHeader(CompileUnit &Unit) { | |
856 unsigned Version = Unit.getOrigUnit().getVersion(); | |
857 switchToDebugInfoSection(Version); | |
858 | |
859 // Emit size of content not including length itself. The size has | |
860 // already been computed in CompileUnit::computeOffsets(). Substract | |
861 // 4 to that size to account for the length field. | |
862 Asm->EmitInt32(Unit.getNextUnitOffset() - Unit.getStartOffset() - 4); | |
863 Asm->EmitInt16(Version); | |
864 // We share one abbreviations table across all units so it's always at the | |
865 // start of the section. | |
866 Asm->EmitInt32(0); | |
867 Asm->EmitInt8(Unit.getOrigUnit().getAddressByteSize()); | |
868 } | |
869 | |
870 /// Emit the \p Abbrevs array as the shared abbreviation table | |
871 /// for the linked Dwarf file. | |
872 void DwarfStreamer::emitAbbrevs( | |
873 const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs, | |
874 unsigned DwarfVersion) { | |
875 MS->SwitchSection(MOFI->getDwarfAbbrevSection()); | |
876 MC->setDwarfVersion(DwarfVersion); | |
877 Asm->emitDwarfAbbrevs(Abbrevs); | |
878 } | |
879 | |
880 /// Recursively emit the DIE tree rooted at \p Die. | |
881 void DwarfStreamer::emitDIE(DIE &Die) { | |
882 MS->SwitchSection(MOFI->getDwarfInfoSection()); | |
883 Asm->emitDwarfDIE(Die); | |
884 } | |
885 | |
886 /// Emit the debug_str section stored in \p Pool. | |
887 void DwarfStreamer::emitStrings(const NonRelocatableStringpool &Pool) { | |
888 Asm->OutStreamer->SwitchSection(MOFI->getDwarfStrSection()); | |
889 std::vector<DwarfStringPoolEntryRef> Entries = Pool.getEntries(); | |
890 for (auto Entry : Entries) { | |
891 if (Entry.getIndex() == -1U) | |
892 break; | |
893 // Emit the string itself. | |
894 Asm->OutStreamer->EmitBytes(Entry.getString()); | |
895 // Emit a null terminator. | |
896 Asm->EmitInt8(0); | |
897 } | |
898 } | |
899 | |
900 void DwarfStreamer::emitAppleNamespaces( | |
901 AppleAccelTable<AppleAccelTableStaticOffsetData> &Table) { | |
902 Asm->OutStreamer->SwitchSection(MOFI->getDwarfAccelNamespaceSection()); | |
903 Table.finalizeTable(Asm.get(), "namespac"); | |
904 auto *SectionBegin = Asm->createTempSymbol("namespac_begin"); | |
905 Asm->OutStreamer->EmitLabel(SectionBegin); | |
906 Table.emit(Asm.get(), SectionBegin); | |
907 } | |
908 | |
909 void DwarfStreamer::emitAppleNames( | |
910 AppleAccelTable<AppleAccelTableStaticOffsetData> &Table) { | |
911 Asm->OutStreamer->SwitchSection(MOFI->getDwarfAccelNamesSection()); | |
912 Table.finalizeTable(Asm.get(), "names"); | |
913 auto *SectionBegin = Asm->createTempSymbol("names_begin"); | |
914 Asm->OutStreamer->EmitLabel(SectionBegin); | |
915 Table.emit(Asm.get(), SectionBegin); | |
916 } | |
917 | |
918 void DwarfStreamer::emitAppleObjc( | |
919 AppleAccelTable<AppleAccelTableStaticOffsetData> &Table) { | |
920 Asm->OutStreamer->SwitchSection(MOFI->getDwarfAccelObjCSection()); | |
921 Table.finalizeTable(Asm.get(), "objc"); | |
922 auto *SectionBegin = Asm->createTempSymbol("objc_begin"); | |
923 Asm->OutStreamer->EmitLabel(SectionBegin); | |
924 Table.emit(Asm.get(), SectionBegin); | |
925 } | |
926 | |
927 void DwarfStreamer::emitAppleTypes( | |
928 AppleAccelTable<AppleAccelTableStaticTypeData> &Table) { | |
929 Asm->OutStreamer->SwitchSection(MOFI->getDwarfAccelTypesSection()); | |
930 Table.finalizeTable(Asm.get(), "types"); | |
931 auto *SectionBegin = Asm->createTempSymbol("types_begin"); | |
932 Asm->OutStreamer->EmitLabel(SectionBegin); | |
933 Table.emit(Asm.get(), SectionBegin); | |
934 } | |
935 | |
936 /// Emit the swift_ast section stored in \p Buffers. | |
937 void DwarfStreamer::emitSwiftAST(StringRef Buffer) { | |
938 MCSection *SwiftASTSection = MOFI->getDwarfSwiftASTSection(); | |
939 SwiftASTSection->setAlignment(1 << 5); | |
940 MS->SwitchSection(SwiftASTSection); | |
941 MS->EmitBytes(Buffer); | |
942 } | |
943 | |
944 /// Emit the debug_range section contents for \p FuncRange by | |
945 /// translating the original \p Entries. The debug_range section | |
946 /// format is totally trivial, consisting just of pairs of address | |
947 /// sized addresses describing the ranges. | |
948 void DwarfStreamer::emitRangesEntries( | |
949 int64_t UnitPcOffset, uint64_t OrigLowPc, | |
950 const FunctionIntervals::const_iterator &FuncRange, | |
951 const std::vector<DWARFDebugRangeList::RangeListEntry> &Entries, | |
952 unsigned AddressSize) { | |
953 MS->SwitchSection(MC->getObjectFileInfo()->getDwarfRangesSection()); | |
954 | |
955 // Offset each range by the right amount. | |
956 int64_t PcOffset = Entries.empty() ? 0 : FuncRange.value() + UnitPcOffset; | |
957 for (const auto &Range : Entries) { | |
958 if (Range.isBaseAddressSelectionEntry(AddressSize)) { | |
959 warn("unsupported base address selection operation", | |
960 "emitting debug_ranges"); | |
961 break; | |
962 } | |
963 // Do not emit empty ranges. | |
964 if (Range.StartAddress == Range.EndAddress) | |
965 continue; | |
966 | |
967 // All range entries should lie in the function range. | |
968 if (!(Range.StartAddress + OrigLowPc >= FuncRange.start() && | |
969 Range.EndAddress + OrigLowPc <= FuncRange.stop())) | |
970 warn("inconsistent range data.", "emitting debug_ranges"); | |
971 MS->EmitIntValue(Range.StartAddress + PcOffset, AddressSize); | |
972 MS->EmitIntValue(Range.EndAddress + PcOffset, AddressSize); | |
973 RangesSectionSize += 2 * AddressSize; | |
974 } | |
975 | |
976 // Add the terminator entry. | |
977 MS->EmitIntValue(0, AddressSize); | |
978 MS->EmitIntValue(0, AddressSize); | |
979 RangesSectionSize += 2 * AddressSize; | |
980 } | |
981 | |
982 /// Emit the debug_aranges contribution of a unit and | |
983 /// if \p DoDebugRanges is true the debug_range contents for a | |
984 /// compile_unit level DW_AT_ranges attribute (Which are basically the | |
985 /// same thing with a different base address). | |
986 /// Just aggregate all the ranges gathered inside that unit. | |
987 void DwarfStreamer::emitUnitRangesEntries(CompileUnit &Unit, | |
988 bool DoDebugRanges) { | |
989 unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize(); | |
990 // Gather the ranges in a vector, so that we can simplify them. The | |
991 // IntervalMap will have coalesced the non-linked ranges, but here | |
992 // we want to coalesce the linked addresses. | |
993 std::vector<std::pair<uint64_t, uint64_t>> Ranges; | |
994 const auto &FunctionRanges = Unit.getFunctionRanges(); | |
995 for (auto Range = FunctionRanges.begin(), End = FunctionRanges.end(); | |
996 Range != End; ++Range) | |
997 Ranges.push_back(std::make_pair(Range.start() + Range.value(), | |
998 Range.stop() + Range.value())); | |
999 | |
1000 // The object addresses where sorted, but again, the linked | |
1001 // addresses might end up in a different order. | |
1002 std::sort(Ranges.begin(), Ranges.end()); | |
1003 | |
1004 if (!Ranges.empty()) { | |
1005 MS->SwitchSection(MC->getObjectFileInfo()->getDwarfARangesSection()); | |
1006 | |
1007 MCSymbol *BeginLabel = Asm->createTempSymbol("Barange"); | |
1008 MCSymbol *EndLabel = Asm->createTempSymbol("Earange"); | |
1009 | |
1010 unsigned HeaderSize = | |
1011 sizeof(int32_t) + // Size of contents (w/o this field | |
1012 sizeof(int16_t) + // DWARF ARange version number | |
1013 sizeof(int32_t) + // Offset of CU in the .debug_info section | |
1014 sizeof(int8_t) + // Pointer Size (in bytes) | |
1015 sizeof(int8_t); // Segment Size (in bytes) | |
1016 | |
1017 unsigned TupleSize = AddressSize * 2; | |
1018 unsigned Padding = OffsetToAlignment(HeaderSize, TupleSize); | |
1019 | |
1020 Asm->EmitLabelDifference(EndLabel, BeginLabel, 4); // Arange length | |
1021 Asm->OutStreamer->EmitLabel(BeginLabel); | |
1022 Asm->EmitInt16(dwarf::DW_ARANGES_VERSION); // Version number | |
1023 Asm->EmitInt32(Unit.getStartOffset()); // Corresponding unit's offset | |
1024 Asm->EmitInt8(AddressSize); // Address size | |
1025 Asm->EmitInt8(0); // Segment size | |
1026 | |
1027 Asm->OutStreamer->emitFill(Padding, 0x0); | |
1028 | |
1029 for (auto Range = Ranges.begin(), End = Ranges.end(); Range != End; | |
1030 ++Range) { | |
1031 uint64_t RangeStart = Range->first; | |
1032 MS->EmitIntValue(RangeStart, AddressSize); | |
1033 while ((Range + 1) != End && Range->second == (Range + 1)->first) | |
1034 ++Range; | |
1035 MS->EmitIntValue(Range->second - RangeStart, AddressSize); | |
1036 } | |
1037 | |
1038 // Emit terminator | |
1039 Asm->OutStreamer->EmitIntValue(0, AddressSize); | |
1040 Asm->OutStreamer->EmitIntValue(0, AddressSize); | |
1041 Asm->OutStreamer->EmitLabel(EndLabel); | |
1042 } | |
1043 | |
1044 if (!DoDebugRanges) | |
1045 return; | |
1046 | |
1047 MS->SwitchSection(MC->getObjectFileInfo()->getDwarfRangesSection()); | |
1048 // Offset each range by the right amount. | |
1049 int64_t PcOffset = -Unit.getLowPc(); | |
1050 // Emit coalesced ranges. | |
1051 for (auto Range = Ranges.begin(), End = Ranges.end(); Range != End; ++Range) { | |
1052 MS->EmitIntValue(Range->first + PcOffset, AddressSize); | |
1053 while (Range + 1 != End && Range->second == (Range + 1)->first) | |
1054 ++Range; | |
1055 MS->EmitIntValue(Range->second + PcOffset, AddressSize); | |
1056 RangesSectionSize += 2 * AddressSize; | |
1057 } | |
1058 | |
1059 // Add the terminator entry. | |
1060 MS->EmitIntValue(0, AddressSize); | |
1061 MS->EmitIntValue(0, AddressSize); | |
1062 RangesSectionSize += 2 * AddressSize; | |
1063 } | |
1064 | |
1065 /// Emit location lists for \p Unit and update attribtues to | |
1066 /// point to the new entries. | |
1067 void DwarfStreamer::emitLocationsForUnit(const CompileUnit &Unit, | |
1068 DWARFContext &Dwarf) { | |
1069 const auto &Attributes = Unit.getLocationAttributes(); | |
1070 | |
1071 if (Attributes.empty()) | |
1072 return; | |
1073 | |
1074 MS->SwitchSection(MC->getObjectFileInfo()->getDwarfLocSection()); | |
1075 | |
1076 unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize(); | |
1077 const DWARFSection &InputSec = Dwarf.getDWARFObj().getLocSection(); | |
1078 DataExtractor Data(InputSec.Data, Dwarf.isLittleEndian(), AddressSize); | |
1079 DWARFUnit &OrigUnit = Unit.getOrigUnit(); | |
1080 auto OrigUnitDie = OrigUnit.getUnitDIE(false); | |
1081 int64_t UnitPcOffset = 0; | |
1082 if (auto OrigLowPc = dwarf::toAddress(OrigUnitDie.find(dwarf::DW_AT_low_pc))) | |
1083 UnitPcOffset = int64_t(*OrigLowPc) - Unit.getLowPc(); | |
1084 | |
1085 for (const auto &Attr : Attributes) { | |
1086 uint32_t Offset = Attr.first.get(); | |
1087 Attr.first.set(LocSectionSize); | |
1088 // This is the quantity to add to the old location address to get | |
1089 // the correct address for the new one. | |
1090 int64_t LocPcOffset = Attr.second + UnitPcOffset; | |
1091 while (Data.isValidOffset(Offset)) { | |
1092 uint64_t Low = Data.getUnsigned(&Offset, AddressSize); | |
1093 uint64_t High = Data.getUnsigned(&Offset, AddressSize); | |
1094 LocSectionSize += 2 * AddressSize; | |
1095 if (Low == 0 && High == 0) { | |
1096 Asm->OutStreamer->EmitIntValue(0, AddressSize); | |
1097 Asm->OutStreamer->EmitIntValue(0, AddressSize); | |
1098 break; | |
1099 } | |
1100 Asm->OutStreamer->EmitIntValue(Low + LocPcOffset, AddressSize); | |
1101 Asm->OutStreamer->EmitIntValue(High + LocPcOffset, AddressSize); | |
1102 uint64_t Length = Data.getU16(&Offset); | |
1103 Asm->OutStreamer->EmitIntValue(Length, 2); | |
1104 // Just copy the bytes over. | |
1105 Asm->OutStreamer->EmitBytes( | |
1106 StringRef(InputSec.Data.substr(Offset, Length))); | |
1107 Offset += Length; | |
1108 LocSectionSize += Length + 2; | |
1109 } | |
1110 } | |
1111 } | |
1112 | |
1113 void DwarfStreamer::emitLineTableForUnit(MCDwarfLineTableParams Params, | |
1114 StringRef PrologueBytes, | |
1115 unsigned MinInstLength, | |
1116 std::vector<DWARFDebugLine::Row> &Rows, | |
1117 unsigned PointerSize) { | |
1118 // Switch to the section where the table will be emitted into. | |
1119 MS->SwitchSection(MC->getObjectFileInfo()->getDwarfLineSection()); | |
1120 MCSymbol *LineStartSym = MC->createTempSymbol(); | |
1121 MCSymbol *LineEndSym = MC->createTempSymbol(); | |
1122 | |
1123 // The first 4 bytes is the total length of the information for this | |
1124 // compilation unit (not including these 4 bytes for the length). | |
1125 Asm->EmitLabelDifference(LineEndSym, LineStartSym, 4); | |
1126 Asm->OutStreamer->EmitLabel(LineStartSym); | |
1127 // Copy Prologue. | |
1128 MS->EmitBytes(PrologueBytes); | |
1129 LineSectionSize += PrologueBytes.size() + 4; | |
1130 | |
1131 SmallString<128> EncodingBuffer; | |
1132 raw_svector_ostream EncodingOS(EncodingBuffer); | |
1133 | |
1134 if (Rows.empty()) { | |
1135 // We only have the dummy entry, dsymutil emits an entry with a 0 | |
1136 // address in that case. | |
1137 MCDwarfLineAddr::Encode(*MC, Params, std::numeric_limits<int64_t>::max(), 0, | |
1138 EncodingOS); | |
1139 MS->EmitBytes(EncodingOS.str()); | |
1140 LineSectionSize += EncodingBuffer.size(); | |
1141 MS->EmitLabel(LineEndSym); | |
1142 return; | |
1143 } | |
1144 | |
1145 // Line table state machine fields | |
1146 unsigned FileNum = 1; | |
1147 unsigned LastLine = 1; | |
1148 unsigned Column = 0; | |
1149 unsigned IsStatement = 1; | |
1150 unsigned Isa = 0; | |
1151 uint64_t Address = -1ULL; | |
1152 | |
1153 unsigned RowsSinceLastSequence = 0; | |
1154 | |
1155 for (unsigned Idx = 0; Idx < Rows.size(); ++Idx) { | |
1156 auto &Row = Rows[Idx]; | |
1157 | |
1158 int64_t AddressDelta; | |
1159 if (Address == -1ULL) { | |
1160 MS->EmitIntValue(dwarf::DW_LNS_extended_op, 1); | |
1161 MS->EmitULEB128IntValue(PointerSize + 1); | |
1162 MS->EmitIntValue(dwarf::DW_LNE_set_address, 1); | |
1163 MS->EmitIntValue(Row.Address, PointerSize); | |
1164 LineSectionSize += 2 + PointerSize + getULEB128Size(PointerSize + 1); | |
1165 AddressDelta = 0; | |
1166 } else { | |
1167 AddressDelta = (Row.Address - Address) / MinInstLength; | |
1168 } | |
1169 | |
1170 // FIXME: code copied and transfromed from | |
1171 // MCDwarf.cpp::EmitDwarfLineTable. We should find a way to share | |
1172 // this code, but the current compatibility requirement with | |
1173 // classic dsymutil makes it hard. Revisit that once this | |
1174 // requirement is dropped. | |
1175 | |
1176 if (FileNum != Row.File) { | |
1177 FileNum = Row.File; | |
1178 MS->EmitIntValue(dwarf::DW_LNS_set_file, 1); | |
1179 MS->EmitULEB128IntValue(FileNum); | |
1180 LineSectionSize += 1 + getULEB128Size(FileNum); | |
1181 } | |
1182 if (Column != Row.Column) { | |
1183 Column = Row.Column; | |
1184 MS->EmitIntValue(dwarf::DW_LNS_set_column, 1); | |
1185 MS->EmitULEB128IntValue(Column); | |
1186 LineSectionSize += 1 + getULEB128Size(Column); | |
1187 } | |
1188 | |
1189 // FIXME: We should handle the discriminator here, but dsymutil | |
1190 // doesn' consider it, thus ignore it for now. | |
1191 | |
1192 if (Isa != Row.Isa) { | |
1193 Isa = Row.Isa; | |
1194 MS->EmitIntValue(dwarf::DW_LNS_set_isa, 1); | |
1195 MS->EmitULEB128IntValue(Isa); | |
1196 LineSectionSize += 1 + getULEB128Size(Isa); | |
1197 } | |
1198 if (IsStatement != Row.IsStmt) { | |
1199 IsStatement = Row.IsStmt; | |
1200 MS->EmitIntValue(dwarf::DW_LNS_negate_stmt, 1); | |
1201 LineSectionSize += 1; | |
1202 } | |
1203 if (Row.BasicBlock) { | |
1204 MS->EmitIntValue(dwarf::DW_LNS_set_basic_block, 1); | |
1205 LineSectionSize += 1; | |
1206 } | |
1207 | |
1208 if (Row.PrologueEnd) { | |
1209 MS->EmitIntValue(dwarf::DW_LNS_set_prologue_end, 1); | |
1210 LineSectionSize += 1; | |
1211 } | |
1212 | |
1213 if (Row.EpilogueBegin) { | |
1214 MS->EmitIntValue(dwarf::DW_LNS_set_epilogue_begin, 1); | |
1215 LineSectionSize += 1; | |
1216 } | |
1217 | |
1218 int64_t LineDelta = int64_t(Row.Line) - LastLine; | |
1219 if (!Row.EndSequence) { | |
1220 MCDwarfLineAddr::Encode(*MC, Params, LineDelta, AddressDelta, EncodingOS); | |
1221 MS->EmitBytes(EncodingOS.str()); | |
1222 LineSectionSize += EncodingBuffer.size(); | |
1223 EncodingBuffer.resize(0); | |
1224 Address = Row.Address; | |
1225 LastLine = Row.Line; | |
1226 RowsSinceLastSequence++; | |
1227 } else { | |
1228 if (LineDelta) { | |
1229 MS->EmitIntValue(dwarf::DW_LNS_advance_line, 1); | |
1230 MS->EmitSLEB128IntValue(LineDelta); | |
1231 LineSectionSize += 1 + getSLEB128Size(LineDelta); | |
1232 } | |
1233 if (AddressDelta) { | |
1234 MS->EmitIntValue(dwarf::DW_LNS_advance_pc, 1); | |
1235 MS->EmitULEB128IntValue(AddressDelta); | |
1236 LineSectionSize += 1 + getULEB128Size(AddressDelta); | |
1237 } | |
1238 MCDwarfLineAddr::Encode(*MC, Params, std::numeric_limits<int64_t>::max(), | |
1239 0, EncodingOS); | |
1240 MS->EmitBytes(EncodingOS.str()); | |
1241 LineSectionSize += EncodingBuffer.size(); | |
1242 EncodingBuffer.resize(0); | |
1243 Address = -1ULL; | |
1244 LastLine = FileNum = IsStatement = 1; | |
1245 RowsSinceLastSequence = Column = Isa = 0; | |
1246 } | |
1247 } | |
1248 | |
1249 if (RowsSinceLastSequence) { | |
1250 MCDwarfLineAddr::Encode(*MC, Params, std::numeric_limits<int64_t>::max(), 0, | |
1251 EncodingOS); | |
1252 MS->EmitBytes(EncodingOS.str()); | |
1253 LineSectionSize += EncodingBuffer.size(); | |
1254 EncodingBuffer.resize(0); | |
1255 } | |
1256 | |
1257 MS->EmitLabel(LineEndSym); | |
1258 } | |
1259 | |
1260 static void emitSectionContents(const object::ObjectFile &Obj, | |
1261 StringRef SecName, MCStreamer *MS) { | |
1262 StringRef Contents; | |
1263 if (auto Sec = getSectionByName(Obj, SecName)) | |
1264 if (!Sec->getContents(Contents)) | |
1265 MS->EmitBytes(Contents); | |
1266 } | |
1267 | |
1268 void DwarfStreamer::copyInvariantDebugSection(const object::ObjectFile &Obj, | |
1269 LinkOptions &Options) { | |
1270 MS->SwitchSection(MC->getObjectFileInfo()->getDwarfLineSection()); | |
1271 emitSectionContents(Obj, "debug_line", MS); | |
1272 | |
1273 MS->SwitchSection(MC->getObjectFileInfo()->getDwarfLocSection()); | |
1274 emitSectionContents(Obj, "debug_loc", MS); | |
1275 | |
1276 MS->SwitchSection(MC->getObjectFileInfo()->getDwarfRangesSection()); | |
1277 emitSectionContents(Obj, "debug_ranges", MS); | |
1278 | |
1279 MS->SwitchSection(MC->getObjectFileInfo()->getDwarfFrameSection()); | |
1280 emitSectionContents(Obj, "debug_frame", MS); | |
1281 | |
1282 MS->SwitchSection(MC->getObjectFileInfo()->getDwarfARangesSection()); | |
1283 emitSectionContents(Obj, "debug_aranges", MS); | |
1284 } | |
1285 | |
1286 /// Emit the pubnames or pubtypes section contribution for \p | |
1287 /// Unit into \p Sec. The data is provided in \p Names. | |
1288 void DwarfStreamer::emitPubSectionForUnit( | |
1289 MCSection *Sec, StringRef SecName, const CompileUnit &Unit, | |
1290 const std::vector<CompileUnit::AccelInfo> &Names) { | |
1291 if (Names.empty()) | |
1292 return; | |
1293 | |
1294 // Start the dwarf pubnames section. | |
1295 Asm->OutStreamer->SwitchSection(Sec); | |
1296 MCSymbol *BeginLabel = Asm->createTempSymbol("pub" + SecName + "_begin"); | |
1297 MCSymbol *EndLabel = Asm->createTempSymbol("pub" + SecName + "_end"); | |
1298 | |
1299 bool HeaderEmitted = false; | |
1300 // Emit the pubnames for this compilation unit. | |
1301 for (const auto &Name : Names) { | |
1302 if (Name.SkipPubSection) | |
1303 continue; | |
1304 | |
1305 if (!HeaderEmitted) { | |
1306 // Emit the header. | |
1307 Asm->EmitLabelDifference(EndLabel, BeginLabel, 4); // Length | |
1308 Asm->OutStreamer->EmitLabel(BeginLabel); | |
1309 Asm->EmitInt16(dwarf::DW_PUBNAMES_VERSION); // Version | |
1310 Asm->EmitInt32(Unit.getStartOffset()); // Unit offset | |
1311 Asm->EmitInt32(Unit.getNextUnitOffset() - Unit.getStartOffset()); // Size | |
1312 HeaderEmitted = true; | |
1313 } | |
1314 Asm->EmitInt32(Name.Die->getOffset()); | |
1315 | |
1316 // Emit the string itself. | |
1317 Asm->OutStreamer->EmitBytes(Name.Name.getString()); | |
1318 // Emit a null terminator. | |
1319 Asm->EmitInt8(0); | |
1320 } | |
1321 | |
1322 if (!HeaderEmitted) | |
1323 return; | |
1324 Asm->EmitInt32(0); // End marker. | |
1325 Asm->OutStreamer->EmitLabel(EndLabel); | |
1326 } | |
1327 | |
1328 /// Emit .debug_pubnames for \p Unit. | |
1329 void DwarfStreamer::emitPubNamesForUnit(const CompileUnit &Unit) { | |
1330 emitPubSectionForUnit(MC->getObjectFileInfo()->getDwarfPubNamesSection(), | |
1331 "names", Unit, Unit.getPubnames()); | |
1332 } | |
1333 | |
1334 /// Emit .debug_pubtypes for \p Unit. | |
1335 void DwarfStreamer::emitPubTypesForUnit(const CompileUnit &Unit) { | |
1336 emitPubSectionForUnit(MC->getObjectFileInfo()->getDwarfPubTypesSection(), | |
1337 "types", Unit, Unit.getPubtypes()); | |
1338 } | |
1339 | |
1340 /// Emit a CIE into the debug_frame section. | |
1341 void DwarfStreamer::emitCIE(StringRef CIEBytes) { | |
1342 MS->SwitchSection(MC->getObjectFileInfo()->getDwarfFrameSection()); | |
1343 | |
1344 MS->EmitBytes(CIEBytes); | |
1345 FrameSectionSize += CIEBytes.size(); | |
1346 } | |
1347 | |
1348 /// Emit a FDE into the debug_frame section. \p FDEBytes | |
1349 /// contains the FDE data without the length, CIE offset and address | |
1350 /// which will be replaced with the parameter values. | |
1351 void DwarfStreamer::emitFDE(uint32_t CIEOffset, uint32_t AddrSize, | |
1352 uint32_t Address, StringRef FDEBytes) { | |
1353 MS->SwitchSection(MC->getObjectFileInfo()->getDwarfFrameSection()); | |
1354 | |
1355 MS->EmitIntValue(FDEBytes.size() + 4 + AddrSize, 4); | |
1356 MS->EmitIntValue(CIEOffset, 4); | |
1357 MS->EmitIntValue(Address, AddrSize); | |
1358 MS->EmitBytes(FDEBytes); | |
1359 FrameSectionSize += FDEBytes.size() + 8 + AddrSize; | |
1360 } | |
1361 | |
1362 namespace { | |
1363 | |
1364 /// The core of the Dwarf linking logic. | |
1365 /// | |
1366 /// The link of the dwarf information from the object files will be | |
1367 /// driven by the selection of 'root DIEs', which are DIEs that | |
1368 /// describe variables or functions that are present in the linked | |
1369 /// binary (and thus have entries in the debug map). All the debug | |
1370 /// information that will be linked (the DIEs, but also the line | |
1371 /// tables, ranges, ...) is derived from that set of root DIEs. | |
1372 /// | |
1373 /// The root DIEs are identified because they contain relocations that | |
1374 /// correspond to a debug map entry at specific places (the low_pc for | |
1375 /// a function, the location for a variable). These relocations are | |
1376 /// called ValidRelocs in the DwarfLinker and are gathered as a very | |
1377 /// first step when we start processing a DebugMapObject. | |
1378 class DwarfLinker { | |
1379 public: | |
1380 DwarfLinker(raw_fd_ostream &OutFile, const LinkOptions &Options) | |
1381 : OutFile(OutFile), Options(Options), BinHolder(Options.Verbose) {} | |
1382 | |
1383 /// Link the contents of the DebugMap. | |
1384 bool link(const DebugMap &); | |
1385 | |
1386 void reportWarning(const Twine &Warning, | |
1387 const DWARFDie *DIE = nullptr) const; | |
1388 | |
1389 private: | |
1390 /// Called at the start of a debug object link. | |
1391 void startDebugObject(DWARFContext &, DebugMapObject &); | |
1392 | |
1393 /// Called at the end of a debug object link. | |
1394 void endDebugObject(); | |
1395 | |
1396 /// Remembers the newest DWARF version we've seen in a unit. | |
1397 void maybeUpdateMaxDwarfVersion(unsigned Version) { | |
1398 if (MaxDwarfVersion < Version) | |
1399 MaxDwarfVersion = Version; | |
1400 } | |
1401 | |
1402 /// Keeps track of relocations. | |
1403 class RelocationManager { | |
1404 struct ValidReloc { | |
1405 uint32_t Offset; | |
1406 uint32_t Size; | |
1407 uint64_t Addend; | |
1408 const DebugMapObject::DebugMapEntry *Mapping; | |
1409 | |
1410 ValidReloc(uint32_t Offset, uint32_t Size, uint64_t Addend, | |
1411 const DebugMapObject::DebugMapEntry *Mapping) | |
1412 : Offset(Offset), Size(Size), Addend(Addend), Mapping(Mapping) {} | |
1413 | |
1414 bool operator<(const ValidReloc &RHS) const { | |
1415 return Offset < RHS.Offset; | |
1416 } | |
1417 }; | |
1418 | |
1419 DwarfLinker &Linker; | |
1420 | |
1421 /// The valid relocations for the current DebugMapObject. | |
1422 /// This vector is sorted by relocation offset. | |
1423 std::vector<ValidReloc> ValidRelocs; | |
1424 | |
1425 /// Index into ValidRelocs of the next relocation to | |
1426 /// consider. As we walk the DIEs in acsending file offset and as | |
1427 /// ValidRelocs is sorted by file offset, keeping this index | |
1428 /// uptodate is all we have to do to have a cheap lookup during the | |
1429 /// root DIE selection and during DIE cloning. | |
1430 unsigned NextValidReloc = 0; | |
1431 | |
1432 public: | |
1433 RelocationManager(DwarfLinker &Linker) : Linker(Linker) {} | |
1434 | |
1435 bool hasValidRelocs() const { return !ValidRelocs.empty(); } | |
1436 | |
1437 /// Reset the NextValidReloc counter. | |
1438 void resetValidRelocs() { NextValidReloc = 0; } | |
1439 | |
1440 /// \defgroup FindValidRelocations Translate debug map into a list | |
1441 /// of relevant relocations | |
1442 /// | |
1443 /// @{ | |
1444 bool findValidRelocsInDebugInfo(const object::ObjectFile &Obj, | |
1445 const DebugMapObject &DMO); | |
1446 | |
1447 bool findValidRelocs(const object::SectionRef &Section, | |
1448 const object::ObjectFile &Obj, | |
1449 const DebugMapObject &DMO); | |
1450 | |
1451 void findValidRelocsMachO(const object::SectionRef &Section, | |
1452 const object::MachOObjectFile &Obj, | |
1453 const DebugMapObject &DMO); | |
1454 /// @} | |
1455 | |
1456 bool hasValidRelocation(uint32_t StartOffset, uint32_t EndOffset, | |
1457 CompileUnit::DIEInfo &Info); | |
1458 | |
1459 bool applyValidRelocs(MutableArrayRef<char> Data, uint32_t BaseOffset, | |
1460 bool isLittleEndian); | |
1461 }; | |
1462 | |
1463 /// \defgroup FindRootDIEs Find DIEs corresponding to debug map entries. | |
1464 /// | |
1465 /// @{ | |
1466 /// Recursively walk the \p DIE tree and look for DIEs to | |
1467 /// keep. Store that information in \p CU's DIEInfo. | |
1468 /// | |
1469 /// The return value indicates whether the DIE is incomplete. | |
1470 bool lookForDIEsToKeep(RelocationManager &RelocMgr, const DWARFDie &DIE, | |
1471 const DebugMapObject &DMO, CompileUnit &CU, | |
1472 unsigned Flags); | |
1473 | |
1474 /// If this compile unit is really a skeleton CU that points to a | |
1475 /// clang module, register it in ClangModules and return true. | |
1476 /// | |
1477 /// A skeleton CU is a CU without children, a DW_AT_gnu_dwo_name | |
1478 /// pointing to the module, and a DW_AT_gnu_dwo_id with the module | |
1479 /// hash. | |
1480 bool registerModuleReference(const DWARFDie &CUDie, | |
1481 const DWARFUnit &Unit, DebugMap &ModuleMap, | |
1482 unsigned Indent = 0); | |
1483 | |
1484 /// Recursively add the debug info in this clang module .pcm | |
1485 /// file (and all the modules imported by it in a bottom-up fashion) | |
1486 /// to Units. | |
1487 Error loadClangModule(StringRef Filename, StringRef ModulePath, | |
1488 StringRef ModuleName, uint64_t DwoId, | |
1489 DebugMap &ModuleMap, unsigned Indent = 0); | |
1490 | |
1491 /// Flags passed to DwarfLinker::lookForDIEsToKeep | |
1492 enum TravesalFlags { | |
1493 TF_Keep = 1 << 0, ///< Mark the traversed DIEs as kept. | |
1494 TF_InFunctionScope = 1 << 1, ///< Current scope is a fucntion scope. | |
1495 TF_DependencyWalk = 1 << 2, ///< Walking the dependencies of a kept DIE. | |
1496 TF_ParentWalk = 1 << 3, ///< Walking up the parents of a kept DIE. | |
1497 TF_ODR = 1 << 4, ///< Use the ODR whhile keeping dependants. | |
1498 TF_SkipPC = 1 << 5, ///< Skip all location attributes. | |
1499 }; | |
1500 | |
1501 /// Mark the passed DIE as well as all the ones it depends on as kept. | |
1502 void keepDIEAndDependencies(RelocationManager &RelocMgr, | |
1503 const DWARFDie &DIE, | |
1504 CompileUnit::DIEInfo &MyInfo, | |
1505 const DebugMapObject &DMO, CompileUnit &CU, | |
1506 bool UseODR); | |
1507 | |
1508 unsigned shouldKeepDIE(RelocationManager &RelocMgr, | |
1509 const DWARFDie &DIE, | |
1510 CompileUnit &Unit, CompileUnit::DIEInfo &MyInfo, | |
1511 unsigned Flags); | |
1512 | |
1513 unsigned shouldKeepVariableDIE(RelocationManager &RelocMgr, | |
1514 const DWARFDie &DIE, | |
1515 CompileUnit &Unit, | |
1516 CompileUnit::DIEInfo &MyInfo, unsigned Flags); | |
1517 | |
1518 unsigned shouldKeepSubprogramDIE(RelocationManager &RelocMgr, | |
1519 const DWARFDie &DIE, | |
1520 CompileUnit &Unit, | |
1521 CompileUnit::DIEInfo &MyInfo, | |
1522 unsigned Flags); | |
1523 | |
1524 bool hasValidRelocation(uint32_t StartOffset, uint32_t EndOffset, | |
1525 CompileUnit::DIEInfo &Info); | |
1526 /// @} | |
1527 | |
1528 /// \defgroup Linking Methods used to link the debug information | |
1529 /// | |
1530 /// @{ | |
1531 | |
1532 class DIECloner { | |
1533 DwarfLinker &Linker; | |
1534 RelocationManager &RelocMgr; | |
1535 | |
1536 /// Allocator used for all the DIEValue objects. | |
1537 BumpPtrAllocator &DIEAlloc; | |
1538 | |
1539 std::vector<std::unique_ptr<CompileUnit>> &CompileUnits; | |
1540 LinkOptions Options; | |
1541 | |
1542 public: | |
1543 DIECloner(DwarfLinker &Linker, RelocationManager &RelocMgr, | |
1544 BumpPtrAllocator &DIEAlloc, | |
1545 std::vector<std::unique_ptr<CompileUnit>> &CompileUnits, | |
1546 LinkOptions &Options) | |
1547 : Linker(Linker), RelocMgr(RelocMgr), DIEAlloc(DIEAlloc), | |
1548 CompileUnits(CompileUnits), Options(Options) {} | |
1549 | |
1550 /// Recursively clone \p InputDIE into an tree of DIE objects | |
1551 /// where useless (as decided by lookForDIEsToKeep()) bits have been | |
1552 /// stripped out and addresses have been rewritten according to the | |
1553 /// debug map. | |
1554 /// | |
1555 /// \param OutOffset is the offset the cloned DIE in the output | |
1556 /// compile unit. | |
1557 /// \param PCOffset (while cloning a function scope) is the offset | |
1558 /// applied to the entry point of the function to get the linked address. | |
1559 /// \param Die the output DIE to use, pass NULL to create one. | |
1560 /// \returns the root of the cloned tree or null if nothing was selected. | |
1561 DIE *cloneDIE(const DWARFDie &InputDIE, CompileUnit &U, | |
1562 int64_t PCOffset, uint32_t OutOffset, unsigned Flags, | |
1563 DIE *Die = nullptr); | |
1564 | |
1565 /// Construct the output DIE tree by cloning the DIEs we | |
1566 /// chose to keep above. If there are no valid relocs, then there's | |
1567 /// nothing to clone/emit. | |
1568 void cloneAllCompileUnits(DWARFContext &DwarfContext); | |
1569 | |
1570 private: | |
1571 using AttributeSpec = DWARFAbbreviationDeclaration::AttributeSpec; | |
1572 | |
1573 /// Information gathered and exchanged between the various | |
1574 /// clone*Attributes helpers about the attributes of a particular DIE. | |
1575 struct AttributesInfo { | |
1576 /// Names. | |
1577 DwarfStringPoolEntryRef Name, MangledName, NameWithoutTemplate; | |
1578 | |
1579 /// Offsets in the string pool. | |
1580 uint32_t NameOffset = 0; | |
1581 uint32_t MangledNameOffset = 0; | |
1582 | |
1583 /// Value of AT_low_pc in the input DIE | |
1584 uint64_t OrigLowPc = std::numeric_limits<uint64_t>::max(); | |
1585 | |
1586 /// Value of AT_high_pc in the input DIE | |
1587 uint64_t OrigHighPc = 0; | |
1588 | |
1589 /// Offset to apply to PC addresses inside a function. | |
1590 int64_t PCOffset = 0; | |
1591 | |
1592 /// Does the DIE have a low_pc attribute? | |
1593 bool HasLowPc = false; | |
1594 | |
1595 /// Does the DIE have a ranges attribute? | |
1596 bool HasRanges = false; | |
1597 | |
1598 /// Is this DIE only a declaration? | |
1599 bool IsDeclaration = false; | |
1600 | |
1601 AttributesInfo() = default; | |
1602 }; | |
1603 | |
1604 /// Helper for cloneDIE. | |
1605 unsigned cloneAttribute(DIE &Die, | |
1606 const DWARFDie &InputDIE, | |
1607 CompileUnit &U, const DWARFFormValue &Val, | |
1608 const AttributeSpec AttrSpec, unsigned AttrSize, | |
1609 AttributesInfo &AttrInfo); | |
1610 | |
1611 /// Clone a string attribute described by \p AttrSpec and add | |
1612 /// it to \p Die. | |
1613 /// \returns the size of the new attribute. | |
1614 unsigned cloneStringAttribute(DIE &Die, AttributeSpec AttrSpec, | |
1615 const DWARFFormValue &Val, const DWARFUnit &U, | |
1616 AttributesInfo &Info); | |
1617 | |
1618 /// Clone an attribute referencing another DIE and add | |
1619 /// it to \p Die. | |
1620 /// \returns the size of the new attribute. | |
1621 unsigned | |
1622 cloneDieReferenceAttribute(DIE &Die, | |
1623 const DWARFDie &InputDIE, | |
1624 AttributeSpec AttrSpec, unsigned AttrSize, | |
1625 const DWARFFormValue &Val, CompileUnit &Unit); | |
1626 | |
1627 /// Clone an attribute referencing another DIE and add | |
1628 /// it to \p Die. | |
1629 /// \returns the size of the new attribute. | |
1630 unsigned cloneBlockAttribute(DIE &Die, AttributeSpec AttrSpec, | |
1631 const DWARFFormValue &Val, unsigned AttrSize); | |
1632 | |
1633 /// Clone an attribute referencing another DIE and add | |
1634 /// it to \p Die. | |
1635 /// \returns the size of the new attribute. | |
1636 unsigned cloneAddressAttribute(DIE &Die, AttributeSpec AttrSpec, | |
1637 const DWARFFormValue &Val, | |
1638 const CompileUnit &Unit, | |
1639 AttributesInfo &Info); | |
1640 | |
1641 /// Clone a scalar attribute and add it to \p Die. | |
1642 /// \returns the size of the new attribute. | |
1643 unsigned cloneScalarAttribute(DIE &Die, | |
1644 const DWARFDie &InputDIE, | |
1645 CompileUnit &U, AttributeSpec AttrSpec, | |
1646 const DWARFFormValue &Val, unsigned AttrSize, | |
1647 AttributesInfo &Info); | |
1648 | |
1649 /// Get the potential name and mangled name for the entity | |
1650 /// described by \p Die and store them in \Info if they are not | |
1651 /// already there. | |
1652 /// \returns is a name was found. | |
1653 bool getDIENames(const DWARFDie &Die, AttributesInfo &Info, | |
1654 bool StripTemplate = false); | |
1655 | |
1656 /// Create a copy of abbreviation Abbrev. | |
1657 void copyAbbrev(const DWARFAbbreviationDeclaration &Abbrev, bool hasODR); | |
1658 | |
1659 uint32_t hashFullyQualifiedName(DWARFDie DIE, CompileUnit &U, | |
1660 int RecurseDepth = 0); | |
1661 | |
1662 /// Helper for cloneDIE. | |
1663 void addObjCAccelerator(CompileUnit &Unit, const DIE *Die, | |
1664 DwarfStringPoolEntryRef Name, bool SkipPubSection); | |
1665 }; | |
1666 | |
1667 /// Assign an abbreviation number to \p Abbrev | |
1668 void AssignAbbrev(DIEAbbrev &Abbrev); | |
1669 | |
1670 /// Compute and emit debug_ranges section for \p Unit, and | |
1671 /// patch the attributes referencing it. | |
1672 void patchRangesForUnit(const CompileUnit &Unit, DWARFContext &Dwarf) const; | |
1673 | |
1674 /// Generate and emit the DW_AT_ranges attribute for a | |
1675 /// compile_unit if it had one. | |
1676 void generateUnitRanges(CompileUnit &Unit) const; | |
1677 | |
1678 /// Extract the line tables fromt he original dwarf, extract | |
1679 /// the relevant parts according to the linked function ranges and | |
1680 /// emit the result in the debug_line section. | |
1681 void patchLineTableForUnit(CompileUnit &Unit, DWARFContext &OrigDwarf); | |
1682 | |
1683 /// Emit the accelerator entries for \p Unit. | |
1684 void emitAcceleratorEntriesForUnit(CompileUnit &Unit); | |
1685 | |
1686 /// Patch the frame info for an object file and emit it. | |
1687 void patchFrameInfoForObject(const DebugMapObject &, DWARFContext &, | |
1688 unsigned AddressSize); | |
1689 | |
1690 /// FoldingSet that uniques the abbreviations. | |
1691 FoldingSet<DIEAbbrev> AbbreviationsSet; | |
1692 | |
1693 /// Storage for the unique Abbreviations. | |
1694 /// This is passed to AsmPrinter::emitDwarfAbbrevs(), thus it cannot | |
1695 /// be changed to a vecot of unique_ptrs. | |
1696 std::vector<std::unique_ptr<DIEAbbrev>> Abbreviations; | |
1697 | |
1698 /// DIELoc objects that need to be destructed (but not freed!). | |
1699 std::vector<DIELoc *> DIELocs; | |
1700 | |
1701 /// DIEBlock objects that need to be destructed (but not freed!). | |
1702 std::vector<DIEBlock *> DIEBlocks; | |
1703 | |
1704 /// Allocator used for all the DIEValue objects. | |
1705 BumpPtrAllocator DIEAlloc; | |
1706 /// @} | |
1707 | |
1708 /// ODR Contexts for that link. | |
1709 DeclContextTree ODRContexts; | |
1710 | |
1711 /// \defgroup Helpers Various helper methods. | |
1712 /// | |
1713 /// @{ | |
1714 bool createStreamer(const Triple &TheTriple, raw_fd_ostream &OutFile); | |
1715 | |
1716 /// Attempt to load a debug object from disk. | |
1717 ErrorOr<const object::ObjectFile &> loadObject(BinaryHolder &BinaryHolder, | |
1718 DebugMapObject &Obj, | |
1719 const DebugMap &Map); | |
1720 /// @} | |
1721 | |
1722 raw_fd_ostream &OutFile; | |
1723 LinkOptions Options; | |
1724 BinaryHolder BinHolder; | |
1725 std::unique_ptr<DwarfStreamer> Streamer; | |
1726 uint64_t OutputDebugInfoSize; | |
1727 | |
1728 /// A unique ID that identifies each compile unit. | |
1729 unsigned UnitID; | |
1730 | |
1731 unsigned MaxDwarfVersion = 0; | |
1732 | |
1733 /// The units of the current debug map object. | |
1734 std::vector<std::unique_ptr<CompileUnit>> Units; | |
1735 | |
1736 /// The debug map object currently under consideration. | |
1737 DebugMapObject *CurrentDebugObject; | |
1738 | |
1739 /// The Dwarf string pool. | |
1740 NonRelocatableStringpool StringPool; | |
1741 | |
1742 /// This map is keyed by the entry PC of functions in that | |
1743 /// debug object and the associated value is a pair storing the | |
1744 /// corresponding end PC and the offset to apply to get the linked | |
1745 /// address. | |
1746 /// | |
1747 /// See startDebugObject() for a more complete description of its use. | |
1748 std::map<uint64_t, std::pair<uint64_t, int64_t>> Ranges; | |
1749 | |
1750 /// The CIEs that have been emitted in the output | |
1751 /// section. The actual CIE data serves a the key to this StringMap, | |
1752 /// this takes care of comparing the semantics of CIEs defined in | |
1753 /// different object files. | |
1754 StringMap<uint32_t> EmittedCIEs; | |
1755 | |
1756 /// Offset of the last CIE that has been emitted in the output | |
1757 /// debug_frame section. | |
1758 uint32_t LastCIEOffset = 0; | |
1759 | |
1760 /// Apple accelerator tables. | |
1761 AppleAccelTable<AppleAccelTableStaticOffsetData> AppleNames; | |
1762 AppleAccelTable<AppleAccelTableStaticOffsetData> AppleNamespaces; | |
1763 AppleAccelTable<AppleAccelTableStaticOffsetData> AppleObjc; | |
1764 AppleAccelTable<AppleAccelTableStaticTypeData> AppleTypes; | |
1765 | |
1766 /// Mapping the PCM filename to the DwoId. | |
1767 StringMap<uint64_t> ClangModules; | |
1768 | |
1769 bool ModuleCacheHintDisplayed = false; | |
1770 bool ArchiveHintDisplayed = false; | |
1771 }; | |
1772 | |
1773 } // end anonymous namespace | |
1774 | |
1775 /// Similar to DWARFUnitSection::getUnitForOffset(), but returning our | 106 /// Similar to DWARFUnitSection::getUnitForOffset(), but returning our |
1776 /// CompileUnit object instead. | 107 /// CompileUnit object instead. |
1777 static CompileUnit *getUnitForOffset( | 108 static CompileUnit *getUnitForOffset(const UnitListTy &Units, uint64_t Offset) { |
1778 std::vector<std::unique_ptr<CompileUnit>> &Units, unsigned Offset) { | 109 auto CU = std::upper_bound( |
1779 auto CU = | 110 Units.begin(), Units.end(), Offset, |
1780 std::upper_bound(Units.begin(), Units.end(), Offset, | 111 [](uint64_t LHS, const std::unique_ptr<CompileUnit> &RHS) { |
1781 [](uint32_t LHS, const std::unique_ptr<CompileUnit> &RHS) { | 112 return LHS < RHS->getOrigUnit().getNextUnitOffset(); |
1782 return LHS < RHS->getOrigUnit().getNextUnitOffset(); | 113 }); |
1783 }); | |
1784 return CU != Units.end() ? CU->get() : nullptr; | 114 return CU != Units.end() ? CU->get() : nullptr; |
1785 } | 115 } |
1786 | 116 |
1787 /// Resolve the DIE attribute reference that has been | 117 /// Resolve the DIE attribute reference that has been extracted in \p RefValue. |
1788 /// extracted in \p RefValue. The resulting DIE migh be in another | 118 /// The resulting DIE might be in another CompileUnit which is stored into \p |
1789 /// CompileUnit which is stored into \p ReferencedCU. | 119 /// ReferencedCU. \returns null if resolving fails for any reason. |
1790 /// \returns null if resolving fails for any reason. | 120 static DWARFDie resolveDIEReference(const DwarfLinker &Linker, |
1791 static DWARFDie resolveDIEReference( | 121 const DebugMapObject &DMO, |
1792 const DwarfLinker &Linker, std::vector<std::unique_ptr<CompileUnit>> &Units, | 122 const UnitListTy &Units, |
1793 const DWARFFormValue &RefValue, const DWARFUnit &Unit, | 123 const DWARFFormValue &RefValue, |
1794 const DWARFDie &DIE, CompileUnit *&RefCU) { | 124 const DWARFDie &DIE, CompileUnit *&RefCU) { |
1795 assert(RefValue.isFormClass(DWARFFormValue::FC_Reference)); | 125 assert(RefValue.isFormClass(DWARFFormValue::FC_Reference)); |
1796 uint64_t RefOffset = *RefValue.getAsReference(); | 126 uint64_t RefOffset = *RefValue.getAsReference(); |
1797 | |
1798 if ((RefCU = getUnitForOffset(Units, RefOffset))) | 127 if ((RefCU = getUnitForOffset(Units, RefOffset))) |
1799 if (const auto RefDie = RefCU->getOrigUnit().getDIEForOffset(RefOffset)) { | 128 if (const auto RefDie = RefCU->getOrigUnit().getDIEForOffset(RefOffset)) { |
1800 // In a file with broken references, an attribute might point to a NULL | 129 // In a file with broken references, an attribute might point to a NULL |
1801 // DIE. | 130 // DIE. |
1802 if(!RefDie.isNULL()) | 131 if (!RefDie.isNULL()) |
1803 return RefDie; | 132 return RefDie; |
1804 } | 133 } |
1805 | 134 |
1806 Linker.reportWarning("could not find referenced DIE", &DIE); | 135 Linker.reportWarning("could not find referenced DIE", DMO, &DIE); |
1807 return DWARFDie(); | 136 return DWARFDie(); |
1808 } | 137 } |
1809 | 138 |
1810 /// \returns whether the passed \a Attr type might contain a DIE | 139 /// \returns whether the passed \a Attr type might contain a DIE reference |
1811 /// reference suitable for ODR uniquing. | 140 /// suitable for ODR uniquing. |
1812 static bool isODRAttribute(uint16_t Attr) { | 141 static bool isODRAttribute(uint16_t Attr) { |
1813 switch (Attr) { | 142 switch (Attr) { |
1814 default: | 143 default: |
1815 return false; | 144 return false; |
1816 case dwarf::DW_AT_type: | 145 case dwarf::DW_AT_type: |
1819 case dwarf::DW_AT_abstract_origin: | 148 case dwarf::DW_AT_abstract_origin: |
1820 case dwarf::DW_AT_import: | 149 case dwarf::DW_AT_import: |
1821 return true; | 150 return true; |
1822 } | 151 } |
1823 llvm_unreachable("Improper attribute."); | 152 llvm_unreachable("Improper attribute."); |
1824 } | |
1825 | |
1826 /// Set the last DIE/CU a context was seen in and, possibly invalidate | |
1827 /// the context if it is ambiguous. | |
1828 /// | |
1829 /// In the current implementation, we don't handle overloaded | |
1830 /// functions well, because the argument types are not taken into | |
1831 /// account when computing the DeclContext tree. | |
1832 /// | |
1833 /// Some of this is mitigated byt using mangled names that do contain | |
1834 /// the arguments types, but sometimes (eg. with function templates) | |
1835 /// we don't have that. In that case, just do not unique anything that | |
1836 /// refers to the contexts we are not able to distinguish. | |
1837 /// | |
1838 /// If a context that is not a namespace appears twice in the same CU, | |
1839 /// we know it is ambiguous. Make it invalid. | |
1840 bool DeclContext::setLastSeenDIE(CompileUnit &U, | |
1841 const DWARFDie &Die) { | |
1842 if (LastSeenCompileUnitID == U.getUniqueID()) { | |
1843 DWARFUnit &OrigUnit = U.getOrigUnit(); | |
1844 uint32_t FirstIdx = OrigUnit.getDIEIndex(LastSeenDIE); | |
1845 U.getInfo(FirstIdx).Ctxt = nullptr; | |
1846 return false; | |
1847 } | |
1848 | |
1849 LastSeenCompileUnitID = U.getUniqueID(); | |
1850 LastSeenDIE = Die; | |
1851 return true; | |
1852 } | |
1853 | |
1854 PointerIntPair<DeclContext *, 1> DeclContextTree::getChildDeclContext( | |
1855 DeclContext &Context, const DWARFDie &DIE, CompileUnit &U, | |
1856 NonRelocatableStringpool &StringPool, bool InClangModule) { | |
1857 unsigned Tag = DIE.getTag(); | |
1858 | |
1859 // FIXME: dsymutil-classic compat: We should bail out here if we | |
1860 // have a specification or an abstract_origin. We will get the | |
1861 // parent context wrong here. | |
1862 | |
1863 switch (Tag) { | |
1864 default: | |
1865 // By default stop gathering child contexts. | |
1866 return PointerIntPair<DeclContext *, 1>(nullptr); | |
1867 case dwarf::DW_TAG_module: | |
1868 break; | |
1869 case dwarf::DW_TAG_compile_unit: | |
1870 return PointerIntPair<DeclContext *, 1>(&Context); | |
1871 case dwarf::DW_TAG_subprogram: | |
1872 // Do not unique anything inside CU local functions. | |
1873 if ((Context.getTag() == dwarf::DW_TAG_namespace || | |
1874 Context.getTag() == dwarf::DW_TAG_compile_unit) && | |
1875 !dwarf::toUnsigned(DIE.find(dwarf::DW_AT_external), 0)) | |
1876 return PointerIntPair<DeclContext *, 1>(nullptr); | |
1877 LLVM_FALLTHROUGH; | |
1878 case dwarf::DW_TAG_member: | |
1879 case dwarf::DW_TAG_namespace: | |
1880 case dwarf::DW_TAG_structure_type: | |
1881 case dwarf::DW_TAG_class_type: | |
1882 case dwarf::DW_TAG_union_type: | |
1883 case dwarf::DW_TAG_enumeration_type: | |
1884 case dwarf::DW_TAG_typedef: | |
1885 // Artificial things might be ambiguous, because they might be | |
1886 // created on demand. For example implicitely defined constructors | |
1887 // are ambiguous because of the way we identify contexts, and they | |
1888 // won't be generated everytime everywhere. | |
1889 if (dwarf::toUnsigned(DIE.find(dwarf::DW_AT_artificial), 0)) | |
1890 return PointerIntPair<DeclContext *, 1>(nullptr); | |
1891 break; | |
1892 } | |
1893 | |
1894 const char *Name = DIE.getName(DINameKind::LinkageName); | |
1895 const char *ShortName = DIE.getName(DINameKind::ShortName); | |
1896 StringRef NameRef; | |
1897 StringRef ShortNameRef; | |
1898 StringRef FileRef; | |
1899 | |
1900 if (Name) | |
1901 NameRef = StringPool.internString(Name); | |
1902 else if (Tag == dwarf::DW_TAG_namespace) | |
1903 // FIXME: For dsymutil-classic compatibility. I think uniquing | |
1904 // within anonymous namespaces is wrong. There is no ODR guarantee | |
1905 // there. | |
1906 NameRef = StringPool.internString("(anonymous namespace)"); | |
1907 | |
1908 if (ShortName && ShortName != Name) | |
1909 ShortNameRef = StringPool.internString(ShortName); | |
1910 else | |
1911 ShortNameRef = NameRef; | |
1912 | |
1913 if (Tag != dwarf::DW_TAG_class_type && Tag != dwarf::DW_TAG_structure_type && | |
1914 Tag != dwarf::DW_TAG_union_type && | |
1915 Tag != dwarf::DW_TAG_enumeration_type && NameRef.empty()) | |
1916 return PointerIntPair<DeclContext *, 1>(nullptr); | |
1917 | |
1918 unsigned Line = 0; | |
1919 unsigned ByteSize = std::numeric_limits<uint32_t>::max(); | |
1920 | |
1921 if (!InClangModule) { | |
1922 // Gather some discriminating data about the DeclContext we will be | |
1923 // creating: File, line number and byte size. This shouldn't be | |
1924 // necessary, because the ODR is just about names, but given that we | |
1925 // do some approximations with overloaded functions and anonymous | |
1926 // namespaces, use these additional data points to make the process | |
1927 // safer. This is disabled for clang modules, because forward | |
1928 // declarations of module-defined types do not have a file and line. | |
1929 ByteSize = dwarf::toUnsigned(DIE.find(dwarf::DW_AT_byte_size), | |
1930 std::numeric_limits<uint64_t>::max()); | |
1931 if (Tag != dwarf::DW_TAG_namespace || !Name) { | |
1932 if (unsigned FileNum = dwarf::toUnsigned(DIE.find(dwarf::DW_AT_decl_file), 0)) { | |
1933 if (const auto *LT = U.getOrigUnit().getContext().getLineTableForUnit( | |
1934 &U.getOrigUnit())) { | |
1935 // FIXME: dsymutil-classic compatibility. I'd rather not | |
1936 // unique anything in anonymous namespaces, but if we do, then | |
1937 // verify that the file and line correspond. | |
1938 if (!Name && Tag == dwarf::DW_TAG_namespace) | |
1939 FileNum = 1; | |
1940 | |
1941 // FIXME: Passing U.getOrigUnit().getCompilationDir() | |
1942 // instead of "" would allow more uniquing, but for now, do | |
1943 // it this way to match dsymutil-classic. | |
1944 if (LT->hasFileAtIndex(FileNum)) { | |
1945 Line = dwarf::toUnsigned(DIE.find(dwarf::DW_AT_decl_line), 0); | |
1946 // Cache the resolved paths, because calling realpath is expansive. | |
1947 StringRef ResolvedPath = U.getResolvedPath(FileNum); | |
1948 if (!ResolvedPath.empty()) { | |
1949 FileRef = ResolvedPath; | |
1950 } else { | |
1951 std::string File; | |
1952 bool gotFileName = | |
1953 LT->getFileNameByIndex(FileNum, "", | |
1954 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, | |
1955 File); | |
1956 (void)gotFileName; | |
1957 assert(gotFileName && "Must get file name from line table"); | |
1958 #ifdef HAVE_REALPATH | |
1959 char RealPath[PATH_MAX + 1]; | |
1960 RealPath[PATH_MAX] = 0; | |
1961 if (::realpath(File.c_str(), RealPath)) | |
1962 File = RealPath; | |
1963 #endif | |
1964 FileRef = StringPool.internString(File); | |
1965 U.setResolvedPath(FileNum, FileRef); | |
1966 } | |
1967 } | |
1968 } | |
1969 } | |
1970 } | |
1971 } | |
1972 | |
1973 if (!Line && NameRef.empty()) | |
1974 return PointerIntPair<DeclContext *, 1>(nullptr); | |
1975 | |
1976 // We hash NameRef, which is the mangled name, in order to get most | |
1977 // overloaded functions resolve correctly. | |
1978 // | |
1979 // Strictly speaking, hashing the Tag is only necessary for a | |
1980 // DW_TAG_module, to prevent uniquing of a module and a namespace | |
1981 // with the same name. | |
1982 // | |
1983 // FIXME: dsymutil-classic won't unique the same type presented | |
1984 // once as a struct and once as a class. Using the Tag in the fully | |
1985 // qualified name hash to get the same effect. | |
1986 unsigned Hash = hash_combine(Context.getQualifiedNameHash(), Tag, NameRef); | |
1987 | |
1988 // FIXME: dsymutil-classic compatibility: when we don't have a name, | |
1989 // use the filename. | |
1990 if (Tag == dwarf::DW_TAG_namespace && NameRef == "(anonymous namespace)") | |
1991 Hash = hash_combine(Hash, FileRef); | |
1992 | |
1993 // Now look if this context already exists. | |
1994 DeclContext Key(Hash, Line, ByteSize, Tag, NameRef, FileRef, Context); | |
1995 auto ContextIter = Contexts.find(&Key); | |
1996 | |
1997 if (ContextIter == Contexts.end()) { | |
1998 // The context wasn't found. | |
1999 bool Inserted; | |
2000 DeclContext *NewContext = | |
2001 new (Allocator) DeclContext(Hash, Line, ByteSize, Tag, NameRef, FileRef, | |
2002 Context, DIE, U.getUniqueID()); | |
2003 std::tie(ContextIter, Inserted) = Contexts.insert(NewContext); | |
2004 assert(Inserted && "Failed to insert DeclContext"); | |
2005 (void)Inserted; | |
2006 } else if (Tag != dwarf::DW_TAG_namespace && | |
2007 !(*ContextIter)->setLastSeenDIE(U, DIE)) { | |
2008 // The context was found, but it is ambiguous with another context | |
2009 // in the same file. Mark it invalid. | |
2010 return PointerIntPair<DeclContext *, 1>(*ContextIter, /* Invalid= */ 1); | |
2011 } | |
2012 | |
2013 assert(ContextIter != Contexts.end()); | |
2014 // FIXME: dsymutil-classic compatibility. Union types aren't | |
2015 // uniques, but their children might be. | |
2016 if ((Tag == dwarf::DW_TAG_subprogram && | |
2017 Context.getTag() != dwarf::DW_TAG_structure_type && | |
2018 Context.getTag() != dwarf::DW_TAG_class_type) || | |
2019 (Tag == dwarf::DW_TAG_union_type)) | |
2020 return PointerIntPair<DeclContext *, 1>(*ContextIter, /* Invalid= */ 1); | |
2021 | |
2022 return PointerIntPair<DeclContext *, 1>(*ContextIter); | |
2023 } | |
2024 | |
2025 bool DwarfLinker::DIECloner::getDIENames(const DWARFDie &Die, | |
2026 AttributesInfo &Info, | |
2027 bool StripTemplate) { | |
2028 // This function will be called on DIEs having low_pcs and | |
2029 // ranges. As getting the name might be more expansive, filter out | |
2030 // blocks directly. | |
2031 if (Die.getTag() == dwarf::DW_TAG_lexical_block) | |
2032 return false; | |
2033 | |
2034 // FIXME: a bit wasteful as the first getName might return the | |
2035 // short name. | |
2036 if (!Info.MangledName) | |
2037 if (const char *MangledName = Die.getName(DINameKind::LinkageName)) | |
2038 Info.MangledName = Linker.StringPool.getEntry(MangledName); | |
2039 | |
2040 if (!Info.Name) | |
2041 if (const char *Name = Die.getName(DINameKind::ShortName)) | |
2042 Info.Name = Linker.StringPool.getEntry(Name); | |
2043 | |
2044 if (StripTemplate && Info.Name && Info.MangledName != Info.Name) { | |
2045 // FIXME: dsymutil compatibility. This is wrong for operator< | |
2046 auto Split = Info.Name.getString().split('<'); | |
2047 if (!Split.second.empty()) | |
2048 Info.NameWithoutTemplate = Linker.StringPool.getEntry(Split.first); | |
2049 } | |
2050 | |
2051 return Info.Name || Info.MangledName; | |
2052 } | |
2053 | |
2054 /// Report a warning to the user, optionaly including | |
2055 /// information about a specific \p DIE related to the warning. | |
2056 void DwarfLinker::reportWarning(const Twine &Warning, | |
2057 const DWARFDie *DIE) const { | |
2058 StringRef Context = "<debug map>"; | |
2059 if (CurrentDebugObject) | |
2060 Context = CurrentDebugObject->getObjectFilename(); | |
2061 warn(Warning, Context); | |
2062 | |
2063 if (!Options.Verbose || !DIE) | |
2064 return; | |
2065 | |
2066 DIDumpOptions DumpOpts; | |
2067 DumpOpts.RecurseDepth = 0; | |
2068 DumpOpts.Verbose = Options.Verbose; | |
2069 | |
2070 errs() << " in DIE:\n"; | |
2071 DIE->dump(errs(), 6 /* Indent */, DumpOpts); | |
2072 } | |
2073 | |
2074 bool DwarfLinker::createStreamer(const Triple &TheTriple, | |
2075 raw_fd_ostream &OutFile) { | |
2076 if (Options.NoOutput) | |
2077 return true; | |
2078 | |
2079 Streamer = llvm::make_unique<DwarfStreamer>(OutFile); | |
2080 return Streamer->init(TheTriple); | |
2081 } | |
2082 | |
2083 /// Recursive helper to build the global DeclContext information and | |
2084 /// gather the child->parent relationships in the original compile unit. | |
2085 /// | |
2086 /// \return true when this DIE and all of its children are only | |
2087 /// forward declarations to types defined in external clang modules | |
2088 /// (i.e., forward declarations that are children of a DW_TAG_module). | |
2089 static bool analyzeContextInfo(const DWARFDie &DIE, | |
2090 unsigned ParentIdx, CompileUnit &CU, | |
2091 DeclContext *CurrentDeclContext, | |
2092 NonRelocatableStringpool &StringPool, | |
2093 DeclContextTree &Contexts, | |
2094 bool InImportedModule = false) { | |
2095 unsigned MyIdx = CU.getOrigUnit().getDIEIndex(DIE); | |
2096 CompileUnit::DIEInfo &Info = CU.getInfo(MyIdx); | |
2097 | |
2098 // Clang imposes an ODR on modules(!) regardless of the language: | |
2099 // "The module-id should consist of only a single identifier, | |
2100 // which provides the name of the module being defined. Each | |
2101 // module shall have a single definition." | |
2102 // | |
2103 // This does not extend to the types inside the modules: | |
2104 // "[I]n C, this implies that if two structs are defined in | |
2105 // different submodules with the same name, those two types are | |
2106 // distinct types (but may be compatible types if their | |
2107 // definitions match)." | |
2108 // | |
2109 // We treat non-C++ modules like namespaces for this reason. | |
2110 if (DIE.getTag() == dwarf::DW_TAG_module && ParentIdx == 0 && | |
2111 dwarf::toString(DIE.find(dwarf::DW_AT_name), "") != | |
2112 CU.getClangModuleName()) { | |
2113 InImportedModule = true; | |
2114 } | |
2115 | |
2116 Info.ParentIdx = ParentIdx; | |
2117 bool InClangModule = CU.isClangModule() || InImportedModule; | |
2118 if (CU.hasODR() || InClangModule) { | |
2119 if (CurrentDeclContext) { | |
2120 auto PtrInvalidPair = Contexts.getChildDeclContext( | |
2121 *CurrentDeclContext, DIE, CU, StringPool, InClangModule); | |
2122 CurrentDeclContext = PtrInvalidPair.getPointer(); | |
2123 Info.Ctxt = | |
2124 PtrInvalidPair.getInt() ? nullptr : PtrInvalidPair.getPointer(); | |
2125 if (Info.Ctxt) | |
2126 Info.Ctxt->setDefinedInClangModule(InClangModule); | |
2127 } else | |
2128 Info.Ctxt = CurrentDeclContext = nullptr; | |
2129 } | |
2130 | |
2131 Info.Prune = InImportedModule; | |
2132 if (DIE.hasChildren()) | |
2133 for (auto Child: DIE.children()) | |
2134 Info.Prune &= analyzeContextInfo(Child, MyIdx, CU, CurrentDeclContext, | |
2135 StringPool, Contexts, InImportedModule); | |
2136 | |
2137 // Prune this DIE if it is either a forward declaration inside a | |
2138 // DW_TAG_module or a DW_TAG_module that contains nothing but | |
2139 // forward declarations. | |
2140 Info.Prune &= | |
2141 (DIE.getTag() == dwarf::DW_TAG_module) || | |
2142 dwarf::toUnsigned(DIE.find(dwarf::DW_AT_declaration), 0); | |
2143 | |
2144 // Don't prune it if there is no definition for the DIE. | |
2145 Info.Prune &= Info.Ctxt && Info.Ctxt->getCanonicalDIEOffset(); | |
2146 | |
2147 return Info.Prune; | |
2148 } | |
2149 | |
2150 static bool dieNeedsChildrenToBeMeaningful(uint32_t Tag) { | |
2151 switch (Tag) { | |
2152 default: | |
2153 return false; | |
2154 case dwarf::DW_TAG_subprogram: | |
2155 case dwarf::DW_TAG_lexical_block: | |
2156 case dwarf::DW_TAG_subroutine_type: | |
2157 case dwarf::DW_TAG_structure_type: | |
2158 case dwarf::DW_TAG_class_type: | |
2159 case dwarf::DW_TAG_union_type: | |
2160 return true; | |
2161 } | |
2162 llvm_unreachable("Invalid Tag"); | |
2163 } | |
2164 | |
2165 void DwarfLinker::startDebugObject(DWARFContext &Dwarf, DebugMapObject &Obj) { | |
2166 // Iterate over the debug map entries and put all the ones that are | |
2167 // functions (because they have a size) into the Ranges map. This | |
2168 // map is very similar to the FunctionRanges that are stored in each | |
2169 // unit, with 2 notable differences: | |
2170 // - obviously this one is global, while the other ones are per-unit. | |
2171 // - this one contains not only the functions described in the DIE | |
2172 // tree, but also the ones that are only in the debug map. | |
2173 // The latter information is required to reproduce dsymutil's logic | |
2174 // while linking line tables. The cases where this information | |
2175 // matters look like bugs that need to be investigated, but for now | |
2176 // we need to reproduce dsymutil's behavior. | |
2177 // FIXME: Once we understood exactly if that information is needed, | |
2178 // maybe totally remove this (or try to use it to do a real | |
2179 // -gline-tables-only on Darwin. | |
2180 for (const auto &Entry : Obj.symbols()) { | |
2181 const auto &Mapping = Entry.getValue(); | |
2182 if (Mapping.Size && Mapping.ObjectAddress) | |
2183 Ranges[*Mapping.ObjectAddress] = std::make_pair( | |
2184 *Mapping.ObjectAddress + Mapping.Size, | |
2185 int64_t(Mapping.BinaryAddress) - *Mapping.ObjectAddress); | |
2186 } | |
2187 } | |
2188 | |
2189 void DwarfLinker::endDebugObject() { | |
2190 Units.clear(); | |
2191 Ranges.clear(); | |
2192 | |
2193 for (auto I = DIEBlocks.begin(), E = DIEBlocks.end(); I != E; ++I) | |
2194 (*I)->~DIEBlock(); | |
2195 for (auto I = DIELocs.begin(), E = DIELocs.end(); I != E; ++I) | |
2196 (*I)->~DIELoc(); | |
2197 | |
2198 DIEBlocks.clear(); | |
2199 DIELocs.clear(); | |
2200 DIEAlloc.Reset(); | |
2201 } | |
2202 | |
2203 static bool isMachOPairedReloc(uint64_t RelocType, uint64_t Arch) { | |
2204 switch (Arch) { | |
2205 case Triple::x86: | |
2206 return RelocType == MachO::GENERIC_RELOC_SECTDIFF || | |
2207 RelocType == MachO::GENERIC_RELOC_LOCAL_SECTDIFF; | |
2208 case Triple::x86_64: | |
2209 return RelocType == MachO::X86_64_RELOC_SUBTRACTOR; | |
2210 case Triple::arm: | |
2211 case Triple::thumb: | |
2212 return RelocType == MachO::ARM_RELOC_SECTDIFF || | |
2213 RelocType == MachO::ARM_RELOC_LOCAL_SECTDIFF || | |
2214 RelocType == MachO::ARM_RELOC_HALF || | |
2215 RelocType == MachO::ARM_RELOC_HALF_SECTDIFF; | |
2216 case Triple::aarch64: | |
2217 return RelocType == MachO::ARM64_RELOC_SUBTRACTOR; | |
2218 default: | |
2219 return false; | |
2220 } | |
2221 } | |
2222 | |
2223 /// Iterate over the relocations of the given \p Section and | |
2224 /// store the ones that correspond to debug map entries into the | |
2225 /// ValidRelocs array. | |
2226 void DwarfLinker::RelocationManager:: | |
2227 findValidRelocsMachO(const object::SectionRef &Section, | |
2228 const object::MachOObjectFile &Obj, | |
2229 const DebugMapObject &DMO) { | |
2230 StringRef Contents; | |
2231 Section.getContents(Contents); | |
2232 DataExtractor Data(Contents, Obj.isLittleEndian(), 0); | |
2233 bool SkipNext = false; | |
2234 | |
2235 for (const object::RelocationRef &Reloc : Section.relocations()) { | |
2236 if (SkipNext) { | |
2237 SkipNext = false; | |
2238 continue; | |
2239 } | |
2240 | |
2241 object::DataRefImpl RelocDataRef = Reloc.getRawDataRefImpl(); | |
2242 MachO::any_relocation_info MachOReloc = Obj.getRelocation(RelocDataRef); | |
2243 | |
2244 if (isMachOPairedReloc(Obj.getAnyRelocationType(MachOReloc), | |
2245 Obj.getArch())) { | |
2246 SkipNext = true; | |
2247 Linker.reportWarning(" unsupported relocation in debug_info section."); | |
2248 continue; | |
2249 } | |
2250 | |
2251 unsigned RelocSize = 1 << Obj.getAnyRelocationLength(MachOReloc); | |
2252 uint64_t Offset64 = Reloc.getOffset(); | |
2253 if ((RelocSize != 4 && RelocSize != 8)) { | |
2254 Linker.reportWarning(" unsupported relocation in debug_info section."); | |
2255 continue; | |
2256 } | |
2257 uint32_t Offset = Offset64; | |
2258 // Mach-o uses REL relocations, the addend is at the relocation offset. | |
2259 uint64_t Addend = Data.getUnsigned(&Offset, RelocSize); | |
2260 uint64_t SymAddress; | |
2261 int64_t SymOffset; | |
2262 | |
2263 if (Obj.isRelocationScattered(MachOReloc)) { | |
2264 // The address of the base symbol for scattered relocations is | |
2265 // stored in the reloc itself. The actual addend will store the | |
2266 // base address plus the offset. | |
2267 SymAddress = Obj.getScatteredRelocationValue(MachOReloc); | |
2268 SymOffset = int64_t(Addend) - SymAddress; | |
2269 } else { | |
2270 SymAddress = Addend; | |
2271 SymOffset = 0; | |
2272 } | |
2273 | |
2274 auto Sym = Reloc.getSymbol(); | |
2275 if (Sym != Obj.symbol_end()) { | |
2276 Expected<StringRef> SymbolName = Sym->getName(); | |
2277 if (!SymbolName) { | |
2278 consumeError(SymbolName.takeError()); | |
2279 Linker.reportWarning("error getting relocation symbol name."); | |
2280 continue; | |
2281 } | |
2282 if (const auto *Mapping = DMO.lookupSymbol(*SymbolName)) | |
2283 ValidRelocs.emplace_back(Offset64, RelocSize, Addend, Mapping); | |
2284 } else if (const auto *Mapping = DMO.lookupObjectAddress(SymAddress)) { | |
2285 // Do not store the addend. The addend was the address of the | |
2286 // symbol in the object file, the address in the binary that is | |
2287 // stored in the debug map doesn't need to be offseted. | |
2288 ValidRelocs.emplace_back(Offset64, RelocSize, SymOffset, Mapping); | |
2289 } | |
2290 } | |
2291 } | |
2292 | |
2293 /// Dispatch the valid relocation finding logic to the | |
2294 /// appropriate handler depending on the object file format. | |
2295 bool DwarfLinker::RelocationManager::findValidRelocs( | |
2296 const object::SectionRef &Section, const object::ObjectFile &Obj, | |
2297 const DebugMapObject &DMO) { | |
2298 // Dispatch to the right handler depending on the file type. | |
2299 if (auto *MachOObj = dyn_cast<object::MachOObjectFile>(&Obj)) | |
2300 findValidRelocsMachO(Section, *MachOObj, DMO); | |
2301 else | |
2302 Linker.reportWarning(Twine("unsupported object file type: ") + | |
2303 Obj.getFileName()); | |
2304 | |
2305 if (ValidRelocs.empty()) | |
2306 return false; | |
2307 | |
2308 // Sort the relocations by offset. We will walk the DIEs linearly in | |
2309 // the file, this allows us to just keep an index in the relocation | |
2310 // array that we advance during our walk, rather than resorting to | |
2311 // some associative container. See DwarfLinker::NextValidReloc. | |
2312 std::sort(ValidRelocs.begin(), ValidRelocs.end()); | |
2313 return true; | |
2314 } | |
2315 | |
2316 /// Look for relocations in the debug_info section that match | |
2317 /// entries in the debug map. These relocations will drive the Dwarf | |
2318 /// link by indicating which DIEs refer to symbols present in the | |
2319 /// linked binary. | |
2320 /// \returns wether there are any valid relocations in the debug info. | |
2321 bool DwarfLinker::RelocationManager:: | |
2322 findValidRelocsInDebugInfo(const object::ObjectFile &Obj, | |
2323 const DebugMapObject &DMO) { | |
2324 // Find the debug_info section. | |
2325 for (const object::SectionRef &Section : Obj.sections()) { | |
2326 StringRef SectionName; | |
2327 Section.getName(SectionName); | |
2328 SectionName = SectionName.substr(SectionName.find_first_not_of("._")); | |
2329 if (SectionName != "debug_info") | |
2330 continue; | |
2331 return findValidRelocs(Section, Obj, DMO); | |
2332 } | |
2333 return false; | |
2334 } | |
2335 | |
2336 /// Checks that there is a relocation against an actual debug | |
2337 /// map entry between \p StartOffset and \p NextOffset. | |
2338 /// | |
2339 /// This function must be called with offsets in strictly ascending | |
2340 /// order because it never looks back at relocations it already 'went past'. | |
2341 /// \returns true and sets Info.InDebugMap if it is the case. | |
2342 bool DwarfLinker::RelocationManager:: | |
2343 hasValidRelocation(uint32_t StartOffset, uint32_t EndOffset, | |
2344 CompileUnit::DIEInfo &Info) { | |
2345 assert(NextValidReloc == 0 || | |
2346 StartOffset > ValidRelocs[NextValidReloc - 1].Offset); | |
2347 if (NextValidReloc >= ValidRelocs.size()) | |
2348 return false; | |
2349 | |
2350 uint64_t RelocOffset = ValidRelocs[NextValidReloc].Offset; | |
2351 | |
2352 // We might need to skip some relocs that we didn't consider. For | |
2353 // example the high_pc of a discarded DIE might contain a reloc that | |
2354 // is in the list because it actually corresponds to the start of a | |
2355 // function that is in the debug map. | |
2356 while (RelocOffset < StartOffset && NextValidReloc < ValidRelocs.size() - 1) | |
2357 RelocOffset = ValidRelocs[++NextValidReloc].Offset; | |
2358 | |
2359 if (RelocOffset < StartOffset || RelocOffset >= EndOffset) | |
2360 return false; | |
2361 | |
2362 const auto &ValidReloc = ValidRelocs[NextValidReloc++]; | |
2363 const auto &Mapping = ValidReloc.Mapping->getValue(); | |
2364 uint64_t ObjectAddress = Mapping.ObjectAddress | |
2365 ? uint64_t(*Mapping.ObjectAddress) | |
2366 : std::numeric_limits<uint64_t>::max(); | |
2367 if (Linker.Options.Verbose) | |
2368 outs() << "Found valid debug map entry: " << ValidReloc.Mapping->getKey() | |
2369 << " " << format("\t%016" PRIx64 " => %016" PRIx64, ObjectAddress, | |
2370 uint64_t(Mapping.BinaryAddress)); | |
2371 | |
2372 Info.AddrAdjust = int64_t(Mapping.BinaryAddress) + ValidReloc.Addend; | |
2373 if (Mapping.ObjectAddress) | |
2374 Info.AddrAdjust -= ObjectAddress; | |
2375 Info.InDebugMap = true; | |
2376 return true; | |
2377 } | |
2378 | |
2379 /// Get the starting and ending (exclusive) offset for the | |
2380 /// attribute with index \p Idx descibed by \p Abbrev. \p Offset is | |
2381 /// supposed to point to the position of the first attribute described | |
2382 /// by \p Abbrev. | |
2383 /// \return [StartOffset, EndOffset) as a pair. | |
2384 static std::pair<uint32_t, uint32_t> | |
2385 getAttributeOffsets(const DWARFAbbreviationDeclaration *Abbrev, unsigned Idx, | |
2386 unsigned Offset, const DWARFUnit &Unit) { | |
2387 DataExtractor Data = Unit.getDebugInfoExtractor(); | |
2388 | |
2389 for (unsigned i = 0; i < Idx; ++i) | |
2390 DWARFFormValue::skipValue(Abbrev->getFormByIndex(i), Data, &Offset, | |
2391 Unit.getFormParams()); | |
2392 | |
2393 uint32_t End = Offset; | |
2394 DWARFFormValue::skipValue(Abbrev->getFormByIndex(Idx), Data, &End, | |
2395 Unit.getFormParams()); | |
2396 | |
2397 return std::make_pair(Offset, End); | |
2398 } | |
2399 | |
2400 /// Check if a variable describing DIE should be kept. | |
2401 /// \returns updated TraversalFlags. | |
2402 unsigned DwarfLinker::shouldKeepVariableDIE(RelocationManager &RelocMgr, | |
2403 const DWARFDie &DIE, | |
2404 CompileUnit &Unit, | |
2405 CompileUnit::DIEInfo &MyInfo, | |
2406 unsigned Flags) { | |
2407 const auto *Abbrev = DIE.getAbbreviationDeclarationPtr(); | |
2408 | |
2409 // Global variables with constant value can always be kept. | |
2410 if (!(Flags & TF_InFunctionScope) && | |
2411 Abbrev->findAttributeIndex(dwarf::DW_AT_const_value)) { | |
2412 MyInfo.InDebugMap = true; | |
2413 return Flags | TF_Keep; | |
2414 } | |
2415 | |
2416 Optional<uint32_t> LocationIdx = | |
2417 Abbrev->findAttributeIndex(dwarf::DW_AT_location); | |
2418 if (!LocationIdx) | |
2419 return Flags; | |
2420 | |
2421 uint32_t Offset = DIE.getOffset() + getULEB128Size(Abbrev->getCode()); | |
2422 const DWARFUnit &OrigUnit = Unit.getOrigUnit(); | |
2423 uint32_t LocationOffset, LocationEndOffset; | |
2424 std::tie(LocationOffset, LocationEndOffset) = | |
2425 getAttributeOffsets(Abbrev, *LocationIdx, Offset, OrigUnit); | |
2426 | |
2427 // See if there is a relocation to a valid debug map entry inside | |
2428 // this variable's location. The order is important here. We want to | |
2429 // always check in the variable has a valid relocation, so that the | |
2430 // DIEInfo is filled. However, we don't want a static variable in a | |
2431 // function to force us to keep the enclosing function. | |
2432 if (!RelocMgr.hasValidRelocation(LocationOffset, LocationEndOffset, MyInfo) || | |
2433 (Flags & TF_InFunctionScope)) | |
2434 return Flags; | |
2435 | |
2436 if (Options.Verbose) { | |
2437 DIDumpOptions DumpOpts; | |
2438 DumpOpts.RecurseDepth = 0; | |
2439 DumpOpts.Verbose = Options.Verbose; | |
2440 DIE.dump(outs(), 8 /* Indent */, DumpOpts); | |
2441 } | |
2442 | |
2443 return Flags | TF_Keep; | |
2444 } | |
2445 | |
2446 /// Check if a function describing DIE should be kept. | |
2447 /// \returns updated TraversalFlags. | |
2448 unsigned DwarfLinker::shouldKeepSubprogramDIE( | |
2449 RelocationManager &RelocMgr, | |
2450 const DWARFDie &DIE, CompileUnit &Unit, | |
2451 CompileUnit::DIEInfo &MyInfo, unsigned Flags) { | |
2452 const auto *Abbrev = DIE.getAbbreviationDeclarationPtr(); | |
2453 | |
2454 Flags |= TF_InFunctionScope; | |
2455 | |
2456 Optional<uint32_t> LowPcIdx = Abbrev->findAttributeIndex(dwarf::DW_AT_low_pc); | |
2457 if (!LowPcIdx) | |
2458 return Flags; | |
2459 | |
2460 uint32_t Offset = DIE.getOffset() + getULEB128Size(Abbrev->getCode()); | |
2461 const DWARFUnit &OrigUnit = Unit.getOrigUnit(); | |
2462 uint32_t LowPcOffset, LowPcEndOffset; | |
2463 std::tie(LowPcOffset, LowPcEndOffset) = | |
2464 getAttributeOffsets(Abbrev, *LowPcIdx, Offset, OrigUnit); | |
2465 | |
2466 auto LowPc = dwarf::toAddress(DIE.find(dwarf::DW_AT_low_pc)); | |
2467 assert(LowPc.hasValue() && "low_pc attribute is not an address."); | |
2468 if (!LowPc || | |
2469 !RelocMgr.hasValidRelocation(LowPcOffset, LowPcEndOffset, MyInfo)) | |
2470 return Flags; | |
2471 | |
2472 if (Options.Verbose) { | |
2473 DIDumpOptions DumpOpts; | |
2474 DumpOpts.RecurseDepth = 0; | |
2475 DumpOpts.Verbose = Options.Verbose; | |
2476 DIE.dump(outs(), 8 /* Indent */, DumpOpts); | |
2477 } | |
2478 | |
2479 Flags |= TF_Keep; | |
2480 | |
2481 Optional<uint64_t> HighPc = DIE.getHighPC(*LowPc); | |
2482 if (!HighPc) { | |
2483 reportWarning("Function without high_pc. Range will be discarded.\n", | |
2484 &DIE); | |
2485 return Flags; | |
2486 } | |
2487 | |
2488 // Replace the debug map range with a more accurate one. | |
2489 Ranges[*LowPc] = std::make_pair(*HighPc, MyInfo.AddrAdjust); | |
2490 Unit.addFunctionRange(*LowPc, *HighPc, MyInfo.AddrAdjust); | |
2491 return Flags; | |
2492 } | |
2493 | |
2494 /// Check if a DIE should be kept. | |
2495 /// \returns updated TraversalFlags. | |
2496 unsigned DwarfLinker::shouldKeepDIE(RelocationManager &RelocMgr, | |
2497 const DWARFDie &DIE, | |
2498 CompileUnit &Unit, | |
2499 CompileUnit::DIEInfo &MyInfo, | |
2500 unsigned Flags) { | |
2501 switch (DIE.getTag()) { | |
2502 case dwarf::DW_TAG_constant: | |
2503 case dwarf::DW_TAG_variable: | |
2504 return shouldKeepVariableDIE(RelocMgr, DIE, Unit, MyInfo, Flags); | |
2505 case dwarf::DW_TAG_subprogram: | |
2506 return shouldKeepSubprogramDIE(RelocMgr, DIE, Unit, MyInfo, Flags); | |
2507 case dwarf::DW_TAG_imported_module: | |
2508 case dwarf::DW_TAG_imported_declaration: | |
2509 case dwarf::DW_TAG_imported_unit: | |
2510 // We always want to keep these. | |
2511 return Flags | TF_Keep; | |
2512 default: | |
2513 break; | |
2514 } | |
2515 | |
2516 return Flags; | |
2517 } | |
2518 | |
2519 /// Mark the passed DIE as well as all the ones it depends on | |
2520 /// as kept. | |
2521 /// | |
2522 /// This function is called by lookForDIEsToKeep on DIEs that are | |
2523 /// newly discovered to be needed in the link. It recursively calls | |
2524 /// back to lookForDIEsToKeep while adding TF_DependencyWalk to the | |
2525 /// TraversalFlags to inform it that it's not doing the primary DIE | |
2526 /// tree walk. | |
2527 void DwarfLinker::keepDIEAndDependencies(RelocationManager &RelocMgr, | |
2528 const DWARFDie &Die, | |
2529 CompileUnit::DIEInfo &MyInfo, | |
2530 const DebugMapObject &DMO, | |
2531 CompileUnit &CU, bool UseODR) { | |
2532 DWARFUnit &Unit = CU.getOrigUnit(); | |
2533 MyInfo.Keep = true; | |
2534 | |
2535 // We're looking for incomplete types. | |
2536 MyInfo.Incomplete = Die.getTag() != dwarf::DW_TAG_subprogram && | |
2537 Die.getTag() != dwarf::DW_TAG_member && | |
2538 dwarf::toUnsigned(Die.find(dwarf::DW_AT_declaration), 0); | |
2539 | |
2540 // First mark all the parent chain as kept. | |
2541 unsigned AncestorIdx = MyInfo.ParentIdx; | |
2542 while (!CU.getInfo(AncestorIdx).Keep) { | |
2543 unsigned ODRFlag = UseODR ? TF_ODR : 0; | |
2544 lookForDIEsToKeep(RelocMgr, Unit.getDIEAtIndex(AncestorIdx), DMO, CU, | |
2545 TF_ParentWalk | TF_Keep | TF_DependencyWalk | ODRFlag); | |
2546 AncestorIdx = CU.getInfo(AncestorIdx).ParentIdx; | |
2547 } | |
2548 | |
2549 // Then we need to mark all the DIEs referenced by this DIE's | |
2550 // attributes as kept. | |
2551 DWARFDataExtractor Data = Unit.getDebugInfoExtractor(); | |
2552 const auto *Abbrev = Die.getAbbreviationDeclarationPtr(); | |
2553 uint32_t Offset = Die.getOffset() + getULEB128Size(Abbrev->getCode()); | |
2554 | |
2555 // Mark all DIEs referenced through attributes as kept. | |
2556 for (const auto &AttrSpec : Abbrev->attributes()) { | |
2557 DWARFFormValue Val(AttrSpec.Form); | |
2558 | |
2559 if (!Val.isFormClass(DWARFFormValue::FC_Reference)) { | |
2560 DWARFFormValue::skipValue(AttrSpec.Form, Data, &Offset, | |
2561 Unit.getFormParams()); | |
2562 continue; | |
2563 } | |
2564 | |
2565 Val.extractValue(Data, &Offset, Unit.getFormParams(), &Unit); | |
2566 CompileUnit *ReferencedCU; | |
2567 if (auto RefDie = | |
2568 resolveDIEReference(*this, Units, Val, Unit, Die, ReferencedCU)) { | |
2569 uint32_t RefIdx = ReferencedCU->getOrigUnit().getDIEIndex(RefDie); | |
2570 CompileUnit::DIEInfo &Info = ReferencedCU->getInfo(RefIdx); | |
2571 bool IsModuleRef = Info.Ctxt && Info.Ctxt->getCanonicalDIEOffset() && | |
2572 Info.Ctxt->isDefinedInClangModule(); | |
2573 // If the referenced DIE has a DeclContext that has already been | |
2574 // emitted, then do not keep the one in this CU. We'll link to | |
2575 // the canonical DIE in cloneDieReferenceAttribute. | |
2576 // FIXME: compatibility with dsymutil-classic. UseODR shouldn't | |
2577 // be necessary and could be advantageously replaced by | |
2578 // ReferencedCU->hasODR() && CU.hasODR(). | |
2579 // FIXME: compatibility with dsymutil-classic. There is no | |
2580 // reason not to unique ref_addr references. | |
2581 if (AttrSpec.Form != dwarf::DW_FORM_ref_addr && (UseODR || IsModuleRef) && | |
2582 Info.Ctxt && | |
2583 Info.Ctxt != ReferencedCU->getInfo(Info.ParentIdx).Ctxt && | |
2584 Info.Ctxt->getCanonicalDIEOffset() && isODRAttribute(AttrSpec.Attr)) | |
2585 continue; | |
2586 | |
2587 // Keep a module forward declaration if there is no definition. | |
2588 if (!(isODRAttribute(AttrSpec.Attr) && Info.Ctxt && | |
2589 Info.Ctxt->getCanonicalDIEOffset())) | |
2590 Info.Prune = false; | |
2591 | |
2592 unsigned ODRFlag = UseODR ? TF_ODR : 0; | |
2593 lookForDIEsToKeep(RelocMgr, RefDie, DMO, *ReferencedCU, | |
2594 TF_Keep | TF_DependencyWalk | ODRFlag); | |
2595 | |
2596 // The incomplete property is propagated if the current DIE is complete | |
2597 // but references an incomplete DIE. | |
2598 if (Info.Incomplete && !MyInfo.Incomplete && | |
2599 (Die.getTag() == dwarf::DW_TAG_typedef || | |
2600 Die.getTag() == dwarf::DW_TAG_member || | |
2601 Die.getTag() == dwarf::DW_TAG_reference_type || | |
2602 Die.getTag() == dwarf::DW_TAG_ptr_to_member_type || | |
2603 Die.getTag() == dwarf::DW_TAG_pointer_type)) | |
2604 MyInfo.Incomplete = true; | |
2605 } | |
2606 } | |
2607 } | |
2608 | |
2609 /// Recursively walk the \p DIE tree and look for DIEs to | |
2610 /// keep. Store that information in \p CU's DIEInfo. | |
2611 /// | |
2612 /// This function is the entry point of the DIE selection | |
2613 /// algorithm. It is expected to walk the DIE tree in file order and | |
2614 /// (though the mediation of its helper) call hasValidRelocation() on | |
2615 /// each DIE that might be a 'root DIE' (See DwarfLinker class | |
2616 /// comment). | |
2617 /// While walking the dependencies of root DIEs, this function is | |
2618 /// also called, but during these dependency walks the file order is | |
2619 /// not respected. The TF_DependencyWalk flag tells us which kind of | |
2620 /// traversal we are currently doing. | |
2621 /// | |
2622 /// The return value indicates whether the DIE is incomplete. | |
2623 bool DwarfLinker::lookForDIEsToKeep(RelocationManager &RelocMgr, | |
2624 const DWARFDie &Die, | |
2625 const DebugMapObject &DMO, CompileUnit &CU, | |
2626 unsigned Flags) { | |
2627 unsigned Idx = CU.getOrigUnit().getDIEIndex(Die); | |
2628 CompileUnit::DIEInfo &MyInfo = CU.getInfo(Idx); | |
2629 bool AlreadyKept = MyInfo.Keep; | |
2630 if (MyInfo.Prune) | |
2631 return true; | |
2632 | |
2633 // If the Keep flag is set, we are marking a required DIE's | |
2634 // dependencies. If our target is already marked as kept, we're all | |
2635 // set. | |
2636 if ((Flags & TF_DependencyWalk) && AlreadyKept) | |
2637 return MyInfo.Incomplete; | |
2638 | |
2639 // We must not call shouldKeepDIE while called from keepDIEAndDependencies, | |
2640 // because it would screw up the relocation finding logic. | |
2641 if (!(Flags & TF_DependencyWalk)) | |
2642 Flags = shouldKeepDIE(RelocMgr, Die, CU, MyInfo, Flags); | |
2643 | |
2644 // If it is a newly kept DIE mark it as well as all its dependencies as kept. | |
2645 if (!AlreadyKept && (Flags & TF_Keep)) { | |
2646 bool UseOdr = (Flags & TF_DependencyWalk) ? (Flags & TF_ODR) : CU.hasODR(); | |
2647 keepDIEAndDependencies(RelocMgr, Die, MyInfo, DMO, CU, UseOdr); | |
2648 } | |
2649 // The TF_ParentWalk flag tells us that we are currently walking up | |
2650 // the parent chain of a required DIE, and we don't want to mark all | |
2651 // the children of the parents as kept (consider for example a | |
2652 // DW_TAG_namespace node in the parent chain). There are however a | |
2653 // set of DIE types for which we want to ignore that directive and still | |
2654 // walk their children. | |
2655 if (dieNeedsChildrenToBeMeaningful(Die.getTag())) | |
2656 Flags &= ~TF_ParentWalk; | |
2657 | |
2658 if (!Die.hasChildren() || (Flags & TF_ParentWalk)) | |
2659 return MyInfo.Incomplete; | |
2660 | |
2661 bool Incomplete = false; | |
2662 for (auto Child : Die.children()) { | |
2663 Incomplete |= lookForDIEsToKeep(RelocMgr, Child, DMO, CU, Flags); | |
2664 | |
2665 // If any of the members are incomplete we propagate the incompleteness. | |
2666 if (!MyInfo.Incomplete && Incomplete && | |
2667 (Die.getTag() == dwarf::DW_TAG_structure_type || | |
2668 Die.getTag() == dwarf::DW_TAG_class_type)) | |
2669 MyInfo.Incomplete = true; | |
2670 } | |
2671 return MyInfo.Incomplete; | |
2672 } | |
2673 | |
2674 /// Assign an abbreviation numer to \p Abbrev. | |
2675 /// | |
2676 /// Our DIEs get freed after every DebugMapObject has been processed, | |
2677 /// thus the FoldingSet we use to unique DIEAbbrevs cannot refer to | |
2678 /// the instances hold by the DIEs. When we encounter an abbreviation | |
2679 /// that we don't know, we create a permanent copy of it. | |
2680 void DwarfLinker::AssignAbbrev(DIEAbbrev &Abbrev) { | |
2681 // Check the set for priors. | |
2682 FoldingSetNodeID ID; | |
2683 Abbrev.Profile(ID); | |
2684 void *InsertToken; | |
2685 DIEAbbrev *InSet = AbbreviationsSet.FindNodeOrInsertPos(ID, InsertToken); | |
2686 | |
2687 // If it's newly added. | |
2688 if (InSet) { | |
2689 // Assign existing abbreviation number. | |
2690 Abbrev.setNumber(InSet->getNumber()); | |
2691 } else { | |
2692 // Add to abbreviation list. | |
2693 Abbreviations.push_back( | |
2694 llvm::make_unique<DIEAbbrev>(Abbrev.getTag(), Abbrev.hasChildren())); | |
2695 for (const auto &Attr : Abbrev.getData()) | |
2696 Abbreviations.back()->AddAttribute(Attr.getAttribute(), Attr.getForm()); | |
2697 AbbreviationsSet.InsertNode(Abbreviations.back().get(), InsertToken); | |
2698 // Assign the unique abbreviation number. | |
2699 Abbrev.setNumber(Abbreviations.size()); | |
2700 Abbreviations.back()->setNumber(Abbreviations.size()); | |
2701 } | |
2702 } | |
2703 | |
2704 unsigned DwarfLinker::DIECloner::cloneStringAttribute(DIE &Die, | |
2705 AttributeSpec AttrSpec, | |
2706 const DWARFFormValue &Val, | |
2707 const DWARFUnit &U, | |
2708 AttributesInfo &Info) { | |
2709 // Switch everything to out of line strings. | |
2710 const char *String = *Val.getAsCString(); | |
2711 auto StringEntry = Linker.StringPool.getEntry(String); | |
2712 if (AttrSpec.Attr == dwarf::DW_AT_name) | |
2713 Info.Name = StringEntry; | |
2714 else if (AttrSpec.Attr == dwarf::DW_AT_MIPS_linkage_name || | |
2715 AttrSpec.Attr == dwarf::DW_AT_linkage_name) | |
2716 Info.MangledName = StringEntry; | |
2717 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr), dwarf::DW_FORM_strp, | |
2718 DIEInteger(StringEntry.getOffset())); | |
2719 return 4; | |
2720 } | |
2721 | |
2722 unsigned DwarfLinker::DIECloner::cloneDieReferenceAttribute( | |
2723 DIE &Die, const DWARFDie &InputDIE, | |
2724 AttributeSpec AttrSpec, unsigned AttrSize, const DWARFFormValue &Val, | |
2725 CompileUnit &Unit) { | |
2726 const DWARFUnit &U = Unit.getOrigUnit(); | |
2727 uint32_t Ref = *Val.getAsReference(); | |
2728 DIE *NewRefDie = nullptr; | |
2729 CompileUnit *RefUnit = nullptr; | |
2730 DeclContext *Ctxt = nullptr; | |
2731 | |
2732 DWARFDie RefDie = resolveDIEReference(Linker, CompileUnits, Val, U, InputDIE, | |
2733 RefUnit); | |
2734 | |
2735 // If the referenced DIE is not found, drop the attribute. | |
2736 if (!RefDie) | |
2737 return 0; | |
2738 | |
2739 unsigned Idx = RefUnit->getOrigUnit().getDIEIndex(RefDie); | |
2740 CompileUnit::DIEInfo &RefInfo = RefUnit->getInfo(Idx); | |
2741 | |
2742 // If we already have emitted an equivalent DeclContext, just point | |
2743 // at it. | |
2744 if (isODRAttribute(AttrSpec.Attr)) { | |
2745 Ctxt = RefInfo.Ctxt; | |
2746 if (Ctxt && Ctxt->getCanonicalDIEOffset()) { | |
2747 DIEInteger Attr(Ctxt->getCanonicalDIEOffset()); | |
2748 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr), | |
2749 dwarf::DW_FORM_ref_addr, Attr); | |
2750 return U.getRefAddrByteSize(); | |
2751 } | |
2752 } | |
2753 | |
2754 if (!RefInfo.Clone) { | |
2755 assert(Ref > InputDIE.getOffset()); | |
2756 // We haven't cloned this DIE yet. Just create an empty one and | |
2757 // store it. It'll get really cloned when we process it. | |
2758 RefInfo.Clone = DIE::get(DIEAlloc, dwarf::Tag(RefDie.getTag())); | |
2759 } | |
2760 NewRefDie = RefInfo.Clone; | |
2761 | |
2762 if (AttrSpec.Form == dwarf::DW_FORM_ref_addr || | |
2763 (Unit.hasODR() && isODRAttribute(AttrSpec.Attr))) { | |
2764 // We cannot currently rely on a DIEEntry to emit ref_addr | |
2765 // references, because the implementation calls back to DwarfDebug | |
2766 // to find the unit offset. (We don't have a DwarfDebug) | |
2767 // FIXME: we should be able to design DIEEntry reliance on | |
2768 // DwarfDebug away. | |
2769 uint64_t Attr; | |
2770 if (Ref < InputDIE.getOffset()) { | |
2771 // We must have already cloned that DIE. | |
2772 uint32_t NewRefOffset = | |
2773 RefUnit->getStartOffset() + NewRefDie->getOffset(); | |
2774 Attr = NewRefOffset; | |
2775 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr), | |
2776 dwarf::DW_FORM_ref_addr, DIEInteger(Attr)); | |
2777 } else { | |
2778 // A forward reference. Note and fixup later. | |
2779 Attr = 0xBADDEF; | |
2780 Unit.noteForwardReference( | |
2781 NewRefDie, RefUnit, Ctxt, | |
2782 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr), | |
2783 dwarf::DW_FORM_ref_addr, DIEInteger(Attr))); | |
2784 } | |
2785 return U.getRefAddrByteSize(); | |
2786 } | |
2787 | |
2788 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr), | |
2789 dwarf::Form(AttrSpec.Form), DIEEntry(*NewRefDie)); | |
2790 return AttrSize; | |
2791 } | |
2792 | |
2793 unsigned DwarfLinker::DIECloner::cloneBlockAttribute(DIE &Die, | |
2794 AttributeSpec AttrSpec, | |
2795 const DWARFFormValue &Val, | |
2796 unsigned AttrSize) { | |
2797 DIEValueList *Attr; | |
2798 DIEValue Value; | |
2799 DIELoc *Loc = nullptr; | |
2800 DIEBlock *Block = nullptr; | |
2801 // Just copy the block data over. | |
2802 if (AttrSpec.Form == dwarf::DW_FORM_exprloc) { | |
2803 Loc = new (DIEAlloc) DIELoc; | |
2804 Linker.DIELocs.push_back(Loc); | |
2805 } else { | |
2806 Block = new (DIEAlloc) DIEBlock; | |
2807 Linker.DIEBlocks.push_back(Block); | |
2808 } | |
2809 Attr = Loc ? static_cast<DIEValueList *>(Loc) | |
2810 : static_cast<DIEValueList *>(Block); | |
2811 | |
2812 if (Loc) | |
2813 Value = DIEValue(dwarf::Attribute(AttrSpec.Attr), | |
2814 dwarf::Form(AttrSpec.Form), Loc); | |
2815 else | |
2816 Value = DIEValue(dwarf::Attribute(AttrSpec.Attr), | |
2817 dwarf::Form(AttrSpec.Form), Block); | |
2818 ArrayRef<uint8_t> Bytes = *Val.getAsBlock(); | |
2819 for (auto Byte : Bytes) | |
2820 Attr->addValue(DIEAlloc, static_cast<dwarf::Attribute>(0), | |
2821 dwarf::DW_FORM_data1, DIEInteger(Byte)); | |
2822 // FIXME: If DIEBlock and DIELoc just reuses the Size field of | |
2823 // the DIE class, this if could be replaced by | |
2824 // Attr->setSize(Bytes.size()). | |
2825 if (Linker.Streamer) { | |
2826 auto *AsmPrinter = &Linker.Streamer->getAsmPrinter(); | |
2827 if (Loc) | |
2828 Loc->ComputeSize(AsmPrinter); | |
2829 else | |
2830 Block->ComputeSize(AsmPrinter); | |
2831 } | |
2832 Die.addValue(DIEAlloc, Value); | |
2833 return AttrSize; | |
2834 } | |
2835 | |
2836 unsigned DwarfLinker::DIECloner::cloneAddressAttribute( | |
2837 DIE &Die, AttributeSpec AttrSpec, const DWARFFormValue &Val, | |
2838 const CompileUnit &Unit, AttributesInfo &Info) { | |
2839 uint64_t Addr = *Val.getAsAddress(); | |
2840 | |
2841 if (LLVM_UNLIKELY(Linker.Options.Update)) { | |
2842 if (AttrSpec.Attr == dwarf::DW_AT_low_pc) | |
2843 Info.HasLowPc = true; | |
2844 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr), | |
2845 dwarf::Form(AttrSpec.Form), DIEInteger(Addr)); | |
2846 return Unit.getOrigUnit().getAddressByteSize(); | |
2847 } | |
2848 | |
2849 if (AttrSpec.Attr == dwarf::DW_AT_low_pc) { | |
2850 if (Die.getTag() == dwarf::DW_TAG_inlined_subroutine || | |
2851 Die.getTag() == dwarf::DW_TAG_lexical_block) | |
2852 // The low_pc of a block or inline subroutine might get | |
2853 // relocated because it happens to match the low_pc of the | |
2854 // enclosing subprogram. To prevent issues with that, always use | |
2855 // the low_pc from the input DIE if relocations have been applied. | |
2856 Addr = (Info.OrigLowPc != std::numeric_limits<uint64_t>::max() | |
2857 ? Info.OrigLowPc | |
2858 : Addr) + | |
2859 Info.PCOffset; | |
2860 else if (Die.getTag() == dwarf::DW_TAG_compile_unit) { | |
2861 Addr = Unit.getLowPc(); | |
2862 if (Addr == std::numeric_limits<uint64_t>::max()) | |
2863 return 0; | |
2864 } | |
2865 Info.HasLowPc = true; | |
2866 } else if (AttrSpec.Attr == dwarf::DW_AT_high_pc) { | |
2867 if (Die.getTag() == dwarf::DW_TAG_compile_unit) { | |
2868 if (uint64_t HighPc = Unit.getHighPc()) | |
2869 Addr = HighPc; | |
2870 else | |
2871 return 0; | |
2872 } else | |
2873 // If we have a high_pc recorded for the input DIE, use | |
2874 // it. Otherwise (when no relocations where applied) just use the | |
2875 // one we just decoded. | |
2876 Addr = (Info.OrigHighPc ? Info.OrigHighPc : Addr) + Info.PCOffset; | |
2877 } | |
2878 | |
2879 Die.addValue(DIEAlloc, static_cast<dwarf::Attribute>(AttrSpec.Attr), | |
2880 static_cast<dwarf::Form>(AttrSpec.Form), DIEInteger(Addr)); | |
2881 return Unit.getOrigUnit().getAddressByteSize(); | |
2882 } | |
2883 | |
2884 unsigned DwarfLinker::DIECloner::cloneScalarAttribute( | |
2885 DIE &Die, const DWARFDie &InputDIE, CompileUnit &Unit, | |
2886 AttributeSpec AttrSpec, const DWARFFormValue &Val, unsigned AttrSize, | |
2887 AttributesInfo &Info) { | |
2888 uint64_t Value; | |
2889 | |
2890 if (LLVM_UNLIKELY(Linker.Options.Update)) { | |
2891 if (auto OptionalValue = Val.getAsUnsignedConstant()) | |
2892 Value = *OptionalValue; | |
2893 else if (auto OptionalValue = Val.getAsSignedConstant()) | |
2894 Value = *OptionalValue; | |
2895 else if (auto OptionalValue = Val.getAsSectionOffset()) | |
2896 Value = *OptionalValue; | |
2897 else { | |
2898 Linker.reportWarning( | |
2899 "Unsupported scalar attribute form. Dropping attribute.", &InputDIE); | |
2900 return 0; | |
2901 } | |
2902 if (AttrSpec.Attr == dwarf::DW_AT_declaration && Value) | |
2903 Info.IsDeclaration = true; | |
2904 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr), | |
2905 dwarf::Form(AttrSpec.Form), DIEInteger(Value)); | |
2906 return AttrSize; | |
2907 } | |
2908 | |
2909 if (AttrSpec.Attr == dwarf::DW_AT_high_pc && | |
2910 Die.getTag() == dwarf::DW_TAG_compile_unit) { | |
2911 if (Unit.getLowPc() == -1ULL) | |
2912 return 0; | |
2913 // Dwarf >= 4 high_pc is an size, not an address. | |
2914 Value = Unit.getHighPc() - Unit.getLowPc(); | |
2915 } else if (AttrSpec.Form == dwarf::DW_FORM_sec_offset) | |
2916 Value = *Val.getAsSectionOffset(); | |
2917 else if (AttrSpec.Form == dwarf::DW_FORM_sdata) | |
2918 Value = *Val.getAsSignedConstant(); | |
2919 else if (auto OptionalValue = Val.getAsUnsignedConstant()) | |
2920 Value = *OptionalValue; | |
2921 else { | |
2922 Linker.reportWarning( | |
2923 "Unsupported scalar attribute form. Dropping attribute.", | |
2924 &InputDIE); | |
2925 return 0; | |
2926 } | |
2927 PatchLocation Patch = | |
2928 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr), | |
2929 dwarf::Form(AttrSpec.Form), DIEInteger(Value)); | |
2930 if (AttrSpec.Attr == dwarf::DW_AT_ranges) { | |
2931 Unit.noteRangeAttribute(Die, Patch); | |
2932 Info.HasRanges = true; | |
2933 } | |
2934 | |
2935 // A more generic way to check for location attributes would be | |
2936 // nice, but it's very unlikely that any other attribute needs a | |
2937 // location list. | |
2938 else if (AttrSpec.Attr == dwarf::DW_AT_location || | |
2939 AttrSpec.Attr == dwarf::DW_AT_frame_base) | |
2940 Unit.noteLocationAttribute(Patch, Info.PCOffset); | |
2941 else if (AttrSpec.Attr == dwarf::DW_AT_declaration && Value) | |
2942 Info.IsDeclaration = true; | |
2943 | |
2944 return AttrSize; | |
2945 } | |
2946 | |
2947 /// Clone \p InputDIE's attribute described by \p AttrSpec with | |
2948 /// value \p Val, and add it to \p Die. | |
2949 /// \returns the size of the cloned attribute. | |
2950 unsigned DwarfLinker::DIECloner::cloneAttribute( | |
2951 DIE &Die, const DWARFDie &InputDIE, CompileUnit &Unit, | |
2952 const DWARFFormValue &Val, const AttributeSpec AttrSpec, unsigned AttrSize, | |
2953 AttributesInfo &Info) { | |
2954 const DWARFUnit &U = Unit.getOrigUnit(); | |
2955 | |
2956 switch (AttrSpec.Form) { | |
2957 case dwarf::DW_FORM_strp: | |
2958 case dwarf::DW_FORM_string: | |
2959 return cloneStringAttribute(Die, AttrSpec, Val, U, Info); | |
2960 case dwarf::DW_FORM_ref_addr: | |
2961 case dwarf::DW_FORM_ref1: | |
2962 case dwarf::DW_FORM_ref2: | |
2963 case dwarf::DW_FORM_ref4: | |
2964 case dwarf::DW_FORM_ref8: | |
2965 return cloneDieReferenceAttribute(Die, InputDIE, AttrSpec, AttrSize, Val, | |
2966 Unit); | |
2967 case dwarf::DW_FORM_block: | |
2968 case dwarf::DW_FORM_block1: | |
2969 case dwarf::DW_FORM_block2: | |
2970 case dwarf::DW_FORM_block4: | |
2971 case dwarf::DW_FORM_exprloc: | |
2972 return cloneBlockAttribute(Die, AttrSpec, Val, AttrSize); | |
2973 case dwarf::DW_FORM_addr: | |
2974 return cloneAddressAttribute(Die, AttrSpec, Val, Unit, Info); | |
2975 case dwarf::DW_FORM_data1: | |
2976 case dwarf::DW_FORM_data2: | |
2977 case dwarf::DW_FORM_data4: | |
2978 case dwarf::DW_FORM_data8: | |
2979 case dwarf::DW_FORM_udata: | |
2980 case dwarf::DW_FORM_sdata: | |
2981 case dwarf::DW_FORM_sec_offset: | |
2982 case dwarf::DW_FORM_flag: | |
2983 case dwarf::DW_FORM_flag_present: | |
2984 return cloneScalarAttribute(Die, InputDIE, Unit, AttrSpec, Val, AttrSize, | |
2985 Info); | |
2986 default: | |
2987 Linker.reportWarning( | |
2988 "Unsupported attribute form in cloneAttribute. Dropping.", &InputDIE); | |
2989 } | |
2990 | |
2991 return 0; | |
2992 } | |
2993 | |
2994 /// Apply the valid relocations found by findValidRelocs() to | |
2995 /// the buffer \p Data, taking into account that Data is at \p BaseOffset | |
2996 /// in the debug_info section. | |
2997 /// | |
2998 /// Like for findValidRelocs(), this function must be called with | |
2999 /// monotonic \p BaseOffset values. | |
3000 /// | |
3001 /// \returns wether any reloc has been applied. | |
3002 bool DwarfLinker::RelocationManager:: | |
3003 applyValidRelocs(MutableArrayRef<char> Data, uint32_t BaseOffset, | |
3004 bool isLittleEndian) { | |
3005 assert((NextValidReloc == 0 || | |
3006 BaseOffset > ValidRelocs[NextValidReloc - 1].Offset) && | |
3007 "BaseOffset should only be increasing."); | |
3008 if (NextValidReloc >= ValidRelocs.size()) | |
3009 return false; | |
3010 | |
3011 // Skip relocs that haven't been applied. | |
3012 while (NextValidReloc < ValidRelocs.size() && | |
3013 ValidRelocs[NextValidReloc].Offset < BaseOffset) | |
3014 ++NextValidReloc; | |
3015 | |
3016 bool Applied = false; | |
3017 uint64_t EndOffset = BaseOffset + Data.size(); | |
3018 while (NextValidReloc < ValidRelocs.size() && | |
3019 ValidRelocs[NextValidReloc].Offset >= BaseOffset && | |
3020 ValidRelocs[NextValidReloc].Offset < EndOffset) { | |
3021 const auto &ValidReloc = ValidRelocs[NextValidReloc++]; | |
3022 assert(ValidReloc.Offset - BaseOffset < Data.size()); | |
3023 assert(ValidReloc.Offset - BaseOffset + ValidReloc.Size <= Data.size()); | |
3024 char Buf[8]; | |
3025 uint64_t Value = ValidReloc.Mapping->getValue().BinaryAddress; | |
3026 Value += ValidReloc.Addend; | |
3027 for (unsigned i = 0; i != ValidReloc.Size; ++i) { | |
3028 unsigned Index = isLittleEndian ? i : (ValidReloc.Size - i - 1); | |
3029 Buf[i] = uint8_t(Value >> (Index * 8)); | |
3030 } | |
3031 assert(ValidReloc.Size <= sizeof(Buf)); | |
3032 memcpy(&Data[ValidReloc.Offset - BaseOffset], Buf, ValidReloc.Size); | |
3033 Applied = true; | |
3034 } | |
3035 | |
3036 return Applied; | |
3037 } | 153 } |
3038 | 154 |
3039 static bool isTypeTag(uint16_t Tag) { | 155 static bool isTypeTag(uint16_t Tag) { |
3040 switch (Tag) { | 156 switch (Tag) { |
3041 case dwarf::DW_TAG_array_type: | 157 case dwarf::DW_TAG_array_type: |
3068 break; | 184 break; |
3069 } | 185 } |
3070 return false; | 186 return false; |
3071 } | 187 } |
3072 | 188 |
189 bool DwarfLinker::DIECloner::getDIENames(const DWARFDie &Die, | |
190 AttributesInfo &Info, | |
191 OffsetsStringPool &StringPool, | |
192 bool StripTemplate) { | |
193 // This function will be called on DIEs having low_pcs and | |
194 // ranges. As getting the name might be more expansive, filter out | |
195 // blocks directly. | |
196 if (Die.getTag() == dwarf::DW_TAG_lexical_block) | |
197 return false; | |
198 | |
199 // FIXME: a bit wasteful as the first getName might return the | |
200 // short name. | |
201 if (!Info.MangledName) | |
202 if (const char *MangledName = Die.getName(DINameKind::LinkageName)) | |
203 Info.MangledName = StringPool.getEntry(MangledName); | |
204 | |
205 if (!Info.Name) | |
206 if (const char *Name = Die.getName(DINameKind::ShortName)) | |
207 Info.Name = StringPool.getEntry(Name); | |
208 | |
209 if (StripTemplate && Info.Name && Info.MangledName != Info.Name) { | |
210 // FIXME: dsymutil compatibility. This is wrong for operator< | |
211 auto Split = Info.Name.getString().split('<'); | |
212 if (!Split.second.empty()) | |
213 Info.NameWithoutTemplate = StringPool.getEntry(Split.first); | |
214 } | |
215 | |
216 return Info.Name || Info.MangledName; | |
217 } | |
218 | |
219 /// Report a warning to the user, optionally including information about a | |
220 /// specific \p DIE related to the warning. | |
221 void DwarfLinker::reportWarning(const Twine &Warning, const DebugMapObject &DMO, | |
222 const DWARFDie *DIE) const { | |
223 StringRef Context = DMO.getObjectFilename(); | |
224 warn(Warning, Context); | |
225 | |
226 if (!Options.Verbose || !DIE) | |
227 return; | |
228 | |
229 DIDumpOptions DumpOpts; | |
230 DumpOpts.ChildRecurseDepth = 0; | |
231 DumpOpts.Verbose = Options.Verbose; | |
232 | |
233 WithColor::note() << " in DIE:\n"; | |
234 DIE->dump(errs(), 6 /* Indent */, DumpOpts); | |
235 } | |
236 | |
237 bool DwarfLinker::createStreamer(const Triple &TheTriple, | |
238 raw_fd_ostream &OutFile) { | |
239 if (Options.NoOutput) | |
240 return true; | |
241 | |
242 Streamer = llvm::make_unique<DwarfStreamer>(OutFile, Options); | |
243 return Streamer->init(TheTriple); | |
244 } | |
245 | |
246 /// Resolve the relative path to a build artifact referenced by DWARF by | |
247 /// applying DW_AT_comp_dir. | |
248 static void resolveRelativeObjectPath(SmallVectorImpl<char> &Buf, DWARFDie CU) { | |
249 sys::path::append(Buf, dwarf::toString(CU.find(dwarf::DW_AT_comp_dir), "")); | |
250 } | |
251 | |
252 /// Collect references to parseable Swift interfaces in imported | |
253 /// DW_TAG_module blocks. | |
254 static void analyzeImportedModule( | |
255 const DWARFDie &DIE, CompileUnit &CU, | |
256 std::map<std::string, std::string> &ParseableSwiftInterfaces, | |
257 std::function<void(const Twine &, const DWARFDie &)> ReportWarning) { | |
258 if (CU.getLanguage() != dwarf::DW_LANG_Swift) | |
259 return; | |
260 | |
261 StringRef Path = dwarf::toStringRef(DIE.find(dwarf::DW_AT_LLVM_include_path)); | |
262 if (!Path.endswith(".swiftinterface")) | |
263 return; | |
264 if (Optional<DWARFFormValue> Val = DIE.find(dwarf::DW_AT_name)) | |
265 if (Optional<const char *> Name = Val->getAsCString()) { | |
266 auto &Entry = ParseableSwiftInterfaces[*Name]; | |
267 // The prepend path is applied later when copying. | |
268 DWARFDie CUDie = CU.getOrigUnit().getUnitDIE(); | |
269 SmallString<128> ResolvedPath; | |
270 if (sys::path::is_relative(Path)) | |
271 resolveRelativeObjectPath(ResolvedPath, CUDie); | |
272 sys::path::append(ResolvedPath, Path); | |
273 if (!Entry.empty() && Entry != ResolvedPath) | |
274 ReportWarning( | |
275 Twine("Conflicting parseable interfaces for Swift Module ") + | |
276 *Name + ": " + Entry + " and " + Path, | |
277 DIE); | |
278 Entry = ResolvedPath.str(); | |
279 } | |
280 } | |
281 | |
282 /// Recursive helper to build the global DeclContext information and | |
283 /// gather the child->parent relationships in the original compile unit. | |
284 /// | |
285 /// \return true when this DIE and all of its children are only | |
286 /// forward declarations to types defined in external clang modules | |
287 /// (i.e., forward declarations that are children of a DW_TAG_module). | |
288 static bool analyzeContextInfo( | |
289 const DWARFDie &DIE, unsigned ParentIdx, CompileUnit &CU, | |
290 DeclContext *CurrentDeclContext, UniquingStringPool &StringPool, | |
291 DeclContextTree &Contexts, uint64_t ModulesEndOffset, | |
292 std::map<std::string, std::string> &ParseableSwiftInterfaces, | |
293 std::function<void(const Twine &, const DWARFDie &)> ReportWarning, | |
294 bool InImportedModule = false) { | |
295 unsigned MyIdx = CU.getOrigUnit().getDIEIndex(DIE); | |
296 CompileUnit::DIEInfo &Info = CU.getInfo(MyIdx); | |
297 | |
298 // Clang imposes an ODR on modules(!) regardless of the language: | |
299 // "The module-id should consist of only a single identifier, | |
300 // which provides the name of the module being defined. Each | |
301 // module shall have a single definition." | |
302 // | |
303 // This does not extend to the types inside the modules: | |
304 // "[I]n C, this implies that if two structs are defined in | |
305 // different submodules with the same name, those two types are | |
306 // distinct types (but may be compatible types if their | |
307 // definitions match)." | |
308 // | |
309 // We treat non-C++ modules like namespaces for this reason. | |
310 if (DIE.getTag() == dwarf::DW_TAG_module && ParentIdx == 0 && | |
311 dwarf::toString(DIE.find(dwarf::DW_AT_name), "") != | |
312 CU.getClangModuleName()) { | |
313 InImportedModule = true; | |
314 analyzeImportedModule(DIE, CU, ParseableSwiftInterfaces, ReportWarning); | |
315 } | |
316 | |
317 Info.ParentIdx = ParentIdx; | |
318 bool InClangModule = CU.isClangModule() || InImportedModule; | |
319 if (CU.hasODR() || InClangModule) { | |
320 if (CurrentDeclContext) { | |
321 auto PtrInvalidPair = Contexts.getChildDeclContext( | |
322 *CurrentDeclContext, DIE, CU, StringPool, InClangModule); | |
323 CurrentDeclContext = PtrInvalidPair.getPointer(); | |
324 Info.Ctxt = | |
325 PtrInvalidPair.getInt() ? nullptr : PtrInvalidPair.getPointer(); | |
326 if (Info.Ctxt) | |
327 Info.Ctxt->setDefinedInClangModule(InClangModule); | |
328 } else | |
329 Info.Ctxt = CurrentDeclContext = nullptr; | |
330 } | |
331 | |
332 Info.Prune = InImportedModule; | |
333 if (DIE.hasChildren()) | |
334 for (auto Child : DIE.children()) | |
335 Info.Prune &= analyzeContextInfo(Child, MyIdx, CU, CurrentDeclContext, | |
336 StringPool, Contexts, ModulesEndOffset, | |
337 ParseableSwiftInterfaces, ReportWarning, | |
338 InImportedModule); | |
339 | |
340 // Prune this DIE if it is either a forward declaration inside a | |
341 // DW_TAG_module or a DW_TAG_module that contains nothing but | |
342 // forward declarations. | |
343 Info.Prune &= (DIE.getTag() == dwarf::DW_TAG_module) || | |
344 (isTypeTag(DIE.getTag()) && | |
345 dwarf::toUnsigned(DIE.find(dwarf::DW_AT_declaration), 0)); | |
346 | |
347 // Only prune forward declarations inside a DW_TAG_module for which a | |
348 // definition exists elsewhere. | |
349 if (ModulesEndOffset == 0) | |
350 Info.Prune &= Info.Ctxt && Info.Ctxt->getCanonicalDIEOffset(); | |
351 else | |
352 Info.Prune &= Info.Ctxt && Info.Ctxt->getCanonicalDIEOffset() > 0 && | |
353 Info.Ctxt->getCanonicalDIEOffset() <= ModulesEndOffset; | |
354 | |
355 return Info.Prune; | |
356 } // namespace dsymutil | |
357 | |
358 static bool dieNeedsChildrenToBeMeaningful(uint32_t Tag) { | |
359 switch (Tag) { | |
360 default: | |
361 return false; | |
362 case dwarf::DW_TAG_subprogram: | |
363 case dwarf::DW_TAG_lexical_block: | |
364 case dwarf::DW_TAG_subroutine_type: | |
365 case dwarf::DW_TAG_structure_type: | |
366 case dwarf::DW_TAG_class_type: | |
367 case dwarf::DW_TAG_union_type: | |
368 return true; | |
369 } | |
370 llvm_unreachable("Invalid Tag"); | |
371 } | |
372 | |
373 void DwarfLinker::startDebugObject(LinkContext &Context) { | |
374 // Iterate over the debug map entries and put all the ones that are | |
375 // functions (because they have a size) into the Ranges map. This map is | |
376 // very similar to the FunctionRanges that are stored in each unit, with 2 | |
377 // notable differences: | |
378 // | |
379 // 1. Obviously this one is global, while the other ones are per-unit. | |
380 // | |
381 // 2. This one contains not only the functions described in the DIE | |
382 // tree, but also the ones that are only in the debug map. | |
383 // | |
384 // The latter information is required to reproduce dsymutil's logic while | |
385 // linking line tables. The cases where this information matters look like | |
386 // bugs that need to be investigated, but for now we need to reproduce | |
387 // dsymutil's behavior. | |
388 // FIXME: Once we understood exactly if that information is needed, | |
389 // maybe totally remove this (or try to use it to do a real | |
390 // -gline-tables-only on Darwin. | |
391 for (const auto &Entry : Context.DMO.symbols()) { | |
392 const auto &Mapping = Entry.getValue(); | |
393 if (Mapping.Size && Mapping.ObjectAddress) | |
394 Context.Ranges[*Mapping.ObjectAddress] = DebugMapObjectRange( | |
395 *Mapping.ObjectAddress + Mapping.Size, | |
396 int64_t(Mapping.BinaryAddress) - *Mapping.ObjectAddress); | |
397 } | |
398 } | |
399 | |
400 void DwarfLinker::endDebugObject(LinkContext &Context) { | |
401 Context.Clear(); | |
402 | |
403 for (auto I = DIEBlocks.begin(), E = DIEBlocks.end(); I != E; ++I) | |
404 (*I)->~DIEBlock(); | |
405 for (auto I = DIELocs.begin(), E = DIELocs.end(); I != E; ++I) | |
406 (*I)->~DIELoc(); | |
407 | |
408 DIEBlocks.clear(); | |
409 DIELocs.clear(); | |
410 DIEAlloc.Reset(); | |
411 } | |
412 | |
413 static bool isMachOPairedReloc(uint64_t RelocType, uint64_t Arch) { | |
414 switch (Arch) { | |
415 case Triple::x86: | |
416 return RelocType == MachO::GENERIC_RELOC_SECTDIFF || | |
417 RelocType == MachO::GENERIC_RELOC_LOCAL_SECTDIFF; | |
418 case Triple::x86_64: | |
419 return RelocType == MachO::X86_64_RELOC_SUBTRACTOR; | |
420 case Triple::arm: | |
421 case Triple::thumb: | |
422 return RelocType == MachO::ARM_RELOC_SECTDIFF || | |
423 RelocType == MachO::ARM_RELOC_LOCAL_SECTDIFF || | |
424 RelocType == MachO::ARM_RELOC_HALF || | |
425 RelocType == MachO::ARM_RELOC_HALF_SECTDIFF; | |
426 case Triple::aarch64: | |
427 return RelocType == MachO::ARM64_RELOC_SUBTRACTOR; | |
428 default: | |
429 return false; | |
430 } | |
431 } | |
432 | |
433 /// Iterate over the relocations of the given \p Section and | |
434 /// store the ones that correspond to debug map entries into the | |
435 /// ValidRelocs array. | |
436 void DwarfLinker::RelocationManager::findValidRelocsMachO( | |
437 const object::SectionRef &Section, const object::MachOObjectFile &Obj, | |
438 const DebugMapObject &DMO) { | |
439 Expected<StringRef> ContentsOrErr = Section.getContents(); | |
440 if (!ContentsOrErr) { | |
441 consumeError(ContentsOrErr.takeError()); | |
442 Linker.reportWarning("error reading section", DMO); | |
443 return; | |
444 } | |
445 DataExtractor Data(*ContentsOrErr, Obj.isLittleEndian(), 0); | |
446 bool SkipNext = false; | |
447 | |
448 for (const object::RelocationRef &Reloc : Section.relocations()) { | |
449 if (SkipNext) { | |
450 SkipNext = false; | |
451 continue; | |
452 } | |
453 | |
454 object::DataRefImpl RelocDataRef = Reloc.getRawDataRefImpl(); | |
455 MachO::any_relocation_info MachOReloc = Obj.getRelocation(RelocDataRef); | |
456 | |
457 if (isMachOPairedReloc(Obj.getAnyRelocationType(MachOReloc), | |
458 Obj.getArch())) { | |
459 SkipNext = true; | |
460 Linker.reportWarning("unsupported relocation in debug_info section.", | |
461 DMO); | |
462 continue; | |
463 } | |
464 | |
465 unsigned RelocSize = 1 << Obj.getAnyRelocationLength(MachOReloc); | |
466 uint64_t Offset64 = Reloc.getOffset(); | |
467 if ((RelocSize != 4 && RelocSize != 8)) { | |
468 Linker.reportWarning("unsupported relocation in debug_info section.", | |
469 DMO); | |
470 continue; | |
471 } | |
472 uint64_t OffsetCopy = Offset64; | |
473 // Mach-o uses REL relocations, the addend is at the relocation offset. | |
474 uint64_t Addend = Data.getUnsigned(&OffsetCopy, RelocSize); | |
475 uint64_t SymAddress; | |
476 int64_t SymOffset; | |
477 | |
478 if (Obj.isRelocationScattered(MachOReloc)) { | |
479 // The address of the base symbol for scattered relocations is | |
480 // stored in the reloc itself. The actual addend will store the | |
481 // base address plus the offset. | |
482 SymAddress = Obj.getScatteredRelocationValue(MachOReloc); | |
483 SymOffset = int64_t(Addend) - SymAddress; | |
484 } else { | |
485 SymAddress = Addend; | |
486 SymOffset = 0; | |
487 } | |
488 | |
489 auto Sym = Reloc.getSymbol(); | |
490 if (Sym != Obj.symbol_end()) { | |
491 Expected<StringRef> SymbolName = Sym->getName(); | |
492 if (!SymbolName) { | |
493 consumeError(SymbolName.takeError()); | |
494 Linker.reportWarning("error getting relocation symbol name.", DMO); | |
495 continue; | |
496 } | |
497 if (const auto *Mapping = DMO.lookupSymbol(*SymbolName)) | |
498 ValidRelocs.emplace_back(Offset64, RelocSize, Addend, Mapping); | |
499 } else if (const auto *Mapping = DMO.lookupObjectAddress(SymAddress)) { | |
500 // Do not store the addend. The addend was the address of the symbol in | |
501 // the object file, the address in the binary that is stored in the debug | |
502 // map doesn't need to be offset. | |
503 ValidRelocs.emplace_back(Offset64, RelocSize, SymOffset, Mapping); | |
504 } | |
505 } | |
506 } | |
507 | |
508 /// Dispatch the valid relocation finding logic to the | |
509 /// appropriate handler depending on the object file format. | |
510 bool DwarfLinker::RelocationManager::findValidRelocs( | |
511 const object::SectionRef &Section, const object::ObjectFile &Obj, | |
512 const DebugMapObject &DMO) { | |
513 // Dispatch to the right handler depending on the file type. | |
514 if (auto *MachOObj = dyn_cast<object::MachOObjectFile>(&Obj)) | |
515 findValidRelocsMachO(Section, *MachOObj, DMO); | |
516 else | |
517 Linker.reportWarning( | |
518 Twine("unsupported object file type: ") + Obj.getFileName(), DMO); | |
519 | |
520 if (ValidRelocs.empty()) | |
521 return false; | |
522 | |
523 // Sort the relocations by offset. We will walk the DIEs linearly in | |
524 // the file, this allows us to just keep an index in the relocation | |
525 // array that we advance during our walk, rather than resorting to | |
526 // some associative container. See DwarfLinker::NextValidReloc. | |
527 llvm::sort(ValidRelocs); | |
528 return true; | |
529 } | |
530 | |
531 /// Look for relocations in the debug_info section that match | |
532 /// entries in the debug map. These relocations will drive the Dwarf | |
533 /// link by indicating which DIEs refer to symbols present in the | |
534 /// linked binary. | |
535 /// \returns whether there are any valid relocations in the debug info. | |
536 bool DwarfLinker::RelocationManager::findValidRelocsInDebugInfo( | |
537 const object::ObjectFile &Obj, const DebugMapObject &DMO) { | |
538 // Find the debug_info section. | |
539 for (const object::SectionRef &Section : Obj.sections()) { | |
540 StringRef SectionName; | |
541 Section.getName(SectionName); | |
542 SectionName = SectionName.substr(SectionName.find_first_not_of("._")); | |
543 if (SectionName != "debug_info") | |
544 continue; | |
545 return findValidRelocs(Section, Obj, DMO); | |
546 } | |
547 return false; | |
548 } | |
549 | |
550 /// Checks that there is a relocation against an actual debug | |
551 /// map entry between \p StartOffset and \p NextOffset. | |
552 /// | |
553 /// This function must be called with offsets in strictly ascending | |
554 /// order because it never looks back at relocations it already 'went past'. | |
555 /// \returns true and sets Info.InDebugMap if it is the case. | |
556 bool DwarfLinker::RelocationManager::hasValidRelocation( | |
557 uint64_t StartOffset, uint64_t EndOffset, CompileUnit::DIEInfo &Info) { | |
558 assert(NextValidReloc == 0 || | |
559 StartOffset > ValidRelocs[NextValidReloc - 1].Offset); | |
560 if (NextValidReloc >= ValidRelocs.size()) | |
561 return false; | |
562 | |
563 uint64_t RelocOffset = ValidRelocs[NextValidReloc].Offset; | |
564 | |
565 // We might need to skip some relocs that we didn't consider. For | |
566 // example the high_pc of a discarded DIE might contain a reloc that | |
567 // is in the list because it actually corresponds to the start of a | |
568 // function that is in the debug map. | |
569 while (RelocOffset < StartOffset && NextValidReloc < ValidRelocs.size() - 1) | |
570 RelocOffset = ValidRelocs[++NextValidReloc].Offset; | |
571 | |
572 if (RelocOffset < StartOffset || RelocOffset >= EndOffset) | |
573 return false; | |
574 | |
575 const auto &ValidReloc = ValidRelocs[NextValidReloc++]; | |
576 const auto &Mapping = ValidReloc.Mapping->getValue(); | |
577 uint64_t ObjectAddress = Mapping.ObjectAddress | |
578 ? uint64_t(*Mapping.ObjectAddress) | |
579 : std::numeric_limits<uint64_t>::max(); | |
580 if (Linker.Options.Verbose) | |
581 outs() << "Found valid debug map entry: " << ValidReloc.Mapping->getKey() | |
582 << " " | |
583 << format("\t%016" PRIx64 " => %016" PRIx64, ObjectAddress, | |
584 uint64_t(Mapping.BinaryAddress)); | |
585 | |
586 Info.AddrAdjust = int64_t(Mapping.BinaryAddress) + ValidReloc.Addend; | |
587 if (Mapping.ObjectAddress) | |
588 Info.AddrAdjust -= ObjectAddress; | |
589 Info.InDebugMap = true; | |
590 return true; | |
591 } | |
592 | |
593 /// Get the starting and ending (exclusive) offset for the | |
594 /// attribute with index \p Idx descibed by \p Abbrev. \p Offset is | |
595 /// supposed to point to the position of the first attribute described | |
596 /// by \p Abbrev. | |
597 /// \return [StartOffset, EndOffset) as a pair. | |
598 static std::pair<uint64_t, uint64_t> | |
599 getAttributeOffsets(const DWARFAbbreviationDeclaration *Abbrev, unsigned Idx, | |
600 uint64_t Offset, const DWARFUnit &Unit) { | |
601 DataExtractor Data = Unit.getDebugInfoExtractor(); | |
602 | |
603 for (unsigned i = 0; i < Idx; ++i) | |
604 DWARFFormValue::skipValue(Abbrev->getFormByIndex(i), Data, &Offset, | |
605 Unit.getFormParams()); | |
606 | |
607 uint64_t End = Offset; | |
608 DWARFFormValue::skipValue(Abbrev->getFormByIndex(Idx), Data, &End, | |
609 Unit.getFormParams()); | |
610 | |
611 return std::make_pair(Offset, End); | |
612 } | |
613 | |
614 /// Check if a variable describing DIE should be kept. | |
615 /// \returns updated TraversalFlags. | |
616 unsigned DwarfLinker::shouldKeepVariableDIE(RelocationManager &RelocMgr, | |
617 const DWARFDie &DIE, | |
618 CompileUnit &Unit, | |
619 CompileUnit::DIEInfo &MyInfo, | |
620 unsigned Flags) { | |
621 const auto *Abbrev = DIE.getAbbreviationDeclarationPtr(); | |
622 | |
623 // Global variables with constant value can always be kept. | |
624 if (!(Flags & TF_InFunctionScope) && | |
625 Abbrev->findAttributeIndex(dwarf::DW_AT_const_value)) { | |
626 MyInfo.InDebugMap = true; | |
627 return Flags | TF_Keep; | |
628 } | |
629 | |
630 Optional<uint32_t> LocationIdx = | |
631 Abbrev->findAttributeIndex(dwarf::DW_AT_location); | |
632 if (!LocationIdx) | |
633 return Flags; | |
634 | |
635 uint64_t Offset = DIE.getOffset() + getULEB128Size(Abbrev->getCode()); | |
636 const DWARFUnit &OrigUnit = Unit.getOrigUnit(); | |
637 uint64_t LocationOffset, LocationEndOffset; | |
638 std::tie(LocationOffset, LocationEndOffset) = | |
639 getAttributeOffsets(Abbrev, *LocationIdx, Offset, OrigUnit); | |
640 | |
641 // See if there is a relocation to a valid debug map entry inside | |
642 // this variable's location. The order is important here. We want to | |
643 // always check in the variable has a valid relocation, so that the | |
644 // DIEInfo is filled. However, we don't want a static variable in a | |
645 // function to force us to keep the enclosing function. | |
646 if (!RelocMgr.hasValidRelocation(LocationOffset, LocationEndOffset, MyInfo) || | |
647 (Flags & TF_InFunctionScope)) | |
648 return Flags; | |
649 | |
650 if (Options.Verbose) { | |
651 DIDumpOptions DumpOpts; | |
652 DumpOpts.ChildRecurseDepth = 0; | |
653 DumpOpts.Verbose = Options.Verbose; | |
654 DIE.dump(outs(), 8 /* Indent */, DumpOpts); | |
655 } | |
656 | |
657 return Flags | TF_Keep; | |
658 } | |
659 | |
660 /// Check if a function describing DIE should be kept. | |
661 /// \returns updated TraversalFlags. | |
662 unsigned DwarfLinker::shouldKeepSubprogramDIE( | |
663 RelocationManager &RelocMgr, RangesTy &Ranges, const DWARFDie &DIE, | |
664 const DebugMapObject &DMO, CompileUnit &Unit, CompileUnit::DIEInfo &MyInfo, | |
665 unsigned Flags) { | |
666 const auto *Abbrev = DIE.getAbbreviationDeclarationPtr(); | |
667 | |
668 Flags |= TF_InFunctionScope; | |
669 | |
670 Optional<uint32_t> LowPcIdx = Abbrev->findAttributeIndex(dwarf::DW_AT_low_pc); | |
671 if (!LowPcIdx) | |
672 return Flags; | |
673 | |
674 uint64_t Offset = DIE.getOffset() + getULEB128Size(Abbrev->getCode()); | |
675 DWARFUnit &OrigUnit = Unit.getOrigUnit(); | |
676 uint64_t LowPcOffset, LowPcEndOffset; | |
677 std::tie(LowPcOffset, LowPcEndOffset) = | |
678 getAttributeOffsets(Abbrev, *LowPcIdx, Offset, OrigUnit); | |
679 | |
680 auto LowPc = dwarf::toAddress(DIE.find(dwarf::DW_AT_low_pc)); | |
681 assert(LowPc.hasValue() && "low_pc attribute is not an address."); | |
682 if (!LowPc || | |
683 !RelocMgr.hasValidRelocation(LowPcOffset, LowPcEndOffset, MyInfo)) | |
684 return Flags; | |
685 | |
686 if (Options.Verbose) { | |
687 DIDumpOptions DumpOpts; | |
688 DumpOpts.ChildRecurseDepth = 0; | |
689 DumpOpts.Verbose = Options.Verbose; | |
690 DIE.dump(outs(), 8 /* Indent */, DumpOpts); | |
691 } | |
692 | |
693 if (DIE.getTag() == dwarf::DW_TAG_label) { | |
694 if (Unit.hasLabelAt(*LowPc)) | |
695 return Flags; | |
696 // FIXME: dsymutil-classic compat. dsymutil-classic doesn't consider labels | |
697 // that don't fall into the CU's aranges. This is wrong IMO. Debug info | |
698 // generation bugs aside, this is really wrong in the case of labels, where | |
699 // a label marking the end of a function will have a PC == CU's high_pc. | |
700 if (dwarf::toAddress(OrigUnit.getUnitDIE().find(dwarf::DW_AT_high_pc)) | |
701 .getValueOr(UINT64_MAX) <= LowPc) | |
702 return Flags; | |
703 Unit.addLabelLowPc(*LowPc, MyInfo.AddrAdjust); | |
704 return Flags | TF_Keep; | |
705 } | |
706 | |
707 Flags |= TF_Keep; | |
708 | |
709 Optional<uint64_t> HighPc = DIE.getHighPC(*LowPc); | |
710 if (!HighPc) { | |
711 reportWarning("Function without high_pc. Range will be discarded.\n", DMO, | |
712 &DIE); | |
713 return Flags; | |
714 } | |
715 | |
716 // Replace the debug map range with a more accurate one. | |
717 Ranges[*LowPc] = DebugMapObjectRange(*HighPc, MyInfo.AddrAdjust); | |
718 Unit.addFunctionRange(*LowPc, *HighPc, MyInfo.AddrAdjust); | |
719 return Flags; | |
720 } | |
721 | |
722 /// Check if a DIE should be kept. | |
723 /// \returns updated TraversalFlags. | |
724 unsigned DwarfLinker::shouldKeepDIE(RelocationManager &RelocMgr, | |
725 RangesTy &Ranges, const DWARFDie &DIE, | |
726 const DebugMapObject &DMO, | |
727 CompileUnit &Unit, | |
728 CompileUnit::DIEInfo &MyInfo, | |
729 unsigned Flags) { | |
730 switch (DIE.getTag()) { | |
731 case dwarf::DW_TAG_constant: | |
732 case dwarf::DW_TAG_variable: | |
733 return shouldKeepVariableDIE(RelocMgr, DIE, Unit, MyInfo, Flags); | |
734 case dwarf::DW_TAG_subprogram: | |
735 case dwarf::DW_TAG_label: | |
736 return shouldKeepSubprogramDIE(RelocMgr, Ranges, DIE, DMO, Unit, MyInfo, | |
737 Flags); | |
738 case dwarf::DW_TAG_base_type: | |
739 // DWARF Expressions may reference basic types, but scanning them | |
740 // is expensive. Basic types are tiny, so just keep all of them. | |
741 case dwarf::DW_TAG_imported_module: | |
742 case dwarf::DW_TAG_imported_declaration: | |
743 case dwarf::DW_TAG_imported_unit: | |
744 // We always want to keep these. | |
745 return Flags | TF_Keep; | |
746 default: | |
747 break; | |
748 } | |
749 | |
750 return Flags; | |
751 } | |
752 | |
753 /// Mark the passed DIE as well as all the ones it depends on | |
754 /// as kept. | |
755 /// | |
756 /// This function is called by lookForDIEsToKeep on DIEs that are | |
757 /// newly discovered to be needed in the link. It recursively calls | |
758 /// back to lookForDIEsToKeep while adding TF_DependencyWalk to the | |
759 /// TraversalFlags to inform it that it's not doing the primary DIE | |
760 /// tree walk. | |
761 void DwarfLinker::keepDIEAndDependencies( | |
762 RelocationManager &RelocMgr, RangesTy &Ranges, const UnitListTy &Units, | |
763 const DWARFDie &Die, CompileUnit::DIEInfo &MyInfo, | |
764 const DebugMapObject &DMO, CompileUnit &CU, bool UseODR) { | |
765 DWARFUnit &Unit = CU.getOrigUnit(); | |
766 MyInfo.Keep = true; | |
767 | |
768 // We're looking for incomplete types. | |
769 MyInfo.Incomplete = Die.getTag() != dwarf::DW_TAG_subprogram && | |
770 Die.getTag() != dwarf::DW_TAG_member && | |
771 dwarf::toUnsigned(Die.find(dwarf::DW_AT_declaration), 0); | |
772 | |
773 // First mark all the parent chain as kept. | |
774 unsigned AncestorIdx = MyInfo.ParentIdx; | |
775 while (!CU.getInfo(AncestorIdx).Keep) { | |
776 unsigned ODRFlag = UseODR ? TF_ODR : 0; | |
777 lookForDIEsToKeep(RelocMgr, Ranges, Units, Unit.getDIEAtIndex(AncestorIdx), | |
778 DMO, CU, | |
779 TF_ParentWalk | TF_Keep | TF_DependencyWalk | ODRFlag); | |
780 AncestorIdx = CU.getInfo(AncestorIdx).ParentIdx; | |
781 } | |
782 | |
783 // Then we need to mark all the DIEs referenced by this DIE's | |
784 // attributes as kept. | |
785 DWARFDataExtractor Data = Unit.getDebugInfoExtractor(); | |
786 const auto *Abbrev = Die.getAbbreviationDeclarationPtr(); | |
787 uint64_t Offset = Die.getOffset() + getULEB128Size(Abbrev->getCode()); | |
788 | |
789 // Mark all DIEs referenced through attributes as kept. | |
790 for (const auto &AttrSpec : Abbrev->attributes()) { | |
791 DWARFFormValue Val(AttrSpec.Form); | |
792 if (!Val.isFormClass(DWARFFormValue::FC_Reference) || | |
793 AttrSpec.Attr == dwarf::DW_AT_sibling) { | |
794 DWARFFormValue::skipValue(AttrSpec.Form, Data, &Offset, | |
795 Unit.getFormParams()); | |
796 continue; | |
797 } | |
798 | |
799 Val.extractValue(Data, &Offset, Unit.getFormParams(), &Unit); | |
800 CompileUnit *ReferencedCU; | |
801 if (auto RefDie = | |
802 resolveDIEReference(*this, DMO, Units, Val, Die, ReferencedCU)) { | |
803 uint32_t RefIdx = ReferencedCU->getOrigUnit().getDIEIndex(RefDie); | |
804 CompileUnit::DIEInfo &Info = ReferencedCU->getInfo(RefIdx); | |
805 bool IsModuleRef = Info.Ctxt && Info.Ctxt->getCanonicalDIEOffset() && | |
806 Info.Ctxt->isDefinedInClangModule(); | |
807 // If the referenced DIE has a DeclContext that has already been | |
808 // emitted, then do not keep the one in this CU. We'll link to | |
809 // the canonical DIE in cloneDieReferenceAttribute. | |
810 // FIXME: compatibility with dsymutil-classic. UseODR shouldn't | |
811 // be necessary and could be advantageously replaced by | |
812 // ReferencedCU->hasODR() && CU.hasODR(). | |
813 // FIXME: compatibility with dsymutil-classic. There is no | |
814 // reason not to unique ref_addr references. | |
815 if (AttrSpec.Form != dwarf::DW_FORM_ref_addr && (UseODR || IsModuleRef) && | |
816 Info.Ctxt && | |
817 Info.Ctxt != ReferencedCU->getInfo(Info.ParentIdx).Ctxt && | |
818 Info.Ctxt->getCanonicalDIEOffset() && isODRAttribute(AttrSpec.Attr)) | |
819 continue; | |
820 | |
821 // Keep a module forward declaration if there is no definition. | |
822 if (!(isODRAttribute(AttrSpec.Attr) && Info.Ctxt && | |
823 Info.Ctxt->getCanonicalDIEOffset())) | |
824 Info.Prune = false; | |
825 | |
826 unsigned ODRFlag = UseODR ? TF_ODR : 0; | |
827 lookForDIEsToKeep(RelocMgr, Ranges, Units, RefDie, DMO, *ReferencedCU, | |
828 TF_Keep | TF_DependencyWalk | ODRFlag); | |
829 | |
830 // The incomplete property is propagated if the current DIE is complete | |
831 // but references an incomplete DIE. | |
832 if (Info.Incomplete && !MyInfo.Incomplete && | |
833 (Die.getTag() == dwarf::DW_TAG_typedef || | |
834 Die.getTag() == dwarf::DW_TAG_member || | |
835 Die.getTag() == dwarf::DW_TAG_reference_type || | |
836 Die.getTag() == dwarf::DW_TAG_ptr_to_member_type || | |
837 Die.getTag() == dwarf::DW_TAG_pointer_type)) | |
838 MyInfo.Incomplete = true; | |
839 } | |
840 } | |
841 } | |
842 | |
843 namespace { | |
844 /// This class represents an item in the work list. In addition to it's obvious | |
845 /// purpose of representing the state associated with a particular run of the | |
846 /// work loop, it also serves as a marker to indicate that we should run the | |
847 /// "continuation" code. | |
848 /// | |
849 /// Originally, the latter was lambda which allowed arbitrary code to be run. | |
850 /// Because we always need to run the exact same code, it made more sense to | |
851 /// use a boolean and repurpose the already existing DIE field. | |
852 struct WorklistItem { | |
853 DWARFDie Die; | |
854 unsigned Flags; | |
855 bool IsContinuation; | |
856 CompileUnit::DIEInfo *ChildInfo = nullptr; | |
857 | |
858 /// Construct a classic worklist item. | |
859 WorklistItem(DWARFDie Die, unsigned Flags) | |
860 : Die(Die), Flags(Flags), IsContinuation(false){}; | |
861 | |
862 /// Creates a continuation marker. | |
863 WorklistItem(DWARFDie Die) : Die(Die), IsContinuation(true){}; | |
864 }; | |
865 } // namespace | |
866 | |
867 // Helper that updates the completeness of the current DIE. It depends on the | |
868 // fact that the incompletness of its children is already computed. | |
869 static void updateIncompleteness(const DWARFDie &Die, | |
870 CompileUnit::DIEInfo &ChildInfo, | |
871 CompileUnit &CU) { | |
872 // Only propagate incomplete members. | |
873 if (Die.getTag() != dwarf::DW_TAG_structure_type && | |
874 Die.getTag() != dwarf::DW_TAG_class_type) | |
875 return; | |
876 | |
877 unsigned Idx = CU.getOrigUnit().getDIEIndex(Die); | |
878 CompileUnit::DIEInfo &MyInfo = CU.getInfo(Idx); | |
879 | |
880 if (MyInfo.Incomplete) | |
881 return; | |
882 | |
883 if (ChildInfo.Incomplete || ChildInfo.Prune) | |
884 MyInfo.Incomplete = true; | |
885 } | |
886 | |
887 /// Recursively walk the \p DIE tree and look for DIEs to | |
888 /// keep. Store that information in \p CU's DIEInfo. | |
889 /// | |
890 /// This function is the entry point of the DIE selection | |
891 /// algorithm. It is expected to walk the DIE tree in file order and | |
892 /// (though the mediation of its helper) call hasValidRelocation() on | |
893 /// each DIE that might be a 'root DIE' (See DwarfLinker class | |
894 /// comment). | |
895 /// While walking the dependencies of root DIEs, this function is | |
896 /// also called, but during these dependency walks the file order is | |
897 /// not respected. The TF_DependencyWalk flag tells us which kind of | |
898 /// traversal we are currently doing. | |
899 /// | |
900 /// The return value indicates whether the DIE is incomplete. | |
901 void DwarfLinker::lookForDIEsToKeep(RelocationManager &RelocMgr, | |
902 RangesTy &Ranges, const UnitListTy &Units, | |
903 const DWARFDie &Die, | |
904 const DebugMapObject &DMO, CompileUnit &CU, | |
905 unsigned Flags) { | |
906 // LIFO work list. | |
907 SmallVector<WorklistItem, 4> Worklist; | |
908 Worklist.emplace_back(Die, Flags); | |
909 | |
910 while (!Worklist.empty()) { | |
911 WorklistItem Current = Worklist.back(); | |
912 Worklist.pop_back(); | |
913 | |
914 if (Current.IsContinuation) { | |
915 updateIncompleteness(Current.Die, *Current.ChildInfo, CU); | |
916 continue; | |
917 } | |
918 | |
919 unsigned Idx = CU.getOrigUnit().getDIEIndex(Current.Die); | |
920 CompileUnit::DIEInfo &MyInfo = CU.getInfo(Idx); | |
921 | |
922 // At this point we are guaranteed to have a continuation marker before us | |
923 // in the worklist, except for the last DIE. | |
924 if (!Worklist.empty()) | |
925 Worklist.back().ChildInfo = &MyInfo; | |
926 | |
927 if (MyInfo.Prune) | |
928 continue; | |
929 | |
930 // If the Keep flag is set, we are marking a required DIE's dependencies. | |
931 // If our target is already marked as kept, we're all set. | |
932 bool AlreadyKept = MyInfo.Keep; | |
933 if ((Current.Flags & TF_DependencyWalk) && AlreadyKept) | |
934 continue; | |
935 | |
936 // We must not call shouldKeepDIE while called from keepDIEAndDependencies, | |
937 // because it would screw up the relocation finding logic. | |
938 if (!(Current.Flags & TF_DependencyWalk)) | |
939 Current.Flags = shouldKeepDIE(RelocMgr, Ranges, Current.Die, DMO, CU, | |
940 MyInfo, Current.Flags); | |
941 | |
942 // If it is a newly kept DIE mark it as well as all its dependencies as | |
943 // kept. | |
944 if (!AlreadyKept && (Current.Flags & TF_Keep)) { | |
945 bool UseOdr = (Current.Flags & TF_DependencyWalk) | |
946 ? (Current.Flags & TF_ODR) | |
947 : CU.hasODR(); | |
948 keepDIEAndDependencies(RelocMgr, Ranges, Units, Current.Die, MyInfo, DMO, | |
949 CU, UseOdr); | |
950 } | |
951 | |
952 // The TF_ParentWalk flag tells us that we are currently walking up | |
953 // the parent chain of a required DIE, and we don't want to mark all | |
954 // the children of the parents as kept (consider for example a | |
955 // DW_TAG_namespace node in the parent chain). There are however a | |
956 // set of DIE types for which we want to ignore that directive and still | |
957 // walk their children. | |
958 if (dieNeedsChildrenToBeMeaningful(Current.Die.getTag())) | |
959 Current.Flags &= ~TF_ParentWalk; | |
960 | |
961 if (!Current.Die.hasChildren() || (Current.Flags & TF_ParentWalk)) | |
962 continue; | |
963 | |
964 // Add children in reverse order to the worklist to effectively process | |
965 // them in order. | |
966 for (auto Child : reverse(Current.Die.children())) { | |
967 // Add continuation marker before every child to calculate incompleteness | |
968 // after the last child is processed. We can't store this information in | |
969 // the same item because we might have to process other continuations | |
970 // first. | |
971 Worklist.emplace_back(Current.Die); | |
972 Worklist.emplace_back(Child, Current.Flags); | |
973 } | |
974 } | |
975 } | |
976 | |
977 /// Assign an abbreviation number to \p Abbrev. | |
978 /// | |
979 /// Our DIEs get freed after every DebugMapObject has been processed, | |
980 /// thus the FoldingSet we use to unique DIEAbbrevs cannot refer to | |
981 /// the instances hold by the DIEs. When we encounter an abbreviation | |
982 /// that we don't know, we create a permanent copy of it. | |
983 void DwarfLinker::AssignAbbrev(DIEAbbrev &Abbrev) { | |
984 // Check the set for priors. | |
985 FoldingSetNodeID ID; | |
986 Abbrev.Profile(ID); | |
987 void *InsertToken; | |
988 DIEAbbrev *InSet = AbbreviationsSet.FindNodeOrInsertPos(ID, InsertToken); | |
989 | |
990 // If it's newly added. | |
991 if (InSet) { | |
992 // Assign existing abbreviation number. | |
993 Abbrev.setNumber(InSet->getNumber()); | |
994 } else { | |
995 // Add to abbreviation list. | |
996 Abbreviations.push_back( | |
997 llvm::make_unique<DIEAbbrev>(Abbrev.getTag(), Abbrev.hasChildren())); | |
998 for (const auto &Attr : Abbrev.getData()) | |
999 Abbreviations.back()->AddAttribute(Attr.getAttribute(), Attr.getForm()); | |
1000 AbbreviationsSet.InsertNode(Abbreviations.back().get(), InsertToken); | |
1001 // Assign the unique abbreviation number. | |
1002 Abbrev.setNumber(Abbreviations.size()); | |
1003 Abbreviations.back()->setNumber(Abbreviations.size()); | |
1004 } | |
1005 } | |
1006 | |
1007 unsigned DwarfLinker::DIECloner::cloneStringAttribute( | |
1008 DIE &Die, AttributeSpec AttrSpec, const DWARFFormValue &Val, | |
1009 const DWARFUnit &U, OffsetsStringPool &StringPool, AttributesInfo &Info) { | |
1010 // Switch everything to out of line strings. | |
1011 const char *String = *Val.getAsCString(); | |
1012 auto StringEntry = StringPool.getEntry(String); | |
1013 | |
1014 // Update attributes info. | |
1015 if (AttrSpec.Attr == dwarf::DW_AT_name) | |
1016 Info.Name = StringEntry; | |
1017 else if (AttrSpec.Attr == dwarf::DW_AT_MIPS_linkage_name || | |
1018 AttrSpec.Attr == dwarf::DW_AT_linkage_name) | |
1019 Info.MangledName = StringEntry; | |
1020 | |
1021 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr), dwarf::DW_FORM_strp, | |
1022 DIEInteger(StringEntry.getOffset())); | |
1023 | |
1024 return 4; | |
1025 } | |
1026 | |
1027 unsigned DwarfLinker::DIECloner::cloneDieReferenceAttribute( | |
1028 DIE &Die, const DWARFDie &InputDIE, AttributeSpec AttrSpec, | |
1029 unsigned AttrSize, const DWARFFormValue &Val, const DebugMapObject &DMO, | |
1030 CompileUnit &Unit) { | |
1031 const DWARFUnit &U = Unit.getOrigUnit(); | |
1032 uint64_t Ref = *Val.getAsReference(); | |
1033 DIE *NewRefDie = nullptr; | |
1034 CompileUnit *RefUnit = nullptr; | |
1035 DeclContext *Ctxt = nullptr; | |
1036 | |
1037 DWARFDie RefDie = | |
1038 resolveDIEReference(Linker, DMO, CompileUnits, Val, InputDIE, RefUnit); | |
1039 | |
1040 // If the referenced DIE is not found, drop the attribute. | |
1041 if (!RefDie || AttrSpec.Attr == dwarf::DW_AT_sibling) | |
1042 return 0; | |
1043 | |
1044 unsigned Idx = RefUnit->getOrigUnit().getDIEIndex(RefDie); | |
1045 CompileUnit::DIEInfo &RefInfo = RefUnit->getInfo(Idx); | |
1046 | |
1047 // If we already have emitted an equivalent DeclContext, just point | |
1048 // at it. | |
1049 if (isODRAttribute(AttrSpec.Attr)) { | |
1050 Ctxt = RefInfo.Ctxt; | |
1051 if (Ctxt && Ctxt->getCanonicalDIEOffset()) { | |
1052 DIEInteger Attr(Ctxt->getCanonicalDIEOffset()); | |
1053 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr), | |
1054 dwarf::DW_FORM_ref_addr, Attr); | |
1055 return U.getRefAddrByteSize(); | |
1056 } | |
1057 } | |
1058 | |
1059 if (!RefInfo.Clone) { | |
1060 assert(Ref > InputDIE.getOffset()); | |
1061 // We haven't cloned this DIE yet. Just create an empty one and | |
1062 // store it. It'll get really cloned when we process it. | |
1063 RefInfo.Clone = DIE::get(DIEAlloc, dwarf::Tag(RefDie.getTag())); | |
1064 } | |
1065 NewRefDie = RefInfo.Clone; | |
1066 | |
1067 if (AttrSpec.Form == dwarf::DW_FORM_ref_addr || | |
1068 (Unit.hasODR() && isODRAttribute(AttrSpec.Attr))) { | |
1069 // We cannot currently rely on a DIEEntry to emit ref_addr | |
1070 // references, because the implementation calls back to DwarfDebug | |
1071 // to find the unit offset. (We don't have a DwarfDebug) | |
1072 // FIXME: we should be able to design DIEEntry reliance on | |
1073 // DwarfDebug away. | |
1074 uint64_t Attr; | |
1075 if (Ref < InputDIE.getOffset()) { | |
1076 // We must have already cloned that DIE. | |
1077 uint32_t NewRefOffset = | |
1078 RefUnit->getStartOffset() + NewRefDie->getOffset(); | |
1079 Attr = NewRefOffset; | |
1080 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr), | |
1081 dwarf::DW_FORM_ref_addr, DIEInteger(Attr)); | |
1082 } else { | |
1083 // A forward reference. Note and fixup later. | |
1084 Attr = 0xBADDEF; | |
1085 Unit.noteForwardReference( | |
1086 NewRefDie, RefUnit, Ctxt, | |
1087 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr), | |
1088 dwarf::DW_FORM_ref_addr, DIEInteger(Attr))); | |
1089 } | |
1090 return U.getRefAddrByteSize(); | |
1091 } | |
1092 | |
1093 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr), | |
1094 dwarf::Form(AttrSpec.Form), DIEEntry(*NewRefDie)); | |
1095 return AttrSize; | |
1096 } | |
1097 | |
1098 void DwarfLinker::DIECloner::cloneExpression( | |
1099 DataExtractor &Data, DWARFExpression Expression, const DebugMapObject &DMO, | |
1100 CompileUnit &Unit, SmallVectorImpl<uint8_t> &OutputBuffer) { | |
1101 using Encoding = DWARFExpression::Operation::Encoding; | |
1102 | |
1103 uint64_t OpOffset = 0; | |
1104 for (auto &Op : Expression) { | |
1105 auto Description = Op.getDescription(); | |
1106 // DW_OP_const_type is variable-length and has 3 | |
1107 // operands. DWARFExpression thus far only supports 2. | |
1108 auto Op0 = Description.Op[0]; | |
1109 auto Op1 = Description.Op[1]; | |
1110 if ((Op0 == Encoding::BaseTypeRef && Op1 != Encoding::SizeNA) || | |
1111 (Op1 == Encoding::BaseTypeRef && Op0 != Encoding::Size1)) | |
1112 Linker.reportWarning("Unsupported DW_OP encoding.", DMO); | |
1113 | |
1114 if ((Op0 == Encoding::BaseTypeRef && Op1 == Encoding::SizeNA) || | |
1115 (Op1 == Encoding::BaseTypeRef && Op0 == Encoding::Size1)) { | |
1116 // This code assumes that the other non-typeref operand fits into 1 byte. | |
1117 assert(OpOffset < Op.getEndOffset()); | |
1118 uint32_t ULEBsize = Op.getEndOffset() - OpOffset - 1; | |
1119 assert(ULEBsize <= 16); | |
1120 | |
1121 // Copy over the operation. | |
1122 OutputBuffer.push_back(Op.getCode()); | |
1123 uint64_t RefOffset; | |
1124 if (Op1 == Encoding::SizeNA) { | |
1125 RefOffset = Op.getRawOperand(0); | |
1126 } else { | |
1127 OutputBuffer.push_back(Op.getRawOperand(0)); | |
1128 RefOffset = Op.getRawOperand(1); | |
1129 } | |
1130 auto RefDie = Unit.getOrigUnit().getDIEForOffset(RefOffset); | |
1131 uint32_t RefIdx = Unit.getOrigUnit().getDIEIndex(RefDie); | |
1132 CompileUnit::DIEInfo &Info = Unit.getInfo(RefIdx); | |
1133 uint32_t Offset = 0; | |
1134 if (DIE *Clone = Info.Clone) | |
1135 Offset = Clone->getOffset(); | |
1136 else | |
1137 Linker.reportWarning("base type ref doesn't point to DW_TAG_base_type.", | |
1138 DMO); | |
1139 uint8_t ULEB[16]; | |
1140 unsigned RealSize = encodeULEB128(Offset, ULEB, ULEBsize); | |
1141 if (RealSize > ULEBsize) { | |
1142 // Emit the generic type as a fallback. | |
1143 RealSize = encodeULEB128(0, ULEB, ULEBsize); | |
1144 Linker.reportWarning("base type ref doesn't fit.", DMO); | |
1145 } | |
1146 assert(RealSize == ULEBsize && "padding failed"); | |
1147 ArrayRef<uint8_t> ULEBbytes(ULEB, ULEBsize); | |
1148 OutputBuffer.append(ULEBbytes.begin(), ULEBbytes.end()); | |
1149 } else { | |
1150 // Copy over everything else unmodified. | |
1151 StringRef Bytes = Data.getData().slice(OpOffset, Op.getEndOffset()); | |
1152 OutputBuffer.append(Bytes.begin(), Bytes.end()); | |
1153 } | |
1154 OpOffset = Op.getEndOffset(); | |
1155 } | |
1156 } | |
1157 | |
1158 unsigned DwarfLinker::DIECloner::cloneBlockAttribute( | |
1159 DIE &Die, const DebugMapObject &DMO, CompileUnit &Unit, | |
1160 AttributeSpec AttrSpec, const DWARFFormValue &Val, unsigned AttrSize, | |
1161 bool IsLittleEndian) { | |
1162 DIEValueList *Attr; | |
1163 DIEValue Value; | |
1164 DIELoc *Loc = nullptr; | |
1165 DIEBlock *Block = nullptr; | |
1166 if (AttrSpec.Form == dwarf::DW_FORM_exprloc) { | |
1167 Loc = new (DIEAlloc) DIELoc; | |
1168 Linker.DIELocs.push_back(Loc); | |
1169 } else { | |
1170 Block = new (DIEAlloc) DIEBlock; | |
1171 Linker.DIEBlocks.push_back(Block); | |
1172 } | |
1173 Attr = Loc ? static_cast<DIEValueList *>(Loc) | |
1174 : static_cast<DIEValueList *>(Block); | |
1175 | |
1176 if (Loc) | |
1177 Value = DIEValue(dwarf::Attribute(AttrSpec.Attr), | |
1178 dwarf::Form(AttrSpec.Form), Loc); | |
1179 else | |
1180 Value = DIEValue(dwarf::Attribute(AttrSpec.Attr), | |
1181 dwarf::Form(AttrSpec.Form), Block); | |
1182 | |
1183 // If the block is a DWARF Expression, clone it into the temporary | |
1184 // buffer using cloneExpression(), otherwise copy the data directly. | |
1185 SmallVector<uint8_t, 32> Buffer; | |
1186 ArrayRef<uint8_t> Bytes = *Val.getAsBlock(); | |
1187 if (DWARFAttribute::mayHaveLocationDescription(AttrSpec.Attr) && | |
1188 (Val.isFormClass(DWARFFormValue::FC_Block) || | |
1189 Val.isFormClass(DWARFFormValue::FC_Exprloc))) { | |
1190 DWARFUnit &OrigUnit = Unit.getOrigUnit(); | |
1191 DataExtractor Data(StringRef((const char *)Bytes.data(), Bytes.size()), | |
1192 IsLittleEndian, OrigUnit.getAddressByteSize()); | |
1193 DWARFExpression Expr(Data, OrigUnit.getVersion(), | |
1194 OrigUnit.getAddressByteSize()); | |
1195 cloneExpression(Data, Expr, DMO, Unit, Buffer); | |
1196 Bytes = Buffer; | |
1197 } | |
1198 for (auto Byte : Bytes) | |
1199 Attr->addValue(DIEAlloc, static_cast<dwarf::Attribute>(0), | |
1200 dwarf::DW_FORM_data1, DIEInteger(Byte)); | |
1201 | |
1202 // FIXME: If DIEBlock and DIELoc just reuses the Size field of | |
1203 // the DIE class, this if could be replaced by | |
1204 // Attr->setSize(Bytes.size()). | |
1205 if (Linker.Streamer) { | |
1206 auto *AsmPrinter = &Linker.Streamer->getAsmPrinter(); | |
1207 if (Loc) | |
1208 Loc->ComputeSize(AsmPrinter); | |
1209 else | |
1210 Block->ComputeSize(AsmPrinter); | |
1211 } | |
1212 Die.addValue(DIEAlloc, Value); | |
1213 return AttrSize; | |
1214 } | |
1215 | |
1216 unsigned DwarfLinker::DIECloner::cloneAddressAttribute( | |
1217 DIE &Die, AttributeSpec AttrSpec, const DWARFFormValue &Val, | |
1218 const CompileUnit &Unit, AttributesInfo &Info) { | |
1219 uint64_t Addr = *Val.getAsAddress(); | |
1220 | |
1221 if (LLVM_UNLIKELY(Linker.Options.Update)) { | |
1222 if (AttrSpec.Attr == dwarf::DW_AT_low_pc) | |
1223 Info.HasLowPc = true; | |
1224 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr), | |
1225 dwarf::Form(AttrSpec.Form), DIEInteger(Addr)); | |
1226 return Unit.getOrigUnit().getAddressByteSize(); | |
1227 } | |
1228 | |
1229 if (AttrSpec.Attr == dwarf::DW_AT_low_pc) { | |
1230 if (Die.getTag() == dwarf::DW_TAG_inlined_subroutine || | |
1231 Die.getTag() == dwarf::DW_TAG_lexical_block) | |
1232 // The low_pc of a block or inline subroutine might get | |
1233 // relocated because it happens to match the low_pc of the | |
1234 // enclosing subprogram. To prevent issues with that, always use | |
1235 // the low_pc from the input DIE if relocations have been applied. | |
1236 Addr = (Info.OrigLowPc != std::numeric_limits<uint64_t>::max() | |
1237 ? Info.OrigLowPc | |
1238 : Addr) + | |
1239 Info.PCOffset; | |
1240 else if (Die.getTag() == dwarf::DW_TAG_compile_unit) { | |
1241 Addr = Unit.getLowPc(); | |
1242 if (Addr == std::numeric_limits<uint64_t>::max()) | |
1243 return 0; | |
1244 } | |
1245 Info.HasLowPc = true; | |
1246 } else if (AttrSpec.Attr == dwarf::DW_AT_high_pc) { | |
1247 if (Die.getTag() == dwarf::DW_TAG_compile_unit) { | |
1248 if (uint64_t HighPc = Unit.getHighPc()) | |
1249 Addr = HighPc; | |
1250 else | |
1251 return 0; | |
1252 } else | |
1253 // If we have a high_pc recorded for the input DIE, use | |
1254 // it. Otherwise (when no relocations where applied) just use the | |
1255 // one we just decoded. | |
1256 Addr = (Info.OrigHighPc ? Info.OrigHighPc : Addr) + Info.PCOffset; | |
1257 } | |
1258 | |
1259 Die.addValue(DIEAlloc, static_cast<dwarf::Attribute>(AttrSpec.Attr), | |
1260 static_cast<dwarf::Form>(AttrSpec.Form), DIEInteger(Addr)); | |
1261 return Unit.getOrigUnit().getAddressByteSize(); | |
1262 } | |
1263 | |
1264 unsigned DwarfLinker::DIECloner::cloneScalarAttribute( | |
1265 DIE &Die, const DWARFDie &InputDIE, const DebugMapObject &DMO, | |
1266 CompileUnit &Unit, AttributeSpec AttrSpec, const DWARFFormValue &Val, | |
1267 unsigned AttrSize, AttributesInfo &Info) { | |
1268 uint64_t Value; | |
1269 | |
1270 if (LLVM_UNLIKELY(Linker.Options.Update)) { | |
1271 if (auto OptionalValue = Val.getAsUnsignedConstant()) | |
1272 Value = *OptionalValue; | |
1273 else if (auto OptionalValue = Val.getAsSignedConstant()) | |
1274 Value = *OptionalValue; | |
1275 else if (auto OptionalValue = Val.getAsSectionOffset()) | |
1276 Value = *OptionalValue; | |
1277 else { | |
1278 Linker.reportWarning( | |
1279 "Unsupported scalar attribute form. Dropping attribute.", DMO, | |
1280 &InputDIE); | |
1281 return 0; | |
1282 } | |
1283 if (AttrSpec.Attr == dwarf::DW_AT_declaration && Value) | |
1284 Info.IsDeclaration = true; | |
1285 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr), | |
1286 dwarf::Form(AttrSpec.Form), DIEInteger(Value)); | |
1287 return AttrSize; | |
1288 } | |
1289 | |
1290 if (AttrSpec.Attr == dwarf::DW_AT_high_pc && | |
1291 Die.getTag() == dwarf::DW_TAG_compile_unit) { | |
1292 if (Unit.getLowPc() == -1ULL) | |
1293 return 0; | |
1294 // Dwarf >= 4 high_pc is an size, not an address. | |
1295 Value = Unit.getHighPc() - Unit.getLowPc(); | |
1296 } else if (AttrSpec.Form == dwarf::DW_FORM_sec_offset) | |
1297 Value = *Val.getAsSectionOffset(); | |
1298 else if (AttrSpec.Form == dwarf::DW_FORM_sdata) | |
1299 Value = *Val.getAsSignedConstant(); | |
1300 else if (auto OptionalValue = Val.getAsUnsignedConstant()) | |
1301 Value = *OptionalValue; | |
1302 else { | |
1303 Linker.reportWarning( | |
1304 "Unsupported scalar attribute form. Dropping attribute.", DMO, | |
1305 &InputDIE); | |
1306 return 0; | |
1307 } | |
1308 PatchLocation Patch = | |
1309 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr), | |
1310 dwarf::Form(AttrSpec.Form), DIEInteger(Value)); | |
1311 if (AttrSpec.Attr == dwarf::DW_AT_ranges) { | |
1312 Unit.noteRangeAttribute(Die, Patch); | |
1313 Info.HasRanges = true; | |
1314 } | |
1315 | |
1316 // A more generic way to check for location attributes would be | |
1317 // nice, but it's very unlikely that any other attribute needs a | |
1318 // location list. | |
1319 // FIXME: use DWARFAttribute::mayHaveLocationDescription(). | |
1320 else if (AttrSpec.Attr == dwarf::DW_AT_location || | |
1321 AttrSpec.Attr == dwarf::DW_AT_frame_base) | |
1322 Unit.noteLocationAttribute(Patch, Info.PCOffset); | |
1323 else if (AttrSpec.Attr == dwarf::DW_AT_declaration && Value) | |
1324 Info.IsDeclaration = true; | |
1325 | |
1326 return AttrSize; | |
1327 } | |
1328 | |
1329 /// Clone \p InputDIE's attribute described by \p AttrSpec with | |
1330 /// value \p Val, and add it to \p Die. | |
1331 /// \returns the size of the cloned attribute. | |
1332 unsigned DwarfLinker::DIECloner::cloneAttribute( | |
1333 DIE &Die, const DWARFDie &InputDIE, const DebugMapObject &DMO, | |
1334 CompileUnit &Unit, OffsetsStringPool &StringPool, const DWARFFormValue &Val, | |
1335 const AttributeSpec AttrSpec, unsigned AttrSize, AttributesInfo &Info, | |
1336 bool IsLittleEndian) { | |
1337 const DWARFUnit &U = Unit.getOrigUnit(); | |
1338 | |
1339 switch (AttrSpec.Form) { | |
1340 case dwarf::DW_FORM_strp: | |
1341 case dwarf::DW_FORM_string: | |
1342 return cloneStringAttribute(Die, AttrSpec, Val, U, StringPool, Info); | |
1343 case dwarf::DW_FORM_ref_addr: | |
1344 case dwarf::DW_FORM_ref1: | |
1345 case dwarf::DW_FORM_ref2: | |
1346 case dwarf::DW_FORM_ref4: | |
1347 case dwarf::DW_FORM_ref8: | |
1348 return cloneDieReferenceAttribute(Die, InputDIE, AttrSpec, AttrSize, Val, | |
1349 DMO, Unit); | |
1350 case dwarf::DW_FORM_block: | |
1351 case dwarf::DW_FORM_block1: | |
1352 case dwarf::DW_FORM_block2: | |
1353 case dwarf::DW_FORM_block4: | |
1354 case dwarf::DW_FORM_exprloc: | |
1355 return cloneBlockAttribute(Die, DMO, Unit, AttrSpec, Val, AttrSize, | |
1356 IsLittleEndian); | |
1357 case dwarf::DW_FORM_addr: | |
1358 return cloneAddressAttribute(Die, AttrSpec, Val, Unit, Info); | |
1359 case dwarf::DW_FORM_data1: | |
1360 case dwarf::DW_FORM_data2: | |
1361 case dwarf::DW_FORM_data4: | |
1362 case dwarf::DW_FORM_data8: | |
1363 case dwarf::DW_FORM_udata: | |
1364 case dwarf::DW_FORM_sdata: | |
1365 case dwarf::DW_FORM_sec_offset: | |
1366 case dwarf::DW_FORM_flag: | |
1367 case dwarf::DW_FORM_flag_present: | |
1368 return cloneScalarAttribute(Die, InputDIE, DMO, Unit, AttrSpec, Val, | |
1369 AttrSize, Info); | |
1370 default: | |
1371 Linker.reportWarning( | |
1372 "Unsupported attribute form in cloneAttribute. Dropping.", DMO, | |
1373 &InputDIE); | |
1374 } | |
1375 | |
1376 return 0; | |
1377 } | |
1378 | |
1379 /// Apply the valid relocations found by findValidRelocs() to | |
1380 /// the buffer \p Data, taking into account that Data is at \p BaseOffset | |
1381 /// in the debug_info section. | |
1382 /// | |
1383 /// Like for findValidRelocs(), this function must be called with | |
1384 /// monotonic \p BaseOffset values. | |
1385 /// | |
1386 /// \returns whether any reloc has been applied. | |
1387 bool DwarfLinker::RelocationManager::applyValidRelocs( | |
1388 MutableArrayRef<char> Data, uint64_t BaseOffset, bool IsLittleEndian) { | |
1389 assert((NextValidReloc == 0 || | |
1390 BaseOffset > ValidRelocs[NextValidReloc - 1].Offset) && | |
1391 "BaseOffset should only be increasing."); | |
1392 if (NextValidReloc >= ValidRelocs.size()) | |
1393 return false; | |
1394 | |
1395 // Skip relocs that haven't been applied. | |
1396 while (NextValidReloc < ValidRelocs.size() && | |
1397 ValidRelocs[NextValidReloc].Offset < BaseOffset) | |
1398 ++NextValidReloc; | |
1399 | |
1400 bool Applied = false; | |
1401 uint64_t EndOffset = BaseOffset + Data.size(); | |
1402 while (NextValidReloc < ValidRelocs.size() && | |
1403 ValidRelocs[NextValidReloc].Offset >= BaseOffset && | |
1404 ValidRelocs[NextValidReloc].Offset < EndOffset) { | |
1405 const auto &ValidReloc = ValidRelocs[NextValidReloc++]; | |
1406 assert(ValidReloc.Offset - BaseOffset < Data.size()); | |
1407 assert(ValidReloc.Offset - BaseOffset + ValidReloc.Size <= Data.size()); | |
1408 char Buf[8]; | |
1409 uint64_t Value = ValidReloc.Mapping->getValue().BinaryAddress; | |
1410 Value += ValidReloc.Addend; | |
1411 for (unsigned i = 0; i != ValidReloc.Size; ++i) { | |
1412 unsigned Index = IsLittleEndian ? i : (ValidReloc.Size - i - 1); | |
1413 Buf[i] = uint8_t(Value >> (Index * 8)); | |
1414 } | |
1415 assert(ValidReloc.Size <= sizeof(Buf)); | |
1416 memcpy(&Data[ValidReloc.Offset - BaseOffset], Buf, ValidReloc.Size); | |
1417 Applied = true; | |
1418 } | |
1419 | |
1420 return Applied; | |
1421 } | |
1422 | |
3073 static bool isObjCSelector(StringRef Name) { | 1423 static bool isObjCSelector(StringRef Name) { |
3074 return Name.size() > 2 && (Name[0] == '-' || Name[0] == '+') && | 1424 return Name.size() > 2 && (Name[0] == '-' || Name[0] == '+') && |
3075 (Name[1] == '['); | 1425 (Name[1] == '['); |
3076 } | 1426 } |
3077 | 1427 |
3078 void DwarfLinker::DIECloner::addObjCAccelerator(CompileUnit &Unit, | 1428 void DwarfLinker::DIECloner::addObjCAccelerator(CompileUnit &Unit, |
3079 const DIE *Die, | 1429 const DIE *Die, |
3080 DwarfStringPoolEntryRef Name, | 1430 DwarfStringPoolEntryRef Name, |
1431 OffsetsStringPool &StringPool, | |
3081 bool SkipPubSection) { | 1432 bool SkipPubSection) { |
3082 assert(isObjCSelector(Name.getString()) && "not an objc selector"); | 1433 assert(isObjCSelector(Name.getString()) && "not an objc selector"); |
3083 // Objective C method or class function. | 1434 // Objective C method or class function. |
3084 // "- [Class(Category) selector :withArg ...]" | 1435 // "- [Class(Category) selector :withArg ...]" |
3085 StringRef ClassNameStart(Name.getString().drop_front(2)); | 1436 StringRef ClassNameStart(Name.getString().drop_front(2)); |
3090 StringRef SelectorStart(ClassNameStart.data() + FirstSpace + 1); | 1441 StringRef SelectorStart(ClassNameStart.data() + FirstSpace + 1); |
3091 if (!SelectorStart.size()) | 1442 if (!SelectorStart.size()) |
3092 return; | 1443 return; |
3093 | 1444 |
3094 StringRef Selector(SelectorStart.data(), SelectorStart.size() - 1); | 1445 StringRef Selector(SelectorStart.data(), SelectorStart.size() - 1); |
3095 Unit.addNameAccelerator(Die, Linker.StringPool.getEntry(Selector), | 1446 Unit.addNameAccelerator(Die, StringPool.getEntry(Selector), SkipPubSection); |
3096 SkipPubSection); | |
3097 | 1447 |
3098 // Add an entry for the class name that points to this | 1448 // Add an entry for the class name that points to this |
3099 // method/class function. | 1449 // method/class function. |
3100 StringRef ClassName(ClassNameStart.data(), FirstSpace); | 1450 StringRef ClassName(ClassNameStart.data(), FirstSpace); |
3101 Unit.addObjCAccelerator(Die, Linker.StringPool.getEntry(ClassName), | 1451 Unit.addObjCAccelerator(Die, StringPool.getEntry(ClassName), SkipPubSection); |
3102 SkipPubSection); | |
3103 | 1452 |
3104 if (ClassName[ClassName.size() - 1] == ')') { | 1453 if (ClassName[ClassName.size() - 1] == ')') { |
3105 size_t OpenParens = ClassName.find('('); | 1454 size_t OpenParens = ClassName.find('('); |
3106 if (OpenParens != StringRef::npos) { | 1455 if (OpenParens != StringRef::npos) { |
3107 StringRef ClassNameNoCategory(ClassName.data(), OpenParens); | 1456 StringRef ClassNameNoCategory(ClassName.data(), OpenParens); |
3108 Unit.addObjCAccelerator( | 1457 Unit.addObjCAccelerator(Die, StringPool.getEntry(ClassNameNoCategory), |
3109 Die, Linker.StringPool.getEntry(ClassNameNoCategory), SkipPubSection); | 1458 SkipPubSection); |
3110 | 1459 |
3111 std::string MethodNameNoCategory(Name.getString().data(), OpenParens + 2); | 1460 std::string MethodNameNoCategory(Name.getString().data(), OpenParens + 2); |
3112 // FIXME: The missing space here may be a bug, but | 1461 // FIXME: The missing space here may be a bug, but |
3113 // dsymutil-classic also does it this way. | 1462 // dsymutil-classic also does it this way. |
3114 MethodNameNoCategory.append(SelectorStart); | 1463 MethodNameNoCategory.append(SelectorStart); |
3115 Unit.addNameAccelerator(Die, | 1464 Unit.addNameAccelerator(Die, StringPool.getEntry(MethodNameNoCategory), |
3116 Linker.StringPool.getEntry(MethodNameNoCategory), | |
3117 SkipPubSection); | 1465 SkipPubSection); |
3118 } | 1466 } |
3119 } | 1467 } |
3120 } | 1468 } |
3121 | 1469 |
3130 case dwarf::DW_AT_high_pc: | 1478 case dwarf::DW_AT_high_pc: |
3131 case dwarf::DW_AT_ranges: | 1479 case dwarf::DW_AT_ranges: |
3132 return SkipPC; | 1480 return SkipPC; |
3133 case dwarf::DW_AT_location: | 1481 case dwarf::DW_AT_location: |
3134 case dwarf::DW_AT_frame_base: | 1482 case dwarf::DW_AT_frame_base: |
3135 // FIXME: for some reason dsymutil-classic keeps the location | 1483 // FIXME: for some reason dsymutil-classic keeps the location attributes |
3136 // attributes when they are of block type (ie. not location | 1484 // when they are of block type (i.e. not location lists). This is totally |
3137 // lists). This is totally wrong for globals where we will keep a | 1485 // wrong for globals where we will keep a wrong address. It is mostly |
3138 // wrong address. It is mostly harmless for locals, but there is | 1486 // harmless for locals, but there is no point in keeping these anyway when |
3139 // no point in keeping these anyway when the function wasn't linked. | 1487 // the function wasn't linked. |
3140 return (SkipPC || (!InFunctionScope && Tag == dwarf::DW_TAG_variable && | 1488 return (SkipPC || (!InFunctionScope && Tag == dwarf::DW_TAG_variable && |
3141 !InDebugMap)) && | 1489 !InDebugMap)) && |
3142 !DWARFFormValue(AttrSpec.Form).isFormClass(DWARFFormValue::FC_Block); | 1490 !DWARFFormValue(AttrSpec.Form).isFormClass(DWARFFormValue::FC_Block); |
3143 } | 1491 } |
3144 } | 1492 } |
3145 | 1493 |
3146 DIE *DwarfLinker::DIECloner::cloneDIE( | 1494 DIE *DwarfLinker::DIECloner::cloneDIE( |
3147 const DWARFDie &InputDIE, CompileUnit &Unit, | 1495 const DWARFDie &InputDIE, const DebugMapObject &DMO, CompileUnit &Unit, |
3148 int64_t PCOffset, uint32_t OutOffset, unsigned Flags, DIE *Die) { | 1496 OffsetsStringPool &StringPool, int64_t PCOffset, uint32_t OutOffset, |
1497 unsigned Flags, bool IsLittleEndian, DIE *Die) { | |
3149 DWARFUnit &U = Unit.getOrigUnit(); | 1498 DWARFUnit &U = Unit.getOrigUnit(); |
3150 unsigned Idx = U.getDIEIndex(InputDIE); | 1499 unsigned Idx = U.getDIEIndex(InputDIE); |
3151 CompileUnit::DIEInfo &Info = Unit.getInfo(Idx); | 1500 CompileUnit::DIEInfo &Info = Unit.getInfo(Idx); |
3152 | 1501 |
3153 // Should the DIE appear in the output? | 1502 // Should the DIE appear in the output? |
3154 if (!Unit.getInfo(Idx).Keep) | 1503 if (!Unit.getInfo(Idx).Keep) |
3155 return nullptr; | 1504 return nullptr; |
3156 | 1505 |
3157 uint32_t Offset = InputDIE.getOffset(); | 1506 uint64_t Offset = InputDIE.getOffset(); |
3158 assert(!(Die && Info.Clone) && "Can't supply a DIE and a cloned DIE"); | 1507 assert(!(Die && Info.Clone) && "Can't supply a DIE and a cloned DIE"); |
3159 if (!Die) { | 1508 if (!Die) { |
3160 // The DIE might have been already created by a forward reference | 1509 // The DIE might have been already created by a forward reference |
3161 // (see cloneDieReferenceAttribute()). | 1510 // (see cloneDieReferenceAttribute()). |
3162 if (!Info.Clone) | 1511 if (!Info.Clone) |
3179 // Extract and clone every attribute. | 1528 // Extract and clone every attribute. |
3180 DWARFDataExtractor Data = U.getDebugInfoExtractor(); | 1529 DWARFDataExtractor Data = U.getDebugInfoExtractor(); |
3181 // Point to the next DIE (generally there is always at least a NULL | 1530 // Point to the next DIE (generally there is always at least a NULL |
3182 // entry after the current one). If this is a lone | 1531 // entry after the current one). If this is a lone |
3183 // DW_TAG_compile_unit without any children, point to the next unit. | 1532 // DW_TAG_compile_unit without any children, point to the next unit. |
3184 uint32_t NextOffset = | 1533 uint64_t NextOffset = (Idx + 1 < U.getNumDIEs()) |
3185 (Idx + 1 < U.getNumDIEs()) | 1534 ? U.getDIEAtIndex(Idx + 1).getOffset() |
3186 ? U.getDIEAtIndex(Idx + 1).getOffset() | 1535 : U.getNextUnitOffset(); |
3187 : U.getNextUnitOffset(); | |
3188 AttributesInfo AttrInfo; | 1536 AttributesInfo AttrInfo; |
3189 | 1537 |
3190 // We could copy the data only if we need to aply a relocation to | 1538 // We could copy the data only if we need to apply a relocation to it. After |
3191 // it. After testing, it seems there is no performance downside to | 1539 // testing, it seems there is no performance downside to doing the copy |
3192 // doing the copy unconditionally, and it makes the code simpler. | 1540 // unconditionally, and it makes the code simpler. |
3193 SmallString<40> DIECopy(Data.getData().substr(Offset, NextOffset - Offset)); | 1541 SmallString<40> DIECopy(Data.getData().substr(Offset, NextOffset - Offset)); |
3194 Data = | 1542 Data = |
3195 DWARFDataExtractor(DIECopy, Data.isLittleEndian(), Data.getAddressSize()); | 1543 DWARFDataExtractor(DIECopy, Data.isLittleEndian(), Data.getAddressSize()); |
3196 // Modify the copy with relocated addresses. | 1544 // Modify the copy with relocated addresses. |
3197 if (RelocMgr.applyValidRelocs(DIECopy, Offset, Data.isLittleEndian())) { | 1545 if (RelocMgr.applyValidRelocs(DIECopy, Offset, Data.isLittleEndian())) { |
3198 // If we applied relocations, we store the value of high_pc that was | 1546 // If we applied relocations, we store the value of high_pc that was |
3199 // potentially stored in the input DIE. If high_pc is an address | 1547 // potentially stored in the input DIE. If high_pc is an address |
3200 // (Dwarf version == 2), then it might have been relocated to a | 1548 // (Dwarf version == 2), then it might have been relocated to a |
3201 // totally unrelated value (because the end address in the object | 1549 // totally unrelated value (because the end address in the object |
3202 // file might be start address of another function which got moved | 1550 // file might be start address of another function which got moved |
3203 // independantly by the linker). The computation of the actual | 1551 // independently by the linker). The computation of the actual |
3204 // high_pc value is done in cloneAddressAttribute(). | 1552 // high_pc value is done in cloneAddressAttribute(). |
3205 AttrInfo.OrigHighPc = | 1553 AttrInfo.OrigHighPc = |
3206 dwarf::toAddress(InputDIE.find(dwarf::DW_AT_high_pc), 0); | 1554 dwarf::toAddress(InputDIE.find(dwarf::DW_AT_high_pc), 0); |
3207 // Also store the low_pc. It might get relocated in an | 1555 // Also store the low_pc. It might get relocated in an |
3208 // inline_subprogram that happens at the beginning of its | 1556 // inline_subprogram that happens at the beginning of its |
3245 } | 1593 } |
3246 continue; | 1594 continue; |
3247 } | 1595 } |
3248 | 1596 |
3249 DWARFFormValue Val(AttrSpec.Form); | 1597 DWARFFormValue Val(AttrSpec.Form); |
3250 uint32_t AttrSize = Offset; | 1598 uint64_t AttrSize = Offset; |
3251 Val.extractValue(Data, &Offset, U.getFormParams(), &U); | 1599 Val.extractValue(Data, &Offset, U.getFormParams(), &U); |
3252 AttrSize = Offset - AttrSize; | 1600 AttrSize = Offset - AttrSize; |
3253 | 1601 |
3254 OutOffset += | 1602 OutOffset += cloneAttribute(*Die, InputDIE, DMO, Unit, StringPool, Val, |
3255 cloneAttribute(*Die, InputDIE, Unit, Val, AttrSpec, AttrSize, AttrInfo); | 1603 AttrSpec, AttrSize, AttrInfo, IsLittleEndian); |
3256 } | 1604 } |
3257 | 1605 |
3258 // Look for accelerator entries. | 1606 // Look for accelerator entries. |
3259 uint16_t Tag = InputDIE.getTag(); | 1607 uint16_t Tag = InputDIE.getTag(); |
3260 // FIXME: This is slightly wrong. An inline_subroutine without a | 1608 // FIXME: This is slightly wrong. An inline_subroutine without a |
3261 // low_pc, but with AT_ranges might be interesting to get into the | 1609 // low_pc, but with AT_ranges might be interesting to get into the |
3262 // accelerator tables too. For now stick with dsymutil's behavior. | 1610 // accelerator tables too. For now stick with dsymutil's behavior. |
3263 if ((Info.InDebugMap || AttrInfo.HasLowPc || AttrInfo.HasRanges) && | 1611 if ((Info.InDebugMap || AttrInfo.HasLowPc || AttrInfo.HasRanges) && |
3264 Tag != dwarf::DW_TAG_compile_unit && | 1612 Tag != dwarf::DW_TAG_compile_unit && |
3265 getDIENames(InputDIE, AttrInfo, | 1613 getDIENames(InputDIE, AttrInfo, StringPool, |
3266 Tag != dwarf::DW_TAG_inlined_subroutine)) { | 1614 Tag != dwarf::DW_TAG_inlined_subroutine)) { |
3267 if (AttrInfo.MangledName && AttrInfo.MangledName != AttrInfo.Name) | 1615 if (AttrInfo.MangledName && AttrInfo.MangledName != AttrInfo.Name) |
3268 Unit.addNameAccelerator(Die, AttrInfo.MangledName, | 1616 Unit.addNameAccelerator(Die, AttrInfo.MangledName, |
3269 Tag == dwarf::DW_TAG_inlined_subroutine); | 1617 Tag == dwarf::DW_TAG_inlined_subroutine); |
3270 if (AttrInfo.Name) { | 1618 if (AttrInfo.Name) { |
3273 /* SkipPubSection */ true); | 1621 /* SkipPubSection */ true); |
3274 Unit.addNameAccelerator(Die, AttrInfo.Name, | 1622 Unit.addNameAccelerator(Die, AttrInfo.Name, |
3275 Tag == dwarf::DW_TAG_inlined_subroutine); | 1623 Tag == dwarf::DW_TAG_inlined_subroutine); |
3276 } | 1624 } |
3277 if (AttrInfo.Name && isObjCSelector(AttrInfo.Name.getString())) | 1625 if (AttrInfo.Name && isObjCSelector(AttrInfo.Name.getString())) |
3278 addObjCAccelerator(Unit, Die, AttrInfo.Name, /* SkipPubSection =*/true); | 1626 addObjCAccelerator(Unit, Die, AttrInfo.Name, StringPool, |
1627 /* SkipPubSection =*/true); | |
3279 | 1628 |
3280 } else if (Tag == dwarf::DW_TAG_namespace) { | 1629 } else if (Tag == dwarf::DW_TAG_namespace) { |
3281 if (!AttrInfo.Name) | 1630 if (!AttrInfo.Name) |
3282 AttrInfo.Name = Linker.StringPool.getEntry("(anonymous namespace)"); | 1631 AttrInfo.Name = StringPool.getEntry("(anonymous namespace)"); |
3283 Unit.addNamespaceAccelerator(Die, AttrInfo.Name); | 1632 Unit.addNamespaceAccelerator(Die, AttrInfo.Name); |
3284 } else if (isTypeTag(Tag) && !AttrInfo.IsDeclaration && | 1633 } else if (isTypeTag(Tag) && !AttrInfo.IsDeclaration && |
3285 getDIENames(InputDIE, AttrInfo) && AttrInfo.Name && | 1634 getDIENames(InputDIE, AttrInfo, StringPool) && AttrInfo.Name && |
3286 AttrInfo.Name.getString()[0]) { | 1635 AttrInfo.Name.getString()[0]) { |
3287 uint32_t Hash = hashFullyQualifiedName(InputDIE, Unit); | 1636 uint32_t Hash = hashFullyQualifiedName(InputDIE, Unit, DMO); |
3288 uint64_t RuntimeLang = | 1637 uint64_t RuntimeLang = |
3289 dwarf::toUnsigned(InputDIE.find(dwarf::DW_AT_APPLE_runtime_class)) | 1638 dwarf::toUnsigned(InputDIE.find(dwarf::DW_AT_APPLE_runtime_class)) |
3290 .getValueOr(0); | 1639 .getValueOr(0); |
3291 bool ObjCClassIsImplementation = | 1640 bool ObjCClassIsImplementation = |
3292 (RuntimeLang == dwarf::DW_LANG_ObjC || | 1641 (RuntimeLang == dwarf::DW_LANG_ObjC || |
3322 Die->setSize(OutOffset - Die->getOffset()); | 1671 Die->setSize(OutOffset - Die->getOffset()); |
3323 return Die; | 1672 return Die; |
3324 } | 1673 } |
3325 | 1674 |
3326 // Recursively clone children. | 1675 // Recursively clone children. |
3327 for (auto Child: InputDIE.children()) { | 1676 for (auto Child : InputDIE.children()) { |
3328 if (DIE *Clone = cloneDIE(Child, Unit, PCOffset, OutOffset, Flags)) { | 1677 if (DIE *Clone = cloneDIE(Child, DMO, Unit, StringPool, PCOffset, OutOffset, |
1678 Flags, IsLittleEndian)) { | |
3329 Die->addChild(Clone); | 1679 Die->addChild(Clone); |
3330 OutOffset = Clone->getOffset() + Clone->getSize(); | 1680 OutOffset = Clone->getOffset() + Clone->getSize(); |
3331 } | 1681 } |
3332 } | 1682 } |
3333 | 1683 |
3340 | 1690 |
3341 /// Patch the input object file relevant debug_ranges entries | 1691 /// Patch the input object file relevant debug_ranges entries |
3342 /// and emit them in the output file. Update the relevant attributes | 1692 /// and emit them in the output file. Update the relevant attributes |
3343 /// to point at the new entries. | 1693 /// to point at the new entries. |
3344 void DwarfLinker::patchRangesForUnit(const CompileUnit &Unit, | 1694 void DwarfLinker::patchRangesForUnit(const CompileUnit &Unit, |
3345 DWARFContext &OrigDwarf) const { | 1695 DWARFContext &OrigDwarf, |
1696 const DebugMapObject &DMO) const { | |
3346 DWARFDebugRangeList RangeList; | 1697 DWARFDebugRangeList RangeList; |
3347 const auto &FunctionRanges = Unit.getFunctionRanges(); | 1698 const auto &FunctionRanges = Unit.getFunctionRanges(); |
3348 unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize(); | 1699 unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize(); |
3349 DWARFDataExtractor RangeExtractor(OrigDwarf.getDWARFObj(), | 1700 DWARFDataExtractor RangeExtractor(OrigDwarf.getDWARFObj(), |
3350 OrigDwarf.getDWARFObj().getRangeSection(), | 1701 OrigDwarf.getDWARFObj().getRangesSection(), |
3351 OrigDwarf.isLittleEndian(), AddressSize); | 1702 OrigDwarf.isLittleEndian(), AddressSize); |
3352 auto InvalidRange = FunctionRanges.end(), CurrRange = InvalidRange; | 1703 auto InvalidRange = FunctionRanges.end(), CurrRange = InvalidRange; |
3353 DWARFUnit &OrigUnit = Unit.getOrigUnit(); | 1704 DWARFUnit &OrigUnit = Unit.getOrigUnit(); |
3354 auto OrigUnitDie = OrigUnit.getUnitDIE(false); | 1705 auto OrigUnitDie = OrigUnit.getUnitDIE(false); |
3355 uint64_t OrigLowPc = | 1706 uint64_t OrigLowPc = |
3359 int64_t UnitPcOffset = 0; | 1710 int64_t UnitPcOffset = 0; |
3360 if (OrigLowPc != -1ULL) | 1711 if (OrigLowPc != -1ULL) |
3361 UnitPcOffset = int64_t(OrigLowPc) - Unit.getLowPc(); | 1712 UnitPcOffset = int64_t(OrigLowPc) - Unit.getLowPc(); |
3362 | 1713 |
3363 for (const auto &RangeAttribute : Unit.getRangesAttributes()) { | 1714 for (const auto &RangeAttribute : Unit.getRangesAttributes()) { |
3364 uint32_t Offset = RangeAttribute.get(); | 1715 uint64_t Offset = RangeAttribute.get(); |
3365 RangeAttribute.set(Streamer->getRangesSectionSize()); | 1716 RangeAttribute.set(Streamer->getRangesSectionSize()); |
3366 RangeList.extract(RangeExtractor, &Offset); | 1717 if (Error E = RangeList.extract(RangeExtractor, &Offset)) { |
1718 llvm::consumeError(std::move(E)); | |
1719 reportWarning("invalid range list ignored.", DMO); | |
1720 RangeList.clear(); | |
1721 } | |
3367 const auto &Entries = RangeList.getEntries(); | 1722 const auto &Entries = RangeList.getEntries(); |
3368 if (!Entries.empty()) { | 1723 if (!Entries.empty()) { |
3369 const DWARFDebugRangeList::RangeListEntry &First = Entries.front(); | 1724 const DWARFDebugRangeList::RangeListEntry &First = Entries.front(); |
3370 | 1725 |
3371 if (CurrRange == InvalidRange || | 1726 if (CurrRange == InvalidRange || |
3372 First.StartAddress + OrigLowPc < CurrRange.start() || | 1727 First.StartAddress + OrigLowPc < CurrRange.start() || |
3373 First.StartAddress + OrigLowPc >= CurrRange.stop()) { | 1728 First.StartAddress + OrigLowPc >= CurrRange.stop()) { |
3374 CurrRange = FunctionRanges.find(First.StartAddress + OrigLowPc); | 1729 CurrRange = FunctionRanges.find(First.StartAddress + OrigLowPc); |
3375 if (CurrRange == InvalidRange || | 1730 if (CurrRange == InvalidRange || |
3376 CurrRange.start() > First.StartAddress + OrigLowPc) { | 1731 CurrRange.start() > First.StartAddress + OrigLowPc) { |
3377 reportWarning("no mapping for range."); | 1732 reportWarning("no mapping for range.", DMO); |
3378 continue; | 1733 continue; |
3379 } | 1734 } |
3380 } | 1735 } |
3381 } | 1736 } |
3382 | 1737 |
3409 Rows.insert(Rows.end(), Seq.begin(), Seq.end()); | 1764 Rows.insert(Rows.end(), Seq.begin(), Seq.end()); |
3410 Seq.clear(); | 1765 Seq.clear(); |
3411 return; | 1766 return; |
3412 } | 1767 } |
3413 | 1768 |
3414 auto InsertPoint = std::lower_bound( | 1769 object::SectionedAddress Front = Seq.front().Address; |
3415 Rows.begin(), Rows.end(), Seq.front(), | 1770 auto InsertPoint = partition_point( |
3416 [](const DWARFDebugLine::Row &LHS, const DWARFDebugLine::Row &RHS) { | 1771 Rows, [=](const DWARFDebugLine::Row &O) { return O.Address < Front; }); |
3417 return LHS.Address < RHS.Address; | |
3418 }); | |
3419 | 1772 |
3420 // FIXME: this only removes the unneeded end_sequence if the | 1773 // FIXME: this only removes the unneeded end_sequence if the |
3421 // sequences have been inserted in order. using a global sort like | 1774 // sequences have been inserted in order. Using a global sort like |
3422 // described in patchLineTableForUnit() and delaying the end_sequene | 1775 // described in patchLineTableForUnit() and delaying the end_sequene |
3423 // elimination to emitLineTableForUnit() we can get rid of all of them. | 1776 // elimination to emitLineTableForUnit() we can get rid of all of them. |
3424 if (InsertPoint != Rows.end() && | 1777 if (InsertPoint != Rows.end() && InsertPoint->Address == Front && |
3425 InsertPoint->Address == Seq.front().Address && InsertPoint->EndSequence) { | 1778 InsertPoint->EndSequence) { |
3426 *InsertPoint = Seq.front(); | 1779 *InsertPoint = Seq.front(); |
3427 Rows.insert(InsertPoint + 1, Seq.begin() + 1, Seq.end()); | 1780 Rows.insert(InsertPoint + 1, Seq.begin() + 1, Seq.end()); |
3428 } else { | 1781 } else { |
3429 Rows.insert(InsertPoint, Seq.begin(), Seq.end()); | 1782 Rows.insert(InsertPoint, Seq.begin(), Seq.end()); |
3430 } | 1783 } |
3444 | 1797 |
3445 /// Extract the line table for \p Unit from \p OrigDwarf, and | 1798 /// Extract the line table for \p Unit from \p OrigDwarf, and |
3446 /// recreate a relocated version of these for the address ranges that | 1799 /// recreate a relocated version of these for the address ranges that |
3447 /// are present in the binary. | 1800 /// are present in the binary. |
3448 void DwarfLinker::patchLineTableForUnit(CompileUnit &Unit, | 1801 void DwarfLinker::patchLineTableForUnit(CompileUnit &Unit, |
3449 DWARFContext &OrigDwarf) { | 1802 DWARFContext &OrigDwarf, |
1803 RangesTy &Ranges, | |
1804 const DebugMapObject &DMO) { | |
3450 DWARFDie CUDie = Unit.getOrigUnit().getUnitDIE(); | 1805 DWARFDie CUDie = Unit.getOrigUnit().getUnitDIE(); |
3451 auto StmtList = dwarf::toSectionOffset(CUDie.find(dwarf::DW_AT_stmt_list)); | 1806 auto StmtList = dwarf::toSectionOffset(CUDie.find(dwarf::DW_AT_stmt_list)); |
3452 if (!StmtList) | 1807 if (!StmtList) |
3453 return; | 1808 return; |
3454 | 1809 |
3456 if (auto *OutputDIE = Unit.getOutputUnitDIE()) | 1811 if (auto *OutputDIE = Unit.getOutputUnitDIE()) |
3457 patchStmtList(*OutputDIE, DIEInteger(Streamer->getLineSectionSize())); | 1812 patchStmtList(*OutputDIE, DIEInteger(Streamer->getLineSectionSize())); |
3458 | 1813 |
3459 // Parse the original line info for the unit. | 1814 // Parse the original line info for the unit. |
3460 DWARFDebugLine::LineTable LineTable; | 1815 DWARFDebugLine::LineTable LineTable; |
3461 uint32_t StmtOffset = *StmtList; | 1816 uint64_t StmtOffset = *StmtList; |
3462 DWARFDataExtractor LineExtractor( | 1817 DWARFDataExtractor LineExtractor( |
3463 OrigDwarf.getDWARFObj(), OrigDwarf.getDWARFObj().getLineSection(), | 1818 OrigDwarf.getDWARFObj(), OrigDwarf.getDWARFObj().getLineSection(), |
3464 OrigDwarf.isLittleEndian(), Unit.getOrigUnit().getAddressByteSize()); | 1819 OrigDwarf.isLittleEndian(), Unit.getOrigUnit().getAddressByteSize()); |
3465 LineTable.parse(LineExtractor, &StmtOffset, OrigDwarf, &Unit.getOrigUnit()); | 1820 if (Options.Translator) |
1821 return Streamer->translateLineTable(LineExtractor, StmtOffset); | |
1822 | |
1823 Error Err = LineTable.parse(LineExtractor, &StmtOffset, OrigDwarf, | |
1824 &Unit.getOrigUnit(), DWARFContext::dumpWarning); | |
1825 DWARFContext::dumpWarning(std::move(Err)); | |
3466 | 1826 |
3467 // This vector is the output line table. | 1827 // This vector is the output line table. |
3468 std::vector<DWARFDebugLine::Row> NewRows; | 1828 std::vector<DWARFDebugLine::Row> NewRows; |
3469 NewRows.reserve(LineTable.Rows.size()); | 1829 NewRows.reserve(LineTable.Rows.size()); |
3470 | 1830 |
3473 std::vector<DWARFDebugLine::Row> Seq; | 1833 std::vector<DWARFDebugLine::Row> Seq; |
3474 const auto &FunctionRanges = Unit.getFunctionRanges(); | 1834 const auto &FunctionRanges = Unit.getFunctionRanges(); |
3475 auto InvalidRange = FunctionRanges.end(), CurrRange = InvalidRange; | 1835 auto InvalidRange = FunctionRanges.end(), CurrRange = InvalidRange; |
3476 | 1836 |
3477 // FIXME: This logic is meant to generate exactly the same output as | 1837 // FIXME: This logic is meant to generate exactly the same output as |
3478 // Darwin's classic dsynutil. There is a nicer way to implement this | 1838 // Darwin's classic dsymutil. There is a nicer way to implement this |
3479 // by simply putting all the relocated line info in NewRows and simply | 1839 // by simply putting all the relocated line info in NewRows and simply |
3480 // sorting NewRows before passing it to emitLineTableForUnit. This | 1840 // sorting NewRows before passing it to emitLineTableForUnit. This |
3481 // should be correct as sequences for a function should stay | 1841 // should be correct as sequences for a function should stay |
3482 // together in the sorted output. There are a few corner cases that | 1842 // together in the sorted output. There are a few corner cases that |
3483 // look suspicious though, and that required to implement the logic | 1843 // look suspicious though, and that required to implement the logic |
3484 // this way. Revisit that once initial validation is finished. | 1844 // this way. Revisit that once initial validation is finished. |
3485 | 1845 |
3486 // Iterate over the object file line info and extract the sequences | 1846 // Iterate over the object file line info and extract the sequences |
3487 // that correspond to linked functions. | 1847 // that correspond to linked functions. |
3488 for (auto &Row : LineTable.Rows) { | 1848 for (auto &Row : LineTable.Rows) { |
3489 // Check wether we stepped out of the range. The range is | 1849 // Check whether we stepped out of the range. The range is |
3490 // half-open, but consider accept the end address of the range if | 1850 // half-open, but consider accept the end address of the range if |
3491 // it is marked as end_sequence in the input (because in that | 1851 // it is marked as end_sequence in the input (because in that |
3492 // case, the relocation offset is accurate and that entry won't | 1852 // case, the relocation offset is accurate and that entry won't |
3493 // serve as the start of another function). | 1853 // serve as the start of another function). |
3494 if (CurrRange == InvalidRange || Row.Address < CurrRange.start() || | 1854 if (CurrRange == InvalidRange || Row.Address.Address < CurrRange.start() || |
3495 Row.Address > CurrRange.stop() || | 1855 Row.Address.Address > CurrRange.stop() || |
3496 (Row.Address == CurrRange.stop() && !Row.EndSequence)) { | 1856 (Row.Address.Address == CurrRange.stop() && !Row.EndSequence)) { |
3497 // We just stepped out of a known range. Insert a end_sequence | 1857 // We just stepped out of a known range. Insert a end_sequence |
3498 // corresponding to the end of the range. | 1858 // corresponding to the end of the range. |
3499 uint64_t StopAddress = CurrRange != InvalidRange | 1859 uint64_t StopAddress = CurrRange != InvalidRange |
3500 ? CurrRange.stop() + CurrRange.value() | 1860 ? CurrRange.stop() + CurrRange.value() |
3501 : -1ULL; | 1861 : -1ULL; |
3502 CurrRange = FunctionRanges.find(Row.Address); | 1862 CurrRange = FunctionRanges.find(Row.Address.Address); |
3503 bool CurrRangeValid = | 1863 bool CurrRangeValid = |
3504 CurrRange != InvalidRange && CurrRange.start() <= Row.Address; | 1864 CurrRange != InvalidRange && CurrRange.start() <= Row.Address.Address; |
3505 if (!CurrRangeValid) { | 1865 if (!CurrRangeValid) { |
3506 CurrRange = InvalidRange; | 1866 CurrRange = InvalidRange; |
3507 if (StopAddress != -1ULL) { | 1867 if (StopAddress != -1ULL) { |
3508 // Try harder by looking in the DebugMapObject function | 1868 // Try harder by looking in the DebugMapObject function |
3509 // ranges map. There are corner cases where this finds a | 1869 // ranges map. There are corner cases where this finds a |
3510 // valid entry. It's unclear if this is right or wrong, but | 1870 // valid entry. It's unclear if this is right or wrong, but |
3511 // for now do as dsymutil. | 1871 // for now do as dsymutil. |
3512 // FIXME: Understand exactly what cases this addresses and | 1872 // FIXME: Understand exactly what cases this addresses and |
3513 // potentially remove it along with the Ranges map. | 1873 // potentially remove it along with the Ranges map. |
3514 auto Range = Ranges.lower_bound(Row.Address); | 1874 auto Range = Ranges.lower_bound(Row.Address.Address); |
3515 if (Range != Ranges.begin() && Range != Ranges.end()) | 1875 if (Range != Ranges.begin() && Range != Ranges.end()) |
3516 --Range; | 1876 --Range; |
3517 | 1877 |
3518 if (Range != Ranges.end() && Range->first <= Row.Address && | 1878 if (Range != Ranges.end() && Range->first <= Row.Address.Address && |
3519 Range->second.first >= Row.Address) { | 1879 Range->second.HighPC >= Row.Address.Address) { |
3520 StopAddress = Row.Address + Range->second.second; | 1880 StopAddress = Row.Address.Address + Range->second.Offset; |
3521 } | 1881 } |
3522 } | 1882 } |
3523 } | 1883 } |
3524 if (StopAddress != -1ULL && !Seq.empty()) { | 1884 if (StopAddress != -1ULL && !Seq.empty()) { |
3525 // Insert end sequence row with the computed end address, but | 1885 // Insert end sequence row with the computed end address, but |
3526 // the same line as the previous one. | 1886 // the same line as the previous one. |
3527 auto NextLine = Seq.back(); | 1887 auto NextLine = Seq.back(); |
3528 NextLine.Address = StopAddress; | 1888 NextLine.Address.Address = StopAddress; |
3529 NextLine.EndSequence = 1; | 1889 NextLine.EndSequence = 1; |
3530 NextLine.PrologueEnd = 0; | 1890 NextLine.PrologueEnd = 0; |
3531 NextLine.BasicBlock = 0; | 1891 NextLine.BasicBlock = 0; |
3532 NextLine.EpilogueBegin = 0; | 1892 NextLine.EpilogueBegin = 0; |
3533 Seq.push_back(NextLine); | 1893 Seq.push_back(NextLine); |
3541 // Ignore empty sequences. | 1901 // Ignore empty sequences. |
3542 if (Row.EndSequence && Seq.empty()) | 1902 if (Row.EndSequence && Seq.empty()) |
3543 continue; | 1903 continue; |
3544 | 1904 |
3545 // Relocate row address and add it to the current sequence. | 1905 // Relocate row address and add it to the current sequence. |
3546 Row.Address += CurrRange.value(); | 1906 Row.Address.Address += CurrRange.value(); |
3547 Seq.emplace_back(Row); | 1907 Seq.emplace_back(Row); |
3548 | 1908 |
3549 if (Row.EndSequence) | 1909 if (Row.EndSequence) |
3550 insertLineSequence(Seq, NewRows); | 1910 insertLineSequence(Seq, NewRows); |
3551 } | 1911 } |
3552 | 1912 |
3553 // Finished extracting, now emit the line tables. | 1913 // Finished extracting, now emit the line tables. |
3554 // FIXME: LLVM hardcodes its prologue values. We just copy the | 1914 // FIXME: LLVM hard-codes its prologue values. We just copy the |
3555 // prologue over and that works because we act as both producer and | 1915 // prologue over and that works because we act as both producer and |
3556 // consumer. It would be nicer to have a real configurable line | 1916 // consumer. It would be nicer to have a real configurable line |
3557 // table emitter. | 1917 // table emitter. |
3558 if (LineTable.Prologue.getVersion() < 2 || | 1918 if (LineTable.Prologue.getVersion() < 2 || |
3559 LineTable.Prologue.getVersion() > 5 || | 1919 LineTable.Prologue.getVersion() > 5 || |
3560 LineTable.Prologue.DefaultIsStmt != DWARF2_LINE_DEFAULT_IS_STMT || | 1920 LineTable.Prologue.DefaultIsStmt != DWARF2_LINE_DEFAULT_IS_STMT || |
3561 LineTable.Prologue.OpcodeBase > 13) | 1921 LineTable.Prologue.OpcodeBase > 13) |
3562 reportWarning("line table parameters mismatch. Cannot emit."); | 1922 reportWarning("line table parameters mismatch. Cannot emit.", DMO); |
3563 else { | 1923 else { |
3564 uint32_t PrologueEnd = *StmtList + 10 + LineTable.Prologue.PrologueLength; | 1924 uint32_t PrologueEnd = *StmtList + 10 + LineTable.Prologue.PrologueLength; |
3565 // DWARF v5 has an extra 2 bytes of information before the header_length | 1925 // DWARF v5 has an extra 2 bytes of information before the header_length |
3566 // field. | 1926 // field. |
3567 if (LineTable.Prologue.getVersion() == 5) | 1927 if (LineTable.Prologue.getVersion() == 5) |
3577 Unit.getOrigUnit().getAddressByteSize()); | 1937 Unit.getOrigUnit().getAddressByteSize()); |
3578 } | 1938 } |
3579 } | 1939 } |
3580 | 1940 |
3581 void DwarfLinker::emitAcceleratorEntriesForUnit(CompileUnit &Unit) { | 1941 void DwarfLinker::emitAcceleratorEntriesForUnit(CompileUnit &Unit) { |
1942 switch (Options.TheAccelTableKind) { | |
1943 case AccelTableKind::Apple: | |
1944 emitAppleAcceleratorEntriesForUnit(Unit); | |
1945 break; | |
1946 case AccelTableKind::Dwarf: | |
1947 emitDwarfAcceleratorEntriesForUnit(Unit); | |
1948 break; | |
1949 case AccelTableKind::Default: | |
1950 llvm_unreachable("The default must be updated to a concrete value."); | |
1951 break; | |
1952 } | |
1953 } | |
1954 | |
1955 void DwarfLinker::emitAppleAcceleratorEntriesForUnit(CompileUnit &Unit) { | |
3582 // Add namespaces. | 1956 // Add namespaces. |
3583 for (const auto &Namespace : Unit.getNamespaces()) | 1957 for (const auto &Namespace : Unit.getNamespaces()) |
3584 AppleNamespaces.addName(Namespace.Name, | 1958 AppleNamespaces.addName(Namespace.Name, |
3585 Namespace.Die->getOffset() + Unit.getStartOffset()); | 1959 Namespace.Die->getOffset() + Unit.getStartOffset()); |
3586 | 1960 |
3605 /// Add ObjC names. | 1979 /// Add ObjC names. |
3606 for (const auto &ObjC : Unit.getObjC()) | 1980 for (const auto &ObjC : Unit.getObjC()) |
3607 AppleObjc.addName(ObjC.Name, ObjC.Die->getOffset() + Unit.getStartOffset()); | 1981 AppleObjc.addName(ObjC.Name, ObjC.Die->getOffset() + Unit.getStartOffset()); |
3608 } | 1982 } |
3609 | 1983 |
1984 void DwarfLinker::emitDwarfAcceleratorEntriesForUnit(CompileUnit &Unit) { | |
1985 for (const auto &Namespace : Unit.getNamespaces()) | |
1986 DebugNames.addName(Namespace.Name, Namespace.Die->getOffset(), | |
1987 Namespace.Die->getTag(), Unit.getUniqueID()); | |
1988 for (const auto &Pubname : Unit.getPubnames()) | |
1989 DebugNames.addName(Pubname.Name, Pubname.Die->getOffset(), | |
1990 Pubname.Die->getTag(), Unit.getUniqueID()); | |
1991 for (const auto &Pubtype : Unit.getPubtypes()) | |
1992 DebugNames.addName(Pubtype.Name, Pubtype.Die->getOffset(), | |
1993 Pubtype.Die->getTag(), Unit.getUniqueID()); | |
1994 } | |
1995 | |
3610 /// Read the frame info stored in the object, and emit the | 1996 /// Read the frame info stored in the object, and emit the |
3611 /// patched frame descriptions for the linked binary. | 1997 /// patched frame descriptions for the linked binary. |
3612 /// | 1998 /// |
3613 /// This is actually pretty easy as the data of the CIEs and FDEs can | 1999 /// This is actually pretty easy as the data of the CIEs and FDEs can |
3614 /// be considered as black boxes and moved as is. The only thing to do | 2000 /// be considered as black boxes and moved as is. The only thing to do |
3615 /// is to patch the addresses in the headers. | 2001 /// is to patch the addresses in the headers. |
3616 void DwarfLinker::patchFrameInfoForObject(const DebugMapObject &DMO, | 2002 void DwarfLinker::patchFrameInfoForObject(const DebugMapObject &DMO, |
2003 RangesTy &Ranges, | |
3617 DWARFContext &OrigDwarf, | 2004 DWARFContext &OrigDwarf, |
3618 unsigned AddrSize) { | 2005 unsigned AddrSize) { |
3619 StringRef FrameData = OrigDwarf.getDWARFObj().getDebugFrameSection(); | 2006 StringRef FrameData = OrigDwarf.getDWARFObj().getFrameSection().Data; |
3620 if (FrameData.empty()) | 2007 if (FrameData.empty()) |
3621 return; | 2008 return; |
3622 | 2009 |
3623 DataExtractor Data(FrameData, OrigDwarf.isLittleEndian(), 0); | 2010 DataExtractor Data(FrameData, OrigDwarf.isLittleEndian(), 0); |
3624 uint32_t InputOffset = 0; | 2011 uint64_t InputOffset = 0; |
3625 | 2012 |
3626 // Store the data of the CIEs defined in this object, keyed by their | 2013 // Store the data of the CIEs defined in this object, keyed by their |
3627 // offsets. | 2014 // offsets. |
3628 DenseMap<uint32_t, StringRef> LocalCIES; | 2015 DenseMap<uint64_t, StringRef> LocalCIES; |
3629 | 2016 |
3630 while (Data.isValidOffset(InputOffset)) { | 2017 while (Data.isValidOffset(InputOffset)) { |
3631 uint32_t EntryOffset = InputOffset; | 2018 uint64_t EntryOffset = InputOffset; |
3632 uint32_t InitialLength = Data.getU32(&InputOffset); | 2019 uint32_t InitialLength = Data.getU32(&InputOffset); |
3633 if (InitialLength == 0xFFFFFFFF) | 2020 if (InitialLength == 0xFFFFFFFF) |
3634 return reportWarning("Dwarf64 bits no supported"); | 2021 return reportWarning("Dwarf64 bits no supported", DMO); |
3635 | 2022 |
3636 uint32_t CIEId = Data.getU32(&InputOffset); | 2023 uint32_t CIEId = Data.getU32(&InputOffset); |
3637 if (CIEId == 0xFFFFFFFF) { | 2024 if (CIEId == 0xFFFFFFFF) { |
3638 // This is a CIE, store it. | 2025 // This is a CIE, store it. |
3639 StringRef CIEData = FrameData.substr(EntryOffset, InitialLength + 4); | 2026 StringRef CIEData = FrameData.substr(EntryOffset, InitialLength + 4); |
3651 // describes something that we can relocate. | 2038 // describes something that we can relocate. |
3652 auto Range = Ranges.upper_bound(Loc); | 2039 auto Range = Ranges.upper_bound(Loc); |
3653 if (Range != Ranges.begin()) | 2040 if (Range != Ranges.begin()) |
3654 --Range; | 2041 --Range; |
3655 if (Range == Ranges.end() || Range->first > Loc || | 2042 if (Range == Ranges.end() || Range->first > Loc || |
3656 Range->second.first <= Loc) { | 2043 Range->second.HighPC <= Loc) { |
3657 // The +4 is to account for the size of the InitialLength field itself. | 2044 // The +4 is to account for the size of the InitialLength field itself. |
3658 InputOffset = EntryOffset + InitialLength + 4; | 2045 InputOffset = EntryOffset + InitialLength + 4; |
3659 continue; | 2046 continue; |
3660 } | 2047 } |
3661 | 2048 |
3662 // This is an FDE, and we have a mapping. | 2049 // This is an FDE, and we have a mapping. |
3663 // Have we already emitted a corresponding CIE? | 2050 // Have we already emitted a corresponding CIE? |
3664 StringRef CIEData = LocalCIES[CIEId]; | 2051 StringRef CIEData = LocalCIES[CIEId]; |
3665 if (CIEData.empty()) | 2052 if (CIEData.empty()) |
3666 return reportWarning("Inconsistent debug_frame content. Dropping."); | 2053 return reportWarning("Inconsistent debug_frame content. Dropping.", DMO); |
3667 | 2054 |
3668 // Look if we already emitted a CIE that corresponds to the | 2055 // Look if we already emitted a CIE that corresponds to the |
3669 // referenced one (the CIE data is the key of that lookup). | 2056 // referenced one (the CIE data is the key of that lookup). |
3670 auto IteratorInserted = EmittedCIEs.insert( | 2057 auto IteratorInserted = EmittedCIEs.insert( |
3671 std::make_pair(CIEData, Streamer->getFrameSectionSize())); | 2058 std::make_pair(CIEData, Streamer->getFrameSectionSize())); |
3684 // Emit the FDE with updated address and CIE pointer. | 2071 // Emit the FDE with updated address and CIE pointer. |
3685 // (4 + AddrSize) is the size of the CIEId + initial_location | 2072 // (4 + AddrSize) is the size of the CIEId + initial_location |
3686 // fields that will get reconstructed by emitFDE(). | 2073 // fields that will get reconstructed by emitFDE(). |
3687 unsigned FDERemainingBytes = InitialLength - (4 + AddrSize); | 2074 unsigned FDERemainingBytes = InitialLength - (4 + AddrSize); |
3688 Streamer->emitFDE(IteratorInserted.first->getValue(), AddrSize, | 2075 Streamer->emitFDE(IteratorInserted.first->getValue(), AddrSize, |
3689 Loc + Range->second.second, | 2076 Loc + Range->second.Offset, |
3690 FrameData.substr(InputOffset, FDERemainingBytes)); | 2077 FrameData.substr(InputOffset, FDERemainingBytes)); |
3691 InputOffset += FDERemainingBytes; | 2078 InputOffset += FDERemainingBytes; |
3692 } | 2079 } |
3693 } | 2080 } |
3694 | 2081 |
3705 } | 2092 } |
3706 | 2093 |
3707 Linker.AssignAbbrev(Copy); | 2094 Linker.AssignAbbrev(Copy); |
3708 } | 2095 } |
3709 | 2096 |
3710 uint32_t DwarfLinker::DIECloner::hashFullyQualifiedName(DWARFDie DIE, | 2097 uint32_t |
3711 CompileUnit &U, | 2098 DwarfLinker::DIECloner::hashFullyQualifiedName(DWARFDie DIE, CompileUnit &U, |
3712 int RecurseDepth) { | 2099 const DebugMapObject &DMO, |
2100 int ChildRecurseDepth) { | |
3713 const char *Name = nullptr; | 2101 const char *Name = nullptr; |
3714 DWARFUnit *OrigUnit = &U.getOrigUnit(); | 2102 DWARFUnit *OrigUnit = &U.getOrigUnit(); |
3715 CompileUnit *CU = &U; | 2103 CompileUnit *CU = &U; |
3716 Optional<DWARFFormValue> Ref; | 2104 Optional<DWARFFormValue> Ref; |
3717 | 2105 |
3725 | 2113 |
3726 if (!Ref->isFormClass(DWARFFormValue::FC_Reference)) | 2114 if (!Ref->isFormClass(DWARFFormValue::FC_Reference)) |
3727 break; | 2115 break; |
3728 | 2116 |
3729 CompileUnit *RefCU; | 2117 CompileUnit *RefCU; |
3730 if (auto RefDIE = resolveDIEReference(Linker, CompileUnits, *Ref, | 2118 if (auto RefDIE = |
3731 U.getOrigUnit(), DIE, RefCU)) { | 2119 resolveDIEReference(Linker, DMO, CompileUnits, *Ref, DIE, RefCU)) { |
3732 CU = RefCU; | 2120 CU = RefCU; |
3733 OrigUnit = &RefCU->getOrigUnit(); | 2121 OrigUnit = &RefCU->getOrigUnit(); |
3734 DIE = RefDIE; | 2122 DIE = RefDIE; |
3735 } | 2123 } |
3736 } | 2124 } |
3741 | 2129 |
3742 if (CU->getInfo(Idx).ParentIdx == 0 || | 2130 if (CU->getInfo(Idx).ParentIdx == 0 || |
3743 // FIXME: dsymutil-classic compatibility. Ignore modules. | 2131 // FIXME: dsymutil-classic compatibility. Ignore modules. |
3744 CU->getOrigUnit().getDIEAtIndex(CU->getInfo(Idx).ParentIdx).getTag() == | 2132 CU->getOrigUnit().getDIEAtIndex(CU->getInfo(Idx).ParentIdx).getTag() == |
3745 dwarf::DW_TAG_module) | 2133 dwarf::DW_TAG_module) |
3746 return djbHash(Name ? Name : "", djbHash(RecurseDepth ? "" : "::")); | 2134 return djbHash(Name ? Name : "", djbHash(ChildRecurseDepth ? "" : "::")); |
3747 | 2135 |
3748 DWARFDie Die = OrigUnit->getDIEAtIndex(CU->getInfo(Idx).ParentIdx); | 2136 DWARFDie Die = OrigUnit->getDIEAtIndex(CU->getInfo(Idx).ParentIdx); |
3749 return djbHash((Name ? Name : ""), | 2137 return djbHash( |
3750 djbHash((Name ? "::" : ""), | 2138 (Name ? Name : ""), |
3751 hashFullyQualifiedName(Die, *CU, ++RecurseDepth))); | 2139 djbHash((Name ? "::" : ""), |
3752 } | 2140 hashFullyQualifiedName(Die, *CU, DMO, ++ChildRecurseDepth))); |
3753 | 2141 } |
3754 static uint64_t getDwoId(const DWARFDie &CUDie, | 2142 |
3755 const DWARFUnit &Unit) { | 2143 static uint64_t getDwoId(const DWARFDie &CUDie, const DWARFUnit &Unit) { |
3756 auto DwoId = dwarf::toUnsigned(CUDie.find({dwarf::DW_AT_dwo_id, | 2144 auto DwoId = dwarf::toUnsigned( |
3757 dwarf::DW_AT_GNU_dwo_id})); | 2145 CUDie.find({dwarf::DW_AT_dwo_id, dwarf::DW_AT_GNU_dwo_id})); |
3758 if (DwoId) | 2146 if (DwoId) |
3759 return *DwoId; | 2147 return *DwoId; |
3760 return 0; | 2148 return 0; |
3761 } | 2149 } |
3762 | 2150 |
3763 bool DwarfLinker::registerModuleReference( | 2151 bool DwarfLinker::registerModuleReference( |
3764 const DWARFDie &CUDie, const DWARFUnit &Unit, | 2152 DWARFDie CUDie, const DWARFUnit &Unit, DebugMap &ModuleMap, |
3765 DebugMap &ModuleMap, unsigned Indent) { | 2153 const DebugMapObject &DMO, RangesTy &Ranges, OffsetsStringPool &StringPool, |
3766 std::string PCMfile = | 2154 UniquingStringPool &UniquingStringPool, DeclContextTree &ODRContexts, |
3767 dwarf::toString(CUDie.find({dwarf::DW_AT_dwo_name, | 2155 uint64_t ModulesEndOffset, unsigned &UnitID, bool IsLittleEndian, |
3768 dwarf::DW_AT_GNU_dwo_name}), ""); | 2156 unsigned Indent, bool Quiet) { |
2157 std::string PCMfile = dwarf::toString( | |
2158 CUDie.find({dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name}), ""); | |
3769 if (PCMfile.empty()) | 2159 if (PCMfile.empty()) |
3770 return false; | 2160 return false; |
3771 | 2161 |
3772 // Clang module DWARF skeleton CUs abuse this for the path to the module. | 2162 // Clang module DWARF skeleton CUs abuse this for the path to the module. |
3773 std::string PCMpath = dwarf::toString(CUDie.find(dwarf::DW_AT_comp_dir), ""); | |
3774 uint64_t DwoId = getDwoId(CUDie, Unit); | 2163 uint64_t DwoId = getDwoId(CUDie, Unit); |
3775 | 2164 |
3776 std::string Name = dwarf::toString(CUDie.find(dwarf::DW_AT_name), ""); | 2165 std::string Name = dwarf::toString(CUDie.find(dwarf::DW_AT_name), ""); |
3777 if (Name.empty()) { | 2166 if (Name.empty()) { |
3778 reportWarning("Anonymous module skeleton CU for " + PCMfile); | 2167 if (!Quiet) |
2168 reportWarning("Anonymous module skeleton CU for " + PCMfile, DMO); | |
3779 return true; | 2169 return true; |
3780 } | 2170 } |
3781 | 2171 |
3782 if (Options.Verbose) { | 2172 if (!Quiet && Options.Verbose) { |
3783 outs().indent(Indent); | 2173 outs().indent(Indent); |
3784 outs() << "Found clang module reference " << PCMfile; | 2174 outs() << "Found clang module reference " << PCMfile; |
3785 } | 2175 } |
3786 | 2176 |
3787 auto Cached = ClangModules.find(PCMfile); | 2177 auto Cached = ClangModules.find(PCMfile); |
3788 if (Cached != ClangModules.end()) { | 2178 if (Cached != ClangModules.end()) { |
3789 // FIXME: Until PR27449 (https://llvm.org/bugs/show_bug.cgi?id=27449) is | 2179 // FIXME: Until PR27449 (https://llvm.org/bugs/show_bug.cgi?id=27449) is |
3790 // fixed in clang, only warn about DWO_id mismatches in verbose mode. | 2180 // fixed in clang, only warn about DWO_id mismatches in verbose mode. |
3791 // ASTFileSignatures will change randomly when a module is rebuilt. | 2181 // ASTFileSignatures will change randomly when a module is rebuilt. |
3792 if (Options.Verbose && (Cached->second != DwoId)) | 2182 if (!Quiet && Options.Verbose && (Cached->second != DwoId)) |
3793 reportWarning(Twine("hash mismatch: this object file was built against a " | 2183 reportWarning(Twine("hash mismatch: this object file was built against a " |
3794 "different version of the module ") + PCMfile); | 2184 "different version of the module ") + |
3795 if (Options.Verbose) | 2185 PCMfile, |
2186 DMO); | |
2187 if (!Quiet && Options.Verbose) | |
3796 outs() << " [cached].\n"; | 2188 outs() << " [cached].\n"; |
3797 return true; | 2189 return true; |
3798 } | 2190 } |
3799 if (Options.Verbose) | 2191 if (!Quiet && Options.Verbose) |
3800 outs() << " ...\n"; | 2192 outs() << " ...\n"; |
3801 | 2193 |
3802 // Cyclic dependencies are disallowed by Clang, but we still | 2194 // Cyclic dependencies are disallowed by Clang, but we still |
3803 // shouldn't run into an infinite loop, so mark it as processed now. | 2195 // shouldn't run into an infinite loop, so mark it as processed now. |
3804 ClangModules.insert({PCMfile, DwoId}); | 2196 ClangModules.insert({PCMfile, DwoId}); |
3805 if (Error E = loadClangModule(PCMfile, PCMpath, Name, DwoId, ModuleMap, | 2197 |
3806 Indent + 2)) { | 2198 if (Error E = loadClangModule(CUDie, PCMfile, Name, DwoId, ModuleMap, DMO, |
2199 Ranges, StringPool, UniquingStringPool, | |
2200 ODRContexts, ModulesEndOffset, UnitID, | |
2201 IsLittleEndian, Indent + 2, Quiet)) { | |
3807 consumeError(std::move(E)); | 2202 consumeError(std::move(E)); |
3808 return false; | 2203 return false; |
3809 } | 2204 } |
3810 return true; | 2205 return true; |
3811 } | 2206 } |
3812 | 2207 |
3813 ErrorOr<const object::ObjectFile &> | 2208 ErrorOr<const object::ObjectFile &> |
3814 DwarfLinker::loadObject(BinaryHolder &BinaryHolder, DebugMapObject &Obj, | 2209 DwarfLinker::loadObject(const DebugMapObject &Obj, const DebugMap &Map) { |
3815 const DebugMap &Map) { | 2210 auto ObjectEntry = |
3816 auto ErrOrObjs = | 2211 BinHolder.getObjectEntry(Obj.getObjectFilename(), Obj.getTimestamp()); |
3817 BinaryHolder.GetObjectFiles(Obj.getObjectFilename(), Obj.getTimestamp()); | 2212 if (!ObjectEntry) { |
3818 if (std::error_code EC = ErrOrObjs.getError()) { | 2213 auto Err = ObjectEntry.takeError(); |
3819 reportWarning(Twine(Obj.getObjectFilename()) + ": " + EC.message()); | 2214 reportWarning( |
3820 return EC; | 2215 Twine(Obj.getObjectFilename()) + ": " + toString(std::move(Err)), Obj); |
3821 } | 2216 return errorToErrorCode(std::move(Err)); |
3822 auto ErrOrObj = BinaryHolder.Get(Map.getTriple()); | 2217 } |
3823 if (std::error_code EC = ErrOrObj.getError()) | 2218 |
3824 reportWarning(Twine(Obj.getObjectFilename()) + ": " + EC.message()); | 2219 auto Object = ObjectEntry->getObject(Map.getTriple()); |
3825 return ErrOrObj; | 2220 if (!Object) { |
3826 } | 2221 auto Err = Object.takeError(); |
3827 | 2222 reportWarning( |
3828 Error DwarfLinker::loadClangModule(StringRef Filename, StringRef ModulePath, | 2223 Twine(Obj.getObjectFilename()) + ": " + toString(std::move(Err)), Obj); |
3829 StringRef ModuleName, uint64_t DwoId, | 2224 return errorToErrorCode(std::move(Err)); |
3830 DebugMap &ModuleMap, unsigned Indent) { | 2225 } |
3831 SmallString<80> Path(Options.PrependPath); | 2226 |
2227 return *Object; | |
2228 } | |
2229 | |
2230 Error DwarfLinker::loadClangModule( | |
2231 DWARFDie CUDie, StringRef Filename, StringRef ModuleName, uint64_t DwoId, | |
2232 DebugMap &ModuleMap, const DebugMapObject &DMO, RangesTy &Ranges, | |
2233 OffsetsStringPool &StringPool, UniquingStringPool &UniquingStringPool, | |
2234 DeclContextTree &ODRContexts, uint64_t ModulesEndOffset, unsigned &UnitID, | |
2235 bool IsLittleEndian, unsigned Indent, bool Quiet) { | |
2236 /// Using a SmallString<0> because loadClangModule() is recursive. | |
2237 SmallString<0> Path(Options.PrependPath); | |
3832 if (sys::path::is_relative(Filename)) | 2238 if (sys::path::is_relative(Filename)) |
3833 sys::path::append(Path, ModulePath, Filename); | 2239 resolveRelativeObjectPath(Path, CUDie); |
3834 else | 2240 sys::path::append(Path, Filename); |
3835 sys::path::append(Path, Filename); | 2241 // Don't use the cached binary holder because we have no thread-safety |
3836 BinaryHolder ObjHolder(Options.Verbose); | 2242 // guarantee and the lifetime is limited. |
3837 auto &Obj = ModuleMap.addDebugMapObject( | 2243 auto &Obj = ModuleMap.addDebugMapObject( |
3838 Path, sys::TimePoint<std::chrono::seconds>(), MachO::N_OSO); | 2244 Path, sys::TimePoint<std::chrono::seconds>(), MachO::N_OSO); |
3839 auto ErrOrObj = loadObject(ObjHolder, Obj, ModuleMap); | 2245 auto ErrOrObj = loadObject(Obj, ModuleMap); |
3840 if (!ErrOrObj) { | 2246 if (!ErrOrObj) { |
3841 // Try and emit more helpful warnings by applying some heuristics. | 2247 // Try and emit more helpful warnings by applying some heuristics. |
3842 StringRef ObjFile = CurrentDebugObject->getObjectFilename(); | 2248 StringRef ObjFile = DMO.getObjectFilename(); |
3843 bool isClangModule = sys::path::extension(Filename).equals(".pcm"); | 2249 bool isClangModule = sys::path::extension(Filename).equals(".pcm"); |
3844 bool isArchive = ObjFile.endswith(")"); | 2250 bool isArchive = ObjFile.endswith(")"); |
3845 if (isClangModule) { | 2251 if (isClangModule) { |
3846 StringRef ModuleCacheDir = sys::path::parent_path(Path); | 2252 StringRef ModuleCacheDir = sys::path::parent_path(Path); |
3847 if (sys::fs::exists(ModuleCacheDir)) { | 2253 if (sys::fs::exists(ModuleCacheDir)) { |
3848 // If the module's parent directory exists, we assume that the module | 2254 // If the module's parent directory exists, we assume that the module |
3849 // cache has expired and was pruned by clang. A more adventurous | 2255 // cache has expired and was pruned by clang. A more adventurous |
3850 // dsymutil would invoke clang to rebuild the module now. | 2256 // dsymutil would invoke clang to rebuild the module now. |
3851 if (!ModuleCacheHintDisplayed) { | 2257 if (!ModuleCacheHintDisplayed) { |
3852 errs() << "note: The clang module cache may have expired since this " | 2258 WithColor::note() << "The clang module cache may have expired since " |
3853 "object file was built. Rebuilding the object file will " | 2259 "this object file was built. Rebuilding the " |
3854 "rebuild the module cache.\n"; | 2260 "object file will rebuild the module cache.\n"; |
3855 ModuleCacheHintDisplayed = true; | 2261 ModuleCacheHintDisplayed = true; |
3856 } | 2262 } |
3857 } else if (isArchive) { | 2263 } else if (isArchive) { |
3858 // If the module cache directory doesn't exist at all and the object | 2264 // If the module cache directory doesn't exist at all and the object |
3859 // file is inside a static library, we assume that the static library | 2265 // file is inside a static library, we assume that the static library |
3860 // was built on a different machine. We don't want to discourage module | 2266 // was built on a different machine. We don't want to discourage module |
3861 // debugging for convenience libraries within a project though. | 2267 // debugging for convenience libraries within a project though. |
3862 if (!ArchiveHintDisplayed) { | 2268 if (!ArchiveHintDisplayed) { |
3863 errs() << "note: Linking a static library that was built with " | 2269 WithColor::note() |
3864 "-gmodules, but the module cache was not found. " | 2270 << "Linking a static library that was built with " |
3865 "Redistributable static libraries should never be built " | 2271 "-gmodules, but the module cache was not found. " |
3866 "with module debugging enabled. The debug experience will " | 2272 "Redistributable static libraries should never be " |
3867 "be degraded due to incomplete debug information.\n"; | 2273 "built with module debugging enabled. The debug " |
2274 "experience will be degraded due to incomplete " | |
2275 "debug information.\n"; | |
3868 ArchiveHintDisplayed = true; | 2276 ArchiveHintDisplayed = true; |
3869 } | 2277 } |
3870 } | 2278 } |
3871 } | 2279 } |
3872 return Error::success(); | 2280 return Error::success(); |
3875 std::unique_ptr<CompileUnit> Unit; | 2283 std::unique_ptr<CompileUnit> Unit; |
3876 | 2284 |
3877 // Setup access to the debug info. | 2285 // Setup access to the debug info. |
3878 auto DwarfContext = DWARFContext::create(*ErrOrObj); | 2286 auto DwarfContext = DWARFContext::create(*ErrOrObj); |
3879 RelocationManager RelocMgr(*this); | 2287 RelocationManager RelocMgr(*this); |
2288 | |
3880 for (const auto &CU : DwarfContext->compile_units()) { | 2289 for (const auto &CU : DwarfContext->compile_units()) { |
3881 maybeUpdateMaxDwarfVersion(CU->getVersion()); | 2290 updateDwarfVersion(CU->getVersion()); |
3882 | |
3883 // Recursively get all modules imported by this one. | 2291 // Recursively get all modules imported by this one. |
3884 auto CUDie = CU->getUnitDIE(false); | 2292 auto CUDie = CU->getUnitDIE(false); |
3885 if (!registerModuleReference(CUDie, *CU, ModuleMap, Indent)) { | 2293 if (!CUDie) |
2294 continue; | |
2295 if (!registerModuleReference(CUDie, *CU, ModuleMap, DMO, Ranges, StringPool, | |
2296 UniquingStringPool, ODRContexts, | |
2297 ModulesEndOffset, UnitID, IsLittleEndian, | |
2298 Indent, Quiet)) { | |
3886 if (Unit) { | 2299 if (Unit) { |
3887 std::string Err = | 2300 std::string Err = |
3888 (Filename + | 2301 (Filename + |
3889 ": Clang modules are expected to have exactly 1 compile unit.\n") | 2302 ": Clang modules are expected to have exactly 1 compile unit.\n") |
3890 .str(); | 2303 .str(); |
3891 errs() << Err; | 2304 error(Err); |
3892 return make_error<StringError>(Err, inconvertibleErrorCode()); | 2305 return make_error<StringError>(Err, inconvertibleErrorCode()); |
3893 } | 2306 } |
3894 // FIXME: Until PR27449 (https://llvm.org/bugs/show_bug.cgi?id=27449) is | 2307 // FIXME: Until PR27449 (https://llvm.org/bugs/show_bug.cgi?id=27449) is |
3895 // fixed in clang, only warn about DWO_id mismatches in verbose mode. | 2308 // fixed in clang, only warn about DWO_id mismatches in verbose mode. |
3896 // ASTFileSignatures will change randomly when a module is rebuilt. | 2309 // ASTFileSignatures will change randomly when a module is rebuilt. |
3897 uint64_t PCMDwoId = getDwoId(CUDie, *CU); | 2310 uint64_t PCMDwoId = getDwoId(CUDie, *CU); |
3898 if (PCMDwoId != DwoId) { | 2311 if (PCMDwoId != DwoId) { |
3899 if (Options.Verbose) | 2312 if (!Quiet && Options.Verbose) |
3900 reportWarning( | 2313 reportWarning( |
3901 Twine("hash mismatch: this object file was built against a " | 2314 Twine("hash mismatch: this object file was built against a " |
3902 "different version of the module ") + Filename); | 2315 "different version of the module ") + |
2316 Filename, | |
2317 DMO); | |
3903 // Update the cache entry with the DwoId of the module loaded from disk. | 2318 // Update the cache entry with the DwoId of the module loaded from disk. |
3904 ClangModules[Filename] = PCMDwoId; | 2319 ClangModules[Filename] = PCMDwoId; |
3905 } | 2320 } |
3906 | 2321 |
3907 // Add this module. | 2322 // Add this module. |
3908 Unit = llvm::make_unique<CompileUnit>(*CU, UnitID++, !Options.NoODR, | 2323 Unit = llvm::make_unique<CompileUnit>(*CU, UnitID++, !Options.NoODR, |
3909 ModuleName); | 2324 ModuleName); |
3910 Unit->setHasInterestingContent(); | 2325 Unit->setHasInterestingContent(); |
3911 analyzeContextInfo(CUDie, 0, *Unit, &ODRContexts.getRoot(), StringPool, | 2326 analyzeContextInfo(CUDie, 0, *Unit, &ODRContexts.getRoot(), |
3912 ODRContexts); | 2327 UniquingStringPool, ODRContexts, ModulesEndOffset, |
2328 ParseableSwiftInterfaces, | |
2329 [&](const Twine &Warning, const DWARFDie &DIE) { | |
2330 reportWarning(Warning, DMO, &DIE); | |
2331 }); | |
3913 // Keep everything. | 2332 // Keep everything. |
3914 Unit->markEverythingAsKept(); | 2333 Unit->markEverythingAsKept(); |
3915 } | 2334 } |
3916 } | 2335 } |
3917 if (!Unit->getOrigUnit().getUnitDIE().hasChildren()) | 2336 if (!Unit->getOrigUnit().getUnitDIE().hasChildren()) |
3918 return Error::success(); | 2337 return Error::success(); |
3919 if (Options.Verbose) { | 2338 if (!Quiet && Options.Verbose) { |
3920 outs().indent(Indent); | 2339 outs().indent(Indent); |
3921 outs() << "cloning .debug_info from " << Filename << "\n"; | 2340 outs() << "cloning .debug_info from " << Filename << "\n"; |
3922 } | 2341 } |
3923 | 2342 |
3924 std::vector<std::unique_ptr<CompileUnit>> CompileUnits; | 2343 UnitListTy CompileUnits; |
3925 CompileUnits.push_back(std::move(Unit)); | 2344 CompileUnits.push_back(std::move(Unit)); |
3926 DIECloner(*this, RelocMgr, DIEAlloc, CompileUnits, Options) | 2345 DIECloner(*this, RelocMgr, DIEAlloc, CompileUnits, Options) |
3927 .cloneAllCompileUnits(*DwarfContext); | 2346 .cloneAllCompileUnits(*DwarfContext, DMO, Ranges, StringPool, |
2347 IsLittleEndian); | |
3928 return Error::success(); | 2348 return Error::success(); |
3929 } | 2349 } |
3930 | 2350 |
3931 void DwarfLinker::DIECloner::cloneAllCompileUnits(DWARFContext &DwarfContext) { | 2351 void DwarfLinker::DIECloner::cloneAllCompileUnits( |
2352 DWARFContext &DwarfContext, const DebugMapObject &DMO, RangesTy &Ranges, | |
2353 OffsetsStringPool &StringPool, bool IsLittleEndian) { | |
3932 if (!Linker.Streamer) | 2354 if (!Linker.Streamer) |
3933 return; | 2355 return; |
3934 | 2356 |
3935 for (auto &CurrentUnit : CompileUnits) { | 2357 for (auto &CurrentUnit : CompileUnits) { |
3936 auto InputDIE = CurrentUnit->getOrigUnit().getUnitDIE(); | 2358 auto InputDIE = CurrentUnit->getOrigUnit().getUnitDIE(); |
3937 CurrentUnit->setStartOffset(Linker.OutputDebugInfoSize); | 2359 CurrentUnit->setStartOffset(Linker.OutputDebugInfoSize); |
2360 if (!InputDIE) { | |
2361 Linker.OutputDebugInfoSize = CurrentUnit->computeNextUnitOffset(); | |
2362 continue; | |
2363 } | |
3938 if (CurrentUnit->getInfo(0).Keep) { | 2364 if (CurrentUnit->getInfo(0).Keep) { |
3939 // Clone the InputDIE into your Unit DIE in our compile unit since it | 2365 // Clone the InputDIE into your Unit DIE in our compile unit since it |
3940 // already has a DIE inside of it. | 2366 // already has a DIE inside of it. |
3941 CurrentUnit->createOutputDIE(); | 2367 CurrentUnit->createOutputDIE(); |
3942 cloneDIE(InputDIE, *CurrentUnit, 0 /* PC offset */, | 2368 cloneDIE(InputDIE, DMO, *CurrentUnit, StringPool, 0 /* PC offset */, |
3943 11 /* Unit Header size */, 0, CurrentUnit->getOutputUnitDIE()); | 2369 11 /* Unit Header size */, 0, IsLittleEndian, |
3944 } | 2370 CurrentUnit->getOutputUnitDIE()); |
2371 } | |
2372 | |
3945 Linker.OutputDebugInfoSize = CurrentUnit->computeNextUnitOffset(); | 2373 Linker.OutputDebugInfoSize = CurrentUnit->computeNextUnitOffset(); |
2374 | |
3946 if (Linker.Options.NoOutput) | 2375 if (Linker.Options.NoOutput) |
3947 continue; | 2376 continue; |
3948 | 2377 |
3949 if (LLVM_LIKELY(!Linker.Options.Update)) { | 2378 // FIXME: for compatibility with the classic dsymutil, we emit |
3950 // FIXME: for compatibility with the classic dsymutil, we emit an empty | 2379 // an empty line table for the unit, even if the unit doesn't |
3951 // line table for the unit, even if the unit doesn't actually exist in | 2380 // actually exist in the DIE tree. |
3952 // the DIE tree. | 2381 if (LLVM_LIKELY(!Linker.Options.Update) || Linker.Options.Translator) |
3953 Linker.patchLineTableForUnit(*CurrentUnit, DwarfContext); | 2382 Linker.patchLineTableForUnit(*CurrentUnit, DwarfContext, Ranges, DMO); |
3954 Linker.emitAcceleratorEntriesForUnit(*CurrentUnit); | 2383 |
3955 Linker.patchRangesForUnit(*CurrentUnit, DwarfContext); | 2384 Linker.emitAcceleratorEntriesForUnit(*CurrentUnit); |
3956 Linker.Streamer->emitLocationsForUnit(*CurrentUnit, DwarfContext); | 2385 |
3957 } else { | 2386 if (LLVM_UNLIKELY(Linker.Options.Update)) |
3958 Linker.emitAcceleratorEntriesForUnit(*CurrentUnit); | 2387 continue; |
3959 } | 2388 |
2389 Linker.patchRangesForUnit(*CurrentUnit, DwarfContext, DMO); | |
2390 auto ProcessExpr = [&](StringRef Bytes, SmallVectorImpl<uint8_t> &Buffer) { | |
2391 DWARFUnit &OrigUnit = CurrentUnit->getOrigUnit(); | |
2392 DataExtractor Data(Bytes, IsLittleEndian, OrigUnit.getAddressByteSize()); | |
2393 cloneExpression(Data, | |
2394 DWARFExpression(Data, OrigUnit.getVersion(), | |
2395 OrigUnit.getAddressByteSize()), | |
2396 DMO, *CurrentUnit, Buffer); | |
2397 }; | |
2398 Linker.Streamer->emitLocationsForUnit(*CurrentUnit, DwarfContext, | |
2399 ProcessExpr); | |
3960 } | 2400 } |
3961 | 2401 |
3962 if (Linker.Options.NoOutput) | 2402 if (Linker.Options.NoOutput) |
3963 return; | 2403 return; |
3964 | 2404 |
3965 // Emit all the compile unit's debug information. | 2405 // Emit all the compile unit's debug information. |
3966 for (auto &CurrentUnit : CompileUnits) { | 2406 for (auto &CurrentUnit : CompileUnits) { |
3967 if (LLVM_LIKELY(!Linker.Options.Update)) | 2407 if (LLVM_LIKELY(!Linker.Options.Update)) |
3968 Linker.generateUnitRanges(*CurrentUnit); | 2408 Linker.generateUnitRanges(*CurrentUnit); |
2409 | |
3969 CurrentUnit->fixupForwardReferences(); | 2410 CurrentUnit->fixupForwardReferences(); |
3970 Linker.Streamer->emitCompileUnitHeader(*CurrentUnit); | 2411 |
3971 if (!CurrentUnit->getOutputUnitDIE()) | 2412 if (!CurrentUnit->getOutputUnitDIE()) |
3972 continue; | 2413 continue; |
2414 | |
2415 Linker.Streamer->emitCompileUnitHeader(*CurrentUnit); | |
3973 Linker.Streamer->emitDIE(*CurrentUnit->getOutputUnitDIE()); | 2416 Linker.Streamer->emitDIE(*CurrentUnit->getOutputUnitDIE()); |
3974 } | 2417 } |
2418 } | |
2419 | |
2420 void DwarfLinker::updateAccelKind(DWARFContext &Dwarf) { | |
2421 if (Options.TheAccelTableKind != AccelTableKind::Default) | |
2422 return; | |
2423 | |
2424 auto &DwarfObj = Dwarf.getDWARFObj(); | |
2425 | |
2426 if (!AtLeastOneDwarfAccelTable && | |
2427 (!DwarfObj.getAppleNamesSection().Data.empty() || | |
2428 !DwarfObj.getAppleTypesSection().Data.empty() || | |
2429 !DwarfObj.getAppleNamespacesSection().Data.empty() || | |
2430 !DwarfObj.getAppleObjCSection().Data.empty())) { | |
2431 AtLeastOneAppleAccelTable = true; | |
2432 } | |
2433 | |
2434 if (!AtLeastOneDwarfAccelTable && | |
2435 !DwarfObj.getNamesSection().Data.empty()) { | |
2436 AtLeastOneDwarfAccelTable = true; | |
2437 } | |
2438 } | |
2439 | |
2440 bool DwarfLinker::emitPaperTrailWarnings(const DebugMapObject &DMO, | |
2441 const DebugMap &Map, | |
2442 OffsetsStringPool &StringPool) { | |
2443 if (DMO.getWarnings().empty() || !DMO.empty()) | |
2444 return false; | |
2445 | |
2446 Streamer->switchToDebugInfoSection(/* Version */ 2); | |
2447 DIE *CUDie = DIE::get(DIEAlloc, dwarf::DW_TAG_compile_unit); | |
2448 CUDie->setOffset(11); | |
2449 StringRef Producer = StringPool.internString("dsymutil"); | |
2450 StringRef File = StringPool.internString(DMO.getObjectFilename()); | |
2451 CUDie->addValue(DIEAlloc, dwarf::DW_AT_producer, dwarf::DW_FORM_strp, | |
2452 DIEInteger(StringPool.getStringOffset(Producer))); | |
2453 DIEBlock *String = new (DIEAlloc) DIEBlock(); | |
2454 DIEBlocks.push_back(String); | |
2455 for (auto &C : File) | |
2456 String->addValue(DIEAlloc, dwarf::Attribute(0), dwarf::DW_FORM_data1, | |
2457 DIEInteger(C)); | |
2458 String->addValue(DIEAlloc, dwarf::Attribute(0), dwarf::DW_FORM_data1, | |
2459 DIEInteger(0)); | |
2460 | |
2461 CUDie->addValue(DIEAlloc, dwarf::DW_AT_name, dwarf::DW_FORM_string, String); | |
2462 for (const auto &Warning : DMO.getWarnings()) { | |
2463 DIE &ConstDie = CUDie->addChild(DIE::get(DIEAlloc, dwarf::DW_TAG_constant)); | |
2464 ConstDie.addValue( | |
2465 DIEAlloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, | |
2466 DIEInteger(StringPool.getStringOffset("dsymutil_warning"))); | |
2467 ConstDie.addValue(DIEAlloc, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, | |
2468 DIEInteger(1)); | |
2469 ConstDie.addValue(DIEAlloc, dwarf::DW_AT_const_value, dwarf::DW_FORM_strp, | |
2470 DIEInteger(StringPool.getStringOffset(Warning))); | |
2471 } | |
2472 unsigned Size = 4 /* FORM_strp */ + File.size() + 1 + | |
2473 DMO.getWarnings().size() * (4 + 1 + 4) + | |
2474 1 /* End of children */; | |
2475 DIEAbbrev Abbrev = CUDie->generateAbbrev(); | |
2476 AssignAbbrev(Abbrev); | |
2477 CUDie->setAbbrevNumber(Abbrev.getNumber()); | |
2478 Size += getULEB128Size(Abbrev.getNumber()); | |
2479 // Abbreviation ordering needed for classic compatibility. | |
2480 for (auto &Child : CUDie->children()) { | |
2481 Abbrev = Child.generateAbbrev(); | |
2482 AssignAbbrev(Abbrev); | |
2483 Child.setAbbrevNumber(Abbrev.getNumber()); | |
2484 Size += getULEB128Size(Abbrev.getNumber()); | |
2485 } | |
2486 CUDie->setSize(Size); | |
2487 auto &Asm = Streamer->getAsmPrinter(); | |
2488 Asm.emitInt32(11 + CUDie->getSize() - 4); | |
2489 Asm.emitInt16(2); | |
2490 Asm.emitInt32(0); | |
2491 Asm.emitInt8(Map.getTriple().isArch64Bit() ? 8 : 4); | |
2492 Streamer->emitDIE(*CUDie); | |
2493 OutputDebugInfoSize += 11 /* Header */ + Size; | |
2494 | |
2495 return true; | |
2496 } | |
2497 | |
2498 static Error copySwiftInterfaces( | |
2499 const std::map<std::string, std::string> &ParseableSwiftInterfaces, | |
2500 StringRef Architecture, const LinkOptions &Options) { | |
2501 std::error_code EC; | |
2502 SmallString<128> InputPath; | |
2503 SmallString<128> Path; | |
2504 sys::path::append(Path, *Options.ResourceDir, "Swift", Architecture); | |
2505 if ((EC = sys::fs::create_directories(Path.str(), true, | |
2506 sys::fs::perms::all_all))) | |
2507 return make_error<StringError>( | |
2508 "cannot create directory: " + toString(errorCodeToError(EC)), EC); | |
2509 unsigned BaseLength = Path.size(); | |
2510 | |
2511 for (auto &I : ParseableSwiftInterfaces) { | |
2512 StringRef ModuleName = I.first; | |
2513 StringRef InterfaceFile = I.second; | |
2514 if (!Options.PrependPath.empty()) { | |
2515 InputPath.clear(); | |
2516 sys::path::append(InputPath, Options.PrependPath, InterfaceFile); | |
2517 InterfaceFile = InputPath; | |
2518 } | |
2519 sys::path::append(Path, ModuleName); | |
2520 Path.append(".swiftinterface"); | |
2521 if (Options.Verbose) | |
2522 outs() << "copy parseable Swift interface " << InterfaceFile << " -> " | |
2523 << Path.str() << '\n'; | |
2524 | |
2525 // copy_file attempts an APFS clone first, so this should be cheap. | |
2526 if ((EC = sys::fs::copy_file(InterfaceFile, Path.str()))) | |
2527 warn(Twine("cannot copy parseable Swift interface ") + | |
2528 InterfaceFile + ": " + | |
2529 toString(errorCodeToError(EC))); | |
2530 Path.resize(BaseLength); | |
2531 } | |
2532 return Error::success(); | |
3975 } | 2533 } |
3976 | 2534 |
3977 bool DwarfLinker::link(const DebugMap &Map) { | 2535 bool DwarfLinker::link(const DebugMap &Map) { |
3978 if (!createStreamer(Map.getTriple(), OutFile)) | 2536 if (!createStreamer(Map.getTriple(), OutFile)) |
3979 return false; | 2537 return false; |
3980 | 2538 |
3981 // Size of the DIEs (and headers) generated for the linked output. | 2539 // Size of the DIEs (and headers) generated for the linked output. |
3982 OutputDebugInfoSize = 0; | 2540 OutputDebugInfoSize = 0; |
3983 // A unique ID that identifies each compile unit. | 2541 // A unique ID that identifies each compile unit. |
3984 UnitID = 0; | 2542 unsigned UnitID = 0; |
3985 DebugMap ModuleMap(Map.getTriple(), Map.getBinaryPath()); | 2543 DebugMap ModuleMap(Map.getTriple(), Map.getBinaryPath()); |
3986 | 2544 |
2545 // First populate the data structure we need for each iteration of the | |
2546 // parallel loop. | |
2547 unsigned NumObjects = Map.getNumberOfObjects(); | |
2548 std::vector<LinkContext> ObjectContexts; | |
2549 ObjectContexts.reserve(NumObjects); | |
3987 for (const auto &Obj : Map.objects()) { | 2550 for (const auto &Obj : Map.objects()) { |
3988 CurrentDebugObject = Obj.get(); | 2551 ObjectContexts.emplace_back(Map, *this, *Obj.get()); |
3989 | 2552 LinkContext &LC = ObjectContexts.back(); |
2553 if (LC.ObjectFile) | |
2554 updateAccelKind(*LC.DwarfContext); | |
2555 } | |
2556 | |
2557 // This Dwarf string pool which is only used for uniquing. This one should | |
2558 // never be used for offsets as its not thread-safe or predictable. | |
2559 UniquingStringPool UniquingStringPool; | |
2560 | |
2561 // This Dwarf string pool which is used for emission. It must be used | |
2562 // serially as the order of calling getStringOffset matters for | |
2563 // reproducibility. | |
2564 OffsetsStringPool OffsetsStringPool(Options.Translator); | |
2565 | |
2566 // ODR Contexts for the link. | |
2567 DeclContextTree ODRContexts; | |
2568 | |
2569 // If we haven't decided on an accelerator table kind yet, we base ourselves | |
2570 // on the DWARF we have seen so far. At this point we haven't pulled in debug | |
2571 // information from modules yet, so it is technically possible that they | |
2572 // would affect the decision. However, as they're built with the same | |
2573 // compiler and flags, it is safe to assume that they will follow the | |
2574 // decision made here. | |
2575 if (Options.TheAccelTableKind == AccelTableKind::Default) { | |
2576 if (AtLeastOneDwarfAccelTable && !AtLeastOneAppleAccelTable) | |
2577 Options.TheAccelTableKind = AccelTableKind::Dwarf; | |
2578 else | |
2579 Options.TheAccelTableKind = AccelTableKind::Apple; | |
2580 } | |
2581 | |
2582 for (LinkContext &LinkContext : ObjectContexts) { | |
3990 if (Options.Verbose) | 2583 if (Options.Verbose) |
3991 outs() << "DEBUG MAP OBJECT: " << Obj->getObjectFilename() << "\n"; | 2584 outs() << "DEBUG MAP OBJECT: " << LinkContext.DMO.getObjectFilename() |
2585 << "\n"; | |
3992 | 2586 |
3993 // N_AST objects (swiftmodule files) should get dumped directly into the | 2587 // N_AST objects (swiftmodule files) should get dumped directly into the |
3994 // appropriate DWARF section. | 2588 // appropriate DWARF section. |
3995 if (Obj->getType() == MachO::N_AST) { | 2589 if (LinkContext.DMO.getType() == MachO::N_AST) { |
3996 StringRef File = Obj->getObjectFilename(); | 2590 StringRef File = LinkContext.DMO.getObjectFilename(); |
3997 auto ErrorOrMem = MemoryBuffer::getFile(File); | 2591 auto ErrorOrMem = MemoryBuffer::getFile(File); |
3998 if (!ErrorOrMem) { | 2592 if (!ErrorOrMem) { |
3999 errs() << "Warning: Could not open " << File << "\n"; | 2593 warn("Could not open '" + File + "'\n"); |
4000 continue; | 2594 continue; |
4001 } | 2595 } |
4002 sys::fs::file_status Stat; | 2596 sys::fs::file_status Stat; |
4003 if (auto errc = sys::fs::status(File, Stat)) { | 2597 if (auto Err = sys::fs::status(File, Stat)) { |
4004 errs() << "Warning: " << errc.message() << "\n"; | 2598 warn(Err.message()); |
4005 continue; | 2599 continue; |
4006 } | 2600 } |
4007 if (!Options.NoTimestamp && Stat.getLastModificationTime() != | 2601 if (!Options.NoTimestamp) { |
4008 sys::TimePoint<>(Obj->getTimestamp())) { | 2602 // The modification can have sub-second precision so we need to cast |
4009 errs() << "Warning: Timestamp mismatch for " << File << ": " | 2603 // away the extra precision that's not present in the debug map. |
4010 << Stat.getLastModificationTime() << " and " | 2604 auto ModificationTime = |
4011 << sys::TimePoint<>(Obj->getTimestamp()) << "\n"; | 2605 std::chrono::time_point_cast<std::chrono::seconds>( |
4012 continue; | 2606 Stat.getLastModificationTime()); |
2607 if (ModificationTime != LinkContext.DMO.getTimestamp()) { | |
2608 // Not using the helper here as we can easily stream TimePoint<>. | |
2609 WithColor::warning() | |
2610 << "Timestamp mismatch for " << File << ": " | |
2611 << Stat.getLastModificationTime() << " and " | |
2612 << sys::TimePoint<>(LinkContext.DMO.getTimestamp()) << "\n"; | |
2613 continue; | |
2614 } | |
4013 } | 2615 } |
4014 | 2616 |
4015 // Copy the module into the .swift_ast section. | 2617 // Copy the module into the .swift_ast section. |
4016 if (!Options.NoOutput) | 2618 if (!Options.NoOutput) |
4017 Streamer->emitSwiftAST((*ErrorOrMem)->getBuffer()); | 2619 Streamer->emitSwiftAST((*ErrorOrMem)->getBuffer()); |
4018 continue; | 2620 continue; |
4019 } | 2621 } |
4020 | 2622 |
4021 auto ErrOrObj = loadObject(BinHolder, *Obj, Map); | 2623 if (emitPaperTrailWarnings(LinkContext.DMO, Map, OffsetsStringPool)) |
4022 if (!ErrOrObj) | |
4023 continue; | 2624 continue; |
4024 | 2625 |
2626 if (!LinkContext.ObjectFile) | |
2627 continue; | |
2628 | |
4025 // Look for relocations that correspond to debug map entries. | 2629 // Look for relocations that correspond to debug map entries. |
4026 RelocationManager RelocMgr(*this); | 2630 |
4027 if (LLVM_LIKELY(!Options.Update) && | 2631 if (LLVM_LIKELY(!Options.Update) && |
4028 !RelocMgr.findValidRelocsInDebugInfo(*ErrOrObj, *Obj)) { | 2632 !LinkContext.RelocMgr.findValidRelocsInDebugInfo( |
2633 *LinkContext.ObjectFile, LinkContext.DMO)) { | |
4029 if (Options.Verbose) | 2634 if (Options.Verbose) |
4030 outs() << "No valid relocations found. Skipping.\n"; | 2635 outs() << "No valid relocations found. Skipping.\n"; |
2636 | |
2637 // Clear this ObjFile entry as a signal to other loops that we should not | |
2638 // process this iteration. | |
2639 LinkContext.ObjectFile = nullptr; | |
4031 continue; | 2640 continue; |
4032 } | 2641 } |
4033 | 2642 |
4034 // Setup access to the debug info. | 2643 // Setup access to the debug info. |
4035 auto DwarfContext = DWARFContext::create(*ErrOrObj); | 2644 if (!LinkContext.DwarfContext) |
4036 startDebugObject(*DwarfContext, *Obj); | 2645 continue; |
2646 | |
2647 startDebugObject(LinkContext); | |
4037 | 2648 |
4038 // In a first phase, just read in the debug info and load all clang modules. | 2649 // In a first phase, just read in the debug info and load all clang modules. |
4039 for (const auto &CU : DwarfContext->compile_units()) { | 2650 LinkContext.CompileUnits.reserve( |
2651 LinkContext.DwarfContext->getNumCompileUnits()); | |
2652 | |
2653 for (const auto &CU : LinkContext.DwarfContext->compile_units()) { | |
2654 updateDwarfVersion(CU->getVersion()); | |
4040 auto CUDie = CU->getUnitDIE(false); | 2655 auto CUDie = CU->getUnitDIE(false); |
4041 if (Options.Verbose) { | 2656 if (Options.Verbose) { |
4042 outs() << "Input compilation unit:"; | 2657 outs() << "Input compilation unit:"; |
4043 DIDumpOptions DumpOpts; | 2658 DIDumpOptions DumpOpts; |
4044 DumpOpts.RecurseDepth = 0; | 2659 DumpOpts.ChildRecurseDepth = 0; |
4045 DumpOpts.Verbose = Options.Verbose; | 2660 DumpOpts.Verbose = Options.Verbose; |
4046 CUDie.dump(outs(), 0, DumpOpts); | 2661 CUDie.dump(outs(), 0, DumpOpts); |
4047 } | 2662 } |
4048 | 2663 if (CUDie && !LLVM_UNLIKELY(Options.Update)) |
2664 registerModuleReference(CUDie, *CU, ModuleMap, LinkContext.DMO, | |
2665 LinkContext.Ranges, OffsetsStringPool, | |
2666 UniquingStringPool, ODRContexts, 0, UnitID, | |
2667 LinkContext.DwarfContext->isLittleEndian()); | |
2668 } | |
2669 } | |
2670 | |
2671 // If we haven't seen any CUs, pick an arbitrary valid Dwarf version anyway. | |
2672 if (MaxDwarfVersion == 0) | |
2673 MaxDwarfVersion = 3; | |
2674 | |
2675 // At this point we know how much data we have emitted. We use this value to | |
2676 // compare canonical DIE offsets in analyzeContextInfo to see if a definition | |
2677 // is already emitted, without being affected by canonical die offsets set | |
2678 // later. This prevents undeterminism when analyze and clone execute | |
2679 // concurrently, as clone set the canonical DIE offset and analyze reads it. | |
2680 const uint64_t ModulesEndOffset = OutputDebugInfoSize; | |
2681 | |
2682 // These variables manage the list of processed object files. | |
2683 // The mutex and condition variable are to ensure that this is thread safe. | |
2684 std::mutex ProcessedFilesMutex; | |
2685 std::condition_variable ProcessedFilesConditionVariable; | |
2686 BitVector ProcessedFiles(NumObjects, false); | |
2687 | |
2688 // Analyzing the context info is particularly expensive so it is executed in | |
2689 // parallel with emitting the previous compile unit. | |
2690 auto AnalyzeLambda = [&](size_t i) { | |
2691 auto &LinkContext = ObjectContexts[i]; | |
2692 | |
2693 if (!LinkContext.ObjectFile || !LinkContext.DwarfContext) | |
2694 return; | |
2695 | |
2696 for (const auto &CU : LinkContext.DwarfContext->compile_units()) { | |
2697 updateDwarfVersion(CU->getVersion()); | |
2698 // The !registerModuleReference() condition effectively skips | |
2699 // over fully resolved skeleton units. This second pass of | |
2700 // registerModuleReferences doesn't do any new work, but it | |
2701 // will collect top-level errors, which are suppressed. Module | |
2702 // warnings were already displayed in the first iteration. | |
2703 bool Quiet = true; | |
2704 auto CUDie = CU->getUnitDIE(false); | |
4049 if (!CUDie || LLVM_UNLIKELY(Options.Update) || | 2705 if (!CUDie || LLVM_UNLIKELY(Options.Update) || |
4050 !registerModuleReference(CUDie, *CU, ModuleMap)) { | 2706 !registerModuleReference(CUDie, *CU, ModuleMap, LinkContext.DMO, |
4051 Units.push_back(llvm::make_unique<CompileUnit>( | 2707 LinkContext.Ranges, OffsetsStringPool, |
2708 UniquingStringPool, ODRContexts, | |
2709 ModulesEndOffset, UnitID, Quiet)) { | |
2710 LinkContext.CompileUnits.push_back(llvm::make_unique<CompileUnit>( | |
4052 *CU, UnitID++, !Options.NoODR && !Options.Update, "")); | 2711 *CU, UnitID++, !Options.NoODR && !Options.Update, "")); |
4053 maybeUpdateMaxDwarfVersion(CU->getVersion()); | |
4054 } | 2712 } |
4055 } | 2713 } |
4056 | 2714 |
4057 // Now build the DIE parent links that we will use during the next phase. | 2715 // Now build the DIE parent links that we will use during the next phase. |
4058 for (auto &CurrentUnit : Units) | 2716 for (auto &CurrentUnit : LinkContext.CompileUnits) { |
4059 analyzeContextInfo(CurrentUnit->getOrigUnit().getUnitDIE(), 0, *CurrentUnit, | 2717 auto CUDie = CurrentUnit->getOrigUnit().getUnitDIE(); |
4060 &ODRContexts.getRoot(), StringPool, ODRContexts); | 2718 if (!CUDie) |
4061 | 2719 continue; |
4062 // Then mark all the DIEs that need to be present in the linked | 2720 analyzeContextInfo(CurrentUnit->getOrigUnit().getUnitDIE(), 0, |
4063 // output and collect some information about them. Note that this | 2721 *CurrentUnit, &ODRContexts.getRoot(), |
4064 // loop can not be merged with the previous one because cross-CU | 2722 UniquingStringPool, ODRContexts, ModulesEndOffset, |
4065 // references require the ParentIdx to be setup for every CU in | 2723 ParseableSwiftInterfaces, |
2724 [&](const Twine &Warning, const DWARFDie &DIE) { | |
2725 reportWarning(Warning, LinkContext.DMO, &DIE); | |
2726 }); | |
2727 } | |
2728 }; | |
2729 | |
2730 // And then the remaining work in serial again. | |
2731 // Note, although this loop runs in serial, it can run in parallel with | |
2732 // the analyzeContextInfo loop so long as we process files with indices >= | |
2733 // than those processed by analyzeContextInfo. | |
2734 auto CloneLambda = [&](size_t i) { | |
2735 auto &LinkContext = ObjectContexts[i]; | |
2736 if (!LinkContext.ObjectFile) | |
2737 return; | |
2738 | |
2739 // Then mark all the DIEs that need to be present in the linked output | |
2740 // and collect some information about them. | |
2741 // Note that this loop can not be merged with the previous one because | |
2742 // cross-cu references require the ParentIdx to be setup for every CU in | |
4066 // the object file before calling this. | 2743 // the object file before calling this. |
4067 if (LLVM_UNLIKELY(Options.Update)) { | 2744 if (LLVM_UNLIKELY(Options.Update)) { |
4068 for (auto &CurrentUnit : Units) | 2745 for (auto &CurrentUnit : LinkContext.CompileUnits) |
4069 CurrentUnit->markEverythingAsKept(); | 2746 CurrentUnit->markEverythingAsKept(); |
4070 Streamer->copyInvariantDebugSection(*ErrOrObj, Options); | 2747 Streamer->copyInvariantDebugSection(*LinkContext.ObjectFile); |
4071 } else { | 2748 } else { |
4072 for (auto &CurrentUnit : Units) | 2749 for (auto &CurrentUnit : LinkContext.CompileUnits) |
4073 lookForDIEsToKeep(RelocMgr, CurrentUnit->getOrigUnit().getUnitDIE(), | 2750 lookForDIEsToKeep(LinkContext.RelocMgr, LinkContext.Ranges, |
4074 *Obj, *CurrentUnit, 0); | 2751 LinkContext.CompileUnits, |
4075 } | 2752 CurrentUnit->getOrigUnit().getUnitDIE(), |
4076 | 2753 LinkContext.DMO, *CurrentUnit, 0); |
4077 // The calls to applyValidRelocs inside cloneDIE will walk the | 2754 } |
4078 // reloc array again (in the same way findValidRelocsInDebugInfo() | 2755 |
4079 // did). We need to reset the NextValidReloc index to the beginning. | 2756 // The calls to applyValidRelocs inside cloneDIE will walk the reloc |
4080 RelocMgr.resetValidRelocs(); | 2757 // array again (in the same way findValidRelocsInDebugInfo() did). We |
4081 if (RelocMgr.hasValidRelocs() || LLVM_UNLIKELY(Options.Update)) | 2758 // need to reset the NextValidReloc index to the beginning. |
4082 DIECloner(*this, RelocMgr, DIEAlloc, Units, Options) | 2759 LinkContext.RelocMgr.resetValidRelocs(); |
4083 .cloneAllCompileUnits(*DwarfContext); | 2760 if (LinkContext.RelocMgr.hasValidRelocs() || LLVM_UNLIKELY(Options.Update)) |
4084 if (!Options.NoOutput && !Units.empty() && LLVM_LIKELY(!Options.Update)) | 2761 DIECloner(*this, LinkContext.RelocMgr, DIEAlloc, LinkContext.CompileUnits, |
4085 patchFrameInfoForObject(*Obj, *DwarfContext, | 2762 Options) |
4086 Units[0]->getOrigUnit().getAddressByteSize()); | 2763 .cloneAllCompileUnits(*LinkContext.DwarfContext, LinkContext.DMO, |
2764 LinkContext.Ranges, OffsetsStringPool, | |
2765 LinkContext.DwarfContext->isLittleEndian()); | |
2766 if (!Options.NoOutput && !LinkContext.CompileUnits.empty() && | |
2767 LLVM_LIKELY(!Options.Update)) | |
2768 patchFrameInfoForObject( | |
2769 LinkContext.DMO, LinkContext.Ranges, *LinkContext.DwarfContext, | |
2770 LinkContext.CompileUnits[0]->getOrigUnit().getAddressByteSize()); | |
4087 | 2771 |
4088 // Clean-up before starting working on the next object. | 2772 // Clean-up before starting working on the next object. |
4089 endDebugObject(); | 2773 endDebugObject(LinkContext); |
4090 } | 2774 }; |
4091 | 2775 |
4092 // Emit everything that's global. | 2776 auto EmitLambda = [&]() { |
4093 if (!Options.NoOutput) { | 2777 // Emit everything that's global. |
4094 Streamer->emitAbbrevs(Abbreviations, MaxDwarfVersion); | 2778 if (!Options.NoOutput) { |
4095 Streamer->emitStrings(StringPool); | 2779 Streamer->emitAbbrevs(Abbreviations, MaxDwarfVersion); |
4096 Streamer->emitAppleNames(AppleNames); | 2780 Streamer->emitStrings(OffsetsStringPool); |
4097 Streamer->emitAppleNamespaces(AppleNamespaces); | 2781 switch (Options.TheAccelTableKind) { |
4098 Streamer->emitAppleTypes(AppleTypes); | 2782 case AccelTableKind::Apple: |
4099 Streamer->emitAppleObjc(AppleObjc); | 2783 Streamer->emitAppleNames(AppleNames); |
4100 } | 2784 Streamer->emitAppleNamespaces(AppleNamespaces); |
4101 | 2785 Streamer->emitAppleTypes(AppleTypes); |
4102 return Options.NoOutput ? true : Streamer->finish(Map); | 2786 Streamer->emitAppleObjc(AppleObjc); |
4103 } | 2787 break; |
4104 | 2788 case AccelTableKind::Dwarf: |
4105 DwarfStringPoolEntryRef NonRelocatableStringpool::getEntry(StringRef S) { | 2789 Streamer->emitDebugNames(DebugNames); |
4106 if (S.empty() && !Strings.empty()) | 2790 break; |
4107 return EmptyString; | 2791 case AccelTableKind::Default: |
4108 | 2792 llvm_unreachable("Default should have already been resolved."); |
4109 auto I = Strings.insert(std::make_pair(S, DwarfStringPoolEntry())); | 2793 break; |
4110 auto &Entry = I.first->second; | 2794 } |
4111 if (I.second || Entry.Index == -1U) { | 2795 } |
4112 Entry.Index = NumEntries++; | 2796 }; |
4113 Entry.Offset = CurrentEndOffset; | 2797 |
4114 Entry.Symbol = nullptr; | 2798 auto AnalyzeAll = [&]() { |
4115 CurrentEndOffset += S.size() + 1; | 2799 for (unsigned i = 0, e = NumObjects; i != e; ++i) { |
4116 } | 2800 AnalyzeLambda(i); |
4117 return DwarfStringPoolEntryRef(*I.first); | 2801 |
4118 } | 2802 std::unique_lock<std::mutex> LockGuard(ProcessedFilesMutex); |
4119 | 2803 ProcessedFiles.set(i); |
4120 uint32_t NonRelocatableStringpool::getStringOffset(StringRef S) { | 2804 ProcessedFilesConditionVariable.notify_one(); |
4121 return getEntry(S).getOffset(); | 2805 } |
4122 } | 2806 }; |
4123 | 2807 |
4124 /// Put \p S into the StringMap so that it gets permanent | 2808 auto CloneAll = [&]() { |
4125 /// storage, but do not actually link it in the chain of elements | 2809 for (unsigned i = 0, e = NumObjects; i != e; ++i) { |
4126 /// that go into the output section. A latter call to | 2810 { |
4127 /// getStringOffset() with the same string will chain it though. | 2811 std::unique_lock<std::mutex> LockGuard(ProcessedFilesMutex); |
4128 StringRef NonRelocatableStringpool::internString(StringRef S) { | 2812 if (!ProcessedFiles[i]) { |
4129 DwarfStringPoolEntry Entry{nullptr, 0, -1U}; | 2813 ProcessedFilesConditionVariable.wait( |
4130 auto InsertResult = Strings.insert(std::make_pair(S, Entry)); | 2814 LockGuard, [&]() { return ProcessedFiles[i]; }); |
4131 return InsertResult.first->getKey(); | 2815 } |
4132 } | 2816 } |
4133 | 2817 |
4134 std::vector<DwarfStringPoolEntryRef> | 2818 CloneLambda(i); |
4135 NonRelocatableStringpool::getEntries() const { | 2819 } |
4136 std::vector<DwarfStringPoolEntryRef> Result; | 2820 EmitLambda(); |
4137 Result.reserve(Strings.size()); | 2821 }; |
4138 for (const auto &E : Strings) | 2822 |
4139 Result.emplace_back(E); | 2823 // To limit memory usage in the single threaded case, analyze and clone are |
4140 std::sort( | 2824 // run sequentially so the LinkContext is freed after processing each object |
4141 Result.begin(), Result.end(), | 2825 // in endDebugObject. |
4142 [](const DwarfStringPoolEntryRef A, const DwarfStringPoolEntryRef B) { | 2826 if (Options.Threads == 1) { |
4143 return A.getIndex() < B.getIndex(); | 2827 for (unsigned i = 0, e = NumObjects; i != e; ++i) { |
4144 }); | 2828 AnalyzeLambda(i); |
4145 return Result; | 2829 CloneLambda(i); |
4146 } | 2830 } |
4147 | 2831 EmitLambda(); |
4148 void warn(const Twine &Warning, const Twine &Context) { | 2832 } else { |
4149 errs() << Twine("while processing ") + Context + ":\n"; | 2833 ThreadPool pool(2); |
4150 errs() << Twine("warning: ") + Warning + "\n"; | 2834 pool.async(AnalyzeAll); |
4151 } | 2835 pool.async(CloneAll); |
4152 | 2836 pool.wait(); |
4153 bool error(const Twine &Error, const Twine &Context) { | 2837 } |
4154 errs() << Twine("while processing ") + Context + ":\n"; | 2838 |
4155 errs() << Twine("error: ") + Error + "\n"; | 2839 if (Options.NoOutput) |
4156 return false; | 2840 return true; |
4157 } | 2841 |
4158 | 2842 if (Options.ResourceDir && !ParseableSwiftInterfaces.empty()) { |
4159 bool linkDwarf(raw_fd_ostream &OutFile, const DebugMap &DM, | 2843 StringRef ArchName = Triple::getArchTypeName(Map.getTriple().getArch()); |
4160 const LinkOptions &Options) { | 2844 if (auto E = |
4161 DwarfLinker Linker(OutFile, Options); | 2845 copySwiftInterfaces(ParseableSwiftInterfaces, ArchName, Options)) |
2846 return error(toString(std::move(E))); | |
2847 } | |
2848 | |
2849 return Streamer->finish(Map, Options.Translator); | |
2850 } // namespace dsymutil | |
2851 | |
2852 bool linkDwarf(raw_fd_ostream &OutFile, BinaryHolder &BinHolder, | |
2853 const DebugMap &DM, LinkOptions Options) { | |
2854 DwarfLinker Linker(OutFile, BinHolder, std::move(Options)); | |
4162 return Linker.link(DM); | 2855 return Linker.link(DM); |
4163 } | 2856 } |
4164 | 2857 |
4165 } // end namespace dsymutil | 2858 } // namespace dsymutil |
4166 } // end namespace llvm | 2859 } // namespace llvm |