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