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