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