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