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