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