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