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