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