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