1 //=== DWARFLinkerCompileUnit.cpp ------------------------------------------===// 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 #include "DWARFLinkerCompileUnit.h" 10 #include "AcceleratorRecordsSaver.h" 11 #include "DIEAttributeCloner.h" 12 #include "DIEGenerator.h" 13 #include "DependencyTracker.h" 14 #include "SyntheticTypeNameBuilder.h" 15 #include "llvm/DWARFLinker/Utils.h" 16 #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h" 17 #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h" 18 #include "llvm/Support/FileSystem.h" 19 #include "llvm/Support/FormatVariadic.h" 20 #include "llvm/Support/Path.h" 21 #include <utility> 22 23 using namespace llvm; 24 using namespace dwarf_linker; 25 using namespace dwarf_linker::parallel; 26 27 CompileUnit::CompileUnit(LinkingGlobalData &GlobalData, unsigned ID, 28 StringRef ClangModuleName, DWARFFile &File, 29 OffsetToUnitTy UnitFromOffset, 30 dwarf::FormParams Format, llvm::endianness Endianess) 31 : DwarfUnit(GlobalData, ID, ClangModuleName), File(File), 32 getUnitFromOffset(UnitFromOffset), Stage(Stage::CreatedNotLoaded), 33 AcceleratorRecords(&GlobalData.getAllocator()) { 34 UnitName = File.FileName; 35 setOutputFormat(Format, Endianess); 36 getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo); 37 } 38 39 CompileUnit::CompileUnit(LinkingGlobalData &GlobalData, DWARFUnit &OrigUnit, 40 unsigned ID, StringRef ClangModuleName, 41 DWARFFile &File, OffsetToUnitTy UnitFromOffset, 42 dwarf::FormParams Format, llvm::endianness Endianess) 43 : DwarfUnit(GlobalData, ID, ClangModuleName), File(File), 44 OrigUnit(&OrigUnit), getUnitFromOffset(UnitFromOffset), 45 Stage(Stage::CreatedNotLoaded), 46 AcceleratorRecords(&GlobalData.getAllocator()) { 47 setOutputFormat(Format, Endianess); 48 getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo); 49 50 DWARFDie CUDie = OrigUnit.getUnitDIE(); 51 if (!CUDie) 52 return; 53 54 if (std::optional<DWARFFormValue> Val = CUDie.find(dwarf::DW_AT_language)) { 55 uint16_t LangVal = dwarf::toUnsigned(Val, 0); 56 if (isODRLanguage(LangVal)) 57 Language = LangVal; 58 } 59 60 if (!GlobalData.getOptions().NoODR && Language.has_value()) 61 NoODR = false; 62 63 if (const char *CUName = CUDie.getName(DINameKind::ShortName)) 64 UnitName = CUName; 65 else 66 UnitName = File.FileName; 67 SysRoot = dwarf::toStringRef(CUDie.find(dwarf::DW_AT_LLVM_sysroot)).str(); 68 } 69 70 void CompileUnit::loadLineTable() { 71 LineTablePtr = File.Dwarf->getLineTableForUnit(&getOrigUnit()); 72 } 73 74 void CompileUnit::maybeResetToLoadedStage() { 75 // Nothing to reset if stage is less than "Loaded". 76 if (getStage() < Stage::Loaded) 77 return; 78 79 // Note: We need to do erasing for "Loaded" stage because 80 // if live analysys failed then we will have "Loaded" stage 81 // with marking from "LivenessAnalysisDone" stage partially 82 // done. That marking should be cleared. 83 84 for (DIEInfo &Info : DieInfoArray) 85 Info.unsetFlagsWhichSetDuringLiveAnalysis(); 86 87 LowPc = std::nullopt; 88 HighPc = 0; 89 Labels.clear(); 90 Ranges.clear(); 91 Dependencies.reset(nullptr); 92 93 if (getStage() < Stage::Cloned) { 94 setStage(Stage::Loaded); 95 return; 96 } 97 98 AcceleratorRecords.erase(); 99 AbbreviationsSet.clear(); 100 Abbreviations.clear(); 101 OutUnitDIE = nullptr; 102 DebugAddrIndexMap.clear(); 103 104 llvm::fill(OutDieOffsetArray, 0); 105 llvm::fill(TypeEntries, nullptr); 106 eraseSections(); 107 108 setStage(Stage::CreatedNotLoaded); 109 } 110 111 bool CompileUnit::loadInputDIEs() { 112 DWARFDie InputUnitDIE = getUnitDIE(false); 113 if (!InputUnitDIE) 114 return false; 115 116 // load input dies, resize Info structures array. 117 DieInfoArray.resize(getOrigUnit().getNumDIEs()); 118 OutDieOffsetArray.resize(getOrigUnit().getNumDIEs(), 0); 119 if (!NoODR) 120 TypeEntries.resize(getOrigUnit().getNumDIEs()); 121 return true; 122 } 123 124 void CompileUnit::analyzeDWARFStructureRec(const DWARFDebugInfoEntry *DieEntry, 125 bool IsODRUnavailableFunctionScope) { 126 CompileUnit::DIEInfo &DieInfo = getDIEInfo(DieEntry); 127 128 for (const DWARFDebugInfoEntry *CurChild = getFirstChildEntry(DieEntry); 129 CurChild && CurChild->getAbbreviationDeclarationPtr(); 130 CurChild = getSiblingEntry(CurChild)) { 131 CompileUnit::DIEInfo &ChildInfo = getDIEInfo(CurChild); 132 bool ChildIsODRUnavailableFunctionScope = IsODRUnavailableFunctionScope; 133 134 if (DieInfo.getIsInMouduleScope()) 135 ChildInfo.setIsInMouduleScope(); 136 137 if (DieInfo.getIsInFunctionScope()) 138 ChildInfo.setIsInFunctionScope(); 139 140 if (DieInfo.getIsInAnonNamespaceScope()) 141 ChildInfo.setIsInAnonNamespaceScope(); 142 143 switch (CurChild->getTag()) { 144 case dwarf::DW_TAG_module: 145 ChildInfo.setIsInMouduleScope(); 146 if (DieEntry->getTag() == dwarf::DW_TAG_compile_unit && 147 dwarf::toString(find(CurChild, dwarf::DW_AT_name), "") != 148 getClangModuleName()) 149 analyzeImportedModule(CurChild); 150 break; 151 case dwarf::DW_TAG_subprogram: 152 ChildInfo.setIsInFunctionScope(); 153 if (!ChildIsODRUnavailableFunctionScope && 154 !ChildInfo.getIsInMouduleScope()) { 155 if (find(CurChild, 156 {dwarf::DW_AT_abstract_origin, dwarf::DW_AT_specification})) 157 ChildIsODRUnavailableFunctionScope = true; 158 } 159 break; 160 case dwarf::DW_TAG_namespace: { 161 UnitEntryPairTy NamespaceEntry = {this, CurChild}; 162 163 if (find(CurChild, dwarf::DW_AT_extension)) 164 NamespaceEntry = NamespaceEntry.getNamespaceOrigin(); 165 166 if (!NamespaceEntry.CU->find(NamespaceEntry.DieEntry, dwarf::DW_AT_name)) 167 ChildInfo.setIsInAnonNamespaceScope(); 168 } break; 169 default: 170 break; 171 } 172 173 if (!isClangModule() && !getGlobalData().getOptions().UpdateIndexTablesOnly) 174 ChildInfo.setTrackLiveness(); 175 176 if ((!ChildInfo.getIsInAnonNamespaceScope() && 177 !ChildIsODRUnavailableFunctionScope && !NoODR)) 178 ChildInfo.setODRAvailable(); 179 180 if (CurChild->hasChildren()) 181 analyzeDWARFStructureRec(CurChild, ChildIsODRUnavailableFunctionScope); 182 } 183 } 184 185 StringEntry *CompileUnit::getFileName(unsigned FileIdx, 186 StringPool &GlobalStrings) { 187 if (LineTablePtr) { 188 if (LineTablePtr->hasFileAtIndex(FileIdx)) { 189 // Cache the resolved paths based on the index in the line table, 190 // because calling realpath is expensive. 191 ResolvedPathsMap::const_iterator It = ResolvedFullPaths.find(FileIdx); 192 if (It == ResolvedFullPaths.end()) { 193 std::string OrigFileName; 194 bool FoundFileName = LineTablePtr->getFileNameByIndex( 195 FileIdx, getOrigUnit().getCompilationDir(), 196 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, 197 OrigFileName); 198 (void)FoundFileName; 199 assert(FoundFileName && "Must get file name from line table"); 200 201 // Second level of caching, this time based on the file's parent 202 // path. 203 StringRef FileName = sys::path::filename(OrigFileName); 204 StringRef ParentPath = sys::path::parent_path(OrigFileName); 205 206 // If the ParentPath has not yet been resolved, resolve and cache it for 207 // future look-ups. 208 StringMap<StringEntry *>::iterator ParentIt = 209 ResolvedParentPaths.find(ParentPath); 210 if (ParentIt == ResolvedParentPaths.end()) { 211 SmallString<256> RealPath; 212 sys::fs::real_path(ParentPath, RealPath); 213 ParentIt = 214 ResolvedParentPaths 215 .insert({ParentPath, GlobalStrings.insert(RealPath).first}) 216 .first; 217 } 218 219 // Join the file name again with the resolved path. 220 SmallString<256> ResolvedPath(ParentIt->second->first()); 221 sys::path::append(ResolvedPath, FileName); 222 223 It = ResolvedFullPaths 224 .insert(std::make_pair( 225 FileIdx, GlobalStrings.insert(ResolvedPath).first)) 226 .first; 227 } 228 229 return It->second; 230 } 231 } 232 233 return nullptr; 234 } 235 236 void CompileUnit::cleanupDataAfterClonning() { 237 AbbreviationsSet.clear(); 238 ResolvedFullPaths.shrink_and_clear(); 239 ResolvedParentPaths.clear(); 240 FileNames.shrink_and_clear(); 241 DieInfoArray = SmallVector<DIEInfo>(); 242 OutDieOffsetArray = SmallVector<uint64_t>(); 243 TypeEntries = SmallVector<TypeEntry *>(); 244 Dependencies.reset(nullptr); 245 getOrigUnit().clear(); 246 } 247 248 /// Collect references to parseable Swift interfaces in imported 249 /// DW_TAG_module blocks. 250 void CompileUnit::analyzeImportedModule(const DWARFDebugInfoEntry *DieEntry) { 251 if (!Language || Language != dwarf::DW_LANG_Swift) 252 return; 253 254 if (!GlobalData.getOptions().ParseableSwiftInterfaces) 255 return; 256 257 StringRef Path = 258 dwarf::toStringRef(find(DieEntry, dwarf::DW_AT_LLVM_include_path)); 259 if (!Path.ends_with(".swiftinterface")) 260 return; 261 // Don't track interfaces that are part of the SDK. 262 StringRef SysRoot = 263 dwarf::toStringRef(find(DieEntry, dwarf::DW_AT_LLVM_sysroot)); 264 if (SysRoot.empty()) 265 SysRoot = getSysRoot(); 266 if (!SysRoot.empty() && Path.starts_with(SysRoot)) 267 return; 268 // Don't track interfaces that are part of the toolchain. 269 // For example: Swift, _Concurrency, ... 270 StringRef DeveloperDir = guessDeveloperDir(SysRoot); 271 if (!DeveloperDir.empty() && Path.starts_with(DeveloperDir)) 272 return; 273 if (isInToolchainDir(Path)) 274 return; 275 if (std::optional<DWARFFormValue> Val = find(DieEntry, dwarf::DW_AT_name)) { 276 Expected<const char *> Name = Val->getAsCString(); 277 if (!Name) { 278 warn(Name.takeError()); 279 return; 280 } 281 282 auto &Entry = (*GlobalData.getOptions().ParseableSwiftInterfaces)[*Name]; 283 // The prepend path is applied later when copying. 284 SmallString<128> ResolvedPath; 285 if (sys::path::is_relative(Path)) 286 sys::path::append( 287 ResolvedPath, 288 dwarf::toString(getUnitDIE().find(dwarf::DW_AT_comp_dir), "")); 289 sys::path::append(ResolvedPath, Path); 290 if (!Entry.empty() && Entry != ResolvedPath) { 291 DWARFDie Die = getDIE(DieEntry); 292 warn(Twine("conflicting parseable interfaces for Swift Module ") + *Name + 293 ": " + Entry + " and " + Path + ".", 294 &Die); 295 } 296 Entry = std::string(ResolvedPath); 297 } 298 } 299 300 Error CompileUnit::assignTypeNames(TypePool &TypePoolRef) { 301 if (!getUnitDIE().isValid()) 302 return Error::success(); 303 304 SyntheticTypeNameBuilder NameBuilder(TypePoolRef); 305 return assignTypeNamesRec(getDebugInfoEntry(0), NameBuilder); 306 } 307 308 Error CompileUnit::assignTypeNamesRec(const DWARFDebugInfoEntry *DieEntry, 309 SyntheticTypeNameBuilder &NameBuilder) { 310 OrderedChildrenIndexAssigner ChildrenIndexAssigner(*this, DieEntry); 311 for (const DWARFDebugInfoEntry *CurChild = getFirstChildEntry(DieEntry); 312 CurChild && CurChild->getAbbreviationDeclarationPtr(); 313 CurChild = getSiblingEntry(CurChild)) { 314 CompileUnit::DIEInfo &ChildInfo = getDIEInfo(CurChild); 315 if (!ChildInfo.needToPlaceInTypeTable()) 316 continue; 317 318 assert(ChildInfo.getODRAvailable()); 319 if (Error Err = NameBuilder.assignName( 320 {this, CurChild}, 321 ChildrenIndexAssigner.getChildIndex(*this, CurChild))) 322 return Err; 323 324 if (Error Err = assignTypeNamesRec(CurChild, NameBuilder)) 325 return Err; 326 } 327 328 return Error::success(); 329 } 330 331 void CompileUnit::updateDieRefPatchesWithClonedOffsets() { 332 if (std::optional<SectionDescriptor *> DebugInfoSection = 333 tryGetSectionDescriptor(DebugSectionKind::DebugInfo)) { 334 335 (*DebugInfoSection) 336 ->ListDebugDieRefPatch.forEach([&](DebugDieRefPatch &Patch) { 337 /// Replace stored DIE indexes with DIE output offsets. 338 Patch.RefDieIdxOrClonedOffset = 339 Patch.RefCU.getPointer()->getDieOutOffset( 340 Patch.RefDieIdxOrClonedOffset); 341 }); 342 343 (*DebugInfoSection) 344 ->ListDebugULEB128DieRefPatch.forEach( 345 [&](DebugULEB128DieRefPatch &Patch) { 346 /// Replace stored DIE indexes with DIE output offsets. 347 Patch.RefDieIdxOrClonedOffset = 348 Patch.RefCU.getPointer()->getDieOutOffset( 349 Patch.RefDieIdxOrClonedOffset); 350 }); 351 } 352 353 if (std::optional<SectionDescriptor *> DebugLocSection = 354 tryGetSectionDescriptor(DebugSectionKind::DebugLoc)) { 355 (*DebugLocSection) 356 ->ListDebugULEB128DieRefPatch.forEach( 357 [](DebugULEB128DieRefPatch &Patch) { 358 /// Replace stored DIE indexes with DIE output offsets. 359 Patch.RefDieIdxOrClonedOffset = 360 Patch.RefCU.getPointer()->getDieOutOffset( 361 Patch.RefDieIdxOrClonedOffset); 362 }); 363 } 364 365 if (std::optional<SectionDescriptor *> DebugLocListsSection = 366 tryGetSectionDescriptor(DebugSectionKind::DebugLocLists)) { 367 (*DebugLocListsSection) 368 ->ListDebugULEB128DieRefPatch.forEach( 369 [](DebugULEB128DieRefPatch &Patch) { 370 /// Replace stored DIE indexes with DIE output offsets. 371 Patch.RefDieIdxOrClonedOffset = 372 Patch.RefCU.getPointer()->getDieOutOffset( 373 Patch.RefDieIdxOrClonedOffset); 374 }); 375 } 376 } 377 378 std::optional<UnitEntryPairTy> CompileUnit::resolveDIEReference( 379 const DWARFFormValue &RefValue, 380 ResolveInterCUReferencesMode CanResolveInterCUReferences) { 381 CompileUnit *RefCU; 382 uint64_t RefDIEOffset; 383 if (std::optional<uint64_t> Offset = RefValue.getAsRelativeReference()) { 384 RefCU = this; 385 RefDIEOffset = RefValue.getUnit()->getOffset() + *Offset; 386 } else if (Offset = RefValue.getAsDebugInfoReference(); Offset) { 387 RefCU = getUnitFromOffset(*Offset); 388 RefDIEOffset = *Offset; 389 } else { 390 return std::nullopt; 391 } 392 393 if (RefCU == this) { 394 // Referenced DIE is in current compile unit. 395 if (std::optional<uint32_t> RefDieIdx = getDIEIndexForOffset(RefDIEOffset)) 396 return UnitEntryPairTy{this, getDebugInfoEntry(*RefDieIdx)}; 397 } else if (RefCU && CanResolveInterCUReferences) { 398 // Referenced DIE is in other compile unit. 399 400 // Check whether DIEs are loaded for that compile unit. 401 enum Stage ReferredCUStage = RefCU->getStage(); 402 if (ReferredCUStage < Stage::Loaded || ReferredCUStage > Stage::Cloned) 403 return UnitEntryPairTy{RefCU, nullptr}; 404 405 if (std::optional<uint32_t> RefDieIdx = 406 RefCU->getDIEIndexForOffset(RefDIEOffset)) 407 return UnitEntryPairTy{RefCU, RefCU->getDebugInfoEntry(*RefDieIdx)}; 408 } else { 409 return UnitEntryPairTy{RefCU, nullptr}; 410 } 411 return std::nullopt; 412 } 413 414 std::optional<UnitEntryPairTy> CompileUnit::resolveDIEReference( 415 const DWARFDebugInfoEntry *DieEntry, dwarf::Attribute Attr, 416 ResolveInterCUReferencesMode CanResolveInterCUReferences) { 417 if (std::optional<DWARFFormValue> AttrVal = find(DieEntry, Attr)) 418 return resolveDIEReference(*AttrVal, CanResolveInterCUReferences); 419 420 return std::nullopt; 421 } 422 423 void CompileUnit::addFunctionRange(uint64_t FuncLowPc, uint64_t FuncHighPc, 424 int64_t PcOffset) { 425 std::lock_guard<std::mutex> Guard(RangesMutex); 426 427 Ranges.insert({FuncLowPc, FuncHighPc}, PcOffset); 428 if (LowPc) 429 LowPc = std::min(*LowPc, FuncLowPc + PcOffset); 430 else 431 LowPc = FuncLowPc + PcOffset; 432 this->HighPc = std::max(HighPc, FuncHighPc + PcOffset); 433 } 434 435 void CompileUnit::addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset) { 436 std::lock_guard<std::mutex> Guard(LabelsMutex); 437 Labels.insert({LabelLowPc, PcOffset}); 438 } 439 440 Error CompileUnit::cloneAndEmitDebugLocations() { 441 if (getGlobalData().getOptions().UpdateIndexTablesOnly) 442 return Error::success(); 443 444 if (getOrigUnit().getVersion() < 5) { 445 emitLocations(DebugSectionKind::DebugLoc); 446 return Error::success(); 447 } 448 449 emitLocations(DebugSectionKind::DebugLocLists); 450 return Error::success(); 451 } 452 453 void CompileUnit::emitLocations(DebugSectionKind LocationSectionKind) { 454 SectionDescriptor &DebugInfoSection = 455 getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo); 456 457 if (!DebugInfoSection.ListDebugLocPatch.empty()) { 458 SectionDescriptor &OutLocationSection = 459 getOrCreateSectionDescriptor(LocationSectionKind); 460 DWARFUnit &OrigUnit = getOrigUnit(); 461 462 uint64_t OffsetAfterUnitLength = emitLocListHeader(OutLocationSection); 463 464 DebugInfoSection.ListDebugLocPatch.forEach([&](DebugLocPatch &Patch) { 465 // Get location expressions vector corresponding to the current 466 // attribute from the source DWARF. 467 uint64_t InputDebugLocSectionOffset = DebugInfoSection.getIntVal( 468 Patch.PatchOffset, 469 DebugInfoSection.getFormParams().getDwarfOffsetByteSize()); 470 Expected<DWARFLocationExpressionsVector> OriginalLocations = 471 OrigUnit.findLoclistFromOffset(InputDebugLocSectionOffset); 472 473 if (!OriginalLocations) { 474 warn(OriginalLocations.takeError()); 475 return; 476 } 477 478 LinkedLocationExpressionsVector LinkedLocationExpressions; 479 for (DWARFLocationExpression &CurExpression : *OriginalLocations) { 480 LinkedLocationExpressionsWithOffsetPatches LinkedExpression; 481 482 if (CurExpression.Range) { 483 // Relocate address range. 484 LinkedExpression.Expression.Range = { 485 CurExpression.Range->LowPC + Patch.AddrAdjustmentValue, 486 CurExpression.Range->HighPC + Patch.AddrAdjustmentValue}; 487 } 488 489 DataExtractor Data(CurExpression.Expr, OrigUnit.isLittleEndian(), 490 OrigUnit.getAddressByteSize()); 491 492 DWARFExpression InputExpression(Data, OrigUnit.getAddressByteSize(), 493 OrigUnit.getFormParams().Format); 494 cloneDieAttrExpression(InputExpression, 495 LinkedExpression.Expression.Expr, 496 OutLocationSection, Patch.AddrAdjustmentValue, 497 LinkedExpression.Patches); 498 499 LinkedLocationExpressions.push_back({LinkedExpression}); 500 } 501 502 // Emit locations list table fragment corresponding to the CurLocAttr. 503 DebugInfoSection.apply(Patch.PatchOffset, dwarf::DW_FORM_sec_offset, 504 OutLocationSection.OS.tell()); 505 emitLocListFragment(LinkedLocationExpressions, OutLocationSection); 506 }); 507 508 if (OffsetAfterUnitLength > 0) { 509 assert(OffsetAfterUnitLength - 510 OutLocationSection.getFormParams().getDwarfOffsetByteSize() < 511 OffsetAfterUnitLength); 512 OutLocationSection.apply( 513 OffsetAfterUnitLength - 514 OutLocationSection.getFormParams().getDwarfOffsetByteSize(), 515 dwarf::DW_FORM_sec_offset, 516 OutLocationSection.OS.tell() - OffsetAfterUnitLength); 517 } 518 } 519 } 520 521 /// Emit debug locations(.debug_loc, .debug_loclists) header. 522 uint64_t CompileUnit::emitLocListHeader(SectionDescriptor &OutLocationSection) { 523 if (getOrigUnit().getVersion() < 5) 524 return 0; 525 526 // unit_length. 527 OutLocationSection.emitUnitLength(0xBADDEF); 528 uint64_t OffsetAfterUnitLength = OutLocationSection.OS.tell(); 529 530 // Version. 531 OutLocationSection.emitIntVal(5, 2); 532 533 // Address size. 534 OutLocationSection.emitIntVal(OutLocationSection.getFormParams().AddrSize, 1); 535 536 // Seg_size 537 OutLocationSection.emitIntVal(0, 1); 538 539 // Offset entry count 540 OutLocationSection.emitIntVal(0, 4); 541 542 return OffsetAfterUnitLength; 543 } 544 545 /// Emit debug locations(.debug_loc, .debug_loclists) fragment. 546 uint64_t CompileUnit::emitLocListFragment( 547 const LinkedLocationExpressionsVector &LinkedLocationExpression, 548 SectionDescriptor &OutLocationSection) { 549 uint64_t OffsetBeforeLocationExpression = 0; 550 551 if (getOrigUnit().getVersion() < 5) { 552 uint64_t BaseAddress = 0; 553 if (std::optional<uint64_t> LowPC = getLowPc()) 554 BaseAddress = *LowPC; 555 556 for (const LinkedLocationExpressionsWithOffsetPatches &LocExpression : 557 LinkedLocationExpression) { 558 if (LocExpression.Expression.Range) { 559 OutLocationSection.emitIntVal( 560 LocExpression.Expression.Range->LowPC - BaseAddress, 561 OutLocationSection.getFormParams().AddrSize); 562 OutLocationSection.emitIntVal( 563 LocExpression.Expression.Range->HighPC - BaseAddress, 564 OutLocationSection.getFormParams().AddrSize); 565 } 566 567 OutLocationSection.emitIntVal(LocExpression.Expression.Expr.size(), 2); 568 OffsetBeforeLocationExpression = OutLocationSection.OS.tell(); 569 for (uint64_t *OffsetPtr : LocExpression.Patches) 570 *OffsetPtr += OffsetBeforeLocationExpression; 571 572 OutLocationSection.OS 573 << StringRef((const char *)LocExpression.Expression.Expr.data(), 574 LocExpression.Expression.Expr.size()); 575 } 576 577 // Emit the terminator entry. 578 OutLocationSection.emitIntVal(0, 579 OutLocationSection.getFormParams().AddrSize); 580 OutLocationSection.emitIntVal(0, 581 OutLocationSection.getFormParams().AddrSize); 582 return OffsetBeforeLocationExpression; 583 } 584 585 std::optional<uint64_t> BaseAddress; 586 for (const LinkedLocationExpressionsWithOffsetPatches &LocExpression : 587 LinkedLocationExpression) { 588 if (LocExpression.Expression.Range) { 589 // Check whether base address is set. If it is not set yet 590 // then set current base address and emit base address selection entry. 591 if (!BaseAddress) { 592 BaseAddress = LocExpression.Expression.Range->LowPC; 593 594 // Emit base address. 595 OutLocationSection.emitIntVal(dwarf::DW_LLE_base_addressx, 1); 596 encodeULEB128(DebugAddrIndexMap.getValueIndex(*BaseAddress), 597 OutLocationSection.OS); 598 } 599 600 // Emit type of entry. 601 OutLocationSection.emitIntVal(dwarf::DW_LLE_offset_pair, 1); 602 603 // Emit start offset relative to base address. 604 encodeULEB128(LocExpression.Expression.Range->LowPC - *BaseAddress, 605 OutLocationSection.OS); 606 607 // Emit end offset relative to base address. 608 encodeULEB128(LocExpression.Expression.Range->HighPC - *BaseAddress, 609 OutLocationSection.OS); 610 } else 611 // Emit type of entry. 612 OutLocationSection.emitIntVal(dwarf::DW_LLE_default_location, 1); 613 614 encodeULEB128(LocExpression.Expression.Expr.size(), OutLocationSection.OS); 615 OffsetBeforeLocationExpression = OutLocationSection.OS.tell(); 616 for (uint64_t *OffsetPtr : LocExpression.Patches) 617 *OffsetPtr += OffsetBeforeLocationExpression; 618 619 OutLocationSection.OS << StringRef( 620 (const char *)LocExpression.Expression.Expr.data(), 621 LocExpression.Expression.Expr.size()); 622 } 623 624 // Emit the terminator entry. 625 OutLocationSection.emitIntVal(dwarf::DW_LLE_end_of_list, 1); 626 return OffsetBeforeLocationExpression; 627 } 628 629 Error CompileUnit::emitDebugAddrSection() { 630 if (GlobalData.getOptions().UpdateIndexTablesOnly) 631 return Error::success(); 632 633 if (getVersion() < 5) 634 return Error::success(); 635 636 if (DebugAddrIndexMap.empty()) 637 return Error::success(); 638 639 SectionDescriptor &OutAddrSection = 640 getOrCreateSectionDescriptor(DebugSectionKind::DebugAddr); 641 642 // Emit section header. 643 644 // Emit length. 645 OutAddrSection.emitUnitLength(0xBADDEF); 646 uint64_t OffsetAfterSectionLength = OutAddrSection.OS.tell(); 647 648 // Emit version. 649 OutAddrSection.emitIntVal(5, 2); 650 651 // Emit address size. 652 OutAddrSection.emitIntVal(getFormParams().AddrSize, 1); 653 654 // Emit segment size. 655 OutAddrSection.emitIntVal(0, 1); 656 657 // Emit addresses. 658 for (uint64_t AddrValue : DebugAddrIndexMap.getValues()) 659 OutAddrSection.emitIntVal(AddrValue, getFormParams().AddrSize); 660 661 // Patch section length. 662 OutAddrSection.apply( 663 OffsetAfterSectionLength - 664 OutAddrSection.getFormParams().getDwarfOffsetByteSize(), 665 dwarf::DW_FORM_sec_offset, 666 OutAddrSection.OS.tell() - OffsetAfterSectionLength); 667 668 return Error::success(); 669 } 670 671 Error CompileUnit::cloneAndEmitRanges() { 672 if (getGlobalData().getOptions().UpdateIndexTablesOnly) 673 return Error::success(); 674 675 // Build set of linked address ranges for unit function ranges. 676 AddressRanges LinkedFunctionRanges; 677 for (const AddressRangeValuePair &Range : getFunctionRanges()) 678 LinkedFunctionRanges.insert( 679 {Range.Range.start() + Range.Value, Range.Range.end() + Range.Value}); 680 681 emitAranges(LinkedFunctionRanges); 682 683 if (getOrigUnit().getVersion() < 5) { 684 cloneAndEmitRangeList(DebugSectionKind::DebugRange, LinkedFunctionRanges); 685 return Error::success(); 686 } 687 688 cloneAndEmitRangeList(DebugSectionKind::DebugRngLists, LinkedFunctionRanges); 689 return Error::success(); 690 } 691 692 void CompileUnit::cloneAndEmitRangeList(DebugSectionKind RngSectionKind, 693 AddressRanges &LinkedFunctionRanges) { 694 SectionDescriptor &DebugInfoSection = 695 getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo); 696 SectionDescriptor &OutRangeSection = 697 getOrCreateSectionDescriptor(RngSectionKind); 698 699 if (!DebugInfoSection.ListDebugRangePatch.empty()) { 700 std::optional<AddressRangeValuePair> CachedRange; 701 uint64_t OffsetAfterUnitLength = emitRangeListHeader(OutRangeSection); 702 703 DebugRangePatch *CompileUnitRangePtr = nullptr; 704 DebugInfoSection.ListDebugRangePatch.forEach([&](DebugRangePatch &Patch) { 705 if (Patch.IsCompileUnitRanges) { 706 CompileUnitRangePtr = &Patch; 707 } else { 708 // Get ranges from the source DWARF corresponding to the current 709 // attribute. 710 AddressRanges LinkedRanges; 711 uint64_t InputDebugRangesSectionOffset = DebugInfoSection.getIntVal( 712 Patch.PatchOffset, 713 DebugInfoSection.getFormParams().getDwarfOffsetByteSize()); 714 if (Expected<DWARFAddressRangesVector> InputRanges = 715 getOrigUnit().findRnglistFromOffset( 716 InputDebugRangesSectionOffset)) { 717 // Apply relocation adjustment. 718 for (const auto &Range : *InputRanges) { 719 if (!CachedRange || !CachedRange->Range.contains(Range.LowPC)) 720 CachedRange = 721 getFunctionRanges().getRangeThatContains(Range.LowPC); 722 723 // All range entries should lie in the function range. 724 if (!CachedRange) { 725 warn("inconsistent range data."); 726 continue; 727 } 728 729 // Store range for emiting. 730 LinkedRanges.insert({Range.LowPC + CachedRange->Value, 731 Range.HighPC + CachedRange->Value}); 732 } 733 } else { 734 llvm::consumeError(InputRanges.takeError()); 735 warn("invalid range list ignored."); 736 } 737 738 // Emit linked ranges. 739 DebugInfoSection.apply(Patch.PatchOffset, dwarf::DW_FORM_sec_offset, 740 OutRangeSection.OS.tell()); 741 emitRangeListFragment(LinkedRanges, OutRangeSection); 742 } 743 }); 744 745 if (CompileUnitRangePtr != nullptr) { 746 // Emit compile unit ranges last to be binary compatible with classic 747 // dsymutil. 748 DebugInfoSection.apply(CompileUnitRangePtr->PatchOffset, 749 dwarf::DW_FORM_sec_offset, 750 OutRangeSection.OS.tell()); 751 emitRangeListFragment(LinkedFunctionRanges, OutRangeSection); 752 } 753 754 if (OffsetAfterUnitLength > 0) { 755 assert(OffsetAfterUnitLength - 756 OutRangeSection.getFormParams().getDwarfOffsetByteSize() < 757 OffsetAfterUnitLength); 758 OutRangeSection.apply( 759 OffsetAfterUnitLength - 760 OutRangeSection.getFormParams().getDwarfOffsetByteSize(), 761 dwarf::DW_FORM_sec_offset, 762 OutRangeSection.OS.tell() - OffsetAfterUnitLength); 763 } 764 } 765 } 766 767 uint64_t CompileUnit::emitRangeListHeader(SectionDescriptor &OutRangeSection) { 768 if (OutRangeSection.getFormParams().Version < 5) 769 return 0; 770 771 // unit_length. 772 OutRangeSection.emitUnitLength(0xBADDEF); 773 uint64_t OffsetAfterUnitLength = OutRangeSection.OS.tell(); 774 775 // Version. 776 OutRangeSection.emitIntVal(5, 2); 777 778 // Address size. 779 OutRangeSection.emitIntVal(OutRangeSection.getFormParams().AddrSize, 1); 780 781 // Seg_size 782 OutRangeSection.emitIntVal(0, 1); 783 784 // Offset entry count 785 OutRangeSection.emitIntVal(0, 4); 786 787 return OffsetAfterUnitLength; 788 } 789 790 void CompileUnit::emitRangeListFragment(const AddressRanges &LinkedRanges, 791 SectionDescriptor &OutRangeSection) { 792 if (OutRangeSection.getFormParams().Version < 5) { 793 // Emit ranges. 794 uint64_t BaseAddress = 0; 795 if (std::optional<uint64_t> LowPC = getLowPc()) 796 BaseAddress = *LowPC; 797 798 for (const AddressRange &Range : LinkedRanges) { 799 OutRangeSection.emitIntVal(Range.start() - BaseAddress, 800 OutRangeSection.getFormParams().AddrSize); 801 OutRangeSection.emitIntVal(Range.end() - BaseAddress, 802 OutRangeSection.getFormParams().AddrSize); 803 } 804 805 // Add the terminator entry. 806 OutRangeSection.emitIntVal(0, OutRangeSection.getFormParams().AddrSize); 807 OutRangeSection.emitIntVal(0, OutRangeSection.getFormParams().AddrSize); 808 return; 809 } 810 811 std::optional<uint64_t> BaseAddress; 812 for (const AddressRange &Range : LinkedRanges) { 813 if (!BaseAddress) { 814 BaseAddress = Range.start(); 815 816 // Emit base address. 817 OutRangeSection.emitIntVal(dwarf::DW_RLE_base_addressx, 1); 818 encodeULEB128(getDebugAddrIndex(*BaseAddress), OutRangeSection.OS); 819 } 820 821 // Emit type of entry. 822 OutRangeSection.emitIntVal(dwarf::DW_RLE_offset_pair, 1); 823 824 // Emit start offset relative to base address. 825 encodeULEB128(Range.start() - *BaseAddress, OutRangeSection.OS); 826 827 // Emit end offset relative to base address. 828 encodeULEB128(Range.end() - *BaseAddress, OutRangeSection.OS); 829 } 830 831 // Emit the terminator entry. 832 OutRangeSection.emitIntVal(dwarf::DW_RLE_end_of_list, 1); 833 } 834 835 void CompileUnit::emitAranges(AddressRanges &LinkedFunctionRanges) { 836 if (LinkedFunctionRanges.empty()) 837 return; 838 839 SectionDescriptor &DebugInfoSection = 840 getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo); 841 SectionDescriptor &OutArangesSection = 842 getOrCreateSectionDescriptor(DebugSectionKind::DebugARanges); 843 844 // Emit Header. 845 unsigned HeaderSize = 846 sizeof(int32_t) + // Size of contents (w/o this field 847 sizeof(int16_t) + // DWARF ARange version number 848 sizeof(int32_t) + // Offset of CU in the .debug_info section 849 sizeof(int8_t) + // Pointer Size (in bytes) 850 sizeof(int8_t); // Segment Size (in bytes) 851 852 unsigned TupleSize = OutArangesSection.getFormParams().AddrSize * 2; 853 unsigned Padding = offsetToAlignment(HeaderSize, Align(TupleSize)); 854 855 OutArangesSection.emitOffset(0xBADDEF); // Aranges length 856 uint64_t OffsetAfterArangesLengthField = OutArangesSection.OS.tell(); 857 858 OutArangesSection.emitIntVal(dwarf::DW_ARANGES_VERSION, 2); // Version number 859 OutArangesSection.notePatch( 860 DebugOffsetPatch{OutArangesSection.OS.tell(), &DebugInfoSection}); 861 OutArangesSection.emitOffset(0xBADDEF); // Corresponding unit's offset 862 OutArangesSection.emitIntVal(OutArangesSection.getFormParams().AddrSize, 863 1); // Address size 864 OutArangesSection.emitIntVal(0, 1); // Segment size 865 866 for (size_t Idx = 0; Idx < Padding; Idx++) 867 OutArangesSection.emitIntVal(0, 1); // Padding 868 869 // Emit linked ranges. 870 for (const AddressRange &Range : LinkedFunctionRanges) { 871 OutArangesSection.emitIntVal(Range.start(), 872 OutArangesSection.getFormParams().AddrSize); 873 OutArangesSection.emitIntVal(Range.end() - Range.start(), 874 OutArangesSection.getFormParams().AddrSize); 875 } 876 877 // Emit terminator. 878 OutArangesSection.emitIntVal(0, OutArangesSection.getFormParams().AddrSize); 879 OutArangesSection.emitIntVal(0, OutArangesSection.getFormParams().AddrSize); 880 881 uint64_t OffsetAfterArangesEnd = OutArangesSection.OS.tell(); 882 883 // Update Aranges lentgh. 884 OutArangesSection.apply( 885 OffsetAfterArangesLengthField - 886 OutArangesSection.getFormParams().getDwarfOffsetByteSize(), 887 dwarf::DW_FORM_sec_offset, 888 OffsetAfterArangesEnd - OffsetAfterArangesLengthField); 889 } 890 891 Error CompileUnit::cloneAndEmitDebugMacro() { 892 if (getOutUnitDIE() == nullptr) 893 return Error::success(); 894 895 DWARFUnit &OrigUnit = getOrigUnit(); 896 DWARFDie OrigUnitDie = OrigUnit.getUnitDIE(); 897 898 // Check for .debug_macro table. 899 if (std::optional<uint64_t> MacroAttr = 900 dwarf::toSectionOffset(OrigUnitDie.find(dwarf::DW_AT_macros))) { 901 if (const DWARFDebugMacro *Table = 902 getContaingFile().Dwarf->getDebugMacro()) { 903 emitMacroTableImpl(Table, *MacroAttr, true); 904 } 905 } 906 907 // Check for .debug_macinfo table. 908 if (std::optional<uint64_t> MacroAttr = 909 dwarf::toSectionOffset(OrigUnitDie.find(dwarf::DW_AT_macro_info))) { 910 if (const DWARFDebugMacro *Table = 911 getContaingFile().Dwarf->getDebugMacinfo()) { 912 emitMacroTableImpl(Table, *MacroAttr, false); 913 } 914 } 915 916 return Error::success(); 917 } 918 919 void CompileUnit::emitMacroTableImpl(const DWARFDebugMacro *MacroTable, 920 uint64_t OffsetToMacroTable, 921 bool hasDWARFv5Header) { 922 SectionDescriptor &OutSection = 923 hasDWARFv5Header 924 ? getOrCreateSectionDescriptor(DebugSectionKind::DebugMacro) 925 : getOrCreateSectionDescriptor(DebugSectionKind::DebugMacinfo); 926 927 bool DefAttributeIsReported = false; 928 bool UndefAttributeIsReported = false; 929 bool ImportAttributeIsReported = false; 930 931 for (const DWARFDebugMacro::MacroList &List : MacroTable->MacroLists) { 932 if (OffsetToMacroTable == List.Offset) { 933 // Write DWARFv5 header. 934 if (hasDWARFv5Header) { 935 // Write header version. 936 OutSection.emitIntVal(List.Header.Version, sizeof(List.Header.Version)); 937 938 uint8_t Flags = List.Header.Flags; 939 940 // Check for OPCODE_OPERANDS_TABLE. 941 if (Flags & 942 DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE) { 943 Flags &= 944 ~DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE; 945 warn("opcode_operands_table is not supported yet."); 946 } 947 948 // Check for DEBUG_LINE_OFFSET. 949 std::optional<uint64_t> StmtListOffset; 950 if (Flags & DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET) { 951 // Get offset to the line table from the cloned compile unit. 952 for (auto &V : getOutUnitDIE()->values()) { 953 if (V.getAttribute() == dwarf::DW_AT_stmt_list) { 954 StmtListOffset = V.getDIEInteger().getValue(); 955 break; 956 } 957 } 958 959 if (!StmtListOffset) { 960 Flags &= ~DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET; 961 warn("couldn`t find line table for macro table."); 962 } 963 } 964 965 // Write flags. 966 OutSection.emitIntVal(Flags, sizeof(Flags)); 967 968 // Write offset to line table. 969 if (StmtListOffset) { 970 OutSection.notePatch(DebugOffsetPatch{ 971 OutSection.OS.tell(), 972 &getOrCreateSectionDescriptor(DebugSectionKind::DebugLine)}); 973 // TODO: check that List.Header.getOffsetByteSize() and 974 // DebugOffsetPatch agree on size. 975 OutSection.emitIntVal(0xBADDEF, List.Header.getOffsetByteSize()); 976 } 977 } 978 979 // Write macro entries. 980 for (const DWARFDebugMacro::Entry &MacroEntry : List.Macros) { 981 if (MacroEntry.Type == 0) { 982 encodeULEB128(MacroEntry.Type, OutSection.OS); 983 continue; 984 } 985 986 uint8_t MacroType = MacroEntry.Type; 987 switch (MacroType) { 988 default: { 989 bool HasVendorSpecificExtension = 990 (!hasDWARFv5Header && 991 MacroType == dwarf::DW_MACINFO_vendor_ext) || 992 (hasDWARFv5Header && (MacroType >= dwarf::DW_MACRO_lo_user && 993 MacroType <= dwarf::DW_MACRO_hi_user)); 994 995 if (HasVendorSpecificExtension) { 996 // Write macinfo type. 997 OutSection.emitIntVal(MacroType, 1); 998 999 // Write vendor extension constant. 1000 encodeULEB128(MacroEntry.ExtConstant, OutSection.OS); 1001 1002 // Write vendor extension string. 1003 OutSection.emitString(dwarf::DW_FORM_string, MacroEntry.ExtStr); 1004 } else 1005 warn("unknown macro type. skip."); 1006 } break; 1007 // debug_macro and debug_macinfo share some common encodings. 1008 // DW_MACRO_define == DW_MACINFO_define 1009 // DW_MACRO_undef == DW_MACINFO_undef 1010 // DW_MACRO_start_file == DW_MACINFO_start_file 1011 // DW_MACRO_end_file == DW_MACINFO_end_file 1012 // For readibility/uniformity we are using DW_MACRO_*. 1013 case dwarf::DW_MACRO_define: 1014 case dwarf::DW_MACRO_undef: { 1015 // Write macinfo type. 1016 OutSection.emitIntVal(MacroType, 1); 1017 1018 // Write source line. 1019 encodeULEB128(MacroEntry.Line, OutSection.OS); 1020 1021 // Write macro string. 1022 OutSection.emitString(dwarf::DW_FORM_string, MacroEntry.MacroStr); 1023 } break; 1024 case dwarf::DW_MACRO_define_strp: 1025 case dwarf::DW_MACRO_undef_strp: 1026 case dwarf::DW_MACRO_define_strx: 1027 case dwarf::DW_MACRO_undef_strx: { 1028 // DW_MACRO_*_strx forms are not supported currently. 1029 // Convert to *_strp. 1030 switch (MacroType) { 1031 case dwarf::DW_MACRO_define_strx: { 1032 MacroType = dwarf::DW_MACRO_define_strp; 1033 if (!DefAttributeIsReported) { 1034 warn("DW_MACRO_define_strx unsupported yet. Convert to " 1035 "DW_MACRO_define_strp."); 1036 DefAttributeIsReported = true; 1037 } 1038 } break; 1039 case dwarf::DW_MACRO_undef_strx: { 1040 MacroType = dwarf::DW_MACRO_undef_strp; 1041 if (!UndefAttributeIsReported) { 1042 warn("DW_MACRO_undef_strx unsupported yet. Convert to " 1043 "DW_MACRO_undef_strp."); 1044 UndefAttributeIsReported = true; 1045 } 1046 } break; 1047 default: 1048 // Nothing to do. 1049 break; 1050 } 1051 1052 // Write macinfo type. 1053 OutSection.emitIntVal(MacroType, 1); 1054 1055 // Write source line. 1056 encodeULEB128(MacroEntry.Line, OutSection.OS); 1057 1058 // Write macro string. 1059 OutSection.emitString(dwarf::DW_FORM_strp, MacroEntry.MacroStr); 1060 break; 1061 } 1062 case dwarf::DW_MACRO_start_file: { 1063 // Write macinfo type. 1064 OutSection.emitIntVal(MacroType, 1); 1065 // Write source line. 1066 encodeULEB128(MacroEntry.Line, OutSection.OS); 1067 // Write source file id. 1068 encodeULEB128(MacroEntry.File, OutSection.OS); 1069 } break; 1070 case dwarf::DW_MACRO_end_file: { 1071 // Write macinfo type. 1072 OutSection.emitIntVal(MacroType, 1); 1073 } break; 1074 case dwarf::DW_MACRO_import: 1075 case dwarf::DW_MACRO_import_sup: { 1076 if (!ImportAttributeIsReported) { 1077 warn("DW_MACRO_import and DW_MACRO_import_sup are unsupported " 1078 "yet. remove."); 1079 ImportAttributeIsReported = true; 1080 } 1081 } break; 1082 } 1083 } 1084 1085 return; 1086 } 1087 } 1088 } 1089 1090 void CompileUnit::cloneDieAttrExpression( 1091 const DWARFExpression &InputExpression, 1092 SmallVectorImpl<uint8_t> &OutputExpression, SectionDescriptor &Section, 1093 std::optional<int64_t> VarAddressAdjustment, 1094 OffsetsPtrVector &PatchesOffsets) { 1095 using Encoding = DWARFExpression::Operation::Encoding; 1096 1097 DWARFUnit &OrigUnit = getOrigUnit(); 1098 uint8_t OrigAddressByteSize = OrigUnit.getAddressByteSize(); 1099 1100 uint64_t OpOffset = 0; 1101 for (auto &Op : InputExpression) { 1102 auto Desc = Op.getDescription(); 1103 // DW_OP_const_type is variable-length and has 3 1104 // operands. Thus far we only support 2. 1105 if ((Desc.Op.size() == 2 && Desc.Op[0] == Encoding::BaseTypeRef) || 1106 (Desc.Op.size() == 2 && Desc.Op[1] == Encoding::BaseTypeRef && 1107 Desc.Op[0] != Encoding::Size1)) 1108 warn("unsupported DW_OP encoding."); 1109 1110 if ((Desc.Op.size() == 1 && Desc.Op[0] == Encoding::BaseTypeRef) || 1111 (Desc.Op.size() == 2 && Desc.Op[1] == Encoding::BaseTypeRef && 1112 Desc.Op[0] == Encoding::Size1)) { 1113 // This code assumes that the other non-typeref operand fits into 1 byte. 1114 assert(OpOffset < Op.getEndOffset()); 1115 uint32_t ULEBsize = Op.getEndOffset() - OpOffset - 1; 1116 assert(ULEBsize <= 16); 1117 1118 // Copy over the operation. 1119 assert(!Op.getSubCode() && "SubOps not yet supported"); 1120 OutputExpression.push_back(Op.getCode()); 1121 uint64_t RefOffset; 1122 if (Desc.Op.size() == 1) { 1123 RefOffset = Op.getRawOperand(0); 1124 } else { 1125 OutputExpression.push_back(Op.getRawOperand(0)); 1126 RefOffset = Op.getRawOperand(1); 1127 } 1128 uint8_t ULEB[16]; 1129 uint32_t Offset = 0; 1130 unsigned RealSize = 0; 1131 // Look up the base type. For DW_OP_convert, the operand may be 0 to 1132 // instead indicate the generic type. The same holds for 1133 // DW_OP_reinterpret, which is currently not supported. 1134 if (RefOffset > 0 || Op.getCode() != dwarf::DW_OP_convert) { 1135 RefOffset += OrigUnit.getOffset(); 1136 uint32_t RefDieIdx = 0; 1137 if (std::optional<uint32_t> Idx = 1138 OrigUnit.getDIEIndexForOffset(RefOffset)) 1139 RefDieIdx = *Idx; 1140 1141 // Use fixed size for ULEB128 data, since we need to update that size 1142 // later with the proper offsets. Use 5 for DWARF32, 9 for DWARF64. 1143 ULEBsize = getFormParams().getDwarfOffsetByteSize() + 1; 1144 1145 RealSize = encodeULEB128(0xBADDEF, ULEB, ULEBsize); 1146 1147 Section.notePatchWithOffsetUpdate( 1148 DebugULEB128DieRefPatch(OutputExpression.size(), this, this, 1149 RefDieIdx), 1150 PatchesOffsets); 1151 } else 1152 RealSize = encodeULEB128(Offset, ULEB, ULEBsize); 1153 1154 if (RealSize > ULEBsize) { 1155 // Emit the generic type as a fallback. 1156 RealSize = encodeULEB128(0, ULEB, ULEBsize); 1157 warn("base type ref doesn't fit."); 1158 } 1159 assert(RealSize == ULEBsize && "padding failed"); 1160 ArrayRef<uint8_t> ULEBbytes(ULEB, ULEBsize); 1161 OutputExpression.append(ULEBbytes.begin(), ULEBbytes.end()); 1162 } else if (!getGlobalData().getOptions().UpdateIndexTablesOnly && 1163 Op.getCode() == dwarf::DW_OP_addrx) { 1164 if (std::optional<object::SectionedAddress> SA = 1165 OrigUnit.getAddrOffsetSectionItem(Op.getRawOperand(0))) { 1166 // DWARFLinker does not use addrx forms since it generates relocated 1167 // addresses. Replace DW_OP_addrx with DW_OP_addr here. 1168 // Argument of DW_OP_addrx should be relocated here as it is not 1169 // processed by applyValidRelocs. 1170 OutputExpression.push_back(dwarf::DW_OP_addr); 1171 uint64_t LinkedAddress = SA->Address + VarAddressAdjustment.value_or(0); 1172 if (getEndianness() != llvm::endianness::native) 1173 sys::swapByteOrder(LinkedAddress); 1174 ArrayRef<uint8_t> AddressBytes( 1175 reinterpret_cast<const uint8_t *>(&LinkedAddress), 1176 OrigAddressByteSize); 1177 OutputExpression.append(AddressBytes.begin(), AddressBytes.end()); 1178 } else 1179 warn("cann't read DW_OP_addrx operand."); 1180 } else if (!getGlobalData().getOptions().UpdateIndexTablesOnly && 1181 Op.getCode() == dwarf::DW_OP_constx) { 1182 if (std::optional<object::SectionedAddress> SA = 1183 OrigUnit.getAddrOffsetSectionItem(Op.getRawOperand(0))) { 1184 // DWARFLinker does not use constx forms since it generates relocated 1185 // addresses. Replace DW_OP_constx with DW_OP_const[*]u here. 1186 // Argument of DW_OP_constx should be relocated here as it is not 1187 // processed by applyValidRelocs. 1188 std::optional<uint8_t> OutOperandKind; 1189 switch (OrigAddressByteSize) { 1190 case 2: 1191 OutOperandKind = dwarf::DW_OP_const2u; 1192 break; 1193 case 4: 1194 OutOperandKind = dwarf::DW_OP_const4u; 1195 break; 1196 case 8: 1197 OutOperandKind = dwarf::DW_OP_const8u; 1198 break; 1199 default: 1200 warn( 1201 formatv(("unsupported address size: {0}."), OrigAddressByteSize)); 1202 break; 1203 } 1204 1205 if (OutOperandKind) { 1206 OutputExpression.push_back(*OutOperandKind); 1207 uint64_t LinkedAddress = 1208 SA->Address + VarAddressAdjustment.value_or(0); 1209 if (getEndianness() != llvm::endianness::native) 1210 sys::swapByteOrder(LinkedAddress); 1211 ArrayRef<uint8_t> AddressBytes( 1212 reinterpret_cast<const uint8_t *>(&LinkedAddress), 1213 OrigAddressByteSize); 1214 OutputExpression.append(AddressBytes.begin(), AddressBytes.end()); 1215 } 1216 } else 1217 warn("cann't read DW_OP_constx operand."); 1218 } else { 1219 // Copy over everything else unmodified. 1220 StringRef Bytes = 1221 InputExpression.getData().slice(OpOffset, Op.getEndOffset()); 1222 OutputExpression.append(Bytes.begin(), Bytes.end()); 1223 } 1224 OpOffset = Op.getEndOffset(); 1225 } 1226 } 1227 1228 Error CompileUnit::cloneAndEmit( 1229 std::optional<std::reference_wrapper<const Triple>> TargetTriple, 1230 TypeUnit *ArtificialTypeUnit) { 1231 BumpPtrAllocator Allocator; 1232 1233 DWARFDie OrigUnitDIE = getOrigUnit().getUnitDIE(); 1234 if (!OrigUnitDIE.isValid()) 1235 return Error::success(); 1236 1237 TypeEntry *RootEntry = nullptr; 1238 if (ArtificialTypeUnit) 1239 RootEntry = ArtificialTypeUnit->getTypePool().getRoot(); 1240 1241 // Clone input DIE entry recursively. 1242 std::pair<DIE *, TypeEntry *> OutCUDie = cloneDIE( 1243 OrigUnitDIE.getDebugInfoEntry(), RootEntry, getDebugInfoHeaderSize(), 1244 std::nullopt, std::nullopt, Allocator, ArtificialTypeUnit); 1245 setOutUnitDIE(OutCUDie.first); 1246 1247 if (!TargetTriple.has_value() || (OutCUDie.first == nullptr)) 1248 return Error::success(); 1249 1250 if (Error Err = cloneAndEmitLineTable((*TargetTriple).get())) 1251 return Err; 1252 1253 if (Error Err = cloneAndEmitDebugMacro()) 1254 return Err; 1255 1256 getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo); 1257 if (Error Err = emitDebugInfo((*TargetTriple).get())) 1258 return Err; 1259 1260 // ASSUMPTION: .debug_info section should already be emitted at this point. 1261 // cloneAndEmitRanges & cloneAndEmitDebugLocations use .debug_info section 1262 // data. 1263 1264 if (Error Err = cloneAndEmitRanges()) 1265 return Err; 1266 1267 if (Error Err = cloneAndEmitDebugLocations()) 1268 return Err; 1269 1270 if (Error Err = emitDebugAddrSection()) 1271 return Err; 1272 1273 // Generate Pub accelerator tables. 1274 if (llvm::is_contained(GlobalData.getOptions().AccelTables, 1275 DWARFLinker::AccelTableKind::Pub)) 1276 emitPubAccelerators(); 1277 1278 if (Error Err = emitDebugStringOffsetSection()) 1279 return Err; 1280 1281 return emitAbbreviations(); 1282 } 1283 1284 std::pair<DIE *, TypeEntry *> CompileUnit::cloneDIE( 1285 const DWARFDebugInfoEntry *InputDieEntry, TypeEntry *ClonedParentTypeDIE, 1286 uint64_t OutOffset, std::optional<int64_t> FuncAddressAdjustment, 1287 std::optional<int64_t> VarAddressAdjustment, BumpPtrAllocator &Allocator, 1288 TypeUnit *ArtificialTypeUnit) { 1289 uint32_t InputDieIdx = getDIEIndex(InputDieEntry); 1290 CompileUnit::DIEInfo &Info = getDIEInfo(InputDieIdx); 1291 1292 bool NeedToClonePlainDIE = Info.needToKeepInPlainDwarf(); 1293 bool NeedToCloneTypeDIE = 1294 (InputDieEntry->getTag() != dwarf::DW_TAG_compile_unit) && 1295 Info.needToPlaceInTypeTable(); 1296 std::pair<DIE *, TypeEntry *> ClonedDIE; 1297 1298 DIEGenerator PlainDIEGenerator(Allocator, *this); 1299 1300 if (NeedToClonePlainDIE) 1301 // Create a cloned DIE which would be placed into the cloned version 1302 // of input compile unit. 1303 ClonedDIE.first = createPlainDIEandCloneAttributes( 1304 InputDieEntry, PlainDIEGenerator, OutOffset, FuncAddressAdjustment, 1305 VarAddressAdjustment); 1306 if (NeedToCloneTypeDIE) { 1307 // Create a cloned DIE which would be placed into the artificial type 1308 // unit. 1309 assert(ArtificialTypeUnit != nullptr); 1310 DIEGenerator TypeDIEGenerator( 1311 ArtificialTypeUnit->getTypePool().getThreadLocalAllocator(), *this); 1312 1313 ClonedDIE.second = createTypeDIEandCloneAttributes( 1314 InputDieEntry, TypeDIEGenerator, ClonedParentTypeDIE, 1315 ArtificialTypeUnit); 1316 } 1317 TypeEntry *TypeParentForChild = 1318 ClonedDIE.second ? ClonedDIE.second : ClonedParentTypeDIE; 1319 1320 bool HasPlainChildrenToClone = 1321 (ClonedDIE.first && Info.getKeepPlainChildren()); 1322 1323 bool HasTypeChildrenToClone = 1324 ((ClonedDIE.second || 1325 InputDieEntry->getTag() == dwarf::DW_TAG_compile_unit) && 1326 Info.getKeepTypeChildren()); 1327 1328 // Recursively clone children. 1329 if (HasPlainChildrenToClone || HasTypeChildrenToClone) { 1330 for (const DWARFDebugInfoEntry *CurChild = 1331 getFirstChildEntry(InputDieEntry); 1332 CurChild && CurChild->getAbbreviationDeclarationPtr(); 1333 CurChild = getSiblingEntry(CurChild)) { 1334 std::pair<DIE *, TypeEntry *> ClonedChild = cloneDIE( 1335 CurChild, TypeParentForChild, OutOffset, FuncAddressAdjustment, 1336 VarAddressAdjustment, Allocator, ArtificialTypeUnit); 1337 1338 if (ClonedChild.first) { 1339 OutOffset = 1340 ClonedChild.first->getOffset() + ClonedChild.first->getSize(); 1341 PlainDIEGenerator.addChild(ClonedChild.first); 1342 } 1343 } 1344 assert(ClonedDIE.first == nullptr || 1345 HasPlainChildrenToClone == ClonedDIE.first->hasChildren()); 1346 1347 // Account for the end of children marker. 1348 if (HasPlainChildrenToClone) 1349 OutOffset += sizeof(int8_t); 1350 } 1351 1352 // Update our size. 1353 if (ClonedDIE.first != nullptr) 1354 ClonedDIE.first->setSize(OutOffset - ClonedDIE.first->getOffset()); 1355 1356 return ClonedDIE; 1357 } 1358 1359 DIE *CompileUnit::createPlainDIEandCloneAttributes( 1360 const DWARFDebugInfoEntry *InputDieEntry, DIEGenerator &PlainDIEGenerator, 1361 uint64_t &OutOffset, std::optional<int64_t> &FuncAddressAdjustment, 1362 std::optional<int64_t> &VarAddressAdjustment) { 1363 uint32_t InputDieIdx = getDIEIndex(InputDieEntry); 1364 CompileUnit::DIEInfo &Info = getDIEInfo(InputDieIdx); 1365 DIE *ClonedDIE = nullptr; 1366 bool HasLocationExpressionAddress = false; 1367 if (InputDieEntry->getTag() == dwarf::DW_TAG_subprogram) { 1368 // Get relocation adjustment value for the current function. 1369 FuncAddressAdjustment = 1370 getContaingFile().Addresses->getSubprogramRelocAdjustment( 1371 getDIE(InputDieEntry), false); 1372 } else if (InputDieEntry->getTag() == dwarf::DW_TAG_label) { 1373 // Get relocation adjustment value for the current label. 1374 std::optional<uint64_t> lowPC = 1375 dwarf::toAddress(find(InputDieEntry, dwarf::DW_AT_low_pc)); 1376 if (lowPC) { 1377 LabelMapTy::iterator It = Labels.find(*lowPC); 1378 if (It != Labels.end()) 1379 FuncAddressAdjustment = It->second; 1380 } 1381 } else if (InputDieEntry->getTag() == dwarf::DW_TAG_variable) { 1382 // Get relocation adjustment value for the current variable. 1383 std::pair<bool, std::optional<int64_t>> LocExprAddrAndRelocAdjustment = 1384 getContaingFile().Addresses->getVariableRelocAdjustment( 1385 getDIE(InputDieEntry), false); 1386 1387 HasLocationExpressionAddress = LocExprAddrAndRelocAdjustment.first; 1388 if (LocExprAddrAndRelocAdjustment.first && 1389 LocExprAddrAndRelocAdjustment.second) 1390 VarAddressAdjustment = *LocExprAddrAndRelocAdjustment.second; 1391 } 1392 1393 ClonedDIE = PlainDIEGenerator.createDIE(InputDieEntry->getTag(), OutOffset); 1394 1395 // Offset to the DIE would be used after output DIE tree is deleted. 1396 // Thus we need to remember DIE offset separately. 1397 rememberDieOutOffset(InputDieIdx, OutOffset); 1398 1399 // Clone Attributes. 1400 DIEAttributeCloner AttributesCloner(ClonedDIE, *this, this, InputDieEntry, 1401 PlainDIEGenerator, FuncAddressAdjustment, 1402 VarAddressAdjustment, 1403 HasLocationExpressionAddress); 1404 AttributesCloner.clone(); 1405 1406 // Remember accelerator info. 1407 AcceleratorRecordsSaver AccelRecordsSaver(getGlobalData(), *this, this); 1408 AccelRecordsSaver.save(InputDieEntry, ClonedDIE, AttributesCloner.AttrInfo, 1409 nullptr); 1410 1411 OutOffset = 1412 AttributesCloner.finalizeAbbreviations(Info.getKeepPlainChildren()); 1413 1414 return ClonedDIE; 1415 } 1416 1417 /// Allocates output DIE for the specified \p TypeDescriptor. 1418 DIE *CompileUnit::allocateTypeDie(TypeEntryBody *TypeDescriptor, 1419 DIEGenerator &TypeDIEGenerator, 1420 dwarf::Tag DieTag, bool IsDeclaration, 1421 bool IsParentDeclaration) { 1422 DIE *DefinitionDie = TypeDescriptor->Die; 1423 // Do not allocate any new DIE if definition DIE is already met. 1424 if (DefinitionDie) 1425 return nullptr; 1426 1427 DIE *DeclarationDie = TypeDescriptor->DeclarationDie; 1428 bool OldParentIsDeclaration = TypeDescriptor->ParentIsDeclaration; 1429 1430 if (IsDeclaration && !DeclarationDie) { 1431 // Alocate declaration DIE. 1432 DIE *NewDie = TypeDIEGenerator.createDIE(DieTag, 0); 1433 if (TypeDescriptor->DeclarationDie.compare_exchange_strong(DeclarationDie, 1434 NewDie)) 1435 return NewDie; 1436 } else if (IsDeclaration && !IsParentDeclaration && OldParentIsDeclaration) { 1437 // Overwrite existing declaration DIE if it's parent is also an declaration 1438 // while parent of current declaration DIE is a definition. 1439 if (TypeDescriptor->ParentIsDeclaration.compare_exchange_strong( 1440 OldParentIsDeclaration, false)) { 1441 DIE *NewDie = TypeDIEGenerator.createDIE(DieTag, 0); 1442 TypeDescriptor->DeclarationDie = NewDie; 1443 return NewDie; 1444 } 1445 } else if (!IsDeclaration && IsParentDeclaration && !DeclarationDie) { 1446 // Alocate declaration DIE since parent of current DIE is marked as 1447 // declaration. 1448 DIE *NewDie = TypeDIEGenerator.createDIE(DieTag, 0); 1449 if (TypeDescriptor->DeclarationDie.compare_exchange_strong(DeclarationDie, 1450 NewDie)) 1451 return NewDie; 1452 } else if (!IsDeclaration && !IsParentDeclaration) { 1453 // Allocate definition DIE. 1454 DIE *NewDie = TypeDIEGenerator.createDIE(DieTag, 0); 1455 if (TypeDescriptor->Die.compare_exchange_strong(DefinitionDie, NewDie)) { 1456 TypeDescriptor->ParentIsDeclaration = false; 1457 return NewDie; 1458 } 1459 } 1460 1461 return nullptr; 1462 } 1463 1464 TypeEntry *CompileUnit::createTypeDIEandCloneAttributes( 1465 const DWARFDebugInfoEntry *InputDieEntry, DIEGenerator &TypeDIEGenerator, 1466 TypeEntry *ClonedParentTypeDIE, TypeUnit *ArtificialTypeUnit) { 1467 assert(ArtificialTypeUnit != nullptr); 1468 uint32_t InputDieIdx = getDIEIndex(InputDieEntry); 1469 1470 TypeEntry *Entry = getDieTypeEntry(InputDieIdx); 1471 assert(Entry != nullptr); 1472 assert(ClonedParentTypeDIE != nullptr); 1473 TypeEntryBody *EntryBody = 1474 ArtificialTypeUnit->getTypePool().getOrCreateTypeEntryBody( 1475 Entry, ClonedParentTypeDIE); 1476 assert(EntryBody); 1477 1478 bool IsDeclaration = 1479 dwarf::toUnsigned(find(InputDieEntry, dwarf::DW_AT_declaration), 0); 1480 1481 bool ParentIsDeclaration = false; 1482 if (std::optional<uint32_t> ParentIdx = InputDieEntry->getParentIdx()) 1483 ParentIsDeclaration = 1484 dwarf::toUnsigned(find(*ParentIdx, dwarf::DW_AT_declaration), 0); 1485 1486 DIE *OutDIE = 1487 allocateTypeDie(EntryBody, TypeDIEGenerator, InputDieEntry->getTag(), 1488 IsDeclaration, ParentIsDeclaration); 1489 1490 if (OutDIE != nullptr) { 1491 assert(ArtificialTypeUnit != nullptr); 1492 ArtificialTypeUnit->getSectionDescriptor(DebugSectionKind::DebugInfo); 1493 1494 DIEAttributeCloner AttributesCloner(OutDIE, *this, ArtificialTypeUnit, 1495 InputDieEntry, TypeDIEGenerator, 1496 std::nullopt, std::nullopt, false); 1497 AttributesCloner.clone(); 1498 1499 // Remember accelerator info. 1500 AcceleratorRecordsSaver AccelRecordsSaver(getGlobalData(), *this, 1501 ArtificialTypeUnit); 1502 AccelRecordsSaver.save(InputDieEntry, OutDIE, AttributesCloner.AttrInfo, 1503 Entry); 1504 1505 // if AttributesCloner.getOutOffset() == 0 then we need to add 1506 // 1 to avoid assertion for zero size. We will subtract it back later. 1507 OutDIE->setSize(AttributesCloner.getOutOffset() + 1); 1508 } 1509 1510 return Entry; 1511 } 1512 1513 Error CompileUnit::cloneAndEmitLineTable(const Triple &TargetTriple) { 1514 const DWARFDebugLine::LineTable *InputLineTable = 1515 getContaingFile().Dwarf->getLineTableForUnit(&getOrigUnit()); 1516 if (InputLineTable == nullptr) { 1517 if (getOrigUnit().getUnitDIE().find(dwarf::DW_AT_stmt_list)) 1518 warn("cann't load line table."); 1519 return Error::success(); 1520 } 1521 1522 DWARFDebugLine::LineTable OutLineTable; 1523 1524 // Set Line Table header. 1525 OutLineTable.Prologue = InputLineTable->Prologue; 1526 OutLineTable.Prologue.FormParams.AddrSize = getFormParams().AddrSize; 1527 1528 // Set Line Table Rows. 1529 if (getGlobalData().getOptions().UpdateIndexTablesOnly) { 1530 OutLineTable.Rows = InputLineTable->Rows; 1531 // If all the line table contains is a DW_LNE_end_sequence, clear the line 1532 // table rows, it will be inserted again in the DWARFStreamer. 1533 if (OutLineTable.Rows.size() == 1 && OutLineTable.Rows[0].EndSequence) 1534 OutLineTable.Rows.clear(); 1535 1536 OutLineTable.Sequences = InputLineTable->Sequences; 1537 } else { 1538 // This vector is the output line table. 1539 std::vector<DWARFDebugLine::Row> NewRows; 1540 NewRows.reserve(InputLineTable->Rows.size()); 1541 1542 // Current sequence of rows being extracted, before being inserted 1543 // in NewRows. 1544 std::vector<DWARFDebugLine::Row> Seq; 1545 1546 const auto &FunctionRanges = getFunctionRanges(); 1547 std::optional<AddressRangeValuePair> CurrRange; 1548 1549 // FIXME: This logic is meant to generate exactly the same output as 1550 // Darwin's classic dsymutil. There is a nicer way to implement this 1551 // by simply putting all the relocated line info in NewRows and simply 1552 // sorting NewRows before passing it to emitLineTableForUnit. This 1553 // should be correct as sequences for a function should stay 1554 // together in the sorted output. There are a few corner cases that 1555 // look suspicious though, and that required to implement the logic 1556 // this way. Revisit that once initial validation is finished. 1557 1558 // Iterate over the object file line info and extract the sequences 1559 // that correspond to linked functions. 1560 for (DWARFDebugLine::Row Row : InputLineTable->Rows) { 1561 // Check whether we stepped out of the range. The range is 1562 // half-open, but consider accept the end address of the range if 1563 // it is marked as end_sequence in the input (because in that 1564 // case, the relocation offset is accurate and that entry won't 1565 // serve as the start of another function). 1566 if (!CurrRange || !CurrRange->Range.contains(Row.Address.Address)) { 1567 // We just stepped out of a known range. Insert a end_sequence 1568 // corresponding to the end of the range. 1569 uint64_t StopAddress = 1570 CurrRange ? CurrRange->Range.end() + CurrRange->Value : -1ULL; 1571 CurrRange = FunctionRanges.getRangeThatContains(Row.Address.Address); 1572 if (StopAddress != -1ULL && !Seq.empty()) { 1573 // Insert end sequence row with the computed end address, but 1574 // the same line as the previous one. 1575 auto NextLine = Seq.back(); 1576 NextLine.Address.Address = StopAddress; 1577 NextLine.EndSequence = 1; 1578 NextLine.PrologueEnd = 0; 1579 NextLine.BasicBlock = 0; 1580 NextLine.EpilogueBegin = 0; 1581 Seq.push_back(NextLine); 1582 insertLineSequence(Seq, NewRows); 1583 } 1584 1585 if (!CurrRange) 1586 continue; 1587 } 1588 1589 // Ignore empty sequences. 1590 if (Row.EndSequence && Seq.empty()) 1591 continue; 1592 1593 // Relocate row address and add it to the current sequence. 1594 Row.Address.Address += CurrRange->Value; 1595 Seq.emplace_back(Row); 1596 1597 if (Row.EndSequence) 1598 insertLineSequence(Seq, NewRows); 1599 } 1600 1601 OutLineTable.Rows = std::move(NewRows); 1602 } 1603 1604 return emitDebugLine(TargetTriple, OutLineTable); 1605 } 1606 1607 void CompileUnit::insertLineSequence(std::vector<DWARFDebugLine::Row> &Seq, 1608 std::vector<DWARFDebugLine::Row> &Rows) { 1609 if (Seq.empty()) 1610 return; 1611 1612 if (!Rows.empty() && Rows.back().Address < Seq.front().Address) { 1613 llvm::append_range(Rows, Seq); 1614 Seq.clear(); 1615 return; 1616 } 1617 1618 object::SectionedAddress Front = Seq.front().Address; 1619 auto InsertPoint = partition_point( 1620 Rows, [=](const DWARFDebugLine::Row &O) { return O.Address < Front; }); 1621 1622 // FIXME: this only removes the unneeded end_sequence if the 1623 // sequences have been inserted in order. Using a global sort like 1624 // described in cloneAndEmitLineTable() and delaying the end_sequene 1625 // elimination to DebugLineEmitter::emit() we can get rid of all of them. 1626 if (InsertPoint != Rows.end() && InsertPoint->Address == Front && 1627 InsertPoint->EndSequence) { 1628 *InsertPoint = Seq.front(); 1629 Rows.insert(InsertPoint + 1, Seq.begin() + 1, Seq.end()); 1630 } else { 1631 Rows.insert(InsertPoint, Seq.begin(), Seq.end()); 1632 } 1633 1634 Seq.clear(); 1635 } 1636 1637 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 1638 LLVM_DUMP_METHOD void CompileUnit::DIEInfo::dump() { 1639 llvm::errs() << "{"; 1640 llvm::errs() << " Placement: "; 1641 switch (getPlacement()) { 1642 case NotSet: 1643 llvm::errs() << "NotSet"; 1644 break; 1645 case TypeTable: 1646 llvm::errs() << "TypeTable"; 1647 break; 1648 case PlainDwarf: 1649 llvm::errs() << "PlainDwarf"; 1650 break; 1651 case Both: 1652 llvm::errs() << "Both"; 1653 break; 1654 } 1655 1656 llvm::errs() << " Keep: " << getKeep(); 1657 llvm::errs() << " KeepPlainChildren: " << getKeepPlainChildren(); 1658 llvm::errs() << " KeepTypeChildren: " << getKeepTypeChildren(); 1659 llvm::errs() << " IsInMouduleScope: " << getIsInMouduleScope(); 1660 llvm::errs() << " IsInFunctionScope: " << getIsInFunctionScope(); 1661 llvm::errs() << " IsInAnonNamespaceScope: " << getIsInAnonNamespaceScope(); 1662 llvm::errs() << " ODRAvailable: " << getODRAvailable(); 1663 llvm::errs() << " TrackLiveness: " << getTrackLiveness(); 1664 llvm::errs() << "}\n"; 1665 } 1666 #endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 1667 1668 std::optional<std::pair<StringRef, StringRef>> 1669 CompileUnit::getDirAndFilenameFromLineTable( 1670 const DWARFFormValue &FileIdxValue) { 1671 uint64_t FileIdx; 1672 if (std::optional<uint64_t> Val = FileIdxValue.getAsUnsignedConstant()) 1673 FileIdx = *Val; 1674 else if (std::optional<int64_t> Val = FileIdxValue.getAsSignedConstant()) 1675 FileIdx = *Val; 1676 else if (std::optional<uint64_t> Val = FileIdxValue.getAsSectionOffset()) 1677 FileIdx = *Val; 1678 else 1679 return std::nullopt; 1680 1681 return getDirAndFilenameFromLineTable(FileIdx); 1682 } 1683 1684 std::optional<std::pair<StringRef, StringRef>> 1685 CompileUnit::getDirAndFilenameFromLineTable(uint64_t FileIdx) { 1686 FileNamesCache::iterator FileData = FileNames.find(FileIdx); 1687 if (FileData != FileNames.end()) 1688 return std::make_pair(StringRef(FileData->second.first), 1689 StringRef(FileData->second.second)); 1690 1691 if (const DWARFDebugLine::LineTable *LineTable = 1692 getOrigUnit().getContext().getLineTableForUnit(&getOrigUnit())) { 1693 if (LineTable->hasFileAtIndex(FileIdx)) { 1694 1695 const llvm::DWARFDebugLine::FileNameEntry &Entry = 1696 LineTable->Prologue.getFileNameEntry(FileIdx); 1697 1698 Expected<const char *> Name = Entry.Name.getAsCString(); 1699 if (!Name) { 1700 warn(Name.takeError()); 1701 return std::nullopt; 1702 } 1703 1704 std::string FileName = *Name; 1705 if (isPathAbsoluteOnWindowsOrPosix(FileName)) { 1706 FileNamesCache::iterator FileData = 1707 FileNames 1708 .insert(std::make_pair( 1709 FileIdx, 1710 std::make_pair(std::string(""), std::move(FileName)))) 1711 .first; 1712 return std::make_pair(StringRef(FileData->second.first), 1713 StringRef(FileData->second.second)); 1714 } 1715 1716 SmallString<256> FilePath; 1717 StringRef IncludeDir; 1718 // Be defensive about the contents of Entry. 1719 if (getVersion() >= 5) { 1720 // DirIdx 0 is the compilation directory, so don't include it for 1721 // relative names. 1722 if ((Entry.DirIdx != 0) && 1723 Entry.DirIdx < LineTable->Prologue.IncludeDirectories.size()) { 1724 Expected<const char *> DirName = 1725 LineTable->Prologue.IncludeDirectories[Entry.DirIdx] 1726 .getAsCString(); 1727 if (DirName) 1728 IncludeDir = *DirName; 1729 else { 1730 warn(DirName.takeError()); 1731 return std::nullopt; 1732 } 1733 } 1734 } else { 1735 if (0 < Entry.DirIdx && 1736 Entry.DirIdx <= LineTable->Prologue.IncludeDirectories.size()) { 1737 Expected<const char *> DirName = 1738 LineTable->Prologue.IncludeDirectories[Entry.DirIdx - 1] 1739 .getAsCString(); 1740 if (DirName) 1741 IncludeDir = *DirName; 1742 else { 1743 warn(DirName.takeError()); 1744 return std::nullopt; 1745 } 1746 } 1747 } 1748 1749 StringRef CompDir = getOrigUnit().getCompilationDir(); 1750 1751 if (!CompDir.empty() && !isPathAbsoluteOnWindowsOrPosix(IncludeDir)) { 1752 sys::path::append(FilePath, sys::path::Style::native, CompDir); 1753 } 1754 1755 sys::path::append(FilePath, sys::path::Style::native, IncludeDir); 1756 1757 FileNamesCache::iterator FileData = 1758 FileNames 1759 .insert( 1760 std::make_pair(FileIdx, std::make_pair(std::string(FilePath), 1761 std::move(FileName)))) 1762 .first; 1763 return std::make_pair(StringRef(FileData->second.first), 1764 StringRef(FileData->second.second)); 1765 } 1766 } 1767 1768 return std::nullopt; 1769 } 1770 1771 #define MAX_REFERENCIES_DEPTH 1000 1772 UnitEntryPairTy UnitEntryPairTy::getNamespaceOrigin() { 1773 UnitEntryPairTy CUDiePair(*this); 1774 std::optional<UnitEntryPairTy> RefDiePair; 1775 int refDepth = 0; 1776 do { 1777 RefDiePair = CUDiePair.CU->resolveDIEReference( 1778 CUDiePair.DieEntry, dwarf::DW_AT_extension, 1779 ResolveInterCUReferencesMode::Resolve); 1780 if (!RefDiePair || !RefDiePair->DieEntry) 1781 return CUDiePair; 1782 1783 CUDiePair = *RefDiePair; 1784 } while (refDepth++ < MAX_REFERENCIES_DEPTH); 1785 1786 return CUDiePair; 1787 } 1788 1789 std::optional<UnitEntryPairTy> UnitEntryPairTy::getParent() { 1790 if (std::optional<uint32_t> ParentIdx = DieEntry->getParentIdx()) 1791 return UnitEntryPairTy{CU, CU->getDebugInfoEntry(*ParentIdx)}; 1792 1793 return std::nullopt; 1794 } 1795 1796 CompileUnit::OutputUnitVariantPtr::OutputUnitVariantPtr(CompileUnit *U) 1797 : Ptr(U) { 1798 assert(U != nullptr); 1799 } 1800 1801 CompileUnit::OutputUnitVariantPtr::OutputUnitVariantPtr(TypeUnit *U) : Ptr(U) { 1802 assert(U != nullptr); 1803 } 1804 1805 DwarfUnit *CompileUnit::OutputUnitVariantPtr::operator->() { 1806 if (isCompileUnit()) 1807 return getAsCompileUnit(); 1808 else 1809 return getAsTypeUnit(); 1810 } 1811 1812 bool CompileUnit::OutputUnitVariantPtr::isCompileUnit() { 1813 return isa<CompileUnit *>(Ptr); 1814 } 1815 1816 bool CompileUnit::OutputUnitVariantPtr::isTypeUnit() { 1817 return isa<TypeUnit *>(Ptr); 1818 } 1819 1820 CompileUnit *CompileUnit::OutputUnitVariantPtr::getAsCompileUnit() { 1821 return cast<CompileUnit *>(Ptr); 1822 } 1823 1824 TypeUnit *CompileUnit::OutputUnitVariantPtr::getAsTypeUnit() { 1825 return cast<TypeUnit *>(Ptr); 1826 } 1827 1828 bool CompileUnit::resolveDependenciesAndMarkLiveness( 1829 bool InterCUProcessingStarted, std::atomic<bool> &HasNewInterconnectedCUs) { 1830 if (!Dependencies) 1831 Dependencies.reset(new DependencyTracker(*this)); 1832 1833 return Dependencies->resolveDependenciesAndMarkLiveness( 1834 InterCUProcessingStarted, HasNewInterconnectedCUs); 1835 } 1836 1837 bool CompileUnit::updateDependenciesCompleteness() { 1838 assert(Dependencies.get()); 1839 1840 return Dependencies->updateDependenciesCompleteness(); 1841 } 1842 1843 void CompileUnit::verifyDependencies() { 1844 assert(Dependencies.get()); 1845 1846 Dependencies->verifyKeepChain(); 1847 } 1848 1849 ArrayRef<dwarf::Attribute> dwarf_linker::parallel::getODRAttributes() { 1850 static dwarf::Attribute ODRAttributes[] = { 1851 dwarf::DW_AT_type, dwarf::DW_AT_specification, 1852 dwarf::DW_AT_abstract_origin, dwarf::DW_AT_import}; 1853 1854 return ODRAttributes; 1855 } 1856