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