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/Utils/Utils.h" 15 #include "llvm/ADT/STLExtras.h" 16 #include "llvm/BinaryFormat/Dwarf.h" 17 #include "llvm/DWP/DWP.h" 18 #include "llvm/DebugInfo/DWARF/DWARFContext.h" 19 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h" 20 #include "llvm/MC/MCAsmBackend.h" 21 #include "llvm/MC/MCAsmLayout.h" 22 #include "llvm/MC/MCContext.h" 23 #include "llvm/MC/MCDwarf.h" 24 #include "llvm/MC/MCObjectWriter.h" 25 #include "llvm/MC/MCSection.h" 26 #include "llvm/MC/MCStreamer.h" 27 #include "llvm/MC/MCSymbol.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 flushPendingRanges(*DebugInfoPatcher); 327 328 finalizeDebugSections(*DebugInfoPatcher); 329 330 if (opts::WriteDWP) 331 writeDWP(DWOIdToName); 332 else 333 writeDWOFiles(DWOIdToName); 334 335 updateGdbIndexSection(); 336 } 337 338 void DWARFRewriter::updateUnitDebugInfo( 339 DWARFUnit &Unit, DebugInfoBinaryPatcher &DebugInfoPatcher, 340 DebugAbbrevWriter &AbbrevWriter, DebugLocWriter &DebugLocWriter, 341 Optional<uint64_t> RangesBase) { 342 // Cache debug ranges so that the offset for identical ranges could be reused. 343 std::map<DebugAddressRangesVector, uint64_t> CachedRanges; 344 345 uint64_t DIEOffset = Unit.getOffset() + Unit.getHeaderSize(); 346 uint64_t NextCUOffset = Unit.getNextUnitOffset(); 347 DWARFDebugInfoEntry Die; 348 DWARFDataExtractor DebugInfoData = Unit.getDebugInfoExtractor(); 349 uint32_t Depth = 0; 350 351 while ( 352 DIEOffset < NextCUOffset && 353 Die.extractFast(Unit, &DIEOffset, DebugInfoData, NextCUOffset, Depth)) { 354 if (const DWARFAbbreviationDeclaration *AbbrDecl = 355 Die.getAbbreviationDeclarationPtr()) { 356 if (AbbrDecl->hasChildren()) 357 ++Depth; 358 } else { 359 // NULL entry. 360 if (Depth > 0) 361 --Depth; 362 if (Depth == 0) 363 break; 364 } 365 366 DWARFDie DIE(&Unit, &Die); 367 368 switch (DIE.getTag()) { 369 case dwarf::DW_TAG_compile_unit: { 370 auto ModuleRangesOrError = DIE.getAddressRanges(); 371 if (!ModuleRangesOrError) { 372 consumeError(ModuleRangesOrError.takeError()); 373 break; 374 } 375 DWARFAddressRangesVector &ModuleRanges = *ModuleRangesOrError; 376 DebugAddressRangesVector OutputRanges = 377 BC.translateModuleAddressRanges(ModuleRanges); 378 const uint64_t RangesSectionOffset = 379 RangesSectionWriter->addRanges(OutputRanges); 380 if (!Unit.isDWOUnit()) 381 ARangesSectionWriter->addCURanges(Unit.getOffset(), 382 std::move(OutputRanges)); 383 updateDWARFObjectAddressRanges(DIE, RangesSectionOffset, DebugInfoPatcher, 384 AbbrevWriter, RangesBase); 385 break; 386 } 387 case dwarf::DW_TAG_subprogram: { 388 // Get function address either from ranges or [LowPC, HighPC) pair. 389 bool UsesRanges = false; 390 uint64_t Address; 391 uint64_t SectionIndex, HighPC; 392 if (!DIE.getLowAndHighPC(Address, HighPC, SectionIndex)) { 393 Expected<DWARFAddressRangesVector> RangesOrError = 394 DIE.getAddressRanges(); 395 if (!RangesOrError) { 396 consumeError(RangesOrError.takeError()); 397 break; 398 } 399 DWARFAddressRangesVector Ranges = *RangesOrError; 400 // Not a function definition. 401 if (Ranges.empty()) 402 break; 403 404 Address = Ranges.front().LowPC; 405 UsesRanges = true; 406 } 407 408 // Clear cached ranges as the new function will have its own set. 409 CachedRanges.clear(); 410 411 DebugAddressRangesVector FunctionRanges; 412 if (const BinaryFunction *Function = 413 BC.getBinaryFunctionAtAddress(Address)) 414 FunctionRanges = Function->getOutputAddressRanges(); 415 // Update ranges. 416 if (UsesRanges) { 417 updateDWARFObjectAddressRanges( 418 DIE, RangesSectionWriter->addRanges(FunctionRanges), 419 DebugInfoPatcher, AbbrevWriter); 420 } else { 421 // Delay conversion of [LowPC, HighPC) into DW_AT_ranges if possible. 422 const DWARFAbbreviationDeclaration *Abbrev = 423 DIE.getAbbreviationDeclarationPtr(); 424 assert(Abbrev && "abbrev expected"); 425 426 // Create a critical section. 427 static std::shared_timed_mutex CriticalSectionMutex; 428 std::unique_lock<std::shared_timed_mutex> Lock(CriticalSectionMutex); 429 430 if (FunctionRanges.size() > 1) { 431 convertPending(Unit, Abbrev, DebugInfoPatcher, AbbrevWriter); 432 // Exit critical section early. 433 Lock.unlock(); 434 convertToRanges(DIE, FunctionRanges, DebugInfoPatcher); 435 } else if (ConvertedRangesAbbrevs.find(Abbrev) != 436 ConvertedRangesAbbrevs.end()) { 437 // Exit critical section early. 438 Lock.unlock(); 439 convertToRanges(DIE, FunctionRanges, DebugInfoPatcher); 440 } else { 441 if (FunctionRanges.empty()) 442 FunctionRanges.emplace_back(DebugAddressRange()); 443 addToPendingRanges(Abbrev, DIE, FunctionRanges, Unit.getDWOId()); 444 } 445 } 446 break; 447 } 448 case dwarf::DW_TAG_lexical_block: 449 case dwarf::DW_TAG_inlined_subroutine: 450 case dwarf::DW_TAG_try_block: 451 case dwarf::DW_TAG_catch_block: { 452 uint64_t RangesSectionOffset = 453 RangesSectionWriter->getEmptyRangesOffset(); 454 Expected<DWARFAddressRangesVector> RangesOrError = DIE.getAddressRanges(); 455 const BinaryFunction *Function = 456 RangesOrError && !RangesOrError->empty() 457 ? BC.getBinaryFunctionContainingAddress( 458 RangesOrError->front().LowPC) 459 : nullptr; 460 if (Function) { 461 DebugAddressRangesVector OutputRanges = 462 Function->translateInputToOutputRanges(*RangesOrError); 463 LLVM_DEBUG(if (OutputRanges.empty() != RangesOrError->empty()) { 464 dbgs() << "BOLT-DEBUG: problem with DIE at 0x" 465 << Twine::utohexstr(DIE.getOffset()) << " in CU at 0x" 466 << Twine::utohexstr(Unit.getOffset()) << '\n'; 467 }); 468 RangesSectionOffset = RangesSectionWriter->addRanges( 469 std::move(OutputRanges), CachedRanges); 470 } else if (!RangesOrError) { 471 consumeError(RangesOrError.takeError()); 472 } 473 updateDWARFObjectAddressRanges(DIE, RangesSectionOffset, DebugInfoPatcher, 474 AbbrevWriter); 475 break; 476 } 477 default: { 478 // Handle any tag that can have DW_AT_location attribute. 479 DWARFFormValue Value; 480 uint64_t AttrOffset; 481 if (Optional<AttrInfo> AttrVal = 482 findAttributeInfo(DIE, dwarf::DW_AT_location)) { 483 AttrOffset = AttrVal->Offset; 484 Value = AttrVal->V; 485 if (Value.isFormClass(DWARFFormValue::FC_Constant) || 486 Value.isFormClass(DWARFFormValue::FC_SectionOffset)) { 487 uint64_t Offset = Value.isFormClass(DWARFFormValue::FC_Constant) 488 ? Value.getAsUnsignedConstant().getValue() 489 : Value.getAsSectionOffset().getValue(); 490 DebugLocationsVector InputLL; 491 492 Optional<object::SectionedAddress> SectionAddress = 493 Unit.getBaseAddress(); 494 uint64_t BaseAddress = 0; 495 if (SectionAddress) 496 BaseAddress = SectionAddress->Address; 497 498 Error E = Unit.getLocationTable().visitLocationList( 499 &Offset, [&](const DWARFLocationEntry &Entry) { 500 switch (Entry.Kind) { 501 default: 502 llvm_unreachable("Unsupported DWARFLocationEntry Kind."); 503 case dwarf::DW_LLE_end_of_list: 504 return false; 505 case dwarf::DW_LLE_base_address: 506 assert(Entry.SectionIndex == SectionedAddress::UndefSection && 507 "absolute address expected"); 508 BaseAddress = Entry.Value0; 509 break; 510 case dwarf::DW_LLE_offset_pair: 511 assert( 512 (Entry.SectionIndex == SectionedAddress::UndefSection && 513 !Unit.isDWOUnit()) && 514 "absolute address expected"); 515 InputLL.emplace_back(DebugLocationEntry{ 516 BaseAddress + Entry.Value0, BaseAddress + Entry.Value1, 517 Entry.Loc}); 518 break; 519 case dwarf::DW_LLE_startx_length: 520 assert(Unit.isDWOUnit() && 521 "None DWO Unit with DW_LLE_startx_length encoding."); 522 Optional<object::SectionedAddress> EntryAddress = 523 Unit.getAddrOffsetSectionItem(Entry.Value0); 524 assert(EntryAddress && "Address does not exist."); 525 InputLL.emplace_back(DebugLocationEntry{ 526 EntryAddress->Address, 527 EntryAddress->Address + Entry.Value1, Entry.Loc}); 528 break; 529 } 530 return true; 531 }); 532 533 if (E || InputLL.empty()) { 534 errs() << "BOLT-WARNING: empty location list detected at 0x" 535 << Twine::utohexstr(Offset) << " for DIE at 0x" 536 << Twine::utohexstr(DIE.getOffset()) << " in CU at 0x" 537 << Twine::utohexstr(Unit.getOffset()) << '\n'; 538 } else { 539 const uint64_t Address = InputLL.front().LowPC; 540 if (const BinaryFunction *Function = 541 BC.getBinaryFunctionContainingAddress(Address)) { 542 DebugLocationsVector OutputLL = 543 Function->translateInputToOutputLocationList(InputLL); 544 LLVM_DEBUG(if (OutputLL.empty()) { 545 dbgs() << "BOLT-DEBUG: location list translated to an empty " 546 "one at 0x" 547 << Twine::utohexstr(DIE.getOffset()) << " in CU at 0x" 548 << Twine::utohexstr(Unit.getOffset()) << '\n'; 549 }); 550 DebugLocWriter.addList(AttrOffset, std::move(OutputLL)); 551 } 552 } 553 } else { 554 assert((Value.isFormClass(DWARFFormValue::FC_Exprloc) || 555 Value.isFormClass(DWARFFormValue::FC_Block)) && 556 "unexpected DW_AT_location form"); 557 if (Unit.isDWOUnit()) { 558 ArrayRef<uint8_t> Expr = *Value.getAsBlock(); 559 DataExtractor Data( 560 StringRef((const char *)Expr.data(), Expr.size()), 561 Unit.getContext().isLittleEndian(), 0); 562 DWARFExpression LocExpr(Data, Unit.getAddressByteSize(), 563 Unit.getFormParams().Format); 564 for (auto &Expr : LocExpr) { 565 if (Expr.getCode() != dwarf::DW_OP_GNU_addr_index) 566 continue; 567 uint64_t Index = Expr.getRawOperand(0); 568 Optional<object::SectionedAddress> EntryAddress = 569 Unit.getAddrOffsetSectionItem(Index); 570 assert(EntryAddress && "Address is not found."); 571 assert(Index <= std::numeric_limits<uint32_t>::max() && 572 "Invalid Operand Index."); 573 AddrWriter->addIndexAddress(EntryAddress->Address, 574 static_cast<uint32_t>(Index), 575 *Unit.getDWOId()); 576 } 577 } 578 } 579 } else if (Optional<AttrInfo> AttrVal = 580 findAttributeInfo(DIE, dwarf::DW_AT_low_pc)) { 581 AttrOffset = AttrVal->Offset; 582 Value = AttrVal->V; 583 const Optional<uint64_t> Result = Value.getAsAddress(); 584 if (Result.hasValue()) { 585 const uint64_t Address = Result.getValue(); 586 uint64_t NewAddress = 0; 587 if (const BinaryFunction *Function = 588 BC.getBinaryFunctionContainingAddress(Address)) { 589 NewAddress = Function->translateInputToOutputAddress(Address); 590 LLVM_DEBUG(dbgs() 591 << "BOLT-DEBUG: Fixing low_pc 0x" 592 << Twine::utohexstr(Address) << " for DIE with tag " 593 << DIE.getTag() << " to 0x" 594 << Twine::utohexstr(NewAddress) << '\n'); 595 } 596 597 dwarf::Form Form = Value.getForm(); 598 assert(Form != dwarf::DW_FORM_LLVM_addrx_offset && 599 "DW_FORM_LLVM_addrx_offset is not supported"); 600 std::lock_guard<std::mutex> Lock(DebugInfoPatcherMutex); 601 if (Form == dwarf::DW_FORM_GNU_addr_index) { 602 assert(Unit.isDWOUnit() && 603 "DW_FORM_GNU_addr_index in Non DWO unit."); 604 uint64_t Index = Value.getRawUValue(); 605 // If there is no new address, storing old address. 606 // Re-using Index to make implementation easier. 607 // DW_FORM_GNU_addr_index is variable lenght encoding so we either 608 // have to create indices of same sizes, or use same index. 609 AddrWriter->addIndexAddress(NewAddress ? NewAddress : Address, 610 Index, *Unit.getDWOId()); 611 } else { 612 DebugInfoPatcher.addLE64Patch(AttrOffset, NewAddress); 613 } 614 } else if (opts::Verbosity >= 1) { 615 errs() << "BOLT-WARNING: unexpected form value for attribute at 0x" 616 << Twine::utohexstr(AttrOffset); 617 } 618 } 619 } 620 } 621 622 // Handling references. 623 assert(DIE.isValid() && "Invalid DIE."); 624 const DWARFAbbreviationDeclaration *AbbrevDecl = 625 DIE.getAbbreviationDeclarationPtr(); 626 if (!AbbrevDecl) 627 continue; 628 uint32_t Index = 0; 629 for (const DWARFAbbreviationDeclaration::AttributeSpec &Decl : 630 AbbrevDecl->attributes()) { 631 switch (Decl.Form) { 632 default: 633 break; 634 case dwarf::DW_FORM_ref1: 635 case dwarf::DW_FORM_ref2: 636 case dwarf::DW_FORM_ref4: 637 case dwarf::DW_FORM_ref8: 638 case dwarf::DW_FORM_ref_udata: 639 case dwarf::DW_FORM_ref_addr: { 640 Optional<AttrInfo> AttrVal = findAttributeInfo(DIE, AbbrevDecl, Index); 641 uint32_t DestinationAddress = 642 AttrVal->V.getRawUValue() + 643 (Decl.Form == dwarf::DW_FORM_ref_addr ? 0 : Unit.getOffset()); 644 DebugInfoPatcher.addReferenceToPatch( 645 AttrVal->Offset, DestinationAddress, AttrVal->Size, Decl.Form); 646 // We can have only one reference, and it can be backward one. 647 DebugInfoPatcher.addDestinationReferenceLabel(DestinationAddress); 648 break; 649 } 650 } 651 ++Index; 652 } 653 } 654 if (DIEOffset > NextCUOffset) 655 errs() << "BOLT-WARNING: corrupt DWARF detected at 0x" 656 << Twine::utohexstr(Unit.getOffset()) << '\n'; 657 } 658 659 void DWARFRewriter::updateDWARFObjectAddressRanges( 660 const DWARFDie DIE, uint64_t DebugRangesOffset, 661 SimpleBinaryPatcher &DebugInfoPatcher, DebugAbbrevWriter &AbbrevWriter, 662 Optional<uint64_t> RangesBase) { 663 664 // Some objects don't have an associated DIE and cannot be updated (such as 665 // compiler-generated functions). 666 if (!DIE) 667 return; 668 669 const DWARFAbbreviationDeclaration *AbbreviationDecl = 670 DIE.getAbbreviationDeclarationPtr(); 671 if (!AbbreviationDecl) { 672 if (opts::Verbosity >= 1) 673 errs() << "BOLT-WARNING: object's DIE doesn't have an abbreviation: " 674 << "skipping update. DIE at offset 0x" 675 << Twine::utohexstr(DIE.getOffset()) << '\n'; 676 return; 677 } 678 679 if (RangesBase) { 680 // If DW_AT_GNU_ranges_base is present, update it. No further modifications 681 // are needed for ranges base. 682 Optional<AttrInfo> RangesBaseAttrInfo = 683 findAttributeInfo(DIE, dwarf::DW_AT_GNU_ranges_base); 684 if (RangesBaseAttrInfo) { 685 DebugInfoPatcher.addLE32Patch(RangesBaseAttrInfo->Offset, 686 static_cast<uint32_t>(*RangesBase), 687 RangesBaseAttrInfo->Size); 688 RangesBase = None; 689 } 690 } 691 692 Optional<AttrInfo> LowPCAttrInfo = 693 findAttributeInfo(DIE, dwarf::DW_AT_low_pc); 694 if (AbbreviationDecl->findAttributeIndex(dwarf::DW_AT_ranges)) { 695 // Case 1: The object was already non-contiguous and had DW_AT_ranges. 696 // In this case we simply need to update the value of DW_AT_ranges 697 // and introduce DW_AT_GNU_ranges_base if required. 698 Optional<AttrInfo> AttrVal = findAttributeInfo(DIE, dwarf::DW_AT_ranges); 699 std::lock_guard<std::mutex> Lock(DebugInfoPatcherMutex); 700 DebugInfoPatcher.addLE32Patch( 701 AttrVal->Offset, DebugRangesOffset - DebugInfoPatcher.getRangeBase(), 702 AttrVal->Size); 703 704 if (!RangesBase) { 705 if (LowPCAttrInfo && 706 LowPCAttrInfo->V.getForm() != dwarf::DW_FORM_GNU_addr_index && 707 LowPCAttrInfo->V.getForm() != dwarf::DW_FORM_addrx) 708 DebugInfoPatcher.addLE64Patch(LowPCAttrInfo->Offset, 0); 709 return; 710 } 711 712 // Convert DW_AT_low_pc into DW_AT_GNU_ranges_base. 713 if (!LowPCAttrInfo) { 714 errs() << "BOLT-ERROR: skeleton CU at 0x" 715 << Twine::utohexstr(DIE.getOffset()) 716 << " does not have DW_AT_GNU_ranges_base or DW_AT_low_pc to" 717 " convert to update ranges base\n"; 718 return; 719 } 720 721 AbbrevWriter.addAttributePatch( 722 *DIE.getDwarfUnit(), AbbreviationDecl, dwarf::DW_AT_low_pc, 723 dwarf::DW_AT_GNU_ranges_base, dwarf::DW_FORM_indirect); 724 DebugInfoPatcher.addUDataPatch(LowPCAttrInfo->Offset, dwarf::DW_FORM_udata, 725 1); 726 DebugInfoPatcher.addUDataPatch(LowPCAttrInfo->Offset + 1, *RangesBase, 7); 727 728 return; 729 } 730 731 // Case 2: The object has both DW_AT_low_pc and DW_AT_high_pc emitted back 732 // to back. Replace with new attributes and patch the DIE. 733 Optional<AttrInfo> HighPCAttrInfo = 734 findAttributeInfo(DIE, dwarf::DW_AT_high_pc); 735 if (LowPCAttrInfo && HighPCAttrInfo) { 736 convertToRangesPatchAbbrev(*DIE.getDwarfUnit(), AbbreviationDecl, 737 AbbrevWriter, RangesBase); 738 convertToRangesPatchDebugInfo(DIE, DebugRangesOffset, DebugInfoPatcher, 739 RangesBase); 740 } else { 741 if (opts::Verbosity >= 1) 742 errs() << "BOLT-ERROR: cannot update ranges for DIE at offset 0x" 743 << Twine::utohexstr(DIE.getOffset()) << '\n'; 744 } 745 } 746 747 void DWARFRewriter::updateLineTableOffsets(const MCAsmLayout &Layout) { 748 ErrorOr<BinarySection &> DbgInfoSection = 749 BC.getUniqueSectionByName(".debug_info"); 750 ErrorOr<BinarySection &> TypeInfoSection = 751 BC.getUniqueSectionByName(".debug_types"); 752 assert(((BC.DwCtx->getNumTypeUnits() > 0 && TypeInfoSection) || 753 BC.DwCtx->getNumTypeUnits() == 0) && 754 "Was not able to retrieve Debug Types section."); 755 756 // We will be re-writing .debug_info so relocation mechanism doesn't work for 757 // Debug Info Patcher. 758 DebugInfoBinaryPatcher *DebugInfoPatcher = nullptr; 759 if (BC.DwCtx->getNumCompileUnits()) { 760 DbgInfoSection->registerPatcher(std::make_unique<DebugInfoBinaryPatcher>()); 761 DebugInfoPatcher = 762 static_cast<DebugInfoBinaryPatcher *>(DbgInfoSection->getPatcher()); 763 } 764 765 // There is no direct connection between CU and TU, but same offsets, 766 // encoded in DW_AT_stmt_list, into .debug_line get modified. 767 // We take advantage of that to map original CU line table offsets to new 768 // ones. 769 std::unordered_map<uint64_t, uint64_t> DebugLineOffsetMap; 770 771 auto GetStatementListValue = [](DWARFUnit *Unit) { 772 Optional<DWARFFormValue> StmtList = 773 Unit->getUnitDIE().find(dwarf::DW_AT_stmt_list); 774 Optional<uint64_t> Offset = dwarf::toSectionOffset(StmtList); 775 assert(Offset && "Was not able to retreive value of DW_AT_stmt_list."); 776 return *Offset; 777 }; 778 779 const uint64_t Reloc32Type = BC.isAArch64() 780 ? static_cast<uint64_t>(ELF::R_AARCH64_ABS32) 781 : static_cast<uint64_t>(ELF::R_X86_64_32); 782 783 for (const std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units()) { 784 const unsigned CUID = CU->getOffset(); 785 MCSymbol *Label = BC.getDwarfLineTable(CUID).getLabel(); 786 if (!Label) 787 continue; 788 789 Optional<AttrInfo> AttrVal = 790 findAttributeInfo(CU.get()->getUnitDIE(), dwarf::DW_AT_stmt_list); 791 if (!AttrVal) 792 continue; 793 794 const uint64_t AttributeOffset = AttrVal->Offset; 795 const uint64_t LineTableOffset = Layout.getSymbolOffset(*Label); 796 DebugLineOffsetMap[GetStatementListValue(CU.get())] = LineTableOffset; 797 assert(DbgInfoSection && ".debug_info section must exist"); 798 DebugInfoPatcher->addLE32Patch(AttributeOffset, LineTableOffset); 799 } 800 801 for (const std::unique_ptr<DWARFUnit> &TU : BC.DwCtx->types_section_units()) { 802 DWARFUnit *Unit = TU.get(); 803 Optional<AttrInfo> AttrVal = 804 findAttributeInfo(TU.get()->getUnitDIE(), dwarf::DW_AT_stmt_list); 805 if (!AttrVal) 806 continue; 807 const uint64_t AttributeOffset = AttrVal->Offset; 808 auto Iter = DebugLineOffsetMap.find(GetStatementListValue(Unit)); 809 assert(Iter != DebugLineOffsetMap.end() && 810 "Type Unit Updated Line Number Entry does not exist."); 811 TypeInfoSection->addRelocation(AttributeOffset, nullptr, Reloc32Type, 812 Iter->second, 0, /*Pending=*/true); 813 } 814 815 // Set .debug_info as finalized so it won't be skipped over when 816 // we process sections while writing out the new binary. This ensures 817 // that the pending relocations will be processed and not ignored. 818 if (DbgInfoSection) 819 DbgInfoSection->setIsFinalized(); 820 821 if (TypeInfoSection) 822 TypeInfoSection->setIsFinalized(); 823 } 824 825 void DWARFRewriter::finalizeDebugSections( 826 DebugInfoBinaryPatcher &DebugInfoPatcher) { 827 if (StrWriter->isInitialized()) { 828 RewriteInstance::addToDebugSectionsToOverwrite(".debug_str"); 829 std::unique_ptr<DebugStrBufferVector> DebugStrSectionContents = 830 StrWriter->finalize(); 831 BC.registerOrUpdateNoteSection(".debug_str", 832 copyByteArray(*DebugStrSectionContents), 833 DebugStrSectionContents->size()); 834 } 835 836 std::unique_ptr<DebugBufferVector> RangesSectionContents = 837 RangesSectionWriter->finalize(); 838 BC.registerOrUpdateNoteSection(".debug_ranges", 839 copyByteArray(*RangesSectionContents), 840 RangesSectionContents->size()); 841 842 std::unique_ptr<DebugBufferVector> LocationListSectionContents = 843 makeFinalLocListsSection(DebugInfoPatcher); 844 BC.registerOrUpdateNoteSection(".debug_loc", 845 copyByteArray(*LocationListSectionContents), 846 LocationListSectionContents->size()); 847 848 // AddrWriter should be finalized after debug_loc since more addresses can be 849 // added there. 850 if (AddrWriter->isInitialized()) { 851 AddressSectionBuffer AddressSectionContents = AddrWriter->finalize(); 852 BC.registerOrUpdateNoteSection(".debug_addr", 853 copyByteArray(AddressSectionContents), 854 AddressSectionContents.size()); 855 for (auto &CU : BC.DwCtx->compile_units()) { 856 DWARFDie DIE = CU->getUnitDIE(); 857 if (Optional<AttrInfo> AttrVal = 858 findAttributeInfo(DIE, dwarf::DW_AT_GNU_addr_base)) { 859 uint64_t Offset = AddrWriter->getOffset(*CU->getDWOId()); 860 DebugInfoPatcher.addLE32Patch( 861 AttrVal->Offset, static_cast<int32_t>(Offset), AttrVal->Size); 862 } 863 } 864 } 865 866 std::unique_ptr<DebugBufferVector> AbbrevSectionContents = 867 AbbrevWriter->finalize(); 868 BC.registerOrUpdateNoteSection(".debug_abbrev", 869 copyByteArray(*AbbrevSectionContents), 870 AbbrevSectionContents->size()); 871 872 // Update abbreviation offsets for CUs/TUs if they were changed. 873 SimpleBinaryPatcher *DebugTypesPatcher = nullptr; 874 for (auto &Unit : BC.DwCtx->normal_units()) { 875 const uint64_t NewAbbrevOffset = 876 AbbrevWriter->getAbbreviationsOffsetForUnit(*Unit); 877 if (Unit->getAbbreviationsOffset() == NewAbbrevOffset) 878 continue; 879 880 // DWARFv4 881 // unit_length - 4 bytes 882 // version - 2 bytes 883 // So + 6 to patch debug_abbrev_offset 884 constexpr uint64_t AbbrevFieldOffset = 6; 885 if (!Unit->isTypeUnit()) { 886 DebugInfoPatcher.addLE32Patch(Unit->getOffset() + AbbrevFieldOffset, 887 static_cast<uint32_t>(NewAbbrevOffset)); 888 continue; 889 } 890 891 if (!DebugTypesPatcher) { 892 ErrorOr<BinarySection &> DebugTypes = 893 BC.getUniqueSectionByName(".debug_types"); 894 DebugTypes->registerPatcher(std::make_unique<SimpleBinaryPatcher>()); 895 DebugTypesPatcher = 896 static_cast<SimpleBinaryPatcher *>(DebugTypes->getPatcher()); 897 } 898 DebugTypesPatcher->addLE32Patch(Unit->getOffset() + AbbrevFieldOffset, 899 static_cast<uint32_t>(NewAbbrevOffset)); 900 } 901 902 // No more creating new DebugInfoPatches. 903 std::unordered_map<uint32_t, uint32_t> CUMap = 904 DebugInfoPatcher.computeNewOffsets(); 905 906 // Skip .debug_aranges if we are re-generating .gdb_index. 907 if (opts::KeepARanges || !BC.getGdbIndexSection()) { 908 SmallVector<char, 16> ARangesBuffer; 909 raw_svector_ostream OS(ARangesBuffer); 910 911 auto MAB = std::unique_ptr<MCAsmBackend>( 912 BC.TheTarget->createMCAsmBackend(*BC.STI, *BC.MRI, MCTargetOptions())); 913 914 ARangesSectionWriter->writeARangesSection(OS, CUMap); 915 const StringRef &ARangesContents = OS.str(); 916 917 BC.registerOrUpdateNoteSection(".debug_aranges", 918 copyByteArray(ARangesContents), 919 ARangesContents.size()); 920 } 921 } 922 923 // Creates all the data structures necessary for creating MCStreamer. 924 // They are passed by reference because they need to be kept around. 925 // Also creates known debug sections. These are sections handled by 926 // handleDebugDataPatching. 927 using KnownSectionsEntry = std::pair<MCSection *, DWARFSectionKind>; 928 namespace { 929 930 std::unique_ptr<BinaryContext> 931 createDwarfOnlyBC(const object::ObjectFile &File) { 932 return BinaryContext::createBinaryContext( 933 &File, false, 934 DWARFContext::create(File, DWARFContext::ProcessDebugRelocations::Ignore, 935 nullptr, "", WithColor::defaultErrorHandler, 936 WithColor::defaultWarningHandler)); 937 } 938 939 StringMap<KnownSectionsEntry> 940 createKnownSectionsMap(const MCObjectFileInfo &MCOFI) { 941 StringMap<KnownSectionsEntry> KnownSectionsTemp = { 942 {"debug_info.dwo", {MCOFI.getDwarfInfoDWOSection(), DW_SECT_INFO}}, 943 {"debug_types.dwo", {MCOFI.getDwarfTypesDWOSection(), DW_SECT_EXT_TYPES}}, 944 {"debug_str_offsets.dwo", 945 {MCOFI.getDwarfStrOffDWOSection(), DW_SECT_STR_OFFSETS}}, 946 {"debug_str.dwo", {MCOFI.getDwarfStrDWOSection(), DW_SECT_EXT_unknown}}, 947 {"debug_loc.dwo", {MCOFI.getDwarfLocDWOSection(), DW_SECT_EXT_LOC}}, 948 {"debug_abbrev.dwo", {MCOFI.getDwarfAbbrevDWOSection(), DW_SECT_ABBREV}}, 949 {"debug_line.dwo", {MCOFI.getDwarfLineDWOSection(), DW_SECT_LINE}}}; 950 return KnownSectionsTemp; 951 } 952 953 StringRef getSectionName(const SectionRef &Section) { 954 Expected<StringRef> SectionName = Section.getName(); 955 assert(SectionName && "Invalid section name."); 956 StringRef Name = *SectionName; 957 Name = Name.substr(Name.find_first_not_of("._")); 958 return Name; 959 } 960 961 // Exctracts an appropriate slice if input is DWP. 962 // Applies patches or overwrites the section. 963 Optional<StringRef> 964 updateDebugData(std::string &Storage, const SectionRef &Section, 965 const StringMap<KnownSectionsEntry> &KnownSections, 966 MCStreamer &Streamer, DWARFRewriter &Writer, 967 const DWARFUnitIndex::Entry *DWOEntry, uint64_t DWOId, 968 std::unique_ptr<DebugBufferVector> &OutputBuffer) { 969 auto applyPatch = [&](DebugInfoBinaryPatcher *Patcher, 970 StringRef Data) -> StringRef { 971 Patcher->computeNewOffsets(); 972 Storage = Patcher->patchBinary(Data); 973 return StringRef(Storage.c_str(), Storage.size()); 974 }; 975 976 using DWOSectionContribution = 977 const DWARFUnitIndex::Entry::SectionContribution; 978 auto getSliceData = [&](const DWARFUnitIndex::Entry *DWOEntry, 979 StringRef OutData, DWARFSectionKind Sec, 980 uint32_t &DWPOffset) -> StringRef { 981 if (DWOEntry) { 982 DWOSectionContribution *DWOContrubution = DWOEntry->getContribution(Sec); 983 DWPOffset = DWOContrubution->Offset; 984 OutData = OutData.substr(DWPOffset, DWOContrubution->Length); 985 } 986 return OutData; 987 }; 988 989 StringRef Name = getSectionName(Section); 990 auto SectionIter = KnownSections.find(Name); 991 if (SectionIter == KnownSections.end()) 992 return None; 993 Streamer.SwitchSection(SectionIter->second.first); 994 Expected<StringRef> Contents = Section.getContents(); 995 assert(Contents && "Invalid contents."); 996 StringRef OutData = *Contents; 997 uint32_t DWPOffset = 0; 998 999 switch (SectionIter->second.second) { 1000 default: { 1001 if (!Name.equals("debug_str.dwo")) 1002 errs() << "BOLT-WARNING: Unsupported Debug section: " << Name << "\n"; 1003 return OutData; 1004 } 1005 case DWARFSectionKind::DW_SECT_INFO: { 1006 OutData = getSliceData(DWOEntry, OutData, DWARFSectionKind::DW_SECT_INFO, 1007 DWPOffset); 1008 DebugInfoBinaryPatcher *Patcher = llvm::cast<DebugInfoBinaryPatcher>( 1009 Writer.getBinaryDWODebugInfoPatcher(DWOId)); 1010 return applyPatch(Patcher, OutData); 1011 } 1012 case DWARFSectionKind::DW_SECT_EXT_TYPES: { 1013 return getSliceData(DWOEntry, OutData, DWARFSectionKind::DW_SECT_EXT_TYPES, 1014 DWPOffset); 1015 } 1016 case DWARFSectionKind::DW_SECT_STR_OFFSETS: { 1017 return getSliceData(DWOEntry, OutData, 1018 DWARFSectionKind::DW_SECT_STR_OFFSETS, DWPOffset); 1019 } 1020 case DWARFSectionKind::DW_SECT_ABBREV: { 1021 DebugAbbrevWriter *AbbrevWriter = Writer.getBinaryDWOAbbrevWriter(DWOId); 1022 OutputBuffer = AbbrevWriter->finalize(); 1023 // Creating explicit StringRef here, otherwise 1024 // with impicit conversion it will take null byte as end of 1025 // string. 1026 return StringRef(reinterpret_cast<const char *>(OutputBuffer->data()), 1027 OutputBuffer->size()); 1028 } 1029 case DWARFSectionKind::DW_SECT_EXT_LOC: { 1030 DebugLocWriter *LocWriter = Writer.getDebugLocWriter(DWOId); 1031 OutputBuffer = LocWriter->getBuffer(); 1032 // Creating explicit StringRef here, otherwise 1033 // with impicit conversion it will take null byte as end of 1034 // string. 1035 return StringRef(reinterpret_cast<const char *>(OutputBuffer->data()), 1036 OutputBuffer->size()); 1037 } 1038 case DWARFSectionKind::DW_SECT_LINE: { 1039 return getSliceData(DWOEntry, OutData, DWARFSectionKind::DW_SECT_LINE, 1040 DWPOffset); 1041 } 1042 } 1043 } 1044 1045 } // namespace 1046 1047 void DWARFRewriter::writeDWP( 1048 std::unordered_map<uint64_t, std::string> &DWOIdToName) { 1049 SmallString<0> OutputNameStr; 1050 StringRef OutputName; 1051 if (opts::DwarfOutputPath.empty()) { 1052 OutputName = 1053 Twine(opts::OutputFilename).concat(".dwp").toStringRef(OutputNameStr); 1054 } else { 1055 StringRef ExeFileName = llvm::sys::path::filename(opts::OutputFilename); 1056 OutputName = Twine(opts::DwarfOutputPath) 1057 .concat("/") 1058 .concat(ExeFileName) 1059 .concat(".dwp") 1060 .toStringRef(OutputNameStr); 1061 errs() << "BOLT-WARNING: dwarf-output-path is in effect and .dwp file will " 1062 "possibly be written to another location that is not the same as " 1063 "the executable\n"; 1064 } 1065 std::error_code EC; 1066 std::unique_ptr<ToolOutputFile> Out = 1067 std::make_unique<ToolOutputFile>(OutputName, EC, sys::fs::OF_None); 1068 1069 const object::ObjectFile *File = BC.DwCtx->getDWARFObj().getFile(); 1070 std::unique_ptr<BinaryContext> TmpBC = createDwarfOnlyBC(*File); 1071 std::unique_ptr<MCStreamer> Streamer = TmpBC->createStreamer(Out->os()); 1072 const MCObjectFileInfo &MCOFI = *Streamer->getContext().getObjectFileInfo(); 1073 StringMap<KnownSectionsEntry> KnownSections = createKnownSectionsMap(MCOFI); 1074 MCSection *const StrSection = MCOFI.getDwarfStrDWOSection(); 1075 MCSection *const StrOffsetSection = MCOFI.getDwarfStrOffDWOSection(); 1076 1077 // Data Structures for DWP book keeping 1078 // Size of array corresponds to the number of sections supported by DWO format 1079 // in DWARF4/5. 1080 uint32_t ContributionOffsets[8] = {}; 1081 std::deque<SmallString<32>> UncompressedSections; 1082 DWPStringPool Strings(*Streamer, StrSection); 1083 MapVector<uint64_t, UnitIndexEntry> IndexEntries; 1084 constexpr uint32_t IndexVersion = 2; 1085 1086 // Setup DWP code once. 1087 DWARFContext *DWOCtx = BC.getDWOContext(); 1088 const DWARFUnitIndex *CUIndex = nullptr; 1089 bool IsDWP = false; 1090 if (DWOCtx) { 1091 CUIndex = &DWOCtx->getCUIndex(); 1092 IsDWP = !CUIndex->getRows().empty(); 1093 } 1094 1095 for (const std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units()) { 1096 Optional<uint64_t> DWOId = CU->getDWOId(); 1097 if (!DWOId) 1098 continue; 1099 1100 // Skipping CUs that we failed to load. 1101 Optional<DWARFUnit *> DWOCU = BC.getDWOCU(*DWOId); 1102 if (!DWOCU) 1103 continue; 1104 1105 assert(CU->getVersion() == 4 && "For DWP output only DWARF4 is supported"); 1106 UnitIndexEntry CurEntry = {}; 1107 CurEntry.DWOName = 1108 dwarf::toString(CU->getUnitDIE().find( 1109 {dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name}), 1110 ""); 1111 const char *Name = CU->getUnitDIE().getShortName(); 1112 if (Name) 1113 CurEntry.Name = Name; 1114 StringRef CurStrSection; 1115 StringRef CurStrOffsetSection; 1116 1117 // This maps each section contained in this file to its length. 1118 // This information is later on used to calculate the contributions, 1119 // i.e. offset and length, of each compile/type unit to a section. 1120 std::vector<std::pair<DWARFSectionKind, uint32_t>> SectionLength; 1121 1122 const DWARFUnitIndex::Entry *DWOEntry = nullptr; 1123 if (IsDWP) 1124 DWOEntry = CUIndex->getFromHash(*DWOId); 1125 1126 bool StrSectionWrittenOut = false; 1127 const object::ObjectFile *DWOFile = 1128 (*DWOCU)->getContext().getDWARFObj().getFile(); 1129 for (const SectionRef &Section : DWOFile->sections()) { 1130 std::string Storage = ""; 1131 std::unique_ptr<DebugBufferVector> OutputData; 1132 Optional<StringRef> TOutData = 1133 updateDebugData(Storage, Section, KnownSections, *Streamer, *this, 1134 DWOEntry, *DWOId, OutputData); 1135 if (!TOutData) 1136 continue; 1137 1138 StringRef OutData = *TOutData; 1139 StringRef Name = getSectionName(Section); 1140 if (Name.equals("debug_str.dwo")) { 1141 CurStrSection = OutData; 1142 } else { 1143 // Since handleDebugDataPatching returned true, we already know this is 1144 // a known section. 1145 auto SectionIter = KnownSections.find(Name); 1146 if (SectionIter->second.second == DWARFSectionKind::DW_SECT_STR_OFFSETS) 1147 CurStrOffsetSection = OutData; 1148 else 1149 Streamer->emitBytes(OutData); 1150 auto Index = 1151 getContributionIndex(SectionIter->second.second, IndexVersion); 1152 CurEntry.Contributions[Index].Offset = ContributionOffsets[Index]; 1153 CurEntry.Contributions[Index].Length = OutData.size(); 1154 ContributionOffsets[Index] += CurEntry.Contributions[Index].Length; 1155 } 1156 1157 // Strings are combined in to a new string section, and de-duplicated 1158 // based on hash. 1159 if (!StrSectionWrittenOut && !CurStrOffsetSection.empty() && 1160 !CurStrSection.empty()) { 1161 writeStringsAndOffsets(*Streamer.get(), Strings, StrOffsetSection, 1162 CurStrSection, CurStrOffsetSection, 1163 CU->getVersion()); 1164 StrSectionWrittenOut = true; 1165 } 1166 } 1167 CompileUnitIdentifiers CUI{*DWOId, CurEntry.Name.c_str(), 1168 CurEntry.DWOName.c_str()}; 1169 auto P = IndexEntries.insert(std::make_pair(CUI.Signature, CurEntry)); 1170 if (!P.second) { 1171 Error Err = buildDuplicateError(*P.first, CUI, ""); 1172 errs() << "BOLT-ERROR: " << toString(std::move(Err)) << "\n"; 1173 return; 1174 } 1175 } 1176 1177 // Lie about the type contribution for DWARF < 5. In DWARFv5 the type 1178 // section does not exist, so no need to do anything about this. 1179 ContributionOffsets[getContributionIndex(DW_SECT_EXT_TYPES, 2)] = 0; 1180 writeIndex(*Streamer.get(), MCOFI.getDwarfCUIndexSection(), 1181 ContributionOffsets, IndexEntries, IndexVersion); 1182 1183 Streamer->Finish(); 1184 Out->keep(); 1185 } 1186 1187 void DWARFRewriter::writeDWOFiles( 1188 std::unordered_map<uint64_t, std::string> &DWOIdToName) { 1189 // Setup DWP code once. 1190 DWARFContext *DWOCtx = BC.getDWOContext(); 1191 const DWARFUnitIndex *CUIndex = nullptr; 1192 bool IsDWP = false; 1193 if (DWOCtx) { 1194 CUIndex = &DWOCtx->getCUIndex(); 1195 IsDWP = !CUIndex->getRows().empty(); 1196 } 1197 1198 for (const std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units()) { 1199 Optional<uint64_t> DWOId = CU->getDWOId(); 1200 if (!DWOId) 1201 continue; 1202 1203 // Skipping CUs that we failed to load. 1204 Optional<DWARFUnit *> DWOCU = BC.getDWOCU(*DWOId); 1205 if (!DWOCU) 1206 continue; 1207 1208 std::string CompDir = opts::DwarfOutputPath.empty() 1209 ? CU->getCompilationDir() 1210 : opts::DwarfOutputPath.c_str(); 1211 std::string ObjectName = getDWOName(*CU.get(), nullptr, DWOIdToName); 1212 auto FullPath = CompDir.append("/").append(ObjectName); 1213 1214 std::error_code EC; 1215 std::unique_ptr<ToolOutputFile> TempOut = 1216 std::make_unique<ToolOutputFile>(FullPath, EC, sys::fs::OF_None); 1217 1218 const DWARFUnitIndex::Entry *DWOEntry = nullptr; 1219 if (IsDWP) 1220 DWOEntry = CUIndex->getFromHash(*DWOId); 1221 1222 const object::ObjectFile *File = 1223 (*DWOCU)->getContext().getDWARFObj().getFile(); 1224 std::unique_ptr<BinaryContext> TmpBC = createDwarfOnlyBC(*File); 1225 std::unique_ptr<MCStreamer> Streamer = TmpBC->createStreamer(TempOut->os()); 1226 StringMap<KnownSectionsEntry> KnownSections = 1227 createKnownSectionsMap(*Streamer->getContext().getObjectFileInfo()); 1228 1229 for (const SectionRef &Section : File->sections()) { 1230 std::string Storage = ""; 1231 std::unique_ptr<DebugBufferVector> OutputData; 1232 if (Optional<StringRef> OutData = 1233 updateDebugData(Storage, Section, KnownSections, *Streamer, *this, 1234 DWOEntry, *DWOId, OutputData)) 1235 Streamer->emitBytes(*OutData); 1236 } 1237 Streamer->Finish(); 1238 TempOut->keep(); 1239 } 1240 } 1241 1242 void DWARFRewriter::updateGdbIndexSection() { 1243 if (!BC.getGdbIndexSection()) 1244 return; 1245 1246 // See https://sourceware.org/gdb/onlinedocs/gdb/Index-Section-Format.html 1247 // for .gdb_index section format. 1248 1249 StringRef GdbIndexContents = BC.getGdbIndexSection()->getContents(); 1250 1251 const char *Data = GdbIndexContents.data(); 1252 1253 // Parse the header. 1254 const uint32_t Version = read32le(Data); 1255 if (Version != 7 && Version != 8) { 1256 errs() << "BOLT-ERROR: can only process .gdb_index versions 7 and 8\n"; 1257 exit(1); 1258 } 1259 1260 // Some .gdb_index generators use file offsets while others use section 1261 // offsets. Hence we can only rely on offsets relative to each other, 1262 // and ignore their absolute values. 1263 const uint32_t CUListOffset = read32le(Data + 4); 1264 const uint32_t CUTypesOffset = read32le(Data + 8); 1265 const uint32_t AddressTableOffset = read32le(Data + 12); 1266 const uint32_t SymbolTableOffset = read32le(Data + 16); 1267 const uint32_t ConstantPoolOffset = read32le(Data + 20); 1268 Data += 24; 1269 1270 // Map CUs offsets to indices and verify existing index table. 1271 std::map<uint32_t, uint32_t> OffsetToIndexMap; 1272 const uint32_t CUListSize = CUTypesOffset - CUListOffset; 1273 const unsigned NumCUs = BC.DwCtx->getNumCompileUnits(); 1274 if (CUListSize != NumCUs * 16) { 1275 errs() << "BOLT-ERROR: .gdb_index: CU count mismatch\n"; 1276 exit(1); 1277 } 1278 for (unsigned Index = 0; Index < NumCUs; ++Index, Data += 16) { 1279 const DWARFUnit *CU = BC.DwCtx->getUnitAtIndex(Index); 1280 const uint64_t Offset = read64le(Data); 1281 if (CU->getOffset() != Offset) { 1282 errs() << "BOLT-ERROR: .gdb_index CU offset mismatch\n"; 1283 exit(1); 1284 } 1285 1286 OffsetToIndexMap[Offset] = Index; 1287 } 1288 1289 // Ignore old address table. 1290 const uint32_t OldAddressTableSize = SymbolTableOffset - AddressTableOffset; 1291 // Move Data to the beginning of symbol table. 1292 Data += SymbolTableOffset - CUTypesOffset; 1293 1294 // Calculate the size of the new address table. 1295 uint32_t NewAddressTableSize = 0; 1296 for (const auto &CURangesPair : ARangesSectionWriter->getCUAddressRanges()) { 1297 const SmallVector<DebugAddressRange, 2> &Ranges = CURangesPair.second; 1298 NewAddressTableSize += Ranges.size() * 20; 1299 } 1300 1301 // Difference between old and new table (and section) sizes. 1302 // Could be negative. 1303 int32_t Delta = NewAddressTableSize - OldAddressTableSize; 1304 1305 size_t NewGdbIndexSize = GdbIndexContents.size() + Delta; 1306 1307 // Free'd by ExecutableFileMemoryManager. 1308 auto *NewGdbIndexContents = new uint8_t[NewGdbIndexSize]; 1309 uint8_t *Buffer = NewGdbIndexContents; 1310 1311 write32le(Buffer, Version); 1312 write32le(Buffer + 4, CUListOffset); 1313 write32le(Buffer + 8, CUTypesOffset); 1314 write32le(Buffer + 12, AddressTableOffset); 1315 write32le(Buffer + 16, SymbolTableOffset + Delta); 1316 write32le(Buffer + 20, ConstantPoolOffset + Delta); 1317 Buffer += 24; 1318 1319 // Copy over CU list and types CU list. 1320 memcpy(Buffer, GdbIndexContents.data() + 24, 1321 AddressTableOffset - CUListOffset); 1322 Buffer += AddressTableOffset - CUListOffset; 1323 1324 // Generate new address table. 1325 for (const std::pair<const uint64_t, DebugAddressRangesVector> &CURangesPair : 1326 ARangesSectionWriter->getCUAddressRanges()) { 1327 const uint32_t CUIndex = OffsetToIndexMap[CURangesPair.first]; 1328 const DebugAddressRangesVector &Ranges = CURangesPair.second; 1329 for (const DebugAddressRange &Range : Ranges) { 1330 write64le(Buffer, Range.LowPC); 1331 write64le(Buffer + 8, Range.HighPC); 1332 write32le(Buffer + 16, CUIndex); 1333 Buffer += 20; 1334 } 1335 } 1336 1337 const size_t TrailingSize = 1338 GdbIndexContents.data() + GdbIndexContents.size() - Data; 1339 assert(Buffer + TrailingSize == NewGdbIndexContents + NewGdbIndexSize && 1340 "size calculation error"); 1341 1342 // Copy over the rest of the original data. 1343 memcpy(Buffer, Data, TrailingSize); 1344 1345 // Register the new section. 1346 BC.registerOrUpdateNoteSection(".gdb_index", NewGdbIndexContents, 1347 NewGdbIndexSize); 1348 } 1349 1350 void DWARFRewriter::convertToRanges(DWARFDie DIE, 1351 const DebugAddressRangesVector &Ranges, 1352 SimpleBinaryPatcher &DebugInfoPatcher) { 1353 uint64_t RangesSectionOffset; 1354 if (Ranges.empty()) 1355 RangesSectionOffset = RangesSectionWriter->getEmptyRangesOffset(); 1356 else 1357 RangesSectionOffset = RangesSectionWriter->addRanges(Ranges); 1358 1359 convertToRangesPatchDebugInfo(DIE, RangesSectionOffset, DebugInfoPatcher); 1360 } 1361 1362 void DWARFRewriter::convertPending(const DWARFUnit &Unit, 1363 const DWARFAbbreviationDeclaration *Abbrev, 1364 SimpleBinaryPatcher &DebugInfoPatcher, 1365 DebugAbbrevWriter &AbbrevWriter) { 1366 if (ConvertedRangesAbbrevs.count(Abbrev)) 1367 return; 1368 1369 convertToRangesPatchAbbrev(Unit, Abbrev, AbbrevWriter); 1370 1371 auto I = PendingRanges.find(Abbrev); 1372 if (I != PendingRanges.end()) { 1373 for (std::pair<DWARFDieWrapper, DebugAddressRange> &Pair : I->second) 1374 convertToRanges(Pair.first, {Pair.second}, DebugInfoPatcher); 1375 PendingRanges.erase(I); 1376 } 1377 1378 ConvertedRangesAbbrevs.emplace(Abbrev); 1379 } 1380 1381 void DWARFRewriter::addToPendingRanges( 1382 const DWARFAbbreviationDeclaration *Abbrev, DWARFDie DIE, 1383 DebugAddressRangesVector &FunctionRanges, Optional<uint64_t> DWOId) { 1384 Optional<DWARFFormValue> LowPcValue = DIE.find(dwarf::DW_AT_low_pc); 1385 Optional<DWARFFormValue> HighPcValue = DIE.find(dwarf::DW_AT_high_pc); 1386 if (LowPcValue && 1387 LowPcValue->getForm() == dwarf::Form::DW_FORM_GNU_addr_index) { 1388 assert(DWOId && "Invalid DWO ID."); 1389 (void)DWOId; 1390 assert(HighPcValue && "Low PC exists, but not High PC."); 1391 (void)HighPcValue; 1392 uint64_t IndexL = LowPcValue->getRawUValue(); 1393 uint64_t IndexH = HighPcValue->getRawUValue(); 1394 for (auto Address : FunctionRanges) { 1395 AddrWriter->addIndexAddress(Address.LowPC, IndexL, *DWOId); 1396 // 2.17.2 1397 // If the value of the DW_AT_high_pc is of class address, it is the 1398 // relocated address of the first location past the last instruction 1399 // associated with the entity; if it is of class constant, the value is 1400 // an unsigned integer offset which when added to the low PC gives the 1401 // address of the first location past the last instruction associated 1402 // with the entity. 1403 if (!HighPcValue->isFormClass(DWARFFormValue::FC_Constant)) 1404 AddrWriter->addIndexAddress(Address.HighPC, IndexH, *DWOId); 1405 } 1406 } 1407 PendingRanges[Abbrev].emplace_back( 1408 std::make_pair(DWARFDieWrapper(DIE), FunctionRanges.front())); 1409 } 1410 1411 std::unique_ptr<DebugBufferVector> 1412 DWARFRewriter::makeFinalLocListsSection(SimpleBinaryPatcher &DebugInfoPatcher) { 1413 auto LocBuffer = std::make_unique<DebugBufferVector>(); 1414 auto LocStream = std::make_unique<raw_svector_ostream>(*LocBuffer); 1415 auto Writer = 1416 std::unique_ptr<MCObjectWriter>(BC.createObjectWriter(*LocStream)); 1417 1418 uint64_t SectionOffset = 0; 1419 1420 // Add an empty list as the first entry; 1421 const char Zeroes[16] = {0}; 1422 *LocStream << StringRef(Zeroes, 16); 1423 SectionOffset += 2 * 8; 1424 1425 for (std::pair<const uint64_t, std::unique_ptr<DebugLocWriter>> &Loc : 1426 LocListWritersByCU) { 1427 DebugLocWriter *LocWriter = Loc.second.get(); 1428 if (auto *LocListWriter = llvm::dyn_cast<DebugLoclistWriter>(LocWriter)) { 1429 SimpleBinaryPatcher *Patcher = 1430 getBinaryDWODebugInfoPatcher(LocListWriter->getDWOID()); 1431 LocListWriter->finalize(0, *Patcher); 1432 continue; 1433 } 1434 LocWriter->finalize(SectionOffset, DebugInfoPatcher); 1435 std::unique_ptr<DebugBufferVector> CurrCULocationLists = 1436 LocWriter->getBuffer(); 1437 *LocStream << *CurrCULocationLists; 1438 SectionOffset += CurrCULocationLists->size(); 1439 } 1440 1441 return LocBuffer; 1442 } 1443 1444 void DWARFRewriter::flushPendingRanges(SimpleBinaryPatcher &DebugInfoPatcher) { 1445 for (std::pair<const DWARFAbbreviationDeclaration *const, 1446 std::vector<std::pair<DWARFDieWrapper, DebugAddressRange>>> 1447 &I : PendingRanges) 1448 for (std::pair<DWARFDieWrapper, DebugAddressRange> &RangePair : I.second) 1449 patchLowHigh(RangePair.first, RangePair.second, DebugInfoPatcher); 1450 clearList(PendingRanges); 1451 } 1452 1453 namespace { 1454 1455 void getRangeAttrData(DWARFDie DIE, Optional<AttrInfo> &LowPCVal, 1456 Optional<AttrInfo> &HighPCVal) { 1457 LowPCVal = findAttributeInfo(DIE, dwarf::DW_AT_low_pc); 1458 HighPCVal = findAttributeInfo(DIE, dwarf::DW_AT_high_pc); 1459 uint64_t LowPCOffset = LowPCVal->Offset; 1460 uint64_t HighPCOffset = HighPCVal->Offset; 1461 dwarf::Form LowPCForm = LowPCVal->V.getForm(); 1462 dwarf::Form HighPCForm = HighPCVal->V.getForm(); 1463 1464 if (LowPCForm != dwarf::DW_FORM_addr && 1465 LowPCForm != dwarf::DW_FORM_GNU_addr_index) { 1466 errs() << "BOLT-WARNING: unexpected low_pc form value. Cannot update DIE " 1467 << "at offset 0x" << Twine::utohexstr(DIE.getOffset()) << "\n"; 1468 return; 1469 } 1470 if (HighPCForm != dwarf::DW_FORM_addr && HighPCForm != dwarf::DW_FORM_data8 && 1471 HighPCForm != dwarf::DW_FORM_data4 && 1472 HighPCForm != dwarf::DW_FORM_data2 && 1473 HighPCForm != dwarf::DW_FORM_data1 && 1474 HighPCForm != dwarf::DW_FORM_udata) { 1475 errs() << "BOLT-WARNING: unexpected high_pc form value. Cannot update DIE " 1476 << "at offset 0x" << Twine::utohexstr(DIE.getOffset()) << "\n"; 1477 return; 1478 } 1479 if ((LowPCOffset == -1U || (LowPCOffset + 8 != HighPCOffset)) && 1480 LowPCForm != dwarf::DW_FORM_GNU_addr_index) { 1481 errs() << "BOLT-WARNING: high_pc expected immediately after low_pc. " 1482 << "Cannot update DIE at offset 0x" 1483 << Twine::utohexstr(DIE.getOffset()) << '\n'; 1484 return; 1485 } 1486 } 1487 1488 } // namespace 1489 1490 void DWARFRewriter::patchLowHigh(DWARFDie DIE, DebugAddressRange Range, 1491 SimpleBinaryPatcher &DebugInfoPatcher) { 1492 Optional<AttrInfo> LowPCVal = None; 1493 Optional<AttrInfo> HighPCVal = None; 1494 getRangeAttrData(DIE, LowPCVal, HighPCVal); 1495 uint64_t LowPCOffset = LowPCVal->Offset; 1496 uint64_t HighPCOffset = HighPCVal->Offset; 1497 auto *TempDebugPatcher = &DebugInfoPatcher; 1498 if (LowPCVal->V.getForm() == dwarf::DW_FORM_GNU_addr_index) { 1499 DWARFUnit *Unit = DIE.getDwarfUnit(); 1500 assert(Unit->isDWOUnit() && "DW_FORM_GNU_addr_index not part of DWO."); 1501 uint32_t AddressIndex = 1502 AddrWriter->getIndexFromAddress(Range.LowPC, *Unit->getDWOId()); 1503 TempDebugPatcher = getBinaryDWODebugInfoPatcher(*Unit->getDWOId()); 1504 TempDebugPatcher->addUDataPatch(LowPCOffset, AddressIndex, 1505 std::abs(int(HighPCOffset - LowPCOffset))); 1506 // TODO: In DWARF5 support ULEB128 for high_pc 1507 } else { 1508 TempDebugPatcher->addLE64Patch(LowPCOffset, Range.LowPC); 1509 } 1510 1511 uint64_t HighPC = Range.HighPC; 1512 // The DW_FORM_data* is delta between high and low pc 1513 if (HighPCVal->V.getForm() != dwarf::Form::DW_FORM_addr) 1514 HighPC -= Range.LowPC; 1515 1516 if (isHighPcFormEightBytes(HighPCVal->V.getForm())) 1517 TempDebugPatcher->addLE64Patch(HighPCOffset, HighPC); 1518 else 1519 TempDebugPatcher->addLE32Patch(HighPCOffset, HighPC); 1520 } 1521 1522 void DWARFRewriter::convertToRangesPatchAbbrev( 1523 const DWARFUnit &Unit, const DWARFAbbreviationDeclaration *Abbrev, 1524 DebugAbbrevWriter &AbbrevWriter, Optional<uint64_t> RangesBase) { 1525 auto getAttributeForm = [&Abbrev](const dwarf::Attribute Attr) { 1526 Optional<uint32_t> Index = Abbrev->findAttributeIndex(Attr); 1527 assert(Index && "attribute not found"); 1528 return Abbrev->getFormByIndex(*Index); 1529 }; 1530 dwarf::Form LowPCForm = getAttributeForm(dwarf::DW_AT_low_pc); 1531 1532 // DW_FORM_GNU_addr_index is already variable encoding so nothing to do 1533 // there. 1534 if (RangesBase) { 1535 assert(LowPCForm != dwarf::DW_FORM_GNU_addr_index); 1536 AbbrevWriter.addAttributePatch(Unit, Abbrev, dwarf::DW_AT_low_pc, 1537 dwarf::DW_AT_GNU_ranges_base, 1538 dwarf::DW_FORM_sec_offset); 1539 } 1540 1541 AbbrevWriter.addAttributePatch(Unit, Abbrev, dwarf::DW_AT_high_pc, 1542 dwarf::DW_AT_ranges, 1543 dwarf::DW_FORM_sec_offset); 1544 } 1545 1546 void DWARFRewriter::convertToRangesPatchDebugInfo( 1547 DWARFDie DIE, uint64_t RangesSectionOffset, 1548 SimpleBinaryPatcher &DebugInfoPatcher, Optional<uint64_t> RangesBase) { 1549 Optional<AttrInfo> LowPCVal = None; 1550 Optional<AttrInfo> HighPCVal = None; 1551 getRangeAttrData(DIE, LowPCVal, HighPCVal); 1552 uint64_t LowPCOffset = LowPCVal->Offset; 1553 uint64_t HighPCOffset = HighPCVal->Offset; 1554 1555 std::lock_guard<std::mutex> Lock(DebugInfoPatcherMutex); 1556 uint32_t BaseOffset = 0; 1557 if (LowPCVal->V.getForm() == dwarf::DW_FORM_GNU_addr_index) { 1558 // Use ULEB128 for the value. 1559 DebugInfoPatcher.addUDataPatch(LowPCOffset, 0, 1560 std::abs(int(HighPCOffset - LowPCOffset))); 1561 // Ranges are relative to DW_AT_GNU_ranges_base. 1562 BaseOffset = DebugInfoPatcher.getRangeBase(); 1563 } else { 1564 // If case DW_AT_low_pc was converted into DW_AT_GNU_ranges_base 1565 if (RangesBase) 1566 DebugInfoPatcher.addLE32Patch(LowPCOffset, *RangesBase, 8); 1567 else 1568 DebugInfoPatcher.addLE64Patch(LowPCOffset, 0); 1569 } 1570 DebugInfoPatcher.addLE32Patch(HighPCOffset, RangesSectionOffset - BaseOffset, 1571 HighPCVal->Size); 1572 } 1573