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/FileSystem.h" 34 #include "llvm/Support/ThreadPool.h" 35 #include "llvm/Support/ToolOutputFile.h" 36 #include <algorithm> 37 #include <cstdint> 38 #include <string> 39 #include <unordered_map> 40 41 #undef DEBUG_TYPE 42 #define DEBUG_TYPE "bolt" 43 44 LLVM_ATTRIBUTE_UNUSED 45 static void printDie(const DWARFDie &DIE) { 46 DIDumpOptions DumpOpts; 47 DumpOpts.ShowForm = true; 48 DumpOpts.Verbose = true; 49 DumpOpts.ChildRecurseDepth = 0; 50 DumpOpts.ShowChildren = 0; 51 DIE.dump(dbgs(), 0, DumpOpts); 52 } 53 54 namespace llvm { 55 namespace bolt { 56 /// Finds attributes FormValue and Offset. 57 /// 58 /// \param DIE die to look up in. 59 /// \param Attr the attribute to extract. 60 /// \return an optional AttrInfo with DWARFFormValue and Offset. 61 static Optional<AttrInfo> findAttributeInfo(const DWARFDie DIE, 62 dwarf::Attribute Attr) { 63 if (!DIE.isValid()) 64 return None; 65 const DWARFAbbreviationDeclaration *AbbrevDecl = 66 DIE.getAbbreviationDeclarationPtr(); 67 if (!AbbrevDecl) 68 return None; 69 Optional<uint32_t> Index = AbbrevDecl->findAttributeIndex(Attr); 70 if (!Index) 71 return None; 72 return findAttributeInfo(DIE, AbbrevDecl, *Index); 73 } 74 } // namespace bolt 75 } // namespace llvm 76 77 using namespace llvm; 78 using namespace llvm::support::endian; 79 using namespace object; 80 using namespace bolt; 81 82 namespace opts { 83 84 extern cl::OptionCategory BoltCategory; 85 extern cl::opt<unsigned> Verbosity; 86 extern cl::opt<std::string> OutputFilename; 87 88 static cl::opt<bool> 89 KeepARanges("keep-aranges", 90 cl::desc("keep or generate .debug_aranges section if .gdb_index is written"), 91 cl::ZeroOrMore, 92 cl::Hidden, 93 cl::cat(BoltCategory)); 94 95 static cl::opt<bool> 96 DeterministicDebugInfo("deterministic-debuginfo", 97 cl::desc("disables parallel execution of tasks that may produce" 98 "nondeterministic debug info"), 99 cl::init(true), 100 cl::cat(BoltCategory)); 101 102 static cl::opt<std::string> DwarfOutputPath( 103 "dwarf-output-path", 104 cl::desc("Path to where .dwo files or dwp file will be written out to."), 105 cl::init(""), cl::cat(BoltCategory)); 106 107 static cl::opt<bool> 108 WriteDWP("write-dwp", 109 cl::desc("output a single dwarf package file (dwp) instead of " 110 "multiple non-relocatable dwarf object files (dwo)."), 111 cl::init(false), cl::cat(BoltCategory)); 112 113 static cl::opt<bool> 114 DebugSkeletonCu("debug-skeleton-cu", 115 cl::desc("prints out offsetrs for abbrev and debu_info of " 116 "Skeleton CUs that get patched."), 117 cl::ZeroOrMore, cl::Hidden, cl::init(false), 118 cl::cat(BoltCategory)); 119 } // namespace opts 120 121 /// Returns DWO Name to be used. Handles case where user specifies output DWO 122 /// directory, and there are duplicate names. Assumes DWO ID is unique. 123 static std::string 124 getDWOName(llvm::DWARFUnit &CU, 125 std::unordered_map<std::string, uint32_t> *NameToIndexMap, 126 std::unordered_map<uint64_t, std::string> &DWOIdToName) { 127 llvm::Optional<uint64_t> DWOId = CU.getDWOId(); 128 assert(DWOId && "DWO ID not found."); 129 (void)DWOId; 130 auto NameIter = DWOIdToName.find(*DWOId); 131 if (NameIter != DWOIdToName.end()) 132 return NameIter->second; 133 134 std::string DWOName = dwarf::toString( 135 CU.getUnitDIE().find({dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name}), 136 ""); 137 assert(!DWOName.empty() && 138 "DW_AT_dwo_name/DW_AT_GNU_dwo_name does not exists."); 139 if (NameToIndexMap && !opts::DwarfOutputPath.empty()) { 140 auto Iter = NameToIndexMap->find(DWOName); 141 if (Iter == NameToIndexMap->end()) 142 Iter = NameToIndexMap->insert({DWOName, 0}).first; 143 DWOName.append(std::to_string(Iter->second)); 144 ++Iter->second; 145 } 146 DWOName.append(".dwo"); 147 DWOIdToName[*DWOId] = DWOName; 148 return DWOName; 149 } 150 151 static bool isHighPcFormEightBytes(dwarf::Form DwarfForm) { 152 return DwarfForm == dwarf::DW_FORM_addr || DwarfForm == dwarf::DW_FORM_data8; 153 } 154 155 void DWARFRewriter::updateDebugInfo() { 156 ErrorOr<BinarySection &> DebugInfo = BC.getUniqueSectionByName(".debug_info"); 157 if (!DebugInfo) 158 return; 159 160 auto *DebugInfoPatcher = 161 static_cast<DebugInfoBinaryPatcher *>(DebugInfo->getPatcher()); 162 163 ARangesSectionWriter = std::make_unique<DebugARangesSectionWriter>(); 164 RangesSectionWriter = std::make_unique<DebugRangesSectionWriter>(); 165 StrWriter = std::make_unique<DebugStrWriter>(&BC); 166 AbbrevWriter = std::make_unique<DebugAbbrevWriter>(*BC.DwCtx); 167 168 AddrWriter = std::make_unique<DebugAddrWriter>(&BC); 169 DebugLoclistWriter::setAddressWriter(AddrWriter.get()); 170 171 uint64_t NumCUs = BC.DwCtx->getNumCompileUnits(); 172 if ((opts::NoThreads || opts::DeterministicDebugInfo) && 173 BC.getNumDWOCUs() == 0) { 174 // Use single entry for efficiency when running single-threaded 175 NumCUs = 1; 176 } 177 178 LocListWritersByCU.reserve(NumCUs); 179 180 for (size_t CUIndex = 0; CUIndex < NumCUs; ++CUIndex) 181 LocListWritersByCU[CUIndex] = std::make_unique<DebugLocWriter>(&BC); 182 183 // Unordered maps to handle name collision if output DWO directory is 184 // specified. 185 std::unordered_map<std::string, uint32_t> NameToIndexMap; 186 std::unordered_map<uint64_t, std::string> DWOIdToName; 187 std::mutex AccessMutex; 188 189 auto updateDWONameCompDir = [&](DWARFUnit &Unit) -> void { 190 const DWARFDie &DIE = Unit.getUnitDIE(); 191 Optional<AttrInfo> AttrInfoVal = 192 findAttributeInfo(DIE, dwarf::DW_AT_GNU_dwo_name); 193 (void)AttrInfoVal; 194 assert(AttrInfoVal && "Skeleton CU doesn't have dwo_name."); 195 196 std::string ObjectName = ""; 197 198 { 199 std::lock_guard<std::mutex> Lock(AccessMutex); 200 ObjectName = getDWOName(Unit, &NameToIndexMap, DWOIdToName); 201 } 202 203 uint32_t NewOffset = StrWriter->addString(ObjectName.c_str()); 204 DebugInfoPatcher->addLE32Patch(AttrInfoVal->Offset, NewOffset, 205 AttrInfoVal->Size); 206 207 AttrInfoVal = findAttributeInfo(DIE, dwarf::DW_AT_comp_dir); 208 (void)AttrInfoVal; 209 assert(AttrInfoVal && "DW_AT_comp_dir is not in Skeleton CU."); 210 211 if (!opts::DwarfOutputPath.empty()) { 212 uint32_t NewOffset = StrWriter->addString(opts::DwarfOutputPath.c_str()); 213 DebugInfoPatcher->addLE32Patch(AttrInfoVal->Offset, NewOffset, 214 AttrInfoVal->Size); 215 } 216 }; 217 218 auto processUnitDIE = [&](size_t CUIndex, DWARFUnit *Unit) { 219 // Check if the unit is a skeleton and we need special updates for it and 220 // its matching split/DWO CU. 221 Optional<DWARFUnit *> SplitCU; 222 Optional<uint64_t> RangesBase; 223 llvm::Optional<uint64_t> DWOId = Unit->getDWOId(); 224 if (DWOId) 225 SplitCU = BC.getDWOCU(*DWOId); 226 227 DebugLocWriter *DebugLocWriter = nullptr; 228 // Skipping CUs that failed to load. 229 if (SplitCU) { 230 updateDWONameCompDir(*Unit); 231 232 // Assuming there is unique DWOID per binary. i.e. two or more CUs don't 233 // have same DWO ID. 234 assert(LocListWritersByCU.count(*DWOId) == 0 && 235 "LocList writer for DWO unit already exists."); 236 { 237 std::lock_guard<std::mutex> Lock(AccessMutex); 238 DebugLocWriter = 239 LocListWritersByCU 240 .insert( 241 {*DWOId, std::make_unique<DebugLoclistWriter>(&BC, *DWOId)}) 242 .first->second.get(); 243 } 244 DebugInfoBinaryPatcher *DwoDebugInfoPatcher = 245 llvm::cast<DebugInfoBinaryPatcher>( 246 getBinaryDWODebugInfoPatcher(*DWOId)); 247 RangesBase = RangesSectionWriter->getSectionOffset(); 248 DWARFContext *DWOCtx = BC.getDWOContext(); 249 // Setting this CU offset with DWP to normalize DIE offsets to uint32_t 250 if (DWOCtx && !DWOCtx->getCUIndex().getRows().empty()) 251 DwoDebugInfoPatcher->setDWPOffset((*SplitCU)->getOffset()); 252 DwoDebugInfoPatcher->setRangeBase(*RangesBase); 253 DwoDebugInfoPatcher->addUnitBaseOffsetLabel((*SplitCU)->getOffset()); 254 DebugAbbrevWriter *DWOAbbrevWriter = 255 createBinaryDWOAbbrevWriter((*SplitCU)->getContext(), *DWOId); 256 updateUnitDebugInfo(*(*SplitCU), *DwoDebugInfoPatcher, *DWOAbbrevWriter, 257 *DebugLocWriter); 258 DwoDebugInfoPatcher->clearDestinationLabels(); 259 if (!DwoDebugInfoPatcher->getWasRangBasedUsed()) 260 RangesBase = None; 261 } 262 263 { 264 std::lock_guard<std::mutex> Lock(AccessMutex); 265 DebugLocWriter = LocListWritersByCU[CUIndex].get(); 266 } 267 DebugInfoPatcher->addUnitBaseOffsetLabel(Unit->getOffset()); 268 updateUnitDebugInfo(*Unit, *DebugInfoPatcher, *AbbrevWriter, 269 *DebugLocWriter, RangesBase); 270 }; 271 272 if (opts::NoThreads || opts::DeterministicDebugInfo) { 273 for (std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units()) 274 processUnitDIE(0, CU.get()); 275 } else { 276 // Update unit debug info in parallel 277 ThreadPool &ThreadPool = ParallelUtilities::getThreadPool(); 278 size_t CUIndex = 0; 279 for (std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units()) { 280 ThreadPool.async(processUnitDIE, CUIndex, CU.get()); 281 CUIndex++; 282 } 283 ThreadPool.wait(); 284 } 285 286 DebugInfoPatcher->clearDestinationLabels(); 287 CUOffsetMap OffsetMap = finalizeDebugSections(*DebugInfoPatcher); 288 289 if (opts::WriteDWP) 290 writeDWP(DWOIdToName); 291 else 292 writeDWOFiles(DWOIdToName); 293 294 updateGdbIndexSection(OffsetMap); 295 } 296 297 void DWARFRewriter::updateUnitDebugInfo( 298 DWARFUnit &Unit, DebugInfoBinaryPatcher &DebugInfoPatcher, 299 DebugAbbrevWriter &AbbrevWriter, DebugLocWriter &DebugLocWriter, 300 Optional<uint64_t> RangesBase) { 301 // Cache debug ranges so that the offset for identical ranges could be reused. 302 std::map<DebugAddressRangesVector, uint64_t> CachedRanges; 303 304 uint64_t DIEOffset = Unit.getOffset() + Unit.getHeaderSize(); 305 uint64_t NextCUOffset = Unit.getNextUnitOffset(); 306 DWARFDebugInfoEntry Die; 307 DWARFDataExtractor DebugInfoData = Unit.getDebugInfoExtractor(); 308 uint32_t Depth = 0; 309 310 while ( 311 DIEOffset < NextCUOffset && 312 Die.extractFast(Unit, &DIEOffset, DebugInfoData, NextCUOffset, Depth)) { 313 if (const DWARFAbbreviationDeclaration *AbbrDecl = 314 Die.getAbbreviationDeclarationPtr()) { 315 if (AbbrDecl->hasChildren()) 316 ++Depth; 317 } else { 318 // NULL entry. 319 if (Depth > 0) 320 --Depth; 321 if (Depth == 0) 322 break; 323 } 324 325 DWARFDie DIE(&Unit, &Die); 326 327 switch (DIE.getTag()) { 328 case dwarf::DW_TAG_compile_unit: { 329 auto ModuleRangesOrError = DIE.getAddressRanges(); 330 if (!ModuleRangesOrError) { 331 consumeError(ModuleRangesOrError.takeError()); 332 break; 333 } 334 DWARFAddressRangesVector &ModuleRanges = *ModuleRangesOrError; 335 DebugAddressRangesVector OutputRanges = 336 BC.translateModuleAddressRanges(ModuleRanges); 337 const uint64_t RangesSectionOffset = 338 RangesSectionWriter->addRanges(OutputRanges); 339 if (!Unit.isDWOUnit()) 340 ARangesSectionWriter->addCURanges(Unit.getOffset(), 341 std::move(OutputRanges)); 342 updateDWARFObjectAddressRanges(DIE, RangesSectionOffset, DebugInfoPatcher, 343 AbbrevWriter, RangesBase); 344 break; 345 } 346 case dwarf::DW_TAG_subprogram: { 347 // Get function address either from ranges or [LowPC, HighPC) pair. 348 uint64_t Address; 349 uint64_t SectionIndex, HighPC; 350 if (!DIE.getLowAndHighPC(Address, HighPC, SectionIndex)) { 351 Expected<DWARFAddressRangesVector> RangesOrError = 352 DIE.getAddressRanges(); 353 if (!RangesOrError) { 354 consumeError(RangesOrError.takeError()); 355 break; 356 } 357 DWARFAddressRangesVector Ranges = *RangesOrError; 358 // Not a function definition. 359 if (Ranges.empty()) 360 break; 361 362 Address = Ranges.front().LowPC; 363 } 364 365 // Clear cached ranges as the new function will have its own set. 366 CachedRanges.clear(); 367 368 DebugAddressRangesVector FunctionRanges; 369 if (const BinaryFunction *Function = 370 BC.getBinaryFunctionAtAddress(Address)) 371 FunctionRanges = Function->getOutputAddressRanges(); 372 373 if (FunctionRanges.empty()) 374 FunctionRanges.push_back({0, 0}); 375 376 updateDWARFObjectAddressRanges( 377 DIE, RangesSectionWriter->addRanges(FunctionRanges), DebugInfoPatcher, 378 AbbrevWriter); 379 380 break; 381 } 382 case dwarf::DW_TAG_lexical_block: 383 case dwarf::DW_TAG_inlined_subroutine: 384 case dwarf::DW_TAG_try_block: 385 case dwarf::DW_TAG_catch_block: { 386 uint64_t RangesSectionOffset = 387 RangesSectionWriter->getEmptyRangesOffset(); 388 Expected<DWARFAddressRangesVector> RangesOrError = DIE.getAddressRanges(); 389 const BinaryFunction *Function = 390 RangesOrError && !RangesOrError->empty() 391 ? BC.getBinaryFunctionContainingAddress( 392 RangesOrError->front().LowPC) 393 : nullptr; 394 if (Function) { 395 DebugAddressRangesVector OutputRanges = 396 Function->translateInputToOutputRanges(*RangesOrError); 397 LLVM_DEBUG(if (OutputRanges.empty() != RangesOrError->empty()) { 398 dbgs() << "BOLT-DEBUG: problem with DIE at 0x" 399 << Twine::utohexstr(DIE.getOffset()) << " in CU at 0x" 400 << Twine::utohexstr(Unit.getOffset()) << '\n'; 401 }); 402 RangesSectionOffset = RangesSectionWriter->addRanges( 403 std::move(OutputRanges), CachedRanges); 404 } else if (!RangesOrError) { 405 consumeError(RangesOrError.takeError()); 406 } 407 updateDWARFObjectAddressRanges(DIE, RangesSectionOffset, DebugInfoPatcher, 408 AbbrevWriter); 409 break; 410 } 411 default: { 412 // Handle any tag that can have DW_AT_location attribute. 413 DWARFFormValue Value; 414 uint64_t AttrOffset; 415 if (Optional<AttrInfo> AttrVal = 416 findAttributeInfo(DIE, dwarf::DW_AT_location)) { 417 AttrOffset = AttrVal->Offset; 418 Value = AttrVal->V; 419 if (Value.isFormClass(DWARFFormValue::FC_Constant) || 420 Value.isFormClass(DWARFFormValue::FC_SectionOffset)) { 421 uint64_t Offset = Value.isFormClass(DWARFFormValue::FC_Constant) 422 ? Value.getAsUnsignedConstant().getValue() 423 : Value.getAsSectionOffset().getValue(); 424 DebugLocationsVector InputLL; 425 426 Optional<object::SectionedAddress> SectionAddress = 427 Unit.getBaseAddress(); 428 uint64_t BaseAddress = 0; 429 if (SectionAddress) 430 BaseAddress = SectionAddress->Address; 431 432 Error E = Unit.getLocationTable().visitLocationList( 433 &Offset, [&](const DWARFLocationEntry &Entry) { 434 switch (Entry.Kind) { 435 default: 436 llvm_unreachable("Unsupported DWARFLocationEntry Kind."); 437 case dwarf::DW_LLE_end_of_list: 438 return false; 439 case dwarf::DW_LLE_base_address: 440 assert(Entry.SectionIndex == SectionedAddress::UndefSection && 441 "absolute address expected"); 442 BaseAddress = Entry.Value0; 443 break; 444 case dwarf::DW_LLE_offset_pair: 445 assert( 446 (Entry.SectionIndex == SectionedAddress::UndefSection && 447 !Unit.isDWOUnit()) && 448 "absolute address expected"); 449 InputLL.emplace_back(DebugLocationEntry{ 450 BaseAddress + Entry.Value0, BaseAddress + Entry.Value1, 451 Entry.Loc}); 452 break; 453 case dwarf::DW_LLE_startx_length: 454 assert(Unit.isDWOUnit() && 455 "None DWO Unit with DW_LLE_startx_length encoding."); 456 Optional<object::SectionedAddress> EntryAddress = 457 Unit.getAddrOffsetSectionItem(Entry.Value0); 458 assert(EntryAddress && "Address does not exist."); 459 InputLL.emplace_back(DebugLocationEntry{ 460 EntryAddress->Address, 461 EntryAddress->Address + Entry.Value1, Entry.Loc}); 462 break; 463 } 464 return true; 465 }); 466 467 if (E || InputLL.empty()) { 468 errs() << "BOLT-WARNING: empty location list detected at 0x" 469 << Twine::utohexstr(Offset) << " for DIE at 0x" 470 << Twine::utohexstr(DIE.getOffset()) << " in CU at 0x" 471 << Twine::utohexstr(Unit.getOffset()) << '\n'; 472 } else { 473 const uint64_t Address = InputLL.front().LowPC; 474 if (const BinaryFunction *Function = 475 BC.getBinaryFunctionContainingAddress(Address)) { 476 DebugLocationsVector OutputLL = 477 Function->translateInputToOutputLocationList(InputLL); 478 LLVM_DEBUG(if (OutputLL.empty()) { 479 dbgs() << "BOLT-DEBUG: location list translated to an empty " 480 "one at 0x" 481 << Twine::utohexstr(DIE.getOffset()) << " in CU at 0x" 482 << Twine::utohexstr(Unit.getOffset()) << '\n'; 483 }); 484 DebugLocWriter.addList(AttrOffset, std::move(OutputLL)); 485 } 486 } 487 } else { 488 assert((Value.isFormClass(DWARFFormValue::FC_Exprloc) || 489 Value.isFormClass(DWARFFormValue::FC_Block)) && 490 "unexpected DW_AT_location form"); 491 if (Unit.isDWOUnit()) { 492 ArrayRef<uint8_t> Expr = *Value.getAsBlock(); 493 DataExtractor Data( 494 StringRef((const char *)Expr.data(), Expr.size()), 495 Unit.getContext().isLittleEndian(), 0); 496 DWARFExpression LocExpr(Data, Unit.getAddressByteSize(), 497 Unit.getFormParams().Format); 498 for (auto &Expr : LocExpr) { 499 if (Expr.getCode() != dwarf::DW_OP_GNU_addr_index) 500 continue; 501 uint64_t Index = Expr.getRawOperand(0); 502 Optional<object::SectionedAddress> EntryAddress = 503 Unit.getAddrOffsetSectionItem(Index); 504 assert(EntryAddress && "Address is not found."); 505 assert(Index <= std::numeric_limits<uint32_t>::max() && 506 "Invalid Operand Index."); 507 AddrWriter->addIndexAddress(EntryAddress->Address, 508 static_cast<uint32_t>(Index), 509 *Unit.getDWOId()); 510 } 511 } 512 } 513 } else if (Optional<AttrInfo> AttrVal = 514 findAttributeInfo(DIE, dwarf::DW_AT_low_pc)) { 515 AttrOffset = AttrVal->Offset; 516 Value = AttrVal->V; 517 const Optional<uint64_t> Result = Value.getAsAddress(); 518 if (Result.hasValue()) { 519 const uint64_t Address = Result.getValue(); 520 uint64_t NewAddress = 0; 521 if (const BinaryFunction *Function = 522 BC.getBinaryFunctionContainingAddress(Address)) { 523 NewAddress = Function->translateInputToOutputAddress(Address); 524 LLVM_DEBUG(dbgs() 525 << "BOLT-DEBUG: Fixing low_pc 0x" 526 << Twine::utohexstr(Address) << " for DIE with tag " 527 << DIE.getTag() << " to 0x" 528 << Twine::utohexstr(NewAddress) << '\n'); 529 } 530 531 dwarf::Form Form = Value.getForm(); 532 assert(Form != dwarf::DW_FORM_LLVM_addrx_offset && 533 "DW_FORM_LLVM_addrx_offset is not supported"); 534 std::lock_guard<std::mutex> Lock(DebugInfoPatcherMutex); 535 if (Form == dwarf::DW_FORM_GNU_addr_index) { 536 assert(Unit.isDWOUnit() && 537 "DW_FORM_GNU_addr_index in Non DWO unit."); 538 uint64_t Index = Value.getRawUValue(); 539 // If there is no new address, storing old address. 540 // Re-using Index to make implementation easier. 541 // DW_FORM_GNU_addr_index is variable lenght encoding so we either 542 // have to create indices of same sizes, or use same index. 543 AddrWriter->addIndexAddress(NewAddress ? NewAddress : Address, 544 Index, *Unit.getDWOId()); 545 } else { 546 DebugInfoPatcher.addLE64Patch(AttrOffset, NewAddress); 547 } 548 } else if (opts::Verbosity >= 1) { 549 errs() << "BOLT-WARNING: unexpected form value for attribute at 0x" 550 << Twine::utohexstr(AttrOffset); 551 } 552 } 553 } 554 } 555 556 // Handling references. 557 assert(DIE.isValid() && "Invalid DIE."); 558 const DWARFAbbreviationDeclaration *AbbrevDecl = 559 DIE.getAbbreviationDeclarationPtr(); 560 if (!AbbrevDecl) 561 continue; 562 uint32_t Index = 0; 563 for (const DWARFAbbreviationDeclaration::AttributeSpec &Decl : 564 AbbrevDecl->attributes()) { 565 switch (Decl.Form) { 566 default: 567 break; 568 case dwarf::DW_FORM_ref1: 569 case dwarf::DW_FORM_ref2: 570 case dwarf::DW_FORM_ref4: 571 case dwarf::DW_FORM_ref8: 572 case dwarf::DW_FORM_ref_udata: 573 case dwarf::DW_FORM_ref_addr: { 574 Optional<AttrInfo> AttrVal = findAttributeInfo(DIE, AbbrevDecl, Index); 575 uint32_t DestinationAddress = 576 AttrVal->V.getRawUValue() + 577 (Decl.Form == dwarf::DW_FORM_ref_addr ? 0 : Unit.getOffset()); 578 DebugInfoPatcher.addReferenceToPatch( 579 AttrVal->Offset, DestinationAddress, AttrVal->Size, Decl.Form); 580 // We can have only one reference, and it can be backward one. 581 DebugInfoPatcher.addDestinationReferenceLabel(DestinationAddress); 582 break; 583 } 584 } 585 ++Index; 586 } 587 } 588 if (DIEOffset > NextCUOffset) 589 errs() << "BOLT-WARNING: corrupt DWARF detected at 0x" 590 << Twine::utohexstr(Unit.getOffset()) << '\n'; 591 } 592 593 void DWARFRewriter::updateDWARFObjectAddressRanges( 594 const DWARFDie DIE, uint64_t DebugRangesOffset, 595 SimpleBinaryPatcher &DebugInfoPatcher, DebugAbbrevWriter &AbbrevWriter, 596 Optional<uint64_t> RangesBase) { 597 598 // Some objects don't have an associated DIE and cannot be updated (such as 599 // compiler-generated functions). 600 if (!DIE) 601 return; 602 603 const DWARFAbbreviationDeclaration *AbbreviationDecl = 604 DIE.getAbbreviationDeclarationPtr(); 605 if (!AbbreviationDecl) { 606 if (opts::Verbosity >= 1) 607 errs() << "BOLT-WARNING: object's DIE doesn't have an abbreviation: " 608 << "skipping update. DIE at offset 0x" 609 << Twine::utohexstr(DIE.getOffset()) << '\n'; 610 return; 611 } 612 613 if (RangesBase) { 614 // If DW_AT_GNU_ranges_base is present, update it. No further modifications 615 // are needed for ranges base. 616 Optional<AttrInfo> RangesBaseAttrInfo = 617 findAttributeInfo(DIE, dwarf::DW_AT_GNU_ranges_base); 618 if (RangesBaseAttrInfo) { 619 DebugInfoPatcher.addLE32Patch(RangesBaseAttrInfo->Offset, 620 static_cast<uint32_t>(*RangesBase), 621 RangesBaseAttrInfo->Size); 622 RangesBase = None; 623 } 624 } 625 626 Optional<AttrInfo> LowPCAttrInfo = 627 findAttributeInfo(DIE, dwarf::DW_AT_low_pc); 628 if (AbbreviationDecl->findAttributeIndex(dwarf::DW_AT_ranges)) { 629 // Case 1: The object was already non-contiguous and had DW_AT_ranges. 630 // In this case we simply need to update the value of DW_AT_ranges 631 // and introduce DW_AT_GNU_ranges_base if required. 632 Optional<AttrInfo> AttrVal = findAttributeInfo(DIE, dwarf::DW_AT_ranges); 633 std::lock_guard<std::mutex> Lock(DebugInfoPatcherMutex); 634 DebugInfoPatcher.addLE32Patch( 635 AttrVal->Offset, DebugRangesOffset - DebugInfoPatcher.getRangeBase(), 636 AttrVal->Size); 637 638 if (!RangesBase) { 639 if (LowPCAttrInfo && 640 LowPCAttrInfo->V.getForm() != dwarf::DW_FORM_GNU_addr_index && 641 LowPCAttrInfo->V.getForm() != dwarf::DW_FORM_addrx) 642 DebugInfoPatcher.addLE64Patch(LowPCAttrInfo->Offset, 0); 643 return; 644 } 645 646 // Convert DW_AT_low_pc into DW_AT_GNU_ranges_base. 647 if (!LowPCAttrInfo) { 648 errs() << "BOLT-ERROR: skeleton CU at 0x" 649 << Twine::utohexstr(DIE.getOffset()) 650 << " does not have DW_AT_GNU_ranges_base or DW_AT_low_pc to" 651 " convert to update ranges base\n"; 652 return; 653 } 654 655 AbbrevWriter.addAttribute(*DIE.getDwarfUnit(), AbbreviationDecl, 656 dwarf::DW_AT_GNU_ranges_base, 657 dwarf::DW_FORM_sec_offset); 658 reinterpret_cast<DebugInfoBinaryPatcher &>(DebugInfoPatcher) 659 .insertNewEntry(DIE, *RangesBase); 660 661 return; 662 } 663 664 // Case 2: The object has both DW_AT_low_pc and DW_AT_high_pc emitted back 665 // to back. Replace with new attributes and patch the DIE. 666 Optional<AttrInfo> HighPCAttrInfo = 667 findAttributeInfo(DIE, dwarf::DW_AT_high_pc); 668 if (LowPCAttrInfo && HighPCAttrInfo) { 669 convertToRangesPatchAbbrev(*DIE.getDwarfUnit(), AbbreviationDecl, 670 AbbrevWriter, RangesBase); 671 convertToRangesPatchDebugInfo(DIE, DebugRangesOffset, DebugInfoPatcher, 672 RangesBase); 673 } else { 674 if (opts::Verbosity >= 1) 675 errs() << "BOLT-ERROR: cannot update ranges for DIE at offset 0x" 676 << Twine::utohexstr(DIE.getOffset()) << '\n'; 677 } 678 } 679 680 void DWARFRewriter::updateLineTableOffsets(const MCAsmLayout &Layout) { 681 ErrorOr<BinarySection &> DbgInfoSection = 682 BC.getUniqueSectionByName(".debug_info"); 683 ErrorOr<BinarySection &> TypeInfoSection = 684 BC.getUniqueSectionByName(".debug_types"); 685 assert(((BC.DwCtx->getNumTypeUnits() > 0 && TypeInfoSection) || 686 BC.DwCtx->getNumTypeUnits() == 0) && 687 "Was not able to retrieve Debug Types section."); 688 689 // We will be re-writing .debug_info so relocation mechanism doesn't work for 690 // Debug Info Patcher. 691 DebugInfoBinaryPatcher *DebugInfoPatcher = nullptr; 692 if (BC.DwCtx->getNumCompileUnits()) { 693 DbgInfoSection->registerPatcher(std::make_unique<DebugInfoBinaryPatcher>()); 694 DebugInfoPatcher = 695 static_cast<DebugInfoBinaryPatcher *>(DbgInfoSection->getPatcher()); 696 } 697 698 // There is no direct connection between CU and TU, but same offsets, 699 // encoded in DW_AT_stmt_list, into .debug_line get modified. 700 // We take advantage of that to map original CU line table offsets to new 701 // ones. 702 std::unordered_map<uint64_t, uint64_t> DebugLineOffsetMap; 703 704 auto GetStatementListValue = [](DWARFUnit *Unit) { 705 Optional<DWARFFormValue> StmtList = 706 Unit->getUnitDIE().find(dwarf::DW_AT_stmt_list); 707 Optional<uint64_t> Offset = dwarf::toSectionOffset(StmtList); 708 assert(Offset && "Was not able to retreive value of DW_AT_stmt_list."); 709 return *Offset; 710 }; 711 712 const uint64_t Reloc32Type = BC.isAArch64() 713 ? static_cast<uint64_t>(ELF::R_AARCH64_ABS32) 714 : static_cast<uint64_t>(ELF::R_X86_64_32); 715 716 for (const std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units()) { 717 const unsigned CUID = CU->getOffset(); 718 MCSymbol *Label = BC.getDwarfLineTable(CUID).getLabel(); 719 if (!Label) 720 continue; 721 722 Optional<AttrInfo> AttrVal = 723 findAttributeInfo(CU.get()->getUnitDIE(), dwarf::DW_AT_stmt_list); 724 if (!AttrVal) 725 continue; 726 727 const uint64_t AttributeOffset = AttrVal->Offset; 728 const uint64_t LineTableOffset = Layout.getSymbolOffset(*Label); 729 DebugLineOffsetMap[GetStatementListValue(CU.get())] = LineTableOffset; 730 assert(DbgInfoSection && ".debug_info section must exist"); 731 DebugInfoPatcher->addLE32Patch(AttributeOffset, LineTableOffset); 732 } 733 734 for (const std::unique_ptr<DWARFUnit> &TU : BC.DwCtx->types_section_units()) { 735 DWARFUnit *Unit = TU.get(); 736 Optional<AttrInfo> AttrVal = 737 findAttributeInfo(TU.get()->getUnitDIE(), dwarf::DW_AT_stmt_list); 738 if (!AttrVal) 739 continue; 740 const uint64_t AttributeOffset = AttrVal->Offset; 741 auto Iter = DebugLineOffsetMap.find(GetStatementListValue(Unit)); 742 assert(Iter != DebugLineOffsetMap.end() && 743 "Type Unit Updated Line Number Entry does not exist."); 744 TypeInfoSection->addRelocation(AttributeOffset, nullptr, Reloc32Type, 745 Iter->second, 0, /*Pending=*/true); 746 } 747 748 // Set .debug_info as finalized so it won't be skipped over when 749 // we process sections while writing out the new binary. This ensures 750 // that the pending relocations will be processed and not ignored. 751 if (DbgInfoSection) 752 DbgInfoSection->setIsFinalized(); 753 754 if (TypeInfoSection) 755 TypeInfoSection->setIsFinalized(); 756 } 757 758 CUOffsetMap 759 DWARFRewriter::finalizeDebugSections(DebugInfoBinaryPatcher &DebugInfoPatcher) { 760 if (StrWriter->isInitialized()) { 761 RewriteInstance::addToDebugSectionsToOverwrite(".debug_str"); 762 std::unique_ptr<DebugStrBufferVector> DebugStrSectionContents = 763 StrWriter->finalize(); 764 BC.registerOrUpdateNoteSection(".debug_str", 765 copyByteArray(*DebugStrSectionContents), 766 DebugStrSectionContents->size()); 767 } 768 769 std::unique_ptr<DebugBufferVector> RangesSectionContents = 770 RangesSectionWriter->finalize(); 771 BC.registerOrUpdateNoteSection(".debug_ranges", 772 copyByteArray(*RangesSectionContents), 773 RangesSectionContents->size()); 774 775 std::unique_ptr<DebugBufferVector> LocationListSectionContents = 776 makeFinalLocListsSection(DebugInfoPatcher); 777 BC.registerOrUpdateNoteSection(".debug_loc", 778 copyByteArray(*LocationListSectionContents), 779 LocationListSectionContents->size()); 780 781 // AddrWriter should be finalized after debug_loc since more addresses can be 782 // added there. 783 if (AddrWriter->isInitialized()) { 784 AddressSectionBuffer AddressSectionContents = AddrWriter->finalize(); 785 BC.registerOrUpdateNoteSection(".debug_addr", 786 copyByteArray(AddressSectionContents), 787 AddressSectionContents.size()); 788 for (auto &CU : BC.DwCtx->compile_units()) { 789 DWARFDie DIE = CU->getUnitDIE(); 790 if (Optional<AttrInfo> AttrVal = 791 findAttributeInfo(DIE, dwarf::DW_AT_GNU_addr_base)) { 792 uint64_t Offset = AddrWriter->getOffset(*CU->getDWOId()); 793 DebugInfoPatcher.addLE32Patch( 794 AttrVal->Offset, static_cast<int32_t>(Offset), AttrVal->Size); 795 } 796 } 797 } 798 799 std::unique_ptr<DebugBufferVector> AbbrevSectionContents = 800 AbbrevWriter->finalize(); 801 BC.registerOrUpdateNoteSection(".debug_abbrev", 802 copyByteArray(*AbbrevSectionContents), 803 AbbrevSectionContents->size()); 804 805 // Update abbreviation offsets for CUs/TUs if they were changed. 806 SimpleBinaryPatcher *DebugTypesPatcher = nullptr; 807 for (auto &Unit : BC.DwCtx->normal_units()) { 808 const uint64_t NewAbbrevOffset = 809 AbbrevWriter->getAbbreviationsOffsetForUnit(*Unit); 810 if (Unit->getAbbreviationsOffset() == NewAbbrevOffset) 811 continue; 812 813 // DWARFv4 814 // unit_length - 4 bytes 815 // version - 2 bytes 816 // So + 6 to patch debug_abbrev_offset 817 constexpr uint64_t AbbrevFieldOffset = 6; 818 if (!Unit->isTypeUnit()) { 819 DebugInfoPatcher.addLE32Patch(Unit->getOffset() + AbbrevFieldOffset, 820 static_cast<uint32_t>(NewAbbrevOffset)); 821 continue; 822 } 823 824 if (!DebugTypesPatcher) { 825 ErrorOr<BinarySection &> DebugTypes = 826 BC.getUniqueSectionByName(".debug_types"); 827 DebugTypes->registerPatcher(std::make_unique<SimpleBinaryPatcher>()); 828 DebugTypesPatcher = 829 static_cast<SimpleBinaryPatcher *>(DebugTypes->getPatcher()); 830 } 831 DebugTypesPatcher->addLE32Patch(Unit->getOffset() + AbbrevFieldOffset, 832 static_cast<uint32_t>(NewAbbrevOffset)); 833 } 834 835 // No more creating new DebugInfoPatches. 836 CUOffsetMap CUMap = 837 DebugInfoPatcher.computeNewOffsets(*BC.DwCtx.get(), false); 838 839 // Skip .debug_aranges if we are re-generating .gdb_index. 840 if (opts::KeepARanges || !BC.getGdbIndexSection()) { 841 SmallVector<char, 16> ARangesBuffer; 842 raw_svector_ostream OS(ARangesBuffer); 843 844 auto MAB = std::unique_ptr<MCAsmBackend>( 845 BC.TheTarget->createMCAsmBackend(*BC.STI, *BC.MRI, MCTargetOptions())); 846 847 ARangesSectionWriter->writeARangesSection(OS, CUMap); 848 const StringRef &ARangesContents = OS.str(); 849 850 BC.registerOrUpdateNoteSection(".debug_aranges", 851 copyByteArray(ARangesContents), 852 ARangesContents.size()); 853 } 854 return CUMap; 855 } 856 857 // Creates all the data structures necessary for creating MCStreamer. 858 // They are passed by reference because they need to be kept around. 859 // Also creates known debug sections. These are sections handled by 860 // handleDebugDataPatching. 861 using KnownSectionsEntry = std::pair<MCSection *, DWARFSectionKind>; 862 namespace { 863 864 std::unique_ptr<BinaryContext> 865 createDwarfOnlyBC(const object::ObjectFile &File) { 866 return BinaryContext::createBinaryContext( 867 &File, false, 868 DWARFContext::create(File, DWARFContext::ProcessDebugRelocations::Ignore, 869 nullptr, "", WithColor::defaultErrorHandler, 870 WithColor::defaultWarningHandler)); 871 } 872 873 StringMap<KnownSectionsEntry> 874 createKnownSectionsMap(const MCObjectFileInfo &MCOFI) { 875 StringMap<KnownSectionsEntry> KnownSectionsTemp = { 876 {"debug_info.dwo", {MCOFI.getDwarfInfoDWOSection(), DW_SECT_INFO}}, 877 {"debug_types.dwo", {MCOFI.getDwarfTypesDWOSection(), DW_SECT_EXT_TYPES}}, 878 {"debug_str_offsets.dwo", 879 {MCOFI.getDwarfStrOffDWOSection(), DW_SECT_STR_OFFSETS}}, 880 {"debug_str.dwo", {MCOFI.getDwarfStrDWOSection(), DW_SECT_EXT_unknown}}, 881 {"debug_loc.dwo", {MCOFI.getDwarfLocDWOSection(), DW_SECT_EXT_LOC}}, 882 {"debug_abbrev.dwo", {MCOFI.getDwarfAbbrevDWOSection(), DW_SECT_ABBREV}}, 883 {"debug_line.dwo", {MCOFI.getDwarfLineDWOSection(), DW_SECT_LINE}}}; 884 return KnownSectionsTemp; 885 } 886 887 StringRef getSectionName(const SectionRef &Section) { 888 Expected<StringRef> SectionName = Section.getName(); 889 assert(SectionName && "Invalid section name."); 890 StringRef Name = *SectionName; 891 Name = Name.substr(Name.find_first_not_of("._")); 892 return Name; 893 } 894 895 // Exctracts an appropriate slice if input is DWP. 896 // Applies patches or overwrites the section. 897 Optional<StringRef> updateDebugData( 898 DWARFContext &DWCtx, std::string &Storage, const SectionRef &Section, 899 const StringMap<KnownSectionsEntry> &KnownSections, MCStreamer &Streamer, 900 DWARFRewriter &Writer, const DWARFUnitIndex::Entry *DWOEntry, 901 uint64_t DWOId, std::unique_ptr<DebugBufferVector> &OutputBuffer) { 902 auto applyPatch = [&](DebugInfoBinaryPatcher *Patcher, 903 StringRef Data) -> StringRef { 904 Patcher->computeNewOffsets(DWCtx, true); 905 Storage = Patcher->patchBinary(Data); 906 return StringRef(Storage.c_str(), Storage.size()); 907 }; 908 909 using DWOSectionContribution = 910 const DWARFUnitIndex::Entry::SectionContribution; 911 auto getSliceData = [&](const DWARFUnitIndex::Entry *DWOEntry, 912 StringRef OutData, DWARFSectionKind Sec, 913 uint32_t &DWPOffset) -> StringRef { 914 if (DWOEntry) { 915 DWOSectionContribution *DWOContrubution = DWOEntry->getContribution(Sec); 916 DWPOffset = DWOContrubution->Offset; 917 OutData = OutData.substr(DWPOffset, DWOContrubution->Length); 918 } 919 return OutData; 920 }; 921 922 StringRef Name = getSectionName(Section); 923 auto SectionIter = KnownSections.find(Name); 924 if (SectionIter == KnownSections.end()) 925 return None; 926 Streamer.SwitchSection(SectionIter->second.first); 927 Expected<StringRef> Contents = Section.getContents(); 928 assert(Contents && "Invalid contents."); 929 StringRef OutData = *Contents; 930 uint32_t DWPOffset = 0; 931 932 switch (SectionIter->second.second) { 933 default: { 934 if (!Name.equals("debug_str.dwo")) 935 errs() << "BOLT-WARNING: Unsupported Debug section: " << Name << "\n"; 936 return OutData; 937 } 938 case DWARFSectionKind::DW_SECT_INFO: { 939 OutData = getSliceData(DWOEntry, OutData, DWARFSectionKind::DW_SECT_INFO, 940 DWPOffset); 941 DebugInfoBinaryPatcher *Patcher = llvm::cast<DebugInfoBinaryPatcher>( 942 Writer.getBinaryDWODebugInfoPatcher(DWOId)); 943 return applyPatch(Patcher, OutData); 944 } 945 case DWARFSectionKind::DW_SECT_EXT_TYPES: { 946 return getSliceData(DWOEntry, OutData, DWARFSectionKind::DW_SECT_EXT_TYPES, 947 DWPOffset); 948 } 949 case DWARFSectionKind::DW_SECT_STR_OFFSETS: { 950 return getSliceData(DWOEntry, OutData, 951 DWARFSectionKind::DW_SECT_STR_OFFSETS, DWPOffset); 952 } 953 case DWARFSectionKind::DW_SECT_ABBREV: { 954 DebugAbbrevWriter *AbbrevWriter = Writer.getBinaryDWOAbbrevWriter(DWOId); 955 OutputBuffer = AbbrevWriter->finalize(); 956 // Creating explicit StringRef here, otherwise 957 // with impicit conversion it will take null byte as end of 958 // string. 959 return StringRef(reinterpret_cast<const char *>(OutputBuffer->data()), 960 OutputBuffer->size()); 961 } 962 case DWARFSectionKind::DW_SECT_EXT_LOC: { 963 DebugLocWriter *LocWriter = Writer.getDebugLocWriter(DWOId); 964 OutputBuffer = LocWriter->getBuffer(); 965 // Creating explicit StringRef here, otherwise 966 // with impicit conversion it will take null byte as end of 967 // string. 968 return StringRef(reinterpret_cast<const char *>(OutputBuffer->data()), 969 OutputBuffer->size()); 970 } 971 case DWARFSectionKind::DW_SECT_LINE: { 972 return getSliceData(DWOEntry, OutData, DWARFSectionKind::DW_SECT_LINE, 973 DWPOffset); 974 } 975 } 976 } 977 978 } // namespace 979 980 void DWARFRewriter::writeDWP( 981 std::unordered_map<uint64_t, std::string> &DWOIdToName) { 982 SmallString<0> OutputNameStr; 983 StringRef OutputName; 984 if (opts::DwarfOutputPath.empty()) { 985 OutputName = 986 Twine(opts::OutputFilename).concat(".dwp").toStringRef(OutputNameStr); 987 } else { 988 StringRef ExeFileName = llvm::sys::path::filename(opts::OutputFilename); 989 OutputName = Twine(opts::DwarfOutputPath) 990 .concat("/") 991 .concat(ExeFileName) 992 .concat(".dwp") 993 .toStringRef(OutputNameStr); 994 errs() << "BOLT-WARNING: dwarf-output-path is in effect and .dwp file will " 995 "possibly be written to another location that is not the same as " 996 "the executable\n"; 997 } 998 std::error_code EC; 999 std::unique_ptr<ToolOutputFile> Out = 1000 std::make_unique<ToolOutputFile>(OutputName, EC, sys::fs::OF_None); 1001 1002 const object::ObjectFile *File = BC.DwCtx->getDWARFObj().getFile(); 1003 std::unique_ptr<BinaryContext> TmpBC = createDwarfOnlyBC(*File); 1004 std::unique_ptr<MCStreamer> Streamer = TmpBC->createStreamer(Out->os()); 1005 const MCObjectFileInfo &MCOFI = *Streamer->getContext().getObjectFileInfo(); 1006 StringMap<KnownSectionsEntry> KnownSections = createKnownSectionsMap(MCOFI); 1007 MCSection *const StrSection = MCOFI.getDwarfStrDWOSection(); 1008 MCSection *const StrOffsetSection = MCOFI.getDwarfStrOffDWOSection(); 1009 1010 // Data Structures for DWP book keeping 1011 // Size of array corresponds to the number of sections supported by DWO format 1012 // in DWARF4/5. 1013 uint32_t ContributionOffsets[8] = {}; 1014 std::deque<SmallString<32>> UncompressedSections; 1015 DWPStringPool Strings(*Streamer, StrSection); 1016 MapVector<uint64_t, UnitIndexEntry> IndexEntries; 1017 constexpr uint32_t IndexVersion = 2; 1018 1019 // Setup DWP code once. 1020 DWARFContext *DWOCtx = BC.getDWOContext(); 1021 const DWARFUnitIndex *CUIndex = nullptr; 1022 bool IsDWP = false; 1023 if (DWOCtx) { 1024 CUIndex = &DWOCtx->getCUIndex(); 1025 IsDWP = !CUIndex->getRows().empty(); 1026 } 1027 1028 for (const std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units()) { 1029 Optional<uint64_t> DWOId = CU->getDWOId(); 1030 if (!DWOId) 1031 continue; 1032 1033 // Skipping CUs that we failed to load. 1034 Optional<DWARFUnit *> DWOCU = BC.getDWOCU(*DWOId); 1035 if (!DWOCU) 1036 continue; 1037 1038 assert(CU->getVersion() == 4 && "For DWP output only DWARF4 is supported"); 1039 UnitIndexEntry CurEntry = {}; 1040 CurEntry.DWOName = 1041 dwarf::toString(CU->getUnitDIE().find( 1042 {dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name}), 1043 ""); 1044 const char *Name = CU->getUnitDIE().getShortName(); 1045 if (Name) 1046 CurEntry.Name = Name; 1047 StringRef CurStrSection; 1048 StringRef CurStrOffsetSection; 1049 1050 // This maps each section contained in this file to its length. 1051 // This information is later on used to calculate the contributions, 1052 // i.e. offset and length, of each compile/type unit to a section. 1053 std::vector<std::pair<DWARFSectionKind, uint32_t>> SectionLength; 1054 1055 const DWARFUnitIndex::Entry *DWOEntry = nullptr; 1056 if (IsDWP) 1057 DWOEntry = CUIndex->getFromHash(*DWOId); 1058 1059 bool StrSectionWrittenOut = false; 1060 const object::ObjectFile *DWOFile = 1061 (*DWOCU)->getContext().getDWARFObj().getFile(); 1062 for (const SectionRef &Section : DWOFile->sections()) { 1063 std::string Storage = ""; 1064 std::unique_ptr<DebugBufferVector> OutputData; 1065 Optional<StringRef> TOutData = updateDebugData( 1066 (*DWOCU)->getContext(), Storage, Section, KnownSections, *Streamer, 1067 *this, DWOEntry, *DWOId, OutputData); 1068 if (!TOutData) 1069 continue; 1070 1071 StringRef OutData = *TOutData; 1072 StringRef Name = getSectionName(Section); 1073 if (Name.equals("debug_str.dwo")) { 1074 CurStrSection = OutData; 1075 } else { 1076 // Since handleDebugDataPatching returned true, we already know this is 1077 // a known section. 1078 auto SectionIter = KnownSections.find(Name); 1079 if (SectionIter->second.second == DWARFSectionKind::DW_SECT_STR_OFFSETS) 1080 CurStrOffsetSection = OutData; 1081 else 1082 Streamer->emitBytes(OutData); 1083 auto Index = 1084 getContributionIndex(SectionIter->second.second, IndexVersion); 1085 CurEntry.Contributions[Index].Offset = ContributionOffsets[Index]; 1086 CurEntry.Contributions[Index].Length = OutData.size(); 1087 ContributionOffsets[Index] += CurEntry.Contributions[Index].Length; 1088 } 1089 1090 // Strings are combined in to a new string section, and de-duplicated 1091 // based on hash. 1092 if (!StrSectionWrittenOut && !CurStrOffsetSection.empty() && 1093 !CurStrSection.empty()) { 1094 writeStringsAndOffsets(*Streamer.get(), Strings, StrOffsetSection, 1095 CurStrSection, CurStrOffsetSection, 1096 CU->getVersion()); 1097 StrSectionWrittenOut = true; 1098 } 1099 } 1100 CompileUnitIdentifiers CUI{*DWOId, CurEntry.Name.c_str(), 1101 CurEntry.DWOName.c_str()}; 1102 auto P = IndexEntries.insert(std::make_pair(CUI.Signature, CurEntry)); 1103 if (!P.second) { 1104 Error Err = buildDuplicateError(*P.first, CUI, ""); 1105 errs() << "BOLT-ERROR: " << toString(std::move(Err)) << "\n"; 1106 return; 1107 } 1108 } 1109 1110 // Lie about the type contribution for DWARF < 5. In DWARFv5 the type 1111 // section does not exist, so no need to do anything about this. 1112 ContributionOffsets[getContributionIndex(DW_SECT_EXT_TYPES, 2)] = 0; 1113 writeIndex(*Streamer.get(), MCOFI.getDwarfCUIndexSection(), 1114 ContributionOffsets, IndexEntries, IndexVersion); 1115 1116 Streamer->Finish(); 1117 Out->keep(); 1118 } 1119 1120 void DWARFRewriter::writeDWOFiles( 1121 std::unordered_map<uint64_t, std::string> &DWOIdToName) { 1122 // Setup DWP code once. 1123 DWARFContext *DWOCtx = BC.getDWOContext(); 1124 const DWARFUnitIndex *CUIndex = nullptr; 1125 bool IsDWP = false; 1126 if (DWOCtx) { 1127 CUIndex = &DWOCtx->getCUIndex(); 1128 IsDWP = !CUIndex->getRows().empty(); 1129 } 1130 1131 for (const std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units()) { 1132 Optional<uint64_t> DWOId = CU->getDWOId(); 1133 if (!DWOId) 1134 continue; 1135 1136 // Skipping CUs that we failed to load. 1137 Optional<DWARFUnit *> DWOCU = BC.getDWOCU(*DWOId); 1138 if (!DWOCU) 1139 continue; 1140 1141 std::string CompDir = opts::DwarfOutputPath.empty() 1142 ? CU->getCompilationDir() 1143 : opts::DwarfOutputPath.c_str(); 1144 std::string ObjectName = getDWOName(*CU.get(), nullptr, DWOIdToName); 1145 auto FullPath = CompDir.append("/").append(ObjectName); 1146 1147 std::error_code EC; 1148 std::unique_ptr<ToolOutputFile> TempOut = 1149 std::make_unique<ToolOutputFile>(FullPath, EC, sys::fs::OF_None); 1150 1151 const DWARFUnitIndex::Entry *DWOEntry = nullptr; 1152 if (IsDWP) 1153 DWOEntry = CUIndex->getFromHash(*DWOId); 1154 1155 const object::ObjectFile *File = 1156 (*DWOCU)->getContext().getDWARFObj().getFile(); 1157 std::unique_ptr<BinaryContext> TmpBC = createDwarfOnlyBC(*File); 1158 std::unique_ptr<MCStreamer> Streamer = TmpBC->createStreamer(TempOut->os()); 1159 StringMap<KnownSectionsEntry> KnownSections = 1160 createKnownSectionsMap(*Streamer->getContext().getObjectFileInfo()); 1161 1162 for (const SectionRef &Section : File->sections()) { 1163 std::string Storage = ""; 1164 std::unique_ptr<DebugBufferVector> OutputData; 1165 if (Optional<StringRef> OutData = updateDebugData( 1166 (*DWOCU)->getContext(), Storage, Section, KnownSections, 1167 *Streamer, *this, DWOEntry, *DWOId, OutputData)) 1168 Streamer->emitBytes(*OutData); 1169 } 1170 Streamer->Finish(); 1171 TempOut->keep(); 1172 } 1173 } 1174 1175 void DWARFRewriter::updateGdbIndexSection(CUOffsetMap &CUMap) { 1176 if (!BC.getGdbIndexSection()) 1177 return; 1178 1179 // See https://sourceware.org/gdb/onlinedocs/gdb/Index-Section-Format.html 1180 // for .gdb_index section format. 1181 1182 StringRef GdbIndexContents = BC.getGdbIndexSection()->getContents(); 1183 1184 const char *Data = GdbIndexContents.data(); 1185 1186 // Parse the header. 1187 const uint32_t Version = read32le(Data); 1188 if (Version != 7 && Version != 8) { 1189 errs() << "BOLT-ERROR: can only process .gdb_index versions 7 and 8\n"; 1190 exit(1); 1191 } 1192 1193 // Some .gdb_index generators use file offsets while others use section 1194 // offsets. Hence we can only rely on offsets relative to each other, 1195 // and ignore their absolute values. 1196 const uint32_t CUListOffset = read32le(Data + 4); 1197 const uint32_t CUTypesOffset = read32le(Data + 8); 1198 const uint32_t AddressTableOffset = read32le(Data + 12); 1199 const uint32_t SymbolTableOffset = read32le(Data + 16); 1200 const uint32_t ConstantPoolOffset = read32le(Data + 20); 1201 Data += 24; 1202 1203 // Map CUs offsets to indices and verify existing index table. 1204 std::map<uint32_t, uint32_t> OffsetToIndexMap; 1205 const uint32_t CUListSize = CUTypesOffset - CUListOffset; 1206 const unsigned NumCUs = BC.DwCtx->getNumCompileUnits(); 1207 if (CUListSize != NumCUs * 16) { 1208 errs() << "BOLT-ERROR: .gdb_index: CU count mismatch\n"; 1209 exit(1); 1210 } 1211 for (unsigned Index = 0; Index < NumCUs; ++Index, Data += 16) { 1212 const DWARFUnit *CU = BC.DwCtx->getUnitAtIndex(Index); 1213 const uint64_t Offset = read64le(Data); 1214 if (CU->getOffset() != Offset) { 1215 errs() << "BOLT-ERROR: .gdb_index CU offset mismatch\n"; 1216 exit(1); 1217 } 1218 1219 OffsetToIndexMap[Offset] = Index; 1220 } 1221 1222 // Ignore old address table. 1223 const uint32_t OldAddressTableSize = SymbolTableOffset - AddressTableOffset; 1224 // Move Data to the beginning of symbol table. 1225 Data += SymbolTableOffset - CUTypesOffset; 1226 1227 // Calculate the size of the new address table. 1228 uint32_t NewAddressTableSize = 0; 1229 for (const auto &CURangesPair : ARangesSectionWriter->getCUAddressRanges()) { 1230 const SmallVector<DebugAddressRange, 2> &Ranges = CURangesPair.second; 1231 NewAddressTableSize += Ranges.size() * 20; 1232 } 1233 1234 // Difference between old and new table (and section) sizes. 1235 // Could be negative. 1236 int32_t Delta = NewAddressTableSize - OldAddressTableSize; 1237 1238 size_t NewGdbIndexSize = GdbIndexContents.size() + Delta; 1239 1240 // Free'd by ExecutableFileMemoryManager. 1241 auto *NewGdbIndexContents = new uint8_t[NewGdbIndexSize]; 1242 uint8_t *Buffer = NewGdbIndexContents; 1243 1244 write32le(Buffer, Version); 1245 write32le(Buffer + 4, CUListOffset); 1246 write32le(Buffer + 8, CUTypesOffset); 1247 write32le(Buffer + 12, AddressTableOffset); 1248 write32le(Buffer + 16, SymbolTableOffset + Delta); 1249 write32le(Buffer + 20, ConstantPoolOffset + Delta); 1250 Buffer += 24; 1251 1252 // Writing out CU List <Offset, Size> 1253 for (auto &CUInfo : CUMap) { 1254 write64le(Buffer, CUInfo.second.Offset); 1255 // Length encoded in CU doesn't contain first 4 bytes that encode length. 1256 write64le(Buffer + 8, CUInfo.second.Length + 4); 1257 Buffer += 16; 1258 } 1259 1260 // Copy over types CU list 1261 // Spec says " triplet, the first value is the CU offset, the second value is 1262 // the type offset in the CU, and the third value is the type signature" 1263 // Looking at what is being generated by gdb-add-index. The first entry is TU 1264 // offset, second entry is offset from it, and third entry is the type 1265 // signature. 1266 memcpy(Buffer, GdbIndexContents.data() + CUTypesOffset, 1267 AddressTableOffset - CUTypesOffset); 1268 Buffer += AddressTableOffset - CUTypesOffset; 1269 1270 // Generate new address table. 1271 for (const std::pair<const uint64_t, DebugAddressRangesVector> &CURangesPair : 1272 ARangesSectionWriter->getCUAddressRanges()) { 1273 const uint32_t CUIndex = OffsetToIndexMap[CURangesPair.first]; 1274 const DebugAddressRangesVector &Ranges = CURangesPair.second; 1275 for (const DebugAddressRange &Range : Ranges) { 1276 write64le(Buffer, Range.LowPC); 1277 write64le(Buffer + 8, Range.HighPC); 1278 write32le(Buffer + 16, CUIndex); 1279 Buffer += 20; 1280 } 1281 } 1282 1283 const size_t TrailingSize = 1284 GdbIndexContents.data() + GdbIndexContents.size() - Data; 1285 assert(Buffer + TrailingSize == NewGdbIndexContents + NewGdbIndexSize && 1286 "size calculation error"); 1287 1288 // Copy over the rest of the original data. 1289 memcpy(Buffer, Data, TrailingSize); 1290 1291 // Register the new section. 1292 BC.registerOrUpdateNoteSection(".gdb_index", NewGdbIndexContents, 1293 NewGdbIndexSize); 1294 } 1295 1296 std::unique_ptr<DebugBufferVector> 1297 DWARFRewriter::makeFinalLocListsSection(SimpleBinaryPatcher &DebugInfoPatcher) { 1298 auto LocBuffer = std::make_unique<DebugBufferVector>(); 1299 auto LocStream = std::make_unique<raw_svector_ostream>(*LocBuffer); 1300 auto Writer = 1301 std::unique_ptr<MCObjectWriter>(BC.createObjectWriter(*LocStream)); 1302 1303 uint64_t SectionOffset = 0; 1304 1305 // Add an empty list as the first entry; 1306 const char Zeroes[16] = {0}; 1307 *LocStream << StringRef(Zeroes, 16); 1308 SectionOffset += 2 * 8; 1309 1310 for (std::pair<const uint64_t, std::unique_ptr<DebugLocWriter>> &Loc : 1311 LocListWritersByCU) { 1312 DebugLocWriter *LocWriter = Loc.second.get(); 1313 if (auto *LocListWriter = llvm::dyn_cast<DebugLoclistWriter>(LocWriter)) { 1314 SimpleBinaryPatcher *Patcher = 1315 getBinaryDWODebugInfoPatcher(LocListWriter->getDWOID()); 1316 LocListWriter->finalize(0, *Patcher); 1317 continue; 1318 } 1319 LocWriter->finalize(SectionOffset, DebugInfoPatcher); 1320 std::unique_ptr<DebugBufferVector> CurrCULocationLists = 1321 LocWriter->getBuffer(); 1322 *LocStream << *CurrCULocationLists; 1323 SectionOffset += CurrCULocationLists->size(); 1324 } 1325 1326 return LocBuffer; 1327 } 1328 1329 namespace { 1330 1331 void getRangeAttrData(DWARFDie DIE, Optional<AttrInfo> &LowPCVal, 1332 Optional<AttrInfo> &HighPCVal) { 1333 LowPCVal = findAttributeInfo(DIE, dwarf::DW_AT_low_pc); 1334 HighPCVal = findAttributeInfo(DIE, dwarf::DW_AT_high_pc); 1335 uint64_t LowPCOffset = LowPCVal->Offset; 1336 uint64_t HighPCOffset = HighPCVal->Offset; 1337 dwarf::Form LowPCForm = LowPCVal->V.getForm(); 1338 dwarf::Form HighPCForm = HighPCVal->V.getForm(); 1339 1340 if (LowPCForm != dwarf::DW_FORM_addr && 1341 LowPCForm != dwarf::DW_FORM_GNU_addr_index) { 1342 errs() << "BOLT-WARNING: unexpected low_pc form value. Cannot update DIE " 1343 << "at offset 0x" << Twine::utohexstr(DIE.getOffset()) << "\n"; 1344 return; 1345 } 1346 if (HighPCForm != dwarf::DW_FORM_addr && HighPCForm != dwarf::DW_FORM_data8 && 1347 HighPCForm != dwarf::DW_FORM_data4 && 1348 HighPCForm != dwarf::DW_FORM_data2 && 1349 HighPCForm != dwarf::DW_FORM_data1 && 1350 HighPCForm != dwarf::DW_FORM_udata) { 1351 errs() << "BOLT-WARNING: unexpected high_pc form value. Cannot update DIE " 1352 << "at offset 0x" << Twine::utohexstr(DIE.getOffset()) << "\n"; 1353 return; 1354 } 1355 if ((LowPCOffset == -1U || (LowPCOffset + 8 != HighPCOffset)) && 1356 LowPCForm != dwarf::DW_FORM_GNU_addr_index) { 1357 errs() << "BOLT-WARNING: high_pc expected immediately after low_pc. " 1358 << "Cannot update DIE at offset 0x" 1359 << Twine::utohexstr(DIE.getOffset()) << '\n'; 1360 return; 1361 } 1362 } 1363 1364 } // namespace 1365 1366 void DWARFRewriter::patchLowHigh(DWARFDie DIE, DebugAddressRange Range, 1367 SimpleBinaryPatcher &DebugInfoPatcher, 1368 Optional<uint64_t> DWOId) { 1369 Optional<AttrInfo> LowPCVal = None; 1370 Optional<AttrInfo> HighPCVal = None; 1371 getRangeAttrData(DIE, LowPCVal, HighPCVal); 1372 uint64_t LowPCOffset = LowPCVal->Offset; 1373 uint64_t HighPCOffset = HighPCVal->Offset; 1374 auto *TempDebugPatcher = &DebugInfoPatcher; 1375 if (LowPCVal->V.getForm() == dwarf::DW_FORM_GNU_addr_index) { 1376 uint32_t AddressIndex = 1377 AddrWriter->getIndexFromAddress(Range.LowPC, *DWOId); 1378 TempDebugPatcher = getBinaryDWODebugInfoPatcher(*DWOId); 1379 TempDebugPatcher->addUDataPatch(LowPCOffset, AddressIndex, LowPCVal->Size); 1380 // 2.17.2 1381 // If the value of the DW_AT_high_pc is of class address, it is the 1382 // relocated address of the first location past the last instruction 1383 // associated with the entity; if it is of class constant, the value is 1384 // an unsigned integer offset which when added to the low PC gives the 1385 // address of the first location past the last instruction associated 1386 // with the entity. 1387 if (!HighPCVal->V.isFormClass(DWARFFormValue::FC_Constant)) { 1388 AddressIndex = AddrWriter->getIndexFromAddress(Range.HighPC, *DWOId); 1389 TempDebugPatcher->addUDataPatch(HighPCOffset, AddressIndex, 1390 HighPCVal->Size); 1391 } 1392 } else { 1393 TempDebugPatcher->addLE64Patch(LowPCOffset, Range.LowPC); 1394 } 1395 1396 uint64_t HighPC = Range.HighPC; 1397 // The DW_FORM_data* is delta between high and low pc 1398 if (HighPCVal->V.getForm() != dwarf::Form::DW_FORM_addr) 1399 HighPC -= Range.LowPC; 1400 1401 if (isHighPcFormEightBytes(HighPCVal->V.getForm())) 1402 TempDebugPatcher->addLE64Patch(HighPCOffset, HighPC); 1403 else 1404 TempDebugPatcher->addLE32Patch(HighPCOffset, HighPC); 1405 } 1406 1407 void DWARFRewriter::convertToRangesPatchAbbrev( 1408 const DWARFUnit &Unit, const DWARFAbbreviationDeclaration *Abbrev, 1409 DebugAbbrevWriter &AbbrevWriter, Optional<uint64_t> RangesBase) { 1410 auto getAttributeForm = [&Abbrev](const dwarf::Attribute Attr) { 1411 Optional<uint32_t> Index = Abbrev->findAttributeIndex(Attr); 1412 assert(Index && "attribute not found"); 1413 return Abbrev->getFormByIndex(*Index); 1414 }; 1415 dwarf::Form LowPCForm = getAttributeForm(dwarf::DW_AT_low_pc); 1416 1417 // DW_FORM_GNU_addr_index is already variable encoding so nothing to do 1418 // there. 1419 if (RangesBase) { 1420 assert(LowPCForm != dwarf::DW_FORM_GNU_addr_index); 1421 AbbrevWriter.addAttribute(Unit, Abbrev, dwarf::DW_AT_GNU_ranges_base, 1422 dwarf::DW_FORM_sec_offset); 1423 } 1424 1425 AbbrevWriter.addAttributePatch(Unit, Abbrev, dwarf::DW_AT_high_pc, 1426 dwarf::DW_AT_ranges, 1427 dwarf::DW_FORM_sec_offset); 1428 } 1429 1430 void DWARFRewriter::convertToRangesPatchDebugInfo( 1431 DWARFDie DIE, uint64_t RangesSectionOffset, 1432 SimpleBinaryPatcher &DebugInfoPatcher, Optional<uint64_t> RangesBase) { 1433 Optional<AttrInfo> LowPCVal = None; 1434 Optional<AttrInfo> HighPCVal = None; 1435 getRangeAttrData(DIE, LowPCVal, HighPCVal); 1436 uint64_t LowPCOffset = LowPCVal->Offset; 1437 uint64_t HighPCOffset = HighPCVal->Offset; 1438 1439 std::lock_guard<std::mutex> Lock(DebugInfoPatcherMutex); 1440 uint32_t BaseOffset = 0; 1441 if (LowPCVal->V.getForm() == dwarf::DW_FORM_GNU_addr_index) { 1442 // Use ULEB128 for the value. 1443 DebugInfoPatcher.addUDataPatch(LowPCOffset, 0, 1444 std::abs(int(HighPCOffset - LowPCOffset))); 1445 // Ranges are relative to DW_AT_GNU_ranges_base. 1446 BaseOffset = DebugInfoPatcher.getRangeBase(); 1447 } else { 1448 DebugInfoPatcher.addLE64Patch(LowPCOffset, 0); 1449 // If DW_AT_GNU_ranges_base was inserted. 1450 if (RangesBase) 1451 reinterpret_cast<DebugInfoBinaryPatcher &>(DebugInfoPatcher) 1452 .insertNewEntry(DIE, *RangesBase); 1453 } 1454 DebugInfoPatcher.addLE32Patch(HighPCOffset, RangesSectionOffset - BaseOffset, 1455 HighPCVal->Size); 1456 } 1457