1 //===- bolt/Rewrite/DWARFRewriter.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 "bolt/Rewrite/DWARFRewriter.h" 10 #include "bolt/Core/BinaryContext.h" 11 #include "bolt/Core/BinaryFunction.h" 12 #include "bolt/Core/DebugData.h" 13 #include "bolt/Core/ParallelUtilities.h" 14 #include "bolt/Rewrite/RewriteInstance.h" 15 #include "bolt/Utils/Utils.h" 16 #include "llvm/ADT/STLExtras.h" 17 #include "llvm/BinaryFormat/Dwarf.h" 18 #include "llvm/DWP/DWP.h" 19 #include "llvm/DebugInfo/DWARF/DWARFContext.h" 20 #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h" 21 #include "llvm/DebugInfo/DWARF/DWARFExpression.h" 22 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h" 23 #include "llvm/MC/MCAsmBackend.h" 24 #include "llvm/MC/MCAsmLayout.h" 25 #include "llvm/MC/MCContext.h" 26 #include "llvm/MC/MCObjectWriter.h" 27 #include "llvm/MC/MCStreamer.h" 28 #include "llvm/Object/ObjectFile.h" 29 #include "llvm/Support/Casting.h" 30 #include "llvm/Support/CommandLine.h" 31 #include "llvm/Support/Debug.h" 32 #include "llvm/Support/Endian.h" 33 #include "llvm/Support/Error.h" 34 #include "llvm/Support/FileSystem.h" 35 #include "llvm/Support/LEB128.h" 36 #include "llvm/Support/ThreadPool.h" 37 #include "llvm/Support/ToolOutputFile.h" 38 #include <algorithm> 39 #include <cstdint> 40 #include <string> 41 #include <unordered_map> 42 #include <utility> 43 #include <vector> 44 45 #undef DEBUG_TYPE 46 #define DEBUG_TYPE "bolt" 47 48 LLVM_ATTRIBUTE_UNUSED 49 static void printDie(const DWARFDie &DIE) { 50 DIDumpOptions DumpOpts; 51 DumpOpts.ShowForm = true; 52 DumpOpts.Verbose = true; 53 DumpOpts.ChildRecurseDepth = 0; 54 DumpOpts.ShowChildren = 0; 55 DIE.dump(dbgs(), 0, DumpOpts); 56 } 57 58 namespace llvm { 59 namespace bolt { 60 /// Finds attributes FormValue and Offset. 61 /// 62 /// \param DIE die to look up in. 63 /// \param Attr the attribute to extract. 64 /// \return an optional AttrInfo with DWARFFormValue and Offset. 65 static Optional<AttrInfo> findAttributeInfo(const DWARFDie DIE, 66 dwarf::Attribute Attr) { 67 if (!DIE.isValid()) 68 return None; 69 const DWARFAbbreviationDeclaration *AbbrevDecl = 70 DIE.getAbbreviationDeclarationPtr(); 71 if (!AbbrevDecl) 72 return None; 73 Optional<uint32_t> Index = AbbrevDecl->findAttributeIndex(Attr); 74 if (!Index) 75 return None; 76 return findAttributeInfo(DIE, AbbrevDecl, *Index); 77 } 78 79 /// Finds attributes FormValue and Offset. 80 /// 81 /// \param DIE die to look up in. 82 /// \param Attrs finds the first attribute that matches and extracts it. 83 /// \return an optional AttrInfo with DWARFFormValue and Offset. 84 Optional<AttrInfo> findAttributeInfo(const DWARFDie DIE, 85 std::vector<dwarf::Attribute> Attrs) { 86 for (dwarf::Attribute &Attr : Attrs) 87 if (Optional<AttrInfo> Info = findAttributeInfo(DIE, Attr)) 88 return Info; 89 return None; 90 } 91 } // namespace bolt 92 } // namespace llvm 93 94 using namespace llvm; 95 using namespace llvm::support::endian; 96 using namespace object; 97 using namespace bolt; 98 99 namespace opts { 100 101 extern cl::OptionCategory BoltCategory; 102 extern cl::opt<unsigned> Verbosity; 103 extern cl::opt<std::string> OutputFilename; 104 105 static cl::opt<bool> KeepARanges( 106 "keep-aranges", 107 cl::desc( 108 "keep or generate .debug_aranges section if .gdb_index is written"), 109 cl::Hidden, cl::cat(BoltCategory)); 110 111 static cl::opt<bool> 112 DeterministicDebugInfo("deterministic-debuginfo", 113 cl::desc("disables parallel execution of tasks that may produce" 114 "nondeterministic debug info"), 115 cl::init(true), 116 cl::cat(BoltCategory)); 117 118 static cl::opt<std::string> DwarfOutputPath( 119 "dwarf-output-path", 120 cl::desc("Path to where .dwo files or dwp file will be written out to."), 121 cl::init(""), cl::cat(BoltCategory)); 122 123 static cl::opt<bool> 124 WriteDWP("write-dwp", 125 cl::desc("output a single dwarf package file (dwp) instead of " 126 "multiple non-relocatable dwarf object files (dwo)."), 127 cl::init(false), cl::cat(BoltCategory)); 128 129 static cl::opt<bool> 130 DebugSkeletonCu("debug-skeleton-cu", 131 cl::desc("prints out offsetrs for abbrev and debu_info of " 132 "Skeleton CUs that get patched."), 133 cl::ZeroOrMore, cl::Hidden, cl::init(false), 134 cl::cat(BoltCategory)); 135 } // namespace opts 136 137 /// Returns DWO Name to be used. Handles case where user specifies output DWO 138 /// directory, and there are duplicate names. Assumes DWO ID is unique. 139 static std::string 140 getDWOName(llvm::DWARFUnit &CU, 141 std::unordered_map<std::string, uint32_t> *NameToIndexMap, 142 std::unordered_map<uint64_t, std::string> &DWOIdToName) { 143 llvm::Optional<uint64_t> DWOId = CU.getDWOId(); 144 assert(DWOId && "DWO ID not found."); 145 (void)DWOId; 146 auto NameIter = DWOIdToName.find(*DWOId); 147 if (NameIter != DWOIdToName.end()) 148 return NameIter->second; 149 150 std::string DWOName = dwarf::toString( 151 CU.getUnitDIE().find({dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name}), 152 ""); 153 assert(!DWOName.empty() && 154 "DW_AT_dwo_name/DW_AT_GNU_dwo_name does not exists."); 155 if (NameToIndexMap && !opts::DwarfOutputPath.empty()) { 156 auto Iter = NameToIndexMap->find(DWOName); 157 if (Iter == NameToIndexMap->end()) 158 Iter = NameToIndexMap->insert({DWOName, 0}).first; 159 DWOName.append(std::to_string(Iter->second)); 160 ++Iter->second; 161 } 162 DWOName.append(".dwo"); 163 DWOIdToName[*DWOId] = DWOName; 164 return DWOName; 165 } 166 167 void DWARFRewriter::addStringHelper(DebugInfoBinaryPatcher &DebugInfoPatcher, 168 const DWARFUnit &Unit, 169 const AttrInfo &AttrInfoVal, 170 StringRef Str) { 171 uint32_t NewOffset = StrWriter->addString(Str); 172 if (Unit.getVersion() == 5) { 173 StrOffstsWriter->updateAddressMap(AttrInfoVal.V.getRawUValue(), NewOffset); 174 return; 175 } 176 DebugInfoPatcher.addLE32Patch(AttrInfoVal.Offset, NewOffset, 177 AttrInfoVal.Size); 178 } 179 180 void DWARFRewriter::updateDebugInfo() { 181 ErrorOr<BinarySection &> DebugInfo = BC.getUniqueSectionByName(".debug_info"); 182 if (!DebugInfo) 183 return; 184 185 auto *DebugInfoPatcher = 186 static_cast<DebugInfoBinaryPatcher *>(DebugInfo->getPatcher()); 187 188 ARangesSectionWriter = std::make_unique<DebugARangesSectionWriter>(); 189 StrWriter = std::make_unique<DebugStrWriter>(BC); 190 191 StrOffstsWriter = std::make_unique<DebugStrOffsetsWriter>(); 192 193 AbbrevWriter = std::make_unique<DebugAbbrevWriter>(*BC.DwCtx); 194 195 if (BC.isDWARF5Used()) { 196 // Disabling none deterministic mode for dwarf5, to keep implementation 197 // simpler. 198 opts::DeterministicDebugInfo = true; 199 AddrWriter = std::make_unique<DebugAddrWriterDwarf5>(&BC); 200 RangesSectionWriter = std::make_unique<DebugRangeListsSectionWriter>(); 201 DebugRangeListsSectionWriter::setAddressWriter(AddrWriter.get()); 202 } else { 203 AddrWriter = std::make_unique<DebugAddrWriter>(&BC); 204 RangesSectionWriter = std::make_unique<DebugRangesSectionWriter>(); 205 } 206 207 DebugLoclistWriter::setAddressWriter(AddrWriter.get()); 208 209 size_t CUIndex = 0; 210 for (std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units()) { 211 const uint16_t DwarfVersion = CU->getVersion(); 212 if (DwarfVersion >= 5) { 213 uint32_t AttrInfoOffset = 214 DebugLoclistWriter::InvalidLocListsBaseAttrOffset; 215 if (Optional<AttrInfo> AttrInfoVal = 216 findAttributeInfo(CU->getUnitDIE(), dwarf::DW_AT_loclists_base)) { 217 AttrInfoOffset = AttrInfoVal->Offset; 218 LocListWritersByCU[CUIndex] = std::make_unique<DebugLoclistWriter>( 219 &BC, *CU.get(), AttrInfoOffset, DwarfVersion, false); 220 } 221 if (Optional<uint64_t> DWOId = CU->getDWOId()) { 222 assert(LocListWritersByCU.count(*DWOId) == 0 && 223 "RangeLists writer for DWO unit already exists."); 224 auto RangeListsSectionWriter = 225 std::make_unique<DebugRangeListsSectionWriter>(); 226 RangeListsSectionWriter->initSection(*CU.get()); 227 RangeListsWritersByCU[*DWOId] = std::move(RangeListsSectionWriter); 228 } 229 230 } else { 231 LocListWritersByCU[CUIndex] = std::make_unique<DebugLocWriter>(&BC); 232 } 233 234 if (Optional<uint64_t> DWOId = CU->getDWOId()) { 235 assert(LocListWritersByCU.count(*DWOId) == 0 && 236 "LocList writer for DWO unit already exists."); 237 // Work around some bug in llvm-15. If I pass in directly lld reports 238 // undefined symbol. 239 auto constexpr WorkAround = 240 DebugLoclistWriter::InvalidLocListsBaseAttrOffset; 241 LocListWritersByCU[*DWOId] = std::make_unique<DebugLoclistWriter>( 242 &BC, *CU.get(), WorkAround, DwarfVersion, true); 243 } 244 ++CUIndex; 245 } 246 247 // Unordered maps to handle name collision if output DWO directory is 248 // specified. 249 std::unordered_map<std::string, uint32_t> NameToIndexMap; 250 std::unordered_map<uint64_t, std::string> DWOIdToName; 251 std::mutex AccessMutex; 252 253 auto updateDWONameCompDir = [&](DWARFUnit &Unit) -> void { 254 const DWARFDie &DIE = Unit.getUnitDIE(); 255 Optional<AttrInfo> AttrInfoVal = findAttributeInfo( 256 DIE, {dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name}); 257 (void)AttrInfoVal; 258 assert(AttrInfoVal && "Skeleton CU doesn't have dwo_name."); 259 260 std::string ObjectName = ""; 261 262 { 263 std::lock_guard<std::mutex> Lock(AccessMutex); 264 ObjectName = getDWOName(Unit, &NameToIndexMap, DWOIdToName); 265 } 266 addStringHelper(*DebugInfoPatcher, Unit, *AttrInfoVal, ObjectName.c_str()); 267 268 AttrInfoVal = findAttributeInfo(DIE, dwarf::DW_AT_comp_dir); 269 (void)AttrInfoVal; 270 assert(AttrInfoVal && "DW_AT_comp_dir is not in Skeleton CU."); 271 272 if (!opts::DwarfOutputPath.empty()) { 273 addStringHelper(*DebugInfoPatcher, Unit, *AttrInfoVal, 274 opts::DwarfOutputPath.c_str()); 275 } 276 }; 277 278 auto processUnitDIE = [&](size_t CUIndex, DWARFUnit *Unit) { 279 // Check if the unit is a skeleton and we need special updates for it and 280 // its matching split/DWO CU. 281 Optional<DWARFUnit *> SplitCU; 282 Optional<uint64_t> RangesBase; 283 llvm::Optional<uint64_t> DWOId = Unit->getDWOId(); 284 StrOffstsWriter->initialize(Unit->getStringOffsetSection(), 285 Unit->getStringOffsetsTableContribution()); 286 if (DWOId) 287 SplitCU = BC.getDWOCU(*DWOId); 288 289 DebugLocWriter *DebugLocWriter = nullptr; 290 // Skipping CUs that failed to load. 291 if (SplitCU) { 292 updateDWONameCompDir(*Unit); 293 294 DebugInfoBinaryPatcher *DwoDebugInfoPatcher = 295 llvm::cast<DebugInfoBinaryPatcher>( 296 getBinaryDWODebugInfoPatcher(*DWOId)); 297 DWARFContext *DWOCtx = BC.getDWOContext(); 298 // Setting this CU offset with DWP to normalize DIE offsets to uint32_t 299 if (DWOCtx && !DWOCtx->getCUIndex().getRows().empty()) 300 DwoDebugInfoPatcher->setDWPOffset((*SplitCU)->getOffset()); 301 302 { 303 std::lock_guard<std::mutex> Lock(AccessMutex); 304 DebugLocWriter = LocListWritersByCU[*DWOId].get(); 305 } 306 DebugRangesSectionWriter *TempRangesSectionWriter = 307 RangesSectionWriter.get(); 308 if (Unit->getVersion() >= 5) { 309 TempRangesSectionWriter = RangeListsWritersByCU[*DWOId].get(); 310 } else { 311 RangesBase = RangesSectionWriter->getSectionOffset(); 312 // For DWARF5 there is now .debug_rnglists.dwo, so don't need to 313 // update rnglists base. 314 DwoDebugInfoPatcher->setRangeBase(*RangesBase); 315 } 316 317 DwoDebugInfoPatcher->addUnitBaseOffsetLabel((*SplitCU)->getOffset()); 318 DebugAbbrevWriter *DWOAbbrevWriter = 319 createBinaryDWOAbbrevWriter((*SplitCU)->getContext(), *DWOId); 320 updateUnitDebugInfo(*(*SplitCU), *DwoDebugInfoPatcher, *DWOAbbrevWriter, 321 *DebugLocWriter, *TempRangesSectionWriter); 322 DwoDebugInfoPatcher->clearDestinationLabels(); 323 if (!DwoDebugInfoPatcher->getWasRangBasedUsed()) 324 RangesBase = None; 325 if (Unit->getVersion() >= 5) 326 TempRangesSectionWriter->finalizeSection(); 327 } 328 329 { 330 std::lock_guard<std::mutex> Lock(AccessMutex); 331 auto LocListWriterIter = LocListWritersByCU.find(CUIndex); 332 if (LocListWriterIter != LocListWritersByCU.end()) 333 DebugLocWriter = LocListWriterIter->second.get(); 334 } 335 if (Unit->getVersion() >= 5) { 336 RangesBase = RangesSectionWriter->getSectionOffset() + 337 getDWARF5RngListLocListHeaderSize(); 338 RangesSectionWriter.get()->initSection(*Unit); 339 StrOffstsWriter->finalizeSection(); 340 } 341 342 DebugInfoPatcher->addUnitBaseOffsetLabel(Unit->getOffset()); 343 updateUnitDebugInfo(*Unit, *DebugInfoPatcher, *AbbrevWriter, 344 *DebugLocWriter, *RangesSectionWriter, RangesBase); 345 if (Unit->getVersion() >= 5) 346 RangesSectionWriter.get()->finalizeSection(); 347 }; 348 349 CUIndex = 0; 350 if (opts::NoThreads || opts::DeterministicDebugInfo) { 351 for (std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units()) { 352 processUnitDIE(CUIndex, CU.get()); 353 if (CU->getVersion() >= 5) 354 ++CUIndex; 355 } 356 } else { 357 // Update unit debug info in parallel 358 ThreadPool &ThreadPool = ParallelUtilities::getThreadPool(); 359 for (std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units()) { 360 ThreadPool.async(processUnitDIE, CUIndex, CU.get()); 361 CUIndex++; 362 } 363 ThreadPool.wait(); 364 } 365 366 DebugInfoPatcher->clearDestinationLabels(); 367 CUOffsetMap OffsetMap = finalizeDebugSections(*DebugInfoPatcher); 368 369 if (opts::WriteDWP) 370 writeDWP(DWOIdToName); 371 else 372 writeDWOFiles(DWOIdToName); 373 374 updateGdbIndexSection(OffsetMap); 375 } 376 377 void DWARFRewriter::updateUnitDebugInfo( 378 DWARFUnit &Unit, DebugInfoBinaryPatcher &DebugInfoPatcher, 379 DebugAbbrevWriter &AbbrevWriter, DebugLocWriter &DebugLocWriter, 380 DebugRangesSectionWriter &RangesSectionWriter, 381 Optional<uint64_t> RangesBase) { 382 // Cache debug ranges so that the offset for identical ranges could be reused. 383 std::map<DebugAddressRangesVector, uint64_t> CachedRanges; 384 385 uint64_t DIEOffset = Unit.getOffset() + Unit.getHeaderSize(); 386 uint64_t NextCUOffset = Unit.getNextUnitOffset(); 387 DWARFDebugInfoEntry Die; 388 DWARFDataExtractor DebugInfoData = Unit.getDebugInfoExtractor(); 389 uint32_t Depth = 0; 390 391 bool IsDWP = false; 392 if (DWARFContext *DWOCtx = BC.getDWOContext()) 393 IsDWP = !DWOCtx->getCUIndex().getRows().empty(); 394 395 while ( 396 DIEOffset < NextCUOffset && 397 Die.extractFast(Unit, &DIEOffset, DebugInfoData, NextCUOffset, Depth)) { 398 if (const DWARFAbbreviationDeclaration *AbbrDecl = 399 Die.getAbbreviationDeclarationPtr()) { 400 if (AbbrDecl->hasChildren()) 401 ++Depth; 402 } else { 403 // NULL entry. 404 if (Depth > 0) 405 --Depth; 406 if (Depth == 0) 407 break; 408 } 409 410 DWARFDie DIE(&Unit, &Die); 411 412 switch (DIE.getTag()) { 413 case dwarf::DW_TAG_compile_unit: 414 case dwarf::DW_TAG_skeleton_unit: { 415 // For dwarf5 section 3.1.3 416 // The following attributes are not part of a split full compilation unit 417 // entry but instead are inherited (if present) from the corresponding 418 // skeleton compilation unit: DW_AT_low_pc, DW_AT_high_pc, DW_AT_ranges, 419 // DW_AT_stmt_list, DW_AT_comp_dir, DW_AT_str_offsets_base, 420 // DW_AT_addr_base and DW_AT_rnglists_base. 421 if (Unit.getVersion() == 5 && Unit.isDWOUnit()) 422 continue; 423 auto ModuleRangesOrError = DIE.getAddressRanges(); 424 if (!ModuleRangesOrError) { 425 consumeError(ModuleRangesOrError.takeError()); 426 break; 427 } 428 DWARFAddressRangesVector &ModuleRanges = *ModuleRangesOrError; 429 DebugAddressRangesVector OutputRanges = 430 BC.translateModuleAddressRanges(ModuleRanges); 431 const uint64_t RangesSectionOffset = 432 RangesSectionWriter.addRanges(OutputRanges); 433 if (!Unit.isDWOUnit()) 434 ARangesSectionWriter->addCURanges(Unit.getOffset(), 435 std::move(OutputRanges)); 436 updateDWARFObjectAddressRanges(DIE, RangesSectionOffset, DebugInfoPatcher, 437 AbbrevWriter, RangesBase); 438 break; 439 } 440 case dwarf::DW_TAG_subprogram: { 441 // Get function address either from ranges or [LowPC, HighPC) pair. 442 uint64_t Address; 443 uint64_t SectionIndex, HighPC; 444 if (!DIE.getLowAndHighPC(Address, HighPC, SectionIndex)) { 445 Expected<DWARFAddressRangesVector> RangesOrError = 446 DIE.getAddressRanges(); 447 if (!RangesOrError) { 448 consumeError(RangesOrError.takeError()); 449 break; 450 } 451 DWARFAddressRangesVector Ranges = *RangesOrError; 452 // Not a function definition. 453 if (Ranges.empty()) 454 break; 455 456 Address = Ranges.front().LowPC; 457 } 458 459 // Clear cached ranges as the new function will have its own set. 460 CachedRanges.clear(); 461 462 DebugAddressRangesVector FunctionRanges; 463 if (const BinaryFunction *Function = 464 BC.getBinaryFunctionAtAddress(Address)) 465 FunctionRanges = Function->getOutputAddressRanges(); 466 467 if (FunctionRanges.empty()) 468 FunctionRanges.push_back({0, 0}); 469 470 updateDWARFObjectAddressRanges( 471 DIE, RangesSectionWriter.addRanges(FunctionRanges), DebugInfoPatcher, 472 AbbrevWriter); 473 474 break; 475 } 476 case dwarf::DW_TAG_lexical_block: 477 case dwarf::DW_TAG_inlined_subroutine: 478 case dwarf::DW_TAG_try_block: 479 case dwarf::DW_TAG_catch_block: { 480 uint64_t RangesSectionOffset = RangesSectionWriter.getEmptyRangesOffset(); 481 Expected<DWARFAddressRangesVector> RangesOrError = DIE.getAddressRanges(); 482 const BinaryFunction *Function = 483 RangesOrError && !RangesOrError->empty() 484 ? BC.getBinaryFunctionContainingAddress( 485 RangesOrError->front().LowPC) 486 : nullptr; 487 if (Function) { 488 DebugAddressRangesVector OutputRanges = 489 Function->translateInputToOutputRanges(*RangesOrError); 490 LLVM_DEBUG(if (OutputRanges.empty() != RangesOrError->empty()) { 491 dbgs() << "BOLT-DEBUG: problem with DIE at 0x" 492 << Twine::utohexstr(DIE.getOffset()) << " in CU at 0x" 493 << Twine::utohexstr(Unit.getOffset()) << '\n'; 494 }); 495 RangesSectionOffset = RangesSectionWriter.addRanges( 496 std::move(OutputRanges), CachedRanges); 497 } else if (!RangesOrError) { 498 consumeError(RangesOrError.takeError()); 499 } 500 updateDWARFObjectAddressRanges(DIE, RangesSectionOffset, DebugInfoPatcher, 501 AbbrevWriter); 502 break; 503 } 504 default: { 505 // Handle any tag that can have DW_AT_location attribute. 506 DWARFFormValue Value; 507 uint64_t AttrOffset; 508 if (Optional<AttrInfo> AttrVal = 509 findAttributeInfo(DIE, dwarf::DW_AT_location)) { 510 AttrOffset = AttrVal->Offset; 511 Value = AttrVal->V; 512 if (Value.isFormClass(DWARFFormValue::FC_Constant) || 513 Value.isFormClass(DWARFFormValue::FC_SectionOffset)) { 514 uint64_t Offset = Value.isFormClass(DWARFFormValue::FC_Constant) 515 ? Value.getAsUnsignedConstant().getValue() 516 : Value.getAsSectionOffset().getValue(); 517 DebugLocationsVector InputLL; 518 519 Optional<object::SectionedAddress> SectionAddress = 520 Unit.getBaseAddress(); 521 uint64_t BaseAddress = 0; 522 if (SectionAddress) 523 BaseAddress = SectionAddress->Address; 524 525 if (Unit.getVersion() >= 5) { 526 Optional<uint64_t> LocOffset = Unit.getLoclistOffset(Offset); 527 assert(LocOffset && "Location Offset is invalid."); 528 Offset = *LocOffset; 529 } 530 531 Error E = Unit.getLocationTable().visitLocationList( 532 &Offset, [&](const DWARFLocationEntry &Entry) { 533 switch (Entry.Kind) { 534 default: 535 llvm_unreachable("Unsupported DWARFLocationEntry Kind."); 536 case dwarf::DW_LLE_end_of_list: 537 return false; 538 case dwarf::DW_LLE_base_address: { 539 assert(Entry.SectionIndex == SectionedAddress::UndefSection && 540 "absolute address expected"); 541 BaseAddress = Entry.Value0; 542 break; 543 } 544 case dwarf::DW_LLE_offset_pair: 545 assert( 546 (Entry.SectionIndex == SectionedAddress::UndefSection && 547 (!Unit.isDWOUnit() || Unit.getVersion() == 5)) && 548 "absolute address expected"); 549 InputLL.emplace_back(DebugLocationEntry{ 550 BaseAddress + Entry.Value0, BaseAddress + Entry.Value1, 551 Entry.Loc}); 552 break; 553 case dwarf::DW_RLE_start_length: 554 InputLL.emplace_back(DebugLocationEntry{ 555 Entry.Value0, Entry.Value0 + Entry.Value1, Entry.Loc}); 556 break; 557 case dwarf::DW_LLE_base_addressx: { 558 Optional<object::SectionedAddress> EntryAddress = 559 Unit.getAddrOffsetSectionItem(Entry.Value0); 560 assert(EntryAddress && "base Address not found."); 561 BaseAddress = EntryAddress->Address; 562 break; 563 } 564 case dwarf::DW_LLE_startx_length: { 565 Optional<object::SectionedAddress> EntryAddress = 566 Unit.getAddrOffsetSectionItem(Entry.Value0); 567 assert(EntryAddress && "Address does not exist."); 568 InputLL.emplace_back(DebugLocationEntry{ 569 EntryAddress->Address, 570 EntryAddress->Address + Entry.Value1, Entry.Loc}); 571 break; 572 } 573 case dwarf::DW_LLE_startx_endx: { 574 Optional<object::SectionedAddress> StartAddress = 575 Unit.getAddrOffsetSectionItem(Entry.Value0); 576 assert(StartAddress && "Start Address does not exist."); 577 Optional<object::SectionedAddress> EndAddress = 578 Unit.getAddrOffsetSectionItem(Entry.Value1); 579 assert(EndAddress && "Start Address does not exist."); 580 InputLL.emplace_back(DebugLocationEntry{ 581 StartAddress->Address, EndAddress->Address, Entry.Loc}); 582 break; 583 } 584 } 585 return true; 586 }); 587 588 if (E || InputLL.empty()) { 589 consumeError(std::move(E)); 590 errs() << "BOLT-WARNING: empty location list detected at 0x" 591 << Twine::utohexstr(Offset) << " for DIE at 0x" 592 << Twine::utohexstr(DIE.getOffset()) << " in CU at 0x" 593 << Twine::utohexstr(Unit.getOffset()) << '\n'; 594 } else { 595 const uint64_t Address = InputLL.front().LowPC; 596 DebugLocationsVector OutputLL; 597 if (const BinaryFunction *Function = 598 BC.getBinaryFunctionContainingAddress(Address)) { 599 OutputLL = Function->translateInputToOutputLocationList(InputLL); 600 LLVM_DEBUG(if (OutputLL.empty()) { 601 dbgs() << "BOLT-DEBUG: location list translated to an empty " 602 "one at 0x" 603 << Twine::utohexstr(DIE.getOffset()) << " in CU at 0x" 604 << Twine::utohexstr(Unit.getOffset()) << '\n'; 605 }); 606 } else { 607 // It's possible for a subprogram to be removed and to have 608 // address of 0. Adding this entry to output to preserve debug 609 // information. 610 OutputLL = InputLL; 611 } 612 uint32_t LocListIndex = 0; 613 dwarf::Form Form = Value.getForm(); 614 if (Form == dwarf::DW_FORM_sec_offset || 615 Form == dwarf::DW_FORM_data4) { 616 // For DWARF5 we can access location list entry either using 617 // index, or offset. If it's offset, then it's from begnning of 618 // the file. This implementation was before we could add entries 619 // to the DIE. For DWARF4 this is no-op. 620 // TODO: For DWARF5 convert all the offset based entries to index 621 // based, and insert loclist_base if necessary. 622 LocListIndex = DebugLoclistWriter::InvalidIndex; 623 } else if (Form == dwarf::DW_FORM_loclistx) { 624 LocListIndex = Value.getRawUValue(); 625 } else { 626 llvm_unreachable("Unsupported LocList access Form."); 627 } 628 DebugLocWriter.addList(AttrOffset, LocListIndex, 629 std::move(OutputLL)); 630 } 631 } else { 632 assert((Value.isFormClass(DWARFFormValue::FC_Exprloc) || 633 Value.isFormClass(DWARFFormValue::FC_Block)) && 634 "unexpected DW_AT_location form"); 635 if (Unit.isDWOUnit() || Unit.getVersion() >= 5) { 636 ArrayRef<uint8_t> Expr = *Value.getAsBlock(); 637 DataExtractor Data( 638 StringRef((const char *)Expr.data(), Expr.size()), 639 Unit.getContext().isLittleEndian(), 0); 640 DWARFExpression LocExpr(Data, Unit.getAddressByteSize(), 641 Unit.getFormParams().Format); 642 uint32_t PrevOffset = 0; 643 constexpr uint32_t SizeOfOpcode = 1; 644 constexpr uint32_t SizeOfForm = 1; 645 for (auto &Expr : LocExpr) { 646 if (!(Expr.getCode() == dwarf::DW_OP_GNU_addr_index || 647 Expr.getCode() == dwarf::DW_OP_addrx)) 648 continue; 649 650 const uint64_t Index = Expr.getRawOperand(0); 651 Optional<object::SectionedAddress> EntryAddress = 652 Unit.getAddrOffsetSectionItem(Index); 653 assert(EntryAddress && "Address is not found."); 654 assert(Index <= std::numeric_limits<uint32_t>::max() && 655 "Invalid Operand Index."); 656 if (Expr.getCode() == dwarf::DW_OP_addrx) { 657 const uint32_t EncodingSize = 658 Expr.getOperandEndOffset(0) - PrevOffset - SizeOfOpcode; 659 const uint32_t Index = AddrWriter->getIndexFromAddress( 660 EntryAddress->Address, Unit); 661 // Encoding new size. 662 SmallString<8> Tmp; 663 raw_svector_ostream OSE(Tmp); 664 encodeULEB128(Index, OSE); 665 DebugInfoPatcher.addUDataPatch(AttrOffset, Tmp.size() + 1, 1); 666 DebugInfoPatcher.addUDataPatch(AttrOffset + PrevOffset + 667 SizeOfOpcode + SizeOfForm, 668 Index, EncodingSize); 669 } else { 670 // TODO: Re-do this as DWARF5. 671 AddrWriter->addIndexAddress(EntryAddress->Address, 672 static_cast<uint32_t>(Index), Unit); 673 } 674 if (Expr.getDescription().Op[1] == 675 DWARFExpression::Operation::SizeNA) 676 PrevOffset = Expr.getOperandEndOffset(0); 677 else 678 PrevOffset = Expr.getOperandEndOffset(1); 679 } 680 } 681 } 682 } else if (Optional<AttrInfo> AttrVal = 683 findAttributeInfo(DIE, dwarf::DW_AT_low_pc)) { 684 AttrOffset = AttrVal->Offset; 685 Value = AttrVal->V; 686 const Optional<uint64_t> Result = Value.getAsAddress(); 687 if (Result.hasValue()) { 688 const uint64_t Address = Result.getValue(); 689 uint64_t NewAddress = 0; 690 if (const BinaryFunction *Function = 691 BC.getBinaryFunctionContainingAddress(Address)) { 692 NewAddress = Function->translateInputToOutputAddress(Address); 693 LLVM_DEBUG(dbgs() 694 << "BOLT-DEBUG: Fixing low_pc 0x" 695 << Twine::utohexstr(Address) << " for DIE with tag " 696 << DIE.getTag() << " to 0x" 697 << Twine::utohexstr(NewAddress) << '\n'); 698 } 699 700 dwarf::Form Form = Value.getForm(); 701 assert(Form != dwarf::DW_FORM_LLVM_addrx_offset && 702 "DW_FORM_LLVM_addrx_offset is not supported"); 703 std::lock_guard<std::mutex> Lock(DebugInfoPatcherMutex); 704 if (Form == dwarf::DW_FORM_GNU_addr_index) { 705 const uint64_t Index = Value.getRawUValue(); 706 // If there is no new address, storing old address. 707 // Re-using Index to make implementation easier. 708 // DW_FORM_GNU_addr_index is variable lenght encoding 709 // so we either have to create indices of same sizes, or use same 710 // index. 711 // TODO: We can now re-write .debug_info. This can be simplified to 712 // just getting a new index and creating a patch. 713 AddrWriter->addIndexAddress(NewAddress ? NewAddress : Address, 714 Index, Unit); 715 } else if (Form == dwarf::DW_FORM_addrx) { 716 const uint32_t Index = AddrWriter->getIndexFromAddress( 717 NewAddress ? NewAddress : Address, Unit); 718 DebugInfoPatcher.addUDataPatch(AttrOffset, Index, AttrVal->Size); 719 } else { 720 DebugInfoPatcher.addLE64Patch(AttrOffset, NewAddress); 721 } 722 } else if (opts::Verbosity >= 1) { 723 errs() << "BOLT-WARNING: unexpected form value for attribute at 0x" 724 << Twine::utohexstr(AttrOffset); 725 } 726 } else if (IsDWP && Unit.isDWOUnit()) { 727 // Not a common path so don't want to search all DIEs all the time. 728 Optional<AttrInfo> SignatureAttrVal = 729 findAttributeInfo(DIE, dwarf::DW_AT_signature); 730 if (!SignatureAttrVal) 731 continue; 732 // If input is DWP file we need to keep track of which TU came from each 733 // CU, so we can write it out correctly. 734 if (Optional<uint64_t> Val = SignatureAttrVal->V.getAsReferenceUVal()) 735 TypeSignaturesPerCU[*DIE.getDwarfUnit()->getDWOId()].insert(*Val); 736 else { 737 errs() << "BOT-ERROR: DW_AT_signature form is not supported.\n"; 738 exit(1); 739 } 740 } 741 } 742 } 743 744 // Handling references. 745 assert(DIE.isValid() && "Invalid DIE."); 746 const DWARFAbbreviationDeclaration *AbbrevDecl = 747 DIE.getAbbreviationDeclarationPtr(); 748 if (!AbbrevDecl) 749 continue; 750 uint32_t Index = 0; 751 for (const DWARFAbbreviationDeclaration::AttributeSpec &Decl : 752 AbbrevDecl->attributes()) { 753 switch (Decl.Form) { 754 default: 755 break; 756 case dwarf::DW_FORM_ref1: 757 case dwarf::DW_FORM_ref2: 758 case dwarf::DW_FORM_ref4: 759 case dwarf::DW_FORM_ref8: 760 case dwarf::DW_FORM_ref_udata: 761 case dwarf::DW_FORM_ref_addr: { 762 Optional<AttrInfo> AttrVal = findAttributeInfo(DIE, AbbrevDecl, Index); 763 uint32_t DestinationAddress = 764 AttrVal->V.getRawUValue() + 765 (Decl.Form == dwarf::DW_FORM_ref_addr ? 0 : Unit.getOffset()); 766 DebugInfoPatcher.addReferenceToPatch( 767 AttrVal->Offset, DestinationAddress, AttrVal->Size, Decl.Form); 768 // We can have only one reference, and it can be backward one. 769 DebugInfoPatcher.addDestinationReferenceLabel(DestinationAddress); 770 break; 771 } 772 } 773 ++Index; 774 } 775 } 776 if (DIEOffset > NextCUOffset) 777 errs() << "BOLT-WARNING: corrupt DWARF detected at 0x" 778 << Twine::utohexstr(Unit.getOffset()) << '\n'; 779 } 780 781 void DWARFRewriter::updateDWARFObjectAddressRanges( 782 const DWARFDie DIE, uint64_t DebugRangesOffset, 783 SimpleBinaryPatcher &DebugInfoPatcher, DebugAbbrevWriter &AbbrevWriter, 784 Optional<uint64_t> RangesBase) { 785 786 // Some objects don't have an associated DIE and cannot be updated (such as 787 // compiler-generated functions). 788 if (!DIE) 789 return; 790 791 const DWARFAbbreviationDeclaration *AbbreviationDecl = 792 DIE.getAbbreviationDeclarationPtr(); 793 if (!AbbreviationDecl) { 794 if (opts::Verbosity >= 1) 795 errs() << "BOLT-WARNING: object's DIE doesn't have an abbreviation: " 796 << "skipping update. DIE at offset 0x" 797 << Twine::utohexstr(DIE.getOffset()) << '\n'; 798 return; 799 } 800 801 if (RangesBase) { 802 // If DW_AT_GNU_ranges_base is present, update it. No further modifications 803 // are needed for ranges base. 804 Optional<AttrInfo> RangesBaseAttrInfo = 805 findAttributeInfo(DIE, dwarf::DW_AT_GNU_ranges_base); 806 if (!RangesBaseAttrInfo) 807 RangesBaseAttrInfo = findAttributeInfo(DIE, dwarf::DW_AT_rnglists_base); 808 809 if (RangesBaseAttrInfo) { 810 DebugInfoPatcher.addLE32Patch(RangesBaseAttrInfo->Offset, 811 static_cast<uint32_t>(*RangesBase), 812 RangesBaseAttrInfo->Size); 813 RangesBase = None; 814 } 815 } 816 817 Optional<AttrInfo> LowPCAttrInfo = 818 findAttributeInfo(DIE, dwarf::DW_AT_low_pc); 819 if (Optional<AttrInfo> AttrVal = 820 findAttributeInfo(DIE, dwarf::DW_AT_ranges)) { 821 // Case 1: The object was already non-contiguous and had DW_AT_ranges. 822 // In this case we simply need to update the value of DW_AT_ranges 823 // and introduce DW_AT_GNU_ranges_base if required. 824 std::lock_guard<std::mutex> Lock(DebugInfoPatcherMutex); 825 // For DWARF5 converting all of DW_AT_ranges into DW_FORM_rnglistx 826 bool Converted = false; 827 if (DIE.getDwarfUnit()->getVersion() >= 5 && 828 AttrVal->V.getForm() == dwarf::DW_FORM_sec_offset) { 829 AbbrevWriter.addAttributePatch(*DIE.getDwarfUnit(), AbbreviationDecl, 830 dwarf::DW_AT_ranges, dwarf::DW_AT_ranges, 831 dwarf::DW_FORM_rnglistx); 832 Converted = true; 833 } 834 if (Converted || AttrVal->V.getForm() == dwarf::DW_FORM_rnglistx) 835 DebugInfoPatcher.addUDataPatch(AttrVal->Offset, DebugRangesOffset, 836 AttrVal->Size); 837 else 838 DebugInfoPatcher.addLE32Patch( 839 AttrVal->Offset, DebugRangesOffset - DebugInfoPatcher.getRangeBase(), 840 AttrVal->Size); 841 842 if (!RangesBase) { 843 if (LowPCAttrInfo && 844 LowPCAttrInfo->V.getForm() != dwarf::DW_FORM_GNU_addr_index && 845 LowPCAttrInfo->V.getForm() != dwarf::DW_FORM_addrx) 846 DebugInfoPatcher.addLE64Patch(LowPCAttrInfo->Offset, 0); 847 return; 848 } 849 850 // Convert DW_AT_low_pc into DW_AT_GNU_ranges_base. 851 if (!LowPCAttrInfo) { 852 errs() << "BOLT-ERROR: skeleton CU at 0x" 853 << Twine::utohexstr(DIE.getOffset()) 854 << " does not have DW_AT_GNU_ranges_base or DW_AT_low_pc to" 855 " convert to update ranges base\n"; 856 return; 857 } 858 859 AbbrevWriter.addAttribute(*DIE.getDwarfUnit(), AbbreviationDecl, 860 dwarf::DW_AT_GNU_ranges_base, 861 dwarf::DW_FORM_sec_offset); 862 reinterpret_cast<DebugInfoBinaryPatcher &>(DebugInfoPatcher) 863 .insertNewEntry(DIE, *RangesBase); 864 865 return; 866 } 867 868 // Case 2: The object has both DW_AT_low_pc and DW_AT_high_pc emitted back 869 // to back. Replace with new attributes and patch the DIE. 870 Optional<AttrInfo> HighPCAttrInfo = 871 findAttributeInfo(DIE, dwarf::DW_AT_high_pc); 872 if (LowPCAttrInfo && HighPCAttrInfo) { 873 convertToRangesPatchAbbrev(*DIE.getDwarfUnit(), AbbreviationDecl, 874 AbbrevWriter, RangesBase); 875 convertToRangesPatchDebugInfo(DIE, DebugRangesOffset, DebugInfoPatcher, 876 RangesBase); 877 } else { 878 if (opts::Verbosity >= 1) 879 errs() << "BOLT-ERROR: cannot update ranges for DIE at offset 0x" 880 << Twine::utohexstr(DIE.getOffset()) << '\n'; 881 } 882 } 883 884 void DWARFRewriter::updateLineTableOffsets(const MCAsmLayout &Layout) { 885 ErrorOr<BinarySection &> DbgInfoSection = 886 BC.getUniqueSectionByName(".debug_info"); 887 ErrorOr<BinarySection &> TypeInfoSection = 888 BC.getUniqueSectionByName(".debug_types"); 889 assert(((BC.DwCtx->getNumTypeUnits() > 0 && TypeInfoSection) || 890 BC.DwCtx->getNumTypeUnits() == 0) && 891 "Was not able to retrieve Debug Types section."); 892 893 // We will be re-writing .debug_info so relocation mechanism doesn't work for 894 // Debug Info Patcher. 895 DebugInfoBinaryPatcher *DebugInfoPatcher = nullptr; 896 if (BC.DwCtx->getNumCompileUnits()) { 897 DbgInfoSection->registerPatcher(std::make_unique<DebugInfoBinaryPatcher>()); 898 DebugInfoPatcher = 899 static_cast<DebugInfoBinaryPatcher *>(DbgInfoSection->getPatcher()); 900 } 901 902 // There is no direct connection between CU and TU, but same offsets, 903 // encoded in DW_AT_stmt_list, into .debug_line get modified. 904 // We take advantage of that to map original CU line table offsets to new 905 // ones. 906 std::unordered_map<uint64_t, uint64_t> DebugLineOffsetMap; 907 908 auto GetStatementListValue = [](DWARFUnit *Unit) { 909 Optional<DWARFFormValue> StmtList = 910 Unit->getUnitDIE().find(dwarf::DW_AT_stmt_list); 911 Optional<uint64_t> Offset = dwarf::toSectionOffset(StmtList); 912 assert(Offset && "Was not able to retreive value of DW_AT_stmt_list."); 913 return *Offset; 914 }; 915 916 const uint64_t Reloc32Type = BC.isAArch64() 917 ? static_cast<uint64_t>(ELF::R_AARCH64_ABS32) 918 : static_cast<uint64_t>(ELF::R_X86_64_32); 919 920 for (const std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units()) { 921 const unsigned CUID = CU->getOffset(); 922 MCSymbol *Label = BC.getDwarfLineTable(CUID).getLabel(); 923 if (!Label) 924 continue; 925 926 Optional<AttrInfo> AttrVal = 927 findAttributeInfo(CU.get()->getUnitDIE(), dwarf::DW_AT_stmt_list); 928 if (!AttrVal) 929 continue; 930 931 const uint64_t AttributeOffset = AttrVal->Offset; 932 const uint64_t LineTableOffset = Layout.getSymbolOffset(*Label); 933 DebugLineOffsetMap[GetStatementListValue(CU.get())] = LineTableOffset; 934 assert(DbgInfoSection && ".debug_info section must exist"); 935 DebugInfoPatcher->addLE32Patch(AttributeOffset, LineTableOffset); 936 } 937 938 for (const std::unique_ptr<DWARFUnit> &TU : BC.DwCtx->types_section_units()) { 939 DWARFUnit *Unit = TU.get(); 940 Optional<AttrInfo> AttrVal = 941 findAttributeInfo(TU.get()->getUnitDIE(), dwarf::DW_AT_stmt_list); 942 if (!AttrVal) 943 continue; 944 const uint64_t AttributeOffset = AttrVal->Offset; 945 auto Iter = DebugLineOffsetMap.find(GetStatementListValue(Unit)); 946 assert(Iter != DebugLineOffsetMap.end() && 947 "Type Unit Updated Line Number Entry does not exist."); 948 TypeInfoSection->addRelocation(AttributeOffset, nullptr, Reloc32Type, 949 Iter->second, 0, /*Pending=*/true); 950 } 951 952 // Set .debug_info as finalized so it won't be skipped over when 953 // we process sections while writing out the new binary. This ensures 954 // that the pending relocations will be processed and not ignored. 955 if (DbgInfoSection) 956 DbgInfoSection->setIsFinalized(); 957 958 if (TypeInfoSection) 959 TypeInfoSection->setIsFinalized(); 960 } 961 962 CUOffsetMap 963 DWARFRewriter::finalizeDebugSections(DebugInfoBinaryPatcher &DebugInfoPatcher) { 964 if (StrWriter->isInitialized()) { 965 RewriteInstance::addToDebugSectionsToOverwrite(".debug_str"); 966 std::unique_ptr<DebugStrBufferVector> DebugStrSectionContents = 967 StrWriter->releaseBuffer(); 968 BC.registerOrUpdateNoteSection(".debug_str", 969 copyByteArray(*DebugStrSectionContents), 970 DebugStrSectionContents->size()); 971 } 972 973 if (StrOffstsWriter->isFinalized()) { 974 RewriteInstance::addToDebugSectionsToOverwrite(".debug_str_offsets"); 975 std::unique_ptr<DebugStrOffsetsBufferVector> 976 DebugStrOffsetsSectionContents = StrOffstsWriter->releaseBuffer(); 977 BC.registerOrUpdateNoteSection( 978 ".debug_str_offsets", copyByteArray(*DebugStrOffsetsSectionContents), 979 DebugStrOffsetsSectionContents->size()); 980 } 981 982 std::unique_ptr<DebugBufferVector> RangesSectionContents = 983 RangesSectionWriter->releaseBuffer(); 984 BC.registerOrUpdateNoteSection( 985 llvm::isa<DebugRangeListsSectionWriter>(*RangesSectionWriter) 986 ? ".debug_rnglists" 987 : ".debug_ranges", 988 copyByteArray(*RangesSectionContents), RangesSectionContents->size()); 989 990 if (BC.isDWARF5Used()) { 991 std::unique_ptr<DebugBufferVector> LocationListSectionContents = 992 makeFinalLocListsSection(DebugInfoPatcher, DWARFVersion::DWARF5); 993 BC.registerOrUpdateNoteSection(".debug_loclists", 994 copyByteArray(*LocationListSectionContents), 995 LocationListSectionContents->size()); 996 } 997 998 if (BC.isDWARFLegacyUsed()) { 999 std::unique_ptr<DebugBufferVector> LocationListSectionContents = 1000 makeFinalLocListsSection(DebugInfoPatcher, DWARFVersion::DWARFLegacy); 1001 BC.registerOrUpdateNoteSection(".debug_loc", 1002 copyByteArray(*LocationListSectionContents), 1003 LocationListSectionContents->size()); 1004 } 1005 1006 // AddrWriter should be finalized after debug_loc since more addresses can be 1007 // added there. 1008 if (AddrWriter->isInitialized()) { 1009 AddressSectionBuffer AddressSectionContents = AddrWriter->finalize(); 1010 BC.registerOrUpdateNoteSection(".debug_addr", 1011 copyByteArray(AddressSectionContents), 1012 AddressSectionContents.size()); 1013 for (auto &CU : BC.DwCtx->compile_units()) { 1014 DWARFDie DIE = CU->getUnitDIE(); 1015 uint64_t Offset = 0; 1016 uint64_t AttrOffset = 0; 1017 uint32_t Size = 0; 1018 Optional<AttrInfo> AttrValGnu = 1019 findAttributeInfo(DIE, dwarf::DW_AT_GNU_addr_base); 1020 Optional<AttrInfo> AttrVal = 1021 findAttributeInfo(DIE, dwarf::DW_AT_addr_base); 1022 1023 // For cases where Skeleton CU does not have DW_AT_GNU_addr_base 1024 if (!AttrValGnu && CU->getVersion() < 5) 1025 continue; 1026 1027 Offset = AddrWriter->getOffset(*CU); 1028 1029 if (AttrValGnu) { 1030 AttrOffset = AttrValGnu->Offset; 1031 Size = AttrValGnu->Size; 1032 } 1033 1034 if (AttrVal) { 1035 AttrOffset = AttrVal->Offset; 1036 Size = AttrVal->Size; 1037 } 1038 1039 if (AttrValGnu || AttrVal) { 1040 DebugInfoPatcher.addLE32Patch(AttrOffset, static_cast<int32_t>(Offset), 1041 Size); 1042 } else if (CU->getVersion() >= 5) { 1043 // A case where we were not using .debug_addr section, but after update 1044 // now using it. 1045 const DWARFAbbreviationDeclaration *Abbrev = 1046 DIE.getAbbreviationDeclarationPtr(); 1047 AbbrevWriter->addAttribute(*CU, Abbrev, dwarf::DW_AT_addr_base, 1048 dwarf::DW_FORM_sec_offset); 1049 DebugInfoPatcher.insertNewEntry(DIE, static_cast<int32_t>(Offset)); 1050 } 1051 } 1052 } 1053 1054 std::unique_ptr<DebugBufferVector> AbbrevSectionContents = 1055 AbbrevWriter->finalize(); 1056 BC.registerOrUpdateNoteSection(".debug_abbrev", 1057 copyByteArray(*AbbrevSectionContents), 1058 AbbrevSectionContents->size()); 1059 1060 // Update abbreviation offsets for CUs/TUs if they were changed. 1061 SimpleBinaryPatcher *DebugTypesPatcher = nullptr; 1062 for (auto &Unit : BC.DwCtx->normal_units()) { 1063 const uint64_t NewAbbrevOffset = 1064 AbbrevWriter->getAbbreviationsOffsetForUnit(*Unit); 1065 if (Unit->getAbbreviationsOffset() == NewAbbrevOffset) 1066 continue; 1067 1068 // DWARFv4 or earlier 1069 // unit_length - 4 bytes 1070 // version - 2 bytes 1071 // So + 6 to patch debug_abbrev_offset 1072 constexpr uint64_t AbbrevFieldOffsetLegacy = 6; 1073 // DWARFv5 1074 // unit_length - 4 bytes 1075 // version - 2 bytes 1076 // unit_type - 1 byte 1077 // address_size - 1 byte 1078 // So + 8 to patch debug_abbrev_offset 1079 constexpr uint64_t AbbrevFieldOffsetV5 = 8; 1080 uint64_t AbbrevOffset = 1081 Unit->getVersion() >= 5 ? AbbrevFieldOffsetV5 : AbbrevFieldOffsetLegacy; 1082 if (!Unit->isTypeUnit() || Unit->getVersion() >= 5) { 1083 DebugInfoPatcher.addLE32Patch(Unit->getOffset() + AbbrevOffset, 1084 static_cast<uint32_t>(NewAbbrevOffset)); 1085 continue; 1086 } 1087 1088 if (!DebugTypesPatcher) { 1089 ErrorOr<BinarySection &> DebugTypes = 1090 BC.getUniqueSectionByName(".debug_types"); 1091 DebugTypes->registerPatcher(std::make_unique<SimpleBinaryPatcher>()); 1092 DebugTypesPatcher = 1093 static_cast<SimpleBinaryPatcher *>(DebugTypes->getPatcher()); 1094 } 1095 DebugTypesPatcher->addLE32Patch(Unit->getOffset() + AbbrevOffset, 1096 static_cast<uint32_t>(NewAbbrevOffset)); 1097 } 1098 1099 // No more creating new DebugInfoPatches. 1100 CUOffsetMap CUMap = 1101 DebugInfoPatcher.computeNewOffsets(*BC.DwCtx.get(), false); 1102 1103 // Skip .debug_aranges if we are re-generating .gdb_index. 1104 if (opts::KeepARanges || !BC.getGdbIndexSection()) { 1105 SmallVector<char, 16> ARangesBuffer; 1106 raw_svector_ostream OS(ARangesBuffer); 1107 1108 auto MAB = std::unique_ptr<MCAsmBackend>( 1109 BC.TheTarget->createMCAsmBackend(*BC.STI, *BC.MRI, MCTargetOptions())); 1110 1111 ARangesSectionWriter->writeARangesSection(OS, CUMap); 1112 const StringRef &ARangesContents = OS.str(); 1113 1114 BC.registerOrUpdateNoteSection(".debug_aranges", 1115 copyByteArray(ARangesContents), 1116 ARangesContents.size()); 1117 } 1118 return CUMap; 1119 } 1120 1121 // Creates all the data structures necessary for creating MCStreamer. 1122 // They are passed by reference because they need to be kept around. 1123 // Also creates known debug sections. These are sections handled by 1124 // handleDebugDataPatching. 1125 using KnownSectionsEntry = std::pair<MCSection *, DWARFSectionKind>; 1126 namespace { 1127 1128 std::unique_ptr<BinaryContext> 1129 createDwarfOnlyBC(const object::ObjectFile &File) { 1130 return cantFail(BinaryContext::createBinaryContext( 1131 &File, false, 1132 DWARFContext::create(File, DWARFContext::ProcessDebugRelocations::Ignore, 1133 nullptr, "", WithColor::defaultErrorHandler, 1134 WithColor::defaultWarningHandler))); 1135 } 1136 1137 StringMap<KnownSectionsEntry> 1138 createKnownSectionsMap(const MCObjectFileInfo &MCOFI) { 1139 StringMap<KnownSectionsEntry> KnownSectionsTemp = { 1140 {"debug_info.dwo", {MCOFI.getDwarfInfoDWOSection(), DW_SECT_INFO}}, 1141 {"debug_types.dwo", {MCOFI.getDwarfTypesDWOSection(), DW_SECT_EXT_TYPES}}, 1142 {"debug_str_offsets.dwo", 1143 {MCOFI.getDwarfStrOffDWOSection(), DW_SECT_STR_OFFSETS}}, 1144 {"debug_str.dwo", {MCOFI.getDwarfStrDWOSection(), DW_SECT_EXT_unknown}}, 1145 {"debug_loc.dwo", {MCOFI.getDwarfLocDWOSection(), DW_SECT_EXT_LOC}}, 1146 {"debug_abbrev.dwo", {MCOFI.getDwarfAbbrevDWOSection(), DW_SECT_ABBREV}}, 1147 {"debug_line.dwo", {MCOFI.getDwarfLineDWOSection(), DW_SECT_LINE}}, 1148 {"debug_loclists.dwo", 1149 {MCOFI.getDwarfLoclistsDWOSection(), DW_SECT_LOCLISTS}}, 1150 {"debug_rnglists.dwo", 1151 {MCOFI.getDwarfRnglistsDWOSection(), DW_SECT_RNGLISTS}}}; 1152 return KnownSectionsTemp; 1153 } 1154 1155 StringRef getSectionName(const SectionRef &Section) { 1156 Expected<StringRef> SectionName = Section.getName(); 1157 assert(SectionName && "Invalid section name."); 1158 StringRef Name = *SectionName; 1159 Name = Name.substr(Name.find_first_not_of("._")); 1160 return Name; 1161 } 1162 1163 // Exctracts an appropriate slice if input is DWP. 1164 // Applies patches or overwrites the section. 1165 Optional<StringRef> 1166 updateDebugData(DWARFContext &DWCtx, std::string &Storage, 1167 StringRef SectionName, StringRef SectionContents, 1168 const StringMap<KnownSectionsEntry> &KnownSections, 1169 MCStreamer &Streamer, DWARFRewriter &Writer, 1170 const DWARFUnitIndex::Entry *CUDWOEntry, uint64_t DWOId, 1171 std::unique_ptr<DebugBufferVector> &OutputBuffer, 1172 DebugRangeListsSectionWriter *RangeListsWriter) { 1173 auto applyPatch = [&](DebugInfoBinaryPatcher *Patcher, 1174 StringRef Data) -> StringRef { 1175 Patcher->computeNewOffsets(DWCtx, true); 1176 Storage = Patcher->patchBinary(Data); 1177 return StringRef(Storage.c_str(), Storage.size()); 1178 }; 1179 1180 using DWOSectionContribution = 1181 const DWARFUnitIndex::Entry::SectionContribution; 1182 auto getSliceData = [&](const DWARFUnitIndex::Entry *DWOEntry, 1183 StringRef OutData, DWARFSectionKind Sec, 1184 uint32_t &DWPOffset) -> StringRef { 1185 if (DWOEntry) { 1186 DWOSectionContribution *DWOContrubution = DWOEntry->getContribution(Sec); 1187 DWPOffset = DWOContrubution->Offset; 1188 OutData = OutData.substr(DWPOffset, DWOContrubution->Length); 1189 } 1190 return OutData; 1191 }; 1192 1193 auto SectionIter = KnownSections.find(SectionName); 1194 if (SectionIter == KnownSections.end()) 1195 return None; 1196 1197 Streamer.SwitchSection(SectionIter->second.first); 1198 StringRef OutData = SectionContents; 1199 uint32_t DWPOffset = 0; 1200 1201 switch (SectionIter->second.second) { 1202 default: { 1203 if (!SectionName.equals("debug_str.dwo")) 1204 errs() << "BOLT-WARNING: unsupported debug section: " << SectionName 1205 << "\n"; 1206 return OutData; 1207 } 1208 case DWARFSectionKind::DW_SECT_INFO: { 1209 OutData = getSliceData(CUDWOEntry, OutData, DWARFSectionKind::DW_SECT_INFO, 1210 DWPOffset); 1211 DebugInfoBinaryPatcher *Patcher = llvm::cast<DebugInfoBinaryPatcher>( 1212 Writer.getBinaryDWODebugInfoPatcher(DWOId)); 1213 return applyPatch(Patcher, OutData); 1214 } 1215 case DWARFSectionKind::DW_SECT_EXT_TYPES: { 1216 return getSliceData(nullptr, OutData, DWARFSectionKind::DW_SECT_EXT_TYPES, 1217 DWPOffset); 1218 } 1219 case DWARFSectionKind::DW_SECT_STR_OFFSETS: { 1220 return getSliceData(CUDWOEntry, OutData, 1221 DWARFSectionKind::DW_SECT_STR_OFFSETS, DWPOffset); 1222 } 1223 case DWARFSectionKind::DW_SECT_ABBREV: { 1224 DebugAbbrevWriter *AbbrevWriter = Writer.getBinaryDWOAbbrevWriter(DWOId); 1225 OutputBuffer = AbbrevWriter->finalize(); 1226 // Creating explicit StringRef here, otherwise 1227 // with impicit conversion it will take null byte as end of 1228 // string. 1229 return StringRef(reinterpret_cast<const char *>(OutputBuffer->data()), 1230 OutputBuffer->size()); 1231 } 1232 case DWARFSectionKind::DW_SECT_EXT_LOC: 1233 case DWARFSectionKind::DW_SECT_LOCLISTS: { 1234 DebugLocWriter *LocWriter = Writer.getDebugLocWriter(DWOId); 1235 OutputBuffer = LocWriter->getBuffer(); 1236 // Creating explicit StringRef here, otherwise 1237 // with impicit conversion it will take null byte as end of 1238 // string. 1239 return StringRef(reinterpret_cast<const char *>(OutputBuffer->data()), 1240 OutputBuffer->size()); 1241 } 1242 case DWARFSectionKind::DW_SECT_LINE: { 1243 return getSliceData(CUDWOEntry, OutData, DWARFSectionKind::DW_SECT_LINE, 1244 DWPOffset); 1245 } 1246 case DWARFSectionKind::DW_SECT_RNGLISTS: { 1247 OutputBuffer = RangeListsWriter->releaseBuffer(); 1248 return StringRef(reinterpret_cast<const char *>(OutputBuffer->data()), 1249 OutputBuffer->size()); 1250 } 1251 } 1252 } 1253 1254 } // namespace 1255 1256 struct TUContribution { 1257 uint64_t Signature{0}; 1258 uint32_t Length{0}; 1259 }; 1260 using TUContributionVector = std::vector<TUContribution>; 1261 /// Iterates over all the signatures used in this CU, and 1262 /// uses TU Index to extract their contributions from the DWP file. 1263 /// It stores them in DWOTUSection. 1264 static std::string extractDWOTUFromDWP( 1265 const DWARFRewriter::DebugTypesSignaturesPerCUMap &TypeSignaturesPerCU, 1266 const DWARFUnitIndex &TUIndex, StringRef Contents, 1267 TUContributionVector &TUContributionsToCU, uint64_t DWOId) { 1268 std::string DWOTUSection; 1269 using TUEntry = 1270 std::pair<uint64_t, const DWARFUnitIndex::Entry::SectionContribution *>; 1271 std::vector<TUEntry> TUContributions; 1272 for (const uint64_t TUSignature : TypeSignaturesPerCU.at(DWOId)) { 1273 const DWARFUnitIndex::Entry *TUDWOEntry = TUIndex.getFromHash(TUSignature); 1274 const DWARFUnitIndex::Entry::SectionContribution *C = 1275 TUDWOEntry->getContribution(DW_SECT_EXT_TYPES); 1276 TUContributions.emplace_back(TUSignature, C); 1277 } 1278 1279 // Sorting so it's easy to compare output. 1280 // They should be sharing the same Abbrev. 1281 std::sort(TUContributions.begin(), TUContributions.end(), 1282 [](const TUEntry &V1, const TUEntry &V2) -> bool { 1283 return V1.second->Offset < V2.second->Offset; 1284 }); 1285 1286 for (auto &PairEntry : TUContributions) { 1287 const DWARFUnitIndex::Entry::SectionContribution *C = PairEntry.second; 1288 const uint64_t TUSignature = PairEntry.first; 1289 DWOTUSection.append(Contents.slice(C->Offset, C->Offset + C->Length).str()); 1290 TUContributionsToCU.push_back({TUSignature, C->Length}); 1291 } 1292 return DWOTUSection; 1293 } 1294 1295 static void extractDWOTUFromDWO(StringRef Contents, 1296 TUContributionVector &TUContributionsToCU) { 1297 uint64_t Offset = 0; 1298 DataExtractor Data(Contents, true, 0); 1299 while (Data.isValidOffset(Offset)) { 1300 auto PrevOffset = Offset; 1301 // Length of the unit, including the 4 byte length field. 1302 const uint32_t Length = Data.getU32(&Offset) + 4; 1303 1304 Data.getU16(&Offset); // Version 1305 Data.getU32(&Offset); // Abbrev offset 1306 Data.getU8(&Offset); // Address size 1307 const auto TUSignature = Data.getU64(&Offset); 1308 Offset = PrevOffset + Length; 1309 TUContributionsToCU.push_back({TUSignature, Length}); 1310 } 1311 } 1312 1313 static void extractTypesFromDWPDWARF5( 1314 const MCObjectFileInfo &MCOFI, const DWARFUnitIndex &TUIndex, 1315 const DWARFRewriter::DebugTypesSignaturesPerCUMap &TypeSignaturesPerCU, 1316 MCStreamer &Streamer, StringRef Contents, uint64_t DWOId) { 1317 std::vector<const DWARFUnitIndex::Entry::SectionContribution *> 1318 TUContributions; 1319 for (const uint64_t Val : TypeSignaturesPerCU.at(DWOId)) { 1320 const DWARFUnitIndex::Entry *TUE = TUIndex.getFromHash(Val); 1321 const DWARFUnitIndex::Entry::SectionContribution *C = 1322 TUE->getContribution(DWARFSectionKind::DW_SECT_INFO); 1323 TUContributions.push_back(C); 1324 } 1325 // Sorting so it's easy to compare output. 1326 // They should be sharing the same Abbrev. 1327 std::sort(TUContributions.begin(), TUContributions.end(), 1328 [](const DWARFUnitIndex::Entry::SectionContribution *V1, 1329 const DWARFUnitIndex::Entry::SectionContribution *V2) -> bool { 1330 return V1->Offset < V2->Offset; 1331 }); 1332 Streamer.SwitchSection(MCOFI.getDwarfInfoDWOSection()); 1333 for (const auto *C : TUContributions) 1334 Streamer.emitBytes(Contents.slice(C->Offset, C->Offset + C->Length)); 1335 } 1336 1337 void DWARFRewriter::writeDWP( 1338 std::unordered_map<uint64_t, std::string> &DWOIdToName) { 1339 SmallString<0> OutputNameStr; 1340 StringRef OutputName; 1341 if (opts::DwarfOutputPath.empty()) { 1342 OutputName = 1343 Twine(opts::OutputFilename).concat(".dwp").toStringRef(OutputNameStr); 1344 } else { 1345 StringRef ExeFileName = llvm::sys::path::filename(opts::OutputFilename); 1346 OutputName = Twine(opts::DwarfOutputPath) 1347 .concat("/") 1348 .concat(ExeFileName) 1349 .concat(".dwp") 1350 .toStringRef(OutputNameStr); 1351 errs() << "BOLT-WARNING: dwarf-output-path is in effect and .dwp file will " 1352 "possibly be written to another location that is not the same as " 1353 "the executable\n"; 1354 } 1355 std::error_code EC; 1356 std::unique_ptr<ToolOutputFile> Out = 1357 std::make_unique<ToolOutputFile>(OutputName, EC, sys::fs::OF_None); 1358 1359 const object::ObjectFile *File = BC.DwCtx->getDWARFObj().getFile(); 1360 std::unique_ptr<BinaryContext> TmpBC = createDwarfOnlyBC(*File); 1361 std::unique_ptr<MCStreamer> Streamer = TmpBC->createStreamer(Out->os()); 1362 const MCObjectFileInfo &MCOFI = *Streamer->getContext().getObjectFileInfo(); 1363 StringMap<KnownSectionsEntry> KnownSections = createKnownSectionsMap(MCOFI); 1364 MCSection *const StrSection = MCOFI.getDwarfStrDWOSection(); 1365 MCSection *const StrOffsetSection = MCOFI.getDwarfStrOffDWOSection(); 1366 1367 // Data Structures for DWP book keeping 1368 // Size of array corresponds to the number of sections supported by DWO format 1369 // in DWARF4/5. 1370 uint32_t ContributionOffsets[8] = {}; 1371 std::deque<SmallString<32>> UncompressedSections; 1372 DWPStringPool Strings(*Streamer, StrSection); 1373 MapVector<uint64_t, UnitIndexEntry> IndexEntries; 1374 MapVector<uint64_t, UnitIndexEntry> TypeIndexEntries; 1375 uint16_t Version = 0; 1376 uint32_t IndexVersion = 2; 1377 1378 // Setup DWP code once. 1379 DWARFContext *DWOCtx = BC.getDWOContext(); 1380 const DWARFUnitIndex *CUIndex = nullptr; 1381 const DWARFUnitIndex *TUIndex = nullptr; 1382 bool IsDWP = false; 1383 if (DWOCtx) { 1384 CUIndex = &DWOCtx->getCUIndex(); 1385 TUIndex = &DWOCtx->getTUIndex(); 1386 IsDWP = !CUIndex->getRows().empty(); 1387 } 1388 1389 for (const std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units()) { 1390 Optional<uint64_t> DWOId = CU->getDWOId(); 1391 if (!DWOId) 1392 continue; 1393 1394 // Skipping CUs that we failed to load. 1395 Optional<DWARFUnit *> DWOCU = BC.getDWOCU(*DWOId); 1396 if (!DWOCU) 1397 continue; 1398 1399 if (Version == 0) { 1400 Version = CU->getVersion(); 1401 IndexVersion = Version < 5 ? 2 : 5; 1402 } else if (Version != CU->getVersion()) { 1403 errs() << "BOLT-ERROR: Incompatible DWARF compile unit versions.\n"; 1404 exit(1); 1405 } 1406 1407 UnitIndexEntry CurEntry = {}; 1408 CurEntry.DWOName = 1409 dwarf::toString(CU->getUnitDIE().find( 1410 {dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name}), 1411 ""); 1412 const char *Name = CU->getUnitDIE().getShortName(); 1413 if (Name) 1414 CurEntry.Name = Name; 1415 StringRef CurStrSection; 1416 StringRef CurStrOffsetSection; 1417 1418 // This maps each section contained in this file to its length. 1419 // This information is later on used to calculate the contributions, 1420 // i.e. offset and length, of each compile/type unit to a section. 1421 std::vector<std::pair<DWARFSectionKind, uint32_t>> SectionLength; 1422 1423 const DWARFUnitIndex::Entry *CUDWOEntry = nullptr; 1424 if (IsDWP) 1425 CUDWOEntry = CUIndex->getFromHash(*DWOId); 1426 1427 bool StrSectionWrittenOut = false; 1428 const object::ObjectFile *DWOFile = 1429 (*DWOCU)->getContext().getDWARFObj().getFile(); 1430 1431 DebugRangeListsSectionWriter *RangeListssWriter = nullptr; 1432 if (CU->getVersion() == 5) { 1433 assert(RangeListsWritersByCU.count(*DWOId) != 0 && 1434 "No RangeListsWriter for DWO ID."); 1435 RangeListssWriter = RangeListsWritersByCU[*DWOId].get(); 1436 } 1437 std::string DWOTUSection; 1438 TUContributionVector TUContributionsToCU; 1439 for (const SectionRef &Section : DWOFile->sections()) { 1440 std::string DWOTUSection; 1441 std::string Storage = ""; 1442 std::unique_ptr<DebugBufferVector> OutputData; 1443 StringRef SectionName = getSectionName(Section); 1444 Expected<StringRef> ContentsExp = Section.getContents(); 1445 assert(ContentsExp && "Invalid contents."); 1446 StringRef Contents = *ContentsExp; 1447 const bool IsTypesDWO = SectionName == "debug_types.dwo"; 1448 if (IsDWP && IsTypesDWO) { 1449 assert(TUIndex && 1450 "DWP Input with .debug_types.dwo section with TU Index."); 1451 DWOTUSection = 1452 extractDWOTUFromDWP(TypeSignaturesPerCU, *TUIndex, Contents, 1453 TUContributionsToCU, *DWOId); 1454 Contents = DWOTUSection; 1455 } else if (IsTypesDWO) { 1456 extractDWOTUFromDWO(Contents, TUContributionsToCU); 1457 } 1458 1459 Optional<StringRef> TOutData = updateDebugData( 1460 (*DWOCU)->getContext(), Storage, SectionName, Contents, KnownSections, 1461 *Streamer, *this, CUDWOEntry, *DWOId, OutputData, RangeListssWriter); 1462 if (!TOutData) 1463 continue; 1464 1465 StringRef OutData = *TOutData; 1466 if (IsTypesDWO) { 1467 Streamer->emitBytes(OutData); 1468 continue; 1469 } 1470 1471 if (SectionName.equals("debug_str.dwo")) { 1472 CurStrSection = OutData; 1473 } else { 1474 // Since handleDebugDataPatching returned true, we already know this is 1475 // a known section. 1476 auto SectionIter = KnownSections.find(SectionName); 1477 if (SectionIter->second.second == DWARFSectionKind::DW_SECT_STR_OFFSETS) 1478 CurStrOffsetSection = OutData; 1479 else 1480 Streamer->emitBytes(OutData); 1481 auto Index = 1482 getContributionIndex(SectionIter->second.second, IndexVersion); 1483 CurEntry.Contributions[Index].Offset = ContributionOffsets[Index]; 1484 CurEntry.Contributions[Index].Length = OutData.size(); 1485 ContributionOffsets[Index] += CurEntry.Contributions[Index].Length; 1486 } 1487 1488 // Strings are combined in to a new string section, and de-duplicated 1489 // based on hash. 1490 if (!StrSectionWrittenOut && !CurStrOffsetSection.empty() && 1491 !CurStrSection.empty()) { 1492 writeStringsAndOffsets(*Streamer.get(), Strings, StrOffsetSection, 1493 CurStrSection, CurStrOffsetSection, 1494 CU->getVersion()); 1495 StrSectionWrittenOut = true; 1496 } 1497 } 1498 CompileUnitIdentifiers CUI{*DWOId, CurEntry.Name.c_str(), 1499 CurEntry.DWOName.c_str()}; 1500 auto P = IndexEntries.insert(std::make_pair(CUI.Signature, CurEntry)); 1501 if (!P.second) { 1502 Error Err = buildDuplicateError(*P.first, CUI, ""); 1503 errs() << "BOLT-ERROR: " << toString(std::move(Err)) << "\n"; 1504 return; 1505 } 1506 1507 // Handling TU 1508 if (!TUContributionsToCU.empty()) { 1509 const unsigned Index = 1510 getContributionIndex(DW_SECT_EXT_TYPES, IndexVersion); 1511 for (const TUContribution &TUC : TUContributionsToCU) { 1512 UnitIndexEntry TUEntry = CurEntry; 1513 TUEntry.Contributions[0] = {}; 1514 TUEntry.Contributions[Index].Offset = ContributionOffsets[Index]; 1515 TUEntry.Contributions[Index].Length = TUC.Length; 1516 ContributionOffsets[Index] += TUEntry.Contributions[Index].Length; 1517 TypeIndexEntries.insert(std::make_pair(TUC.Signature, TUEntry)); 1518 } 1519 } 1520 } 1521 1522 if (Version < 5) { 1523 // Lie about there being no info contributions so the TU index only includes 1524 // the type unit contribution for DWARF < 5. In DWARFv5 the TU index has a 1525 // contribution to the info section, so we do not want to lie about it. 1526 ContributionOffsets[0] = 0; 1527 } 1528 writeIndex(*Streamer.get(), MCOFI.getDwarfTUIndexSection(), 1529 ContributionOffsets, TypeIndexEntries, IndexVersion); 1530 1531 if (Version < 5) { 1532 // Lie about the type contribution for DWARF < 5. In DWARFv5 the type 1533 // section does not exist, so no need to do anything about this. 1534 ContributionOffsets[getContributionIndex(DW_SECT_EXT_TYPES, 2)] = 0; 1535 // Unlie about the info contribution 1536 ContributionOffsets[0] = 1; 1537 } 1538 writeIndex(*Streamer.get(), MCOFI.getDwarfCUIndexSection(), 1539 ContributionOffsets, IndexEntries, IndexVersion); 1540 1541 Streamer->finish(); 1542 Out->keep(); 1543 } 1544 1545 void DWARFRewriter::writeDWOFiles( 1546 std::unordered_map<uint64_t, std::string> &DWOIdToName) { 1547 // Setup DWP code once. 1548 DWARFContext *DWOCtx = BC.getDWOContext(); 1549 const DWARFUnitIndex *CUIndex = nullptr; 1550 const DWARFUnitIndex *TUIndex = nullptr; 1551 bool IsDWP = false; 1552 if (DWOCtx) { 1553 CUIndex = &DWOCtx->getCUIndex(); 1554 TUIndex = &DWOCtx->getTUIndex(); 1555 IsDWP = !CUIndex->getRows().empty(); 1556 } 1557 1558 for (const std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units()) { 1559 Optional<uint64_t> DWOId = CU->getDWOId(); 1560 if (!DWOId) 1561 continue; 1562 1563 // Skipping CUs that we failed to load. 1564 Optional<DWARFUnit *> DWOCU = BC.getDWOCU(*DWOId); 1565 if (!DWOCU) 1566 continue; 1567 1568 std::string CompDir = opts::DwarfOutputPath.empty() 1569 ? CU->getCompilationDir() 1570 : opts::DwarfOutputPath.c_str(); 1571 std::string ObjectName = getDWOName(*CU.get(), nullptr, DWOIdToName); 1572 auto FullPath = CompDir.append("/").append(ObjectName); 1573 1574 std::error_code EC; 1575 std::unique_ptr<ToolOutputFile> TempOut = 1576 std::make_unique<ToolOutputFile>(FullPath, EC, sys::fs::OF_None); 1577 1578 const DWARFUnitIndex::Entry *CUDWOEntry = nullptr; 1579 if (IsDWP) 1580 CUDWOEntry = CUIndex->getFromHash(*DWOId); 1581 1582 const object::ObjectFile *File = 1583 (*DWOCU)->getContext().getDWARFObj().getFile(); 1584 std::unique_ptr<BinaryContext> TmpBC = createDwarfOnlyBC(*File); 1585 std::unique_ptr<MCStreamer> Streamer = TmpBC->createStreamer(TempOut->os()); 1586 const MCObjectFileInfo &MCOFI = *Streamer->getContext().getObjectFileInfo(); 1587 StringMap<KnownSectionsEntry> KnownSections = createKnownSectionsMap(MCOFI); 1588 1589 DebugRangeListsSectionWriter *RangeListssWriter = nullptr; 1590 if (CU->getVersion() == 5) { 1591 assert(RangeListsWritersByCU.count(*DWOId) != 0 && 1592 "No RangeListsWriter for DWO ID."); 1593 RangeListssWriter = RangeListsWritersByCU[*DWOId].get(); 1594 1595 // Handling .debug_rnglists.dwo seperatly. The original .o/.dwo might not 1596 // have .debug_rnglists so won't be part of the loop below. 1597 if (!RangeListssWriter->empty()) { 1598 std::string Storage = ""; 1599 std::unique_ptr<DebugBufferVector> OutputData; 1600 if (Optional<StringRef> OutData = updateDebugData( 1601 (*DWOCU)->getContext(), Storage, "debug_rnglists.dwo", "", 1602 KnownSections, *Streamer, *this, CUDWOEntry, *DWOId, OutputData, 1603 RangeListssWriter)) 1604 Streamer->emitBytes(*OutData); 1605 } 1606 } 1607 1608 TUContributionVector TUContributionsToCU; 1609 for (const SectionRef &Section : File->sections()) { 1610 std::string Storage = ""; 1611 std::string DWOTUSection; 1612 std::unique_ptr<DebugBufferVector> OutputData; 1613 StringRef SectionName = getSectionName(Section); 1614 if (SectionName == "debug_rnglists.dwo") 1615 continue; 1616 Expected<StringRef> ContentsExp = Section.getContents(); 1617 assert(ContentsExp && "Invalid contents."); 1618 StringRef Contents = *ContentsExp; 1619 if (IsDWP && SectionName == "debug_types.dwo") { 1620 assert(TUIndex && 1621 "DWP Input with .debug_types.dwo section with TU Index."); 1622 DWOTUSection = 1623 extractDWOTUFromDWP(TypeSignaturesPerCU, *TUIndex, Contents, 1624 TUContributionsToCU, *DWOId); 1625 Contents = DWOTUSection; 1626 } else if (IsDWP && CU->getVersion() >= 5 && 1627 SectionName == "debug_info.dwo") { 1628 assert(TUIndex && 1629 "DWP Input with .debug_types.dwo section with TU Index."); 1630 extractTypesFromDWPDWARF5(MCOFI, *TUIndex, TypeSignaturesPerCU, 1631 *Streamer, Contents, *DWOId); 1632 } 1633 1634 if (Optional<StringRef> OutData = updateDebugData( 1635 (*DWOCU)->getContext(), Storage, SectionName, Contents, 1636 KnownSections, *Streamer, *this, CUDWOEntry, *DWOId, OutputData, 1637 RangeListssWriter)) 1638 Streamer->emitBytes(*OutData); 1639 } 1640 Streamer->finish(); 1641 TempOut->keep(); 1642 } 1643 } 1644 1645 void DWARFRewriter::updateGdbIndexSection(CUOffsetMap &CUMap) { 1646 if (!BC.getGdbIndexSection()) 1647 return; 1648 1649 // See https://sourceware.org/gdb/onlinedocs/gdb/Index-Section-Format.html 1650 // for .gdb_index section format. 1651 1652 StringRef GdbIndexContents = BC.getGdbIndexSection()->getContents(); 1653 1654 const char *Data = GdbIndexContents.data(); 1655 1656 // Parse the header. 1657 const uint32_t Version = read32le(Data); 1658 if (Version != 7 && Version != 8) { 1659 errs() << "BOLT-ERROR: can only process .gdb_index versions 7 and 8\n"; 1660 exit(1); 1661 } 1662 1663 // Some .gdb_index generators use file offsets while others use section 1664 // offsets. Hence we can only rely on offsets relative to each other, 1665 // and ignore their absolute values. 1666 const uint32_t CUListOffset = read32le(Data + 4); 1667 const uint32_t CUTypesOffset = read32le(Data + 8); 1668 const uint32_t AddressTableOffset = read32le(Data + 12); 1669 const uint32_t SymbolTableOffset = read32le(Data + 16); 1670 const uint32_t ConstantPoolOffset = read32le(Data + 20); 1671 Data += 24; 1672 1673 // Map CUs offsets to indices and verify existing index table. 1674 std::map<uint32_t, uint32_t> OffsetToIndexMap; 1675 const uint32_t CUListSize = CUTypesOffset - CUListOffset; 1676 const unsigned NumCUs = BC.DwCtx->getNumCompileUnits(); 1677 if (CUListSize != NumCUs * 16) { 1678 errs() << "BOLT-ERROR: .gdb_index: CU count mismatch\n"; 1679 exit(1); 1680 } 1681 for (unsigned Index = 0; Index < NumCUs; ++Index, Data += 16) { 1682 const DWARFUnit *CU = BC.DwCtx->getUnitAtIndex(Index); 1683 const uint64_t Offset = read64le(Data); 1684 if (CU->getOffset() != Offset) { 1685 errs() << "BOLT-ERROR: .gdb_index CU offset mismatch\n"; 1686 exit(1); 1687 } 1688 1689 OffsetToIndexMap[Offset] = Index; 1690 } 1691 1692 // Ignore old address table. 1693 const uint32_t OldAddressTableSize = SymbolTableOffset - AddressTableOffset; 1694 // Move Data to the beginning of symbol table. 1695 Data += SymbolTableOffset - CUTypesOffset; 1696 1697 // Calculate the size of the new address table. 1698 uint32_t NewAddressTableSize = 0; 1699 for (const auto &CURangesPair : ARangesSectionWriter->getCUAddressRanges()) { 1700 const SmallVector<DebugAddressRange, 2> &Ranges = CURangesPair.second; 1701 NewAddressTableSize += Ranges.size() * 20; 1702 } 1703 1704 // Difference between old and new table (and section) sizes. 1705 // Could be negative. 1706 int32_t Delta = NewAddressTableSize - OldAddressTableSize; 1707 1708 size_t NewGdbIndexSize = GdbIndexContents.size() + Delta; 1709 1710 // Free'd by ExecutableFileMemoryManager. 1711 auto *NewGdbIndexContents = new uint8_t[NewGdbIndexSize]; 1712 uint8_t *Buffer = NewGdbIndexContents; 1713 1714 write32le(Buffer, Version); 1715 write32le(Buffer + 4, CUListOffset); 1716 write32le(Buffer + 8, CUTypesOffset); 1717 write32le(Buffer + 12, AddressTableOffset); 1718 write32le(Buffer + 16, SymbolTableOffset + Delta); 1719 write32le(Buffer + 20, ConstantPoolOffset + Delta); 1720 Buffer += 24; 1721 1722 // Writing out CU List <Offset, Size> 1723 for (auto &CUInfo : CUMap) { 1724 write64le(Buffer, CUInfo.second.Offset); 1725 // Length encoded in CU doesn't contain first 4 bytes that encode length. 1726 write64le(Buffer + 8, CUInfo.second.Length + 4); 1727 Buffer += 16; 1728 } 1729 1730 // Copy over types CU list 1731 // Spec says " triplet, the first value is the CU offset, the second value is 1732 // the type offset in the CU, and the third value is the type signature" 1733 // Looking at what is being generated by gdb-add-index. The first entry is TU 1734 // offset, second entry is offset from it, and third entry is the type 1735 // signature. 1736 memcpy(Buffer, GdbIndexContents.data() + CUTypesOffset, 1737 AddressTableOffset - CUTypesOffset); 1738 Buffer += AddressTableOffset - CUTypesOffset; 1739 1740 // Generate new address table. 1741 for (const std::pair<const uint64_t, DebugAddressRangesVector> &CURangesPair : 1742 ARangesSectionWriter->getCUAddressRanges()) { 1743 const uint32_t CUIndex = OffsetToIndexMap[CURangesPair.first]; 1744 const DebugAddressRangesVector &Ranges = CURangesPair.second; 1745 for (const DebugAddressRange &Range : Ranges) { 1746 write64le(Buffer, Range.LowPC); 1747 write64le(Buffer + 8, Range.HighPC); 1748 write32le(Buffer + 16, CUIndex); 1749 Buffer += 20; 1750 } 1751 } 1752 1753 const size_t TrailingSize = 1754 GdbIndexContents.data() + GdbIndexContents.size() - Data; 1755 assert(Buffer + TrailingSize == NewGdbIndexContents + NewGdbIndexSize && 1756 "size calculation error"); 1757 1758 // Copy over the rest of the original data. 1759 memcpy(Buffer, Data, TrailingSize); 1760 1761 // Register the new section. 1762 BC.registerOrUpdateNoteSection(".gdb_index", NewGdbIndexContents, 1763 NewGdbIndexSize); 1764 } 1765 1766 std::unique_ptr<DebugBufferVector> 1767 DWARFRewriter::makeFinalLocListsSection(SimpleBinaryPatcher &DebugInfoPatcher, 1768 DWARFVersion Version) { 1769 auto LocBuffer = std::make_unique<DebugBufferVector>(); 1770 auto LocStream = std::make_unique<raw_svector_ostream>(*LocBuffer); 1771 auto Writer = 1772 std::unique_ptr<MCObjectWriter>(BC.createObjectWriter(*LocStream)); 1773 1774 uint64_t SectionOffset = 0; 1775 // Add an empty list as the first entry; 1776 if (LocListWritersByCU.empty() || 1777 LocListWritersByCU.begin()->second.get()->getDwarfVersion() < 5) { 1778 // Should be fine for both DWARF4 and DWARF5? 1779 const char Zeroes[16] = {0}; 1780 *LocStream << StringRef(Zeroes, 16); 1781 SectionOffset += 2 * 8; 1782 } 1783 1784 for (std::pair<const uint64_t, std::unique_ptr<DebugLocWriter>> &Loc : 1785 LocListWritersByCU) { 1786 DebugLocWriter *LocWriter = Loc.second.get(); 1787 auto *LocListWriter = llvm::dyn_cast<DebugLoclistWriter>(LocWriter); 1788 1789 if (Version == DWARFVersion::DWARF5 && 1790 (!LocListWriter || LocListWriter->getDwarfVersion() <= 4)) 1791 continue; 1792 1793 if (Version == DWARFVersion::DWARFLegacy && 1794 (LocListWriter && LocListWriter->getDwarfVersion() >= 5)) 1795 continue; 1796 if (LocListWriter && (LocListWriter->getDwarfVersion() <= 4 || 1797 (LocListWriter->getDwarfVersion() >= 5 && 1798 LocListWriter->isSplitDwarf()))) { 1799 SimpleBinaryPatcher *Patcher = 1800 getBinaryDWODebugInfoPatcher(LocListWriter->getCUID()); 1801 LocListWriter->finalize(0, *Patcher); 1802 continue; 1803 } 1804 LocWriter->finalize(SectionOffset, DebugInfoPatcher); 1805 std::unique_ptr<DebugBufferVector> CurrCULocationLists = 1806 LocWriter->getBuffer(); 1807 *LocStream << *CurrCULocationLists; 1808 SectionOffset += CurrCULocationLists->size(); 1809 } 1810 1811 return LocBuffer; 1812 } 1813 1814 namespace { 1815 1816 void getRangeAttrData(DWARFDie DIE, Optional<AttrInfo> &LowPCVal, 1817 Optional<AttrInfo> &HighPCVal) { 1818 LowPCVal = findAttributeInfo(DIE, dwarf::DW_AT_low_pc); 1819 HighPCVal = findAttributeInfo(DIE, dwarf::DW_AT_high_pc); 1820 uint64_t LowPCOffset = LowPCVal->Offset; 1821 uint64_t HighPCOffset = HighPCVal->Offset; 1822 dwarf::Form LowPCForm = LowPCVal->V.getForm(); 1823 dwarf::Form HighPCForm = HighPCVal->V.getForm(); 1824 1825 if (LowPCForm != dwarf::DW_FORM_addr && 1826 LowPCForm != dwarf::DW_FORM_GNU_addr_index && 1827 LowPCForm != dwarf::DW_FORM_addrx) { 1828 errs() << "BOLT-WARNING: unexpected low_pc form value. Cannot update DIE " 1829 << "at offset 0x" << Twine::utohexstr(DIE.getOffset()) << "\n"; 1830 return; 1831 } 1832 if (HighPCForm != dwarf::DW_FORM_addr && HighPCForm != dwarf::DW_FORM_data8 && 1833 HighPCForm != dwarf::DW_FORM_data4 && 1834 HighPCForm != dwarf::DW_FORM_data2 && 1835 HighPCForm != dwarf::DW_FORM_data1 && 1836 HighPCForm != dwarf::DW_FORM_udata) { 1837 errs() << "BOLT-WARNING: unexpected high_pc form value. Cannot update DIE " 1838 << "at offset 0x" << Twine::utohexstr(DIE.getOffset()) << "\n"; 1839 return; 1840 } 1841 if ((LowPCOffset == -1U || (LowPCOffset + 8 != HighPCOffset)) && 1842 LowPCForm != dwarf::DW_FORM_GNU_addr_index && 1843 LowPCForm != dwarf::DW_FORM_addrx) { 1844 errs() << "BOLT-WARNING: high_pc expected immediately after low_pc. " 1845 << "Cannot update DIE at offset 0x" 1846 << Twine::utohexstr(DIE.getOffset()) << '\n'; 1847 return; 1848 } 1849 } 1850 1851 } // namespace 1852 1853 void DWARFRewriter::convertToRangesPatchAbbrev( 1854 const DWARFUnit &Unit, const DWARFAbbreviationDeclaration *Abbrev, 1855 DebugAbbrevWriter &AbbrevWriter, Optional<uint64_t> RangesBase) { 1856 1857 dwarf::Attribute RangeBaseAttribute = dwarf::DW_AT_GNU_ranges_base; 1858 dwarf::Form RangesForm = dwarf::DW_FORM_sec_offset; 1859 1860 if (Unit.getVersion() >= 5) { 1861 RangeBaseAttribute = dwarf::DW_AT_rnglists_base; 1862 RangesForm = dwarf::DW_FORM_rnglistx; 1863 } 1864 // If we hit this point it means we converted subprogram DIEs from 1865 // low_pc/high_pc into ranges. The CU originally didn't have DW_AT_*_base, so 1866 // we are adding it here. 1867 if (RangesBase) 1868 AbbrevWriter.addAttribute(Unit, Abbrev, RangeBaseAttribute, 1869 dwarf::DW_FORM_sec_offset); 1870 1871 // Converting DW_AT_high_pc into DW_AT_ranges. 1872 // For DWARF4 it's DW_FORM_sec_offset. 1873 // For DWARF5 it can be either DW_FORM_sec_offset or DW_FORM_rnglistx. 1874 // For consistency for DWARF5 we always use DW_FORM_rnglistx. 1875 AbbrevWriter.addAttributePatch(Unit, Abbrev, dwarf::DW_AT_high_pc, 1876 dwarf::DW_AT_ranges, RangesForm); 1877 } 1878 1879 void DWARFRewriter::convertToRangesPatchDebugInfo( 1880 DWARFDie DIE, uint64_t RangesSectionOffset, 1881 SimpleBinaryPatcher &DebugInfoPatcher, Optional<uint64_t> RangesBase) { 1882 Optional<AttrInfo> LowPCVal = None; 1883 Optional<AttrInfo> HighPCVal = None; 1884 getRangeAttrData(DIE, LowPCVal, HighPCVal); 1885 uint64_t LowPCOffset = LowPCVal->Offset; 1886 uint64_t HighPCOffset = HighPCVal->Offset; 1887 1888 std::lock_guard<std::mutex> Lock(DebugInfoPatcherMutex); 1889 uint32_t BaseOffset = 0; 1890 dwarf::Form LowForm = LowPCVal->V.getForm(); 1891 1892 // In DWARF4 for DW_AT_low_pc in binary DW_FORM_addr is used. In the DWO 1893 // section DW_FORM_GNU_addr_index is used. So for if we are converting 1894 // DW_AT_low_pc/DW_AT_high_pc and see DW_FORM_GNU_addr_index. We are 1895 // converting in DWO section, and DW_AT_ranges [DW_FORM_sec_offset] is 1896 // relative to DW_AT_GNU_ranges_base. 1897 if (LowForm == dwarf::DW_FORM_GNU_addr_index) { 1898 // Use ULEB128 for the value. 1899 DebugInfoPatcher.addUDataPatch(LowPCOffset, 0, LowPCVal->Size); 1900 // Ranges are relative to DW_AT_GNU_ranges_base. 1901 BaseOffset = DebugInfoPatcher.getRangeBase(); 1902 } else { 1903 // In DWARF 5 we can have DW_AT_low_pc either as DW_FORM_addr, or 1904 // DW_FORM_addrx. Former is when DW_AT_rnglists_base is present. Latter is 1905 // when it's absent. 1906 if (LowForm == dwarf::DW_FORM_addrx) { 1907 const uint32_t Index = 1908 AddrWriter->getIndexFromAddress(0, *DIE.getDwarfUnit()); 1909 DebugInfoPatcher.addUDataPatch(LowPCOffset, Index, LowPCVal->Size); 1910 } else 1911 DebugInfoPatcher.addLE64Patch(LowPCOffset, 0); 1912 1913 // Original CU didn't have DW_AT_*_base. We converted it's children (or 1914 // dwo), so need to insert it into CU. 1915 if (RangesBase) 1916 reinterpret_cast<DebugInfoBinaryPatcher &>(DebugInfoPatcher) 1917 .insertNewEntry(DIE, *RangesBase); 1918 } 1919 1920 // HighPC was conveted into DW_AT_ranges. 1921 // For DWARF5 we only access ranges throught index. 1922 if (DIE.getDwarfUnit()->getVersion() >= 5) 1923 DebugInfoPatcher.addUDataPatch(HighPCOffset, RangesSectionOffset, 1924 HighPCVal->Size); 1925 else 1926 DebugInfoPatcher.addLE32Patch( 1927 HighPCOffset, RangesSectionOffset - BaseOffset, HighPCVal->Size); 1928 } 1929