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 if (AbbreviationDecl->findAttributeIndex(dwarf::DW_AT_ranges)) { 693 // Case 1: The object was already non-contiguous and had DW_AT_ranges. 694 // In this case we simply need to update the value of DW_AT_ranges 695 // and introduce DW_AT_GNU_ranges_base if required. 696 Optional<AttrInfo> AttrVal = findAttributeInfo(DIE, dwarf::DW_AT_ranges); 697 698 std::lock_guard<std::mutex> Lock(DebugInfoPatcherMutex); 699 DebugInfoPatcher.addLE32Patch( 700 AttrVal->Offset, DebugRangesOffset - DebugInfoPatcher.getRangeBase(), 701 AttrVal->Size); 702 if (!RangesBase) 703 return; 704 705 // Convert DW_AT_low_pc into DW_AT_GNU_ranges_base. 706 Optional<AttrInfo> LowPCAttrInfo = 707 findAttributeInfo(DIE, dwarf::DW_AT_low_pc); 708 if (!LowPCAttrInfo) { 709 errs() << "BOLT-ERROR: skeleton CU at 0x" 710 << Twine::utohexstr(DIE.getOffset()) 711 << " does not have DW_AT_GNU_ranges_base or DW_AT_low_pc to" 712 " convert to update ranges base\n"; 713 return; 714 } 715 716 AbbrevWriter.addAttributePatch( 717 *DIE.getDwarfUnit(), AbbreviationDecl, dwarf::DW_AT_low_pc, 718 dwarf::DW_AT_GNU_ranges_base, dwarf::DW_FORM_indirect); 719 DebugInfoPatcher.addUDataPatch(LowPCAttrInfo->Offset, dwarf::DW_FORM_udata, 720 1); 721 DebugInfoPatcher.addUDataPatch(LowPCAttrInfo->Offset + 1, *RangesBase, 7); 722 723 return; 724 } 725 726 // Case 2: The object has both DW_AT_low_pc and DW_AT_high_pc emitted back 727 // to back. Replace with new attributes and patch the DIE. 728 if (AbbreviationDecl->findAttributeIndex(dwarf::DW_AT_low_pc) && 729 AbbreviationDecl->findAttributeIndex(dwarf::DW_AT_high_pc)) { 730 convertToRangesPatchAbbrev(*DIE.getDwarfUnit(), AbbreviationDecl, 731 AbbrevWriter, RangesBase); 732 convertToRangesPatchDebugInfo(DIE, DebugRangesOffset, DebugInfoPatcher, 733 RangesBase); 734 } else { 735 if (opts::Verbosity >= 1) 736 errs() << "BOLT-ERROR: cannot update ranges for DIE at offset 0x" 737 << Twine::utohexstr(DIE.getOffset()) << '\n'; 738 } 739 } 740 741 void DWARFRewriter::updateLineTableOffsets(const MCAsmLayout &Layout) { 742 ErrorOr<BinarySection &> DbgInfoSection = 743 BC.getUniqueSectionByName(".debug_info"); 744 ErrorOr<BinarySection &> TypeInfoSection = 745 BC.getUniqueSectionByName(".debug_types"); 746 assert(((BC.DwCtx->getNumTypeUnits() > 0 && TypeInfoSection) || 747 BC.DwCtx->getNumTypeUnits() == 0) && 748 "Was not able to retrieve Debug Types section."); 749 750 // We will be re-writing .debug_info so relocation mechanism doesn't work for 751 // Debug Info Patcher. 752 DebugInfoBinaryPatcher *DebugInfoPatcher = nullptr; 753 if (BC.DwCtx->getNumCompileUnits()) { 754 DbgInfoSection->registerPatcher(std::make_unique<DebugInfoBinaryPatcher>()); 755 DebugInfoPatcher = 756 static_cast<DebugInfoBinaryPatcher *>(DbgInfoSection->getPatcher()); 757 } 758 759 // There is no direct connection between CU and TU, but same offsets, 760 // encoded in DW_AT_stmt_list, into .debug_line get modified. 761 // We take advantage of that to map original CU line table offsets to new 762 // ones. 763 std::unordered_map<uint64_t, uint64_t> DebugLineOffsetMap; 764 765 auto GetStatementListValue = [](DWARFUnit *Unit) { 766 Optional<DWARFFormValue> StmtList = 767 Unit->getUnitDIE().find(dwarf::DW_AT_stmt_list); 768 Optional<uint64_t> Offset = dwarf::toSectionOffset(StmtList); 769 assert(Offset && "Was not able to retreive value of DW_AT_stmt_list."); 770 return *Offset; 771 }; 772 773 const uint64_t Reloc32Type = BC.isAArch64() 774 ? static_cast<uint64_t>(ELF::R_AARCH64_ABS32) 775 : static_cast<uint64_t>(ELF::R_X86_64_32); 776 777 for (const std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units()) { 778 const unsigned CUID = CU->getOffset(); 779 MCSymbol *Label = BC.getDwarfLineTable(CUID).getLabel(); 780 if (!Label) 781 continue; 782 783 Optional<AttrInfo> AttrVal = 784 findAttributeInfo(CU.get()->getUnitDIE(), dwarf::DW_AT_stmt_list); 785 if (!AttrVal) 786 continue; 787 788 const uint64_t AttributeOffset = AttrVal->Offset; 789 const uint64_t LineTableOffset = Layout.getSymbolOffset(*Label); 790 DebugLineOffsetMap[GetStatementListValue(CU.get())] = LineTableOffset; 791 assert(DbgInfoSection && ".debug_info section must exist"); 792 DebugInfoPatcher->addLE32Patch(AttributeOffset, LineTableOffset); 793 } 794 795 for (const std::unique_ptr<DWARFUnit> &TU : BC.DwCtx->types_section_units()) { 796 DWARFUnit *Unit = TU.get(); 797 Optional<AttrInfo> AttrVal = 798 findAttributeInfo(TU.get()->getUnitDIE(), dwarf::DW_AT_stmt_list); 799 if (!AttrVal) 800 continue; 801 const uint64_t AttributeOffset = AttrVal->Offset; 802 auto Iter = DebugLineOffsetMap.find(GetStatementListValue(Unit)); 803 assert(Iter != DebugLineOffsetMap.end() && 804 "Type Unit Updated Line Number Entry does not exist."); 805 TypeInfoSection->addRelocation(AttributeOffset, nullptr, Reloc32Type, 806 Iter->second, 0, /*Pending=*/true); 807 } 808 809 // Set .debug_info as finalized so it won't be skipped over when 810 // we process sections while writing out the new binary. This ensures 811 // that the pending relocations will be processed and not ignored. 812 if (DbgInfoSection) 813 DbgInfoSection->setIsFinalized(); 814 815 if (TypeInfoSection) 816 TypeInfoSection->setIsFinalized(); 817 } 818 819 void DWARFRewriter::finalizeDebugSections( 820 DebugInfoBinaryPatcher &DebugInfoPatcher) { 821 if (StrWriter->isInitialized()) { 822 RewriteInstance::addToDebugSectionsToOverwrite(".debug_str"); 823 std::unique_ptr<DebugStrBufferVector> DebugStrSectionContents = 824 StrWriter->finalize(); 825 BC.registerOrUpdateNoteSection(".debug_str", 826 copyByteArray(*DebugStrSectionContents), 827 DebugStrSectionContents->size()); 828 } 829 830 std::unique_ptr<DebugBufferVector> RangesSectionContents = 831 RangesSectionWriter->finalize(); 832 BC.registerOrUpdateNoteSection(".debug_ranges", 833 copyByteArray(*RangesSectionContents), 834 RangesSectionContents->size()); 835 836 std::unique_ptr<DebugBufferVector> LocationListSectionContents = 837 makeFinalLocListsSection(DebugInfoPatcher); 838 BC.registerOrUpdateNoteSection(".debug_loc", 839 copyByteArray(*LocationListSectionContents), 840 LocationListSectionContents->size()); 841 842 // AddrWriter should be finalized after debug_loc since more addresses can be 843 // added there. 844 if (AddrWriter->isInitialized()) { 845 AddressSectionBuffer AddressSectionContents = AddrWriter->finalize(); 846 BC.registerOrUpdateNoteSection(".debug_addr", 847 copyByteArray(AddressSectionContents), 848 AddressSectionContents.size()); 849 for (auto &CU : BC.DwCtx->compile_units()) { 850 DWARFDie DIE = CU->getUnitDIE(); 851 if (Optional<AttrInfo> AttrVal = 852 findAttributeInfo(DIE, dwarf::DW_AT_GNU_addr_base)) { 853 uint64_t Offset = AddrWriter->getOffset(*CU->getDWOId()); 854 DebugInfoPatcher.addLE32Patch( 855 AttrVal->Offset, static_cast<int32_t>(Offset), AttrVal->Size); 856 } 857 } 858 } 859 860 std::unique_ptr<DebugBufferVector> AbbrevSectionContents = 861 AbbrevWriter->finalize(); 862 BC.registerOrUpdateNoteSection(".debug_abbrev", 863 copyByteArray(*AbbrevSectionContents), 864 AbbrevSectionContents->size()); 865 866 // Update abbreviation offsets for CUs/TUs if they were changed. 867 SimpleBinaryPatcher *DebugTypesPatcher = nullptr; 868 for (auto &Unit : BC.DwCtx->normal_units()) { 869 const uint64_t NewAbbrevOffset = 870 AbbrevWriter->getAbbreviationsOffsetForUnit(*Unit); 871 if (Unit->getAbbreviationsOffset() == NewAbbrevOffset) 872 continue; 873 874 // DWARFv4 875 // unit_length - 4 bytes 876 // version - 2 bytes 877 // So + 6 to patch debug_abbrev_offset 878 constexpr uint64_t AbbrevFieldOffset = 6; 879 if (!Unit->isTypeUnit()) { 880 DebugInfoPatcher.addLE32Patch(Unit->getOffset() + AbbrevFieldOffset, 881 static_cast<uint32_t>(NewAbbrevOffset)); 882 continue; 883 } 884 885 if (!DebugTypesPatcher) { 886 ErrorOr<BinarySection &> DebugTypes = 887 BC.getUniqueSectionByName(".debug_types"); 888 DebugTypes->registerPatcher(std::make_unique<SimpleBinaryPatcher>()); 889 DebugTypesPatcher = 890 static_cast<SimpleBinaryPatcher *>(DebugTypes->getPatcher()); 891 } 892 DebugTypesPatcher->addLE32Patch(Unit->getOffset() + AbbrevFieldOffset, 893 static_cast<uint32_t>(NewAbbrevOffset)); 894 } 895 896 // No more creating new DebugInfoPatches. 897 std::unordered_map<uint32_t, uint32_t> CUMap = 898 DebugInfoPatcher.computeNewOffsets(); 899 900 // Skip .debug_aranges if we are re-generating .gdb_index. 901 if (opts::KeepARanges || !BC.getGdbIndexSection()) { 902 SmallVector<char, 16> ARangesBuffer; 903 raw_svector_ostream OS(ARangesBuffer); 904 905 auto MAB = std::unique_ptr<MCAsmBackend>( 906 BC.TheTarget->createMCAsmBackend(*BC.STI, *BC.MRI, MCTargetOptions())); 907 908 ARangesSectionWriter->writeARangesSection(OS, CUMap); 909 const StringRef &ARangesContents = OS.str(); 910 911 BC.registerOrUpdateNoteSection(".debug_aranges", 912 copyByteArray(ARangesContents), 913 ARangesContents.size()); 914 } 915 } 916 917 // Creates all the data structures necessary for creating MCStreamer. 918 // They are passed by reference because they need to be kept around. 919 // Also creates known debug sections. These are sections handled by 920 // handleDebugDataPatching. 921 using KnownSectionsEntry = std::pair<MCSection *, DWARFSectionKind>; 922 namespace { 923 924 std::unique_ptr<BinaryContext> 925 createDwarfOnlyBC(const object::ObjectFile &File) { 926 return BinaryContext::createBinaryContext( 927 &File, false, 928 DWARFContext::create(File, DWARFContext::ProcessDebugRelocations::Ignore, 929 nullptr, "", WithColor::defaultErrorHandler, 930 WithColor::defaultWarningHandler)); 931 } 932 933 StringMap<KnownSectionsEntry> 934 createKnownSectionsMap(const MCObjectFileInfo &MCOFI) { 935 StringMap<KnownSectionsEntry> KnownSectionsTemp = { 936 {"debug_info.dwo", {MCOFI.getDwarfInfoDWOSection(), DW_SECT_INFO}}, 937 {"debug_types.dwo", {MCOFI.getDwarfTypesDWOSection(), DW_SECT_EXT_TYPES}}, 938 {"debug_str_offsets.dwo", 939 {MCOFI.getDwarfStrOffDWOSection(), DW_SECT_STR_OFFSETS}}, 940 {"debug_str.dwo", {MCOFI.getDwarfStrDWOSection(), DW_SECT_EXT_unknown}}, 941 {"debug_loc.dwo", {MCOFI.getDwarfLocDWOSection(), DW_SECT_EXT_LOC}}, 942 {"debug_abbrev.dwo", {MCOFI.getDwarfAbbrevDWOSection(), DW_SECT_ABBREV}}, 943 {"debug_line.dwo", {MCOFI.getDwarfLineDWOSection(), DW_SECT_LINE}}}; 944 return KnownSectionsTemp; 945 } 946 947 StringRef getSectionName(const SectionRef &Section) { 948 Expected<StringRef> SectionName = Section.getName(); 949 assert(SectionName && "Invalid section name."); 950 StringRef Name = *SectionName; 951 Name = Name.substr(Name.find_first_not_of("._")); 952 return Name; 953 } 954 955 // Exctracts an appropriate slice if input is DWP. 956 // Applies patches or overwrites the section. 957 Optional<StringRef> 958 updateDebugData(std::string &Storage, const SectionRef &Section, 959 const StringMap<KnownSectionsEntry> &KnownSections, 960 MCStreamer &Streamer, DWARFRewriter &Writer, 961 const DWARFUnitIndex::Entry *DWOEntry, uint64_t DWOId, 962 std::unique_ptr<DebugBufferVector> &OutputBuffer) { 963 auto applyPatch = [&](DebugInfoBinaryPatcher *Patcher, 964 StringRef Data) -> StringRef { 965 Patcher->computeNewOffsets(); 966 Storage = Patcher->patchBinary(Data); 967 return StringRef(Storage.c_str(), Storage.size()); 968 }; 969 970 using DWOSectionContribution = 971 const DWARFUnitIndex::Entry::SectionContribution; 972 auto getSliceData = [&](const DWARFUnitIndex::Entry *DWOEntry, 973 StringRef OutData, DWARFSectionKind Sec, 974 uint32_t &DWPOffset) -> StringRef { 975 if (DWOEntry) { 976 DWOSectionContribution *DWOContrubution = DWOEntry->getContribution(Sec); 977 DWPOffset = DWOContrubution->Offset; 978 OutData = OutData.substr(DWPOffset, DWOContrubution->Length); 979 } 980 return OutData; 981 }; 982 983 StringRef Name = getSectionName(Section); 984 auto SectionIter = KnownSections.find(Name); 985 if (SectionIter == KnownSections.end()) 986 return None; 987 Streamer.SwitchSection(SectionIter->second.first); 988 Expected<StringRef> Contents = Section.getContents(); 989 assert(Contents && "Invalid contents."); 990 StringRef OutData = *Contents; 991 uint32_t DWPOffset = 0; 992 993 switch (SectionIter->second.second) { 994 default: { 995 if (!Name.equals("debug_str.dwo")) 996 errs() << "BOLT-WARNING: Unsupported Debug section: " << Name << "\n"; 997 return OutData; 998 } 999 case DWARFSectionKind::DW_SECT_INFO: { 1000 OutData = getSliceData(DWOEntry, OutData, DWARFSectionKind::DW_SECT_INFO, 1001 DWPOffset); 1002 DebugInfoBinaryPatcher *Patcher = llvm::cast<DebugInfoBinaryPatcher>( 1003 Writer.getBinaryDWODebugInfoPatcher(DWOId)); 1004 return applyPatch(Patcher, OutData); 1005 } 1006 case DWARFSectionKind::DW_SECT_EXT_TYPES: { 1007 return getSliceData(DWOEntry, OutData, DWARFSectionKind::DW_SECT_EXT_TYPES, 1008 DWPOffset); 1009 } 1010 case DWARFSectionKind::DW_SECT_STR_OFFSETS: { 1011 return getSliceData(DWOEntry, OutData, 1012 DWARFSectionKind::DW_SECT_STR_OFFSETS, DWPOffset); 1013 } 1014 case DWARFSectionKind::DW_SECT_ABBREV: { 1015 DebugAbbrevWriter *AbbrevWriter = Writer.getBinaryDWOAbbrevWriter(DWOId); 1016 OutputBuffer = AbbrevWriter->finalize(); 1017 // Creating explicit StringRef here, otherwise 1018 // with impicit conversion it will take null byte as end of 1019 // string. 1020 return StringRef(reinterpret_cast<const char *>(OutputBuffer->data()), 1021 OutputBuffer->size()); 1022 } 1023 case DWARFSectionKind::DW_SECT_EXT_LOC: { 1024 DebugLocWriter *LocWriter = Writer.getDebugLocWriter(DWOId); 1025 OutputBuffer = LocWriter->getBuffer(); 1026 // Creating explicit StringRef here, otherwise 1027 // with impicit conversion it will take null byte as end of 1028 // string. 1029 return StringRef(reinterpret_cast<const char *>(OutputBuffer->data()), 1030 OutputBuffer->size()); 1031 } 1032 case DWARFSectionKind::DW_SECT_LINE: { 1033 return getSliceData(DWOEntry, OutData, DWARFSectionKind::DW_SECT_LINE, 1034 DWPOffset); 1035 } 1036 } 1037 } 1038 1039 } // namespace 1040 1041 void DWARFRewriter::writeDWP( 1042 std::unordered_map<uint64_t, std::string> &DWOIdToName) { 1043 SmallString<0> OutputNameStr; 1044 StringRef OutputName; 1045 if (opts::DwarfOutputPath.empty()) { 1046 OutputName = 1047 Twine(opts::OutputFilename).concat(".dwp").toStringRef(OutputNameStr); 1048 } else { 1049 StringRef ExeFileName = llvm::sys::path::filename(opts::OutputFilename); 1050 OutputName = Twine(opts::DwarfOutputPath) 1051 .concat("/") 1052 .concat(ExeFileName) 1053 .concat(".dwp") 1054 .toStringRef(OutputNameStr); 1055 errs() << "BOLT-WARNING: dwarf-output-path is in effect and .dwp file will " 1056 "possibly be written to another location that is not the same as " 1057 "the executable\n"; 1058 } 1059 std::error_code EC; 1060 std::unique_ptr<ToolOutputFile> Out = 1061 std::make_unique<ToolOutputFile>(OutputName, EC, sys::fs::OF_None); 1062 1063 const object::ObjectFile *File = BC.DwCtx->getDWARFObj().getFile(); 1064 std::unique_ptr<BinaryContext> TmpBC = createDwarfOnlyBC(*File); 1065 std::unique_ptr<MCStreamer> Streamer = TmpBC->createStreamer(Out->os()); 1066 const MCObjectFileInfo &MCOFI = *Streamer->getContext().getObjectFileInfo(); 1067 StringMap<KnownSectionsEntry> KnownSections = createKnownSectionsMap(MCOFI); 1068 MCSection *const StrSection = MCOFI.getDwarfStrDWOSection(); 1069 MCSection *const StrOffsetSection = MCOFI.getDwarfStrOffDWOSection(); 1070 1071 // Data Structures for DWP book keeping 1072 // Size of array corresponds to the number of sections supported by DWO format 1073 // in DWARF4/5. 1074 uint32_t ContributionOffsets[8] = {}; 1075 std::deque<SmallString<32>> UncompressedSections; 1076 DWPStringPool Strings(*Streamer, StrSection); 1077 MapVector<uint64_t, UnitIndexEntry> IndexEntries; 1078 constexpr uint32_t IndexVersion = 2; 1079 1080 // Setup DWP code once. 1081 DWARFContext *DWOCtx = BC.getDWOContext(); 1082 const DWARFUnitIndex *CUIndex = nullptr; 1083 bool IsDWP = false; 1084 if (DWOCtx) { 1085 CUIndex = &DWOCtx->getCUIndex(); 1086 IsDWP = !CUIndex->getRows().empty(); 1087 } 1088 1089 for (const std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units()) { 1090 Optional<uint64_t> DWOId = CU->getDWOId(); 1091 if (!DWOId) 1092 continue; 1093 1094 // Skipping CUs that we failed to load. 1095 Optional<DWARFUnit *> DWOCU = BC.getDWOCU(*DWOId); 1096 if (!DWOCU) 1097 continue; 1098 1099 assert(CU->getVersion() == 4 && "For DWP output only DWARF4 is supported"); 1100 UnitIndexEntry CurEntry = {}; 1101 CurEntry.DWOName = 1102 dwarf::toString(CU->getUnitDIE().find( 1103 {dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name}), 1104 ""); 1105 const char *Name = CU->getUnitDIE().getShortName(); 1106 if (Name) 1107 CurEntry.Name = Name; 1108 StringRef CurStrSection; 1109 StringRef CurStrOffsetSection; 1110 1111 // This maps each section contained in this file to its length. 1112 // This information is later on used to calculate the contributions, 1113 // i.e. offset and length, of each compile/type unit to a section. 1114 std::vector<std::pair<DWARFSectionKind, uint32_t>> SectionLength; 1115 1116 const DWARFUnitIndex::Entry *DWOEntry = nullptr; 1117 if (IsDWP) 1118 DWOEntry = CUIndex->getFromHash(*DWOId); 1119 1120 bool StrSectionWrittenOut = false; 1121 const object::ObjectFile *DWOFile = 1122 (*DWOCU)->getContext().getDWARFObj().getFile(); 1123 for (const SectionRef &Section : DWOFile->sections()) { 1124 std::string Storage = ""; 1125 std::unique_ptr<DebugBufferVector> OutputData; 1126 Optional<StringRef> TOutData = 1127 updateDebugData(Storage, Section, KnownSections, *Streamer, *this, 1128 DWOEntry, *DWOId, OutputData); 1129 if (!TOutData) 1130 continue; 1131 1132 StringRef OutData = *TOutData; 1133 StringRef Name = getSectionName(Section); 1134 if (Name.equals("debug_str.dwo")) { 1135 CurStrSection = OutData; 1136 } else { 1137 // Since handleDebugDataPatching returned true, we already know this is 1138 // a known section. 1139 auto SectionIter = KnownSections.find(Name); 1140 if (SectionIter->second.second == DWARFSectionKind::DW_SECT_STR_OFFSETS) 1141 CurStrOffsetSection = OutData; 1142 else 1143 Streamer->emitBytes(OutData); 1144 auto Index = 1145 getContributionIndex(SectionIter->second.second, IndexVersion); 1146 CurEntry.Contributions[Index].Offset = ContributionOffsets[Index]; 1147 CurEntry.Contributions[Index].Length = OutData.size(); 1148 ContributionOffsets[Index] += CurEntry.Contributions[Index].Length; 1149 } 1150 1151 // Strings are combined in to a new string section, and de-duplicated 1152 // based on hash. 1153 if (!StrSectionWrittenOut && !CurStrOffsetSection.empty() && 1154 !CurStrSection.empty()) { 1155 writeStringsAndOffsets(*Streamer.get(), Strings, StrOffsetSection, 1156 CurStrSection, CurStrOffsetSection, 1157 CU->getVersion()); 1158 StrSectionWrittenOut = true; 1159 } 1160 } 1161 CompileUnitIdentifiers CUI{*DWOId, CurEntry.Name.c_str(), 1162 CurEntry.DWOName.c_str()}; 1163 auto P = IndexEntries.insert(std::make_pair(CUI.Signature, CurEntry)); 1164 if (!P.second) { 1165 Error Err = buildDuplicateError(*P.first, CUI, ""); 1166 errs() << "BOLT-ERROR: " << toString(std::move(Err)) << "\n"; 1167 return; 1168 } 1169 } 1170 1171 // Lie about the type contribution for DWARF < 5. In DWARFv5 the type 1172 // section does not exist, so no need to do anything about this. 1173 ContributionOffsets[getContributionIndex(DW_SECT_EXT_TYPES, 2)] = 0; 1174 writeIndex(*Streamer.get(), MCOFI.getDwarfCUIndexSection(), 1175 ContributionOffsets, IndexEntries, IndexVersion); 1176 1177 Streamer->Finish(); 1178 Out->keep(); 1179 } 1180 1181 void DWARFRewriter::writeDWOFiles( 1182 std::unordered_map<uint64_t, std::string> &DWOIdToName) { 1183 // Setup DWP code once. 1184 DWARFContext *DWOCtx = BC.getDWOContext(); 1185 const DWARFUnitIndex *CUIndex = nullptr; 1186 bool IsDWP = false; 1187 if (DWOCtx) { 1188 CUIndex = &DWOCtx->getCUIndex(); 1189 IsDWP = !CUIndex->getRows().empty(); 1190 } 1191 1192 for (const std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units()) { 1193 Optional<uint64_t> DWOId = CU->getDWOId(); 1194 if (!DWOId) 1195 continue; 1196 1197 // Skipping CUs that we failed to load. 1198 Optional<DWARFUnit *> DWOCU = BC.getDWOCU(*DWOId); 1199 if (!DWOCU) 1200 continue; 1201 1202 std::string CompDir = opts::DwarfOutputPath.empty() 1203 ? CU->getCompilationDir() 1204 : opts::DwarfOutputPath.c_str(); 1205 std::string ObjectName = getDWOName(*CU.get(), nullptr, DWOIdToName); 1206 auto FullPath = CompDir.append("/").append(ObjectName); 1207 1208 std::error_code EC; 1209 std::unique_ptr<ToolOutputFile> TempOut = 1210 std::make_unique<ToolOutputFile>(FullPath, EC, sys::fs::OF_None); 1211 1212 const DWARFUnitIndex::Entry *DWOEntry = nullptr; 1213 if (IsDWP) 1214 DWOEntry = CUIndex->getFromHash(*DWOId); 1215 1216 const object::ObjectFile *File = 1217 (*DWOCU)->getContext().getDWARFObj().getFile(); 1218 std::unique_ptr<BinaryContext> TmpBC = createDwarfOnlyBC(*File); 1219 std::unique_ptr<MCStreamer> Streamer = TmpBC->createStreamer(TempOut->os()); 1220 StringMap<KnownSectionsEntry> KnownSections = 1221 createKnownSectionsMap(*Streamer->getContext().getObjectFileInfo()); 1222 1223 for (const SectionRef &Section : File->sections()) { 1224 std::string Storage = ""; 1225 std::unique_ptr<DebugBufferVector> OutputData; 1226 if (Optional<StringRef> OutData = 1227 updateDebugData(Storage, Section, KnownSections, *Streamer, *this, 1228 DWOEntry, *DWOId, OutputData)) 1229 Streamer->emitBytes(*OutData); 1230 } 1231 Streamer->Finish(); 1232 TempOut->keep(); 1233 } 1234 } 1235 1236 void DWARFRewriter::updateGdbIndexSection() { 1237 if (!BC.getGdbIndexSection()) 1238 return; 1239 1240 // See https://sourceware.org/gdb/onlinedocs/gdb/Index-Section-Format.html 1241 // for .gdb_index section format. 1242 1243 StringRef GdbIndexContents = BC.getGdbIndexSection()->getContents(); 1244 1245 const char *Data = GdbIndexContents.data(); 1246 1247 // Parse the header. 1248 const uint32_t Version = read32le(Data); 1249 if (Version != 7 && Version != 8) { 1250 errs() << "BOLT-ERROR: can only process .gdb_index versions 7 and 8\n"; 1251 exit(1); 1252 } 1253 1254 // Some .gdb_index generators use file offsets while others use section 1255 // offsets. Hence we can only rely on offsets relative to each other, 1256 // and ignore their absolute values. 1257 const uint32_t CUListOffset = read32le(Data + 4); 1258 const uint32_t CUTypesOffset = read32le(Data + 8); 1259 const uint32_t AddressTableOffset = read32le(Data + 12); 1260 const uint32_t SymbolTableOffset = read32le(Data + 16); 1261 const uint32_t ConstantPoolOffset = read32le(Data + 20); 1262 Data += 24; 1263 1264 // Map CUs offsets to indices and verify existing index table. 1265 std::map<uint32_t, uint32_t> OffsetToIndexMap; 1266 const uint32_t CUListSize = CUTypesOffset - CUListOffset; 1267 const unsigned NumCUs = BC.DwCtx->getNumCompileUnits(); 1268 if (CUListSize != NumCUs * 16) { 1269 errs() << "BOLT-ERROR: .gdb_index: CU count mismatch\n"; 1270 exit(1); 1271 } 1272 for (unsigned Index = 0; Index < NumCUs; ++Index, Data += 16) { 1273 const DWARFUnit *CU = BC.DwCtx->getUnitAtIndex(Index); 1274 const uint64_t Offset = read64le(Data); 1275 if (CU->getOffset() != Offset) { 1276 errs() << "BOLT-ERROR: .gdb_index CU offset mismatch\n"; 1277 exit(1); 1278 } 1279 1280 OffsetToIndexMap[Offset] = Index; 1281 } 1282 1283 // Ignore old address table. 1284 const uint32_t OldAddressTableSize = SymbolTableOffset - AddressTableOffset; 1285 // Move Data to the beginning of symbol table. 1286 Data += SymbolTableOffset - CUTypesOffset; 1287 1288 // Calculate the size of the new address table. 1289 uint32_t NewAddressTableSize = 0; 1290 for (const auto &CURangesPair : ARangesSectionWriter->getCUAddressRanges()) { 1291 const SmallVector<DebugAddressRange, 2> &Ranges = CURangesPair.second; 1292 NewAddressTableSize += Ranges.size() * 20; 1293 } 1294 1295 // Difference between old and new table (and section) sizes. 1296 // Could be negative. 1297 int32_t Delta = NewAddressTableSize - OldAddressTableSize; 1298 1299 size_t NewGdbIndexSize = GdbIndexContents.size() + Delta; 1300 1301 // Free'd by ExecutableFileMemoryManager. 1302 auto *NewGdbIndexContents = new uint8_t[NewGdbIndexSize]; 1303 uint8_t *Buffer = NewGdbIndexContents; 1304 1305 write32le(Buffer, Version); 1306 write32le(Buffer + 4, CUListOffset); 1307 write32le(Buffer + 8, CUTypesOffset); 1308 write32le(Buffer + 12, AddressTableOffset); 1309 write32le(Buffer + 16, SymbolTableOffset + Delta); 1310 write32le(Buffer + 20, ConstantPoolOffset + Delta); 1311 Buffer += 24; 1312 1313 // Copy over CU list and types CU list. 1314 memcpy(Buffer, GdbIndexContents.data() + 24, 1315 AddressTableOffset - CUListOffset); 1316 Buffer += AddressTableOffset - CUListOffset; 1317 1318 // Generate new address table. 1319 for (const std::pair<const uint64_t, DebugAddressRangesVector> &CURangesPair : 1320 ARangesSectionWriter->getCUAddressRanges()) { 1321 const uint32_t CUIndex = OffsetToIndexMap[CURangesPair.first]; 1322 const DebugAddressRangesVector &Ranges = CURangesPair.second; 1323 for (const DebugAddressRange &Range : Ranges) { 1324 write64le(Buffer, Range.LowPC); 1325 write64le(Buffer + 8, Range.HighPC); 1326 write32le(Buffer + 16, CUIndex); 1327 Buffer += 20; 1328 } 1329 } 1330 1331 const size_t TrailingSize = 1332 GdbIndexContents.data() + GdbIndexContents.size() - Data; 1333 assert(Buffer + TrailingSize == NewGdbIndexContents + NewGdbIndexSize && 1334 "size calculation error"); 1335 1336 // Copy over the rest of the original data. 1337 memcpy(Buffer, Data, TrailingSize); 1338 1339 // Register the new section. 1340 BC.registerOrUpdateNoteSection(".gdb_index", NewGdbIndexContents, 1341 NewGdbIndexSize); 1342 } 1343 1344 void DWARFRewriter::convertToRanges(DWARFDie DIE, 1345 const DebugAddressRangesVector &Ranges, 1346 SimpleBinaryPatcher &DebugInfoPatcher) { 1347 uint64_t RangesSectionOffset; 1348 if (Ranges.empty()) 1349 RangesSectionOffset = RangesSectionWriter->getEmptyRangesOffset(); 1350 else 1351 RangesSectionOffset = RangesSectionWriter->addRanges(Ranges); 1352 1353 convertToRangesPatchDebugInfo(DIE, RangesSectionOffset, DebugInfoPatcher); 1354 } 1355 1356 void DWARFRewriter::convertPending(const DWARFUnit &Unit, 1357 const DWARFAbbreviationDeclaration *Abbrev, 1358 SimpleBinaryPatcher &DebugInfoPatcher, 1359 DebugAbbrevWriter &AbbrevWriter) { 1360 if (ConvertedRangesAbbrevs.count(Abbrev)) 1361 return; 1362 1363 convertToRangesPatchAbbrev(Unit, Abbrev, AbbrevWriter); 1364 1365 auto I = PendingRanges.find(Abbrev); 1366 if (I != PendingRanges.end()) { 1367 for (std::pair<DWARFDieWrapper, DebugAddressRange> &Pair : I->second) 1368 convertToRanges(Pair.first, {Pair.second}, DebugInfoPatcher); 1369 PendingRanges.erase(I); 1370 } 1371 1372 ConvertedRangesAbbrevs.emplace(Abbrev); 1373 } 1374 1375 void DWARFRewriter::addToPendingRanges( 1376 const DWARFAbbreviationDeclaration *Abbrev, DWARFDie DIE, 1377 DebugAddressRangesVector &FunctionRanges, Optional<uint64_t> DWOId) { 1378 Optional<DWARFFormValue> LowPcValue = DIE.find(dwarf::DW_AT_low_pc); 1379 Optional<DWARFFormValue> HighPcValue = DIE.find(dwarf::DW_AT_high_pc); 1380 if (LowPcValue && 1381 LowPcValue->getForm() == dwarf::Form::DW_FORM_GNU_addr_index) { 1382 assert(DWOId && "Invalid DWO ID."); 1383 (void)DWOId; 1384 assert(HighPcValue && "Low PC exists, but not High PC."); 1385 (void)HighPcValue; 1386 uint64_t IndexL = LowPcValue->getRawUValue(); 1387 uint64_t IndexH = HighPcValue->getRawUValue(); 1388 for (auto Address : FunctionRanges) { 1389 AddrWriter->addIndexAddress(Address.LowPC, IndexL, *DWOId); 1390 // 2.17.2 1391 // If the value of the DW_AT_high_pc is of class address, it is the 1392 // relocated address of the first location past the last instruction 1393 // associated with the entity; if it is of class constant, the value is 1394 // an unsigned integer offset which when added to the low PC gives the 1395 // address of the first location past the last instruction associated 1396 // with the entity. 1397 if (!HighPcValue->isFormClass(DWARFFormValue::FC_Constant)) 1398 AddrWriter->addIndexAddress(Address.HighPC, IndexH, *DWOId); 1399 } 1400 } 1401 PendingRanges[Abbrev].emplace_back( 1402 std::make_pair(DWARFDieWrapper(DIE), FunctionRanges.front())); 1403 } 1404 1405 std::unique_ptr<DebugBufferVector> 1406 DWARFRewriter::makeFinalLocListsSection(SimpleBinaryPatcher &DebugInfoPatcher) { 1407 auto LocBuffer = std::make_unique<DebugBufferVector>(); 1408 auto LocStream = std::make_unique<raw_svector_ostream>(*LocBuffer); 1409 auto Writer = 1410 std::unique_ptr<MCObjectWriter>(BC.createObjectWriter(*LocStream)); 1411 1412 uint64_t SectionOffset = 0; 1413 1414 // Add an empty list as the first entry; 1415 const char Zeroes[16] = {0}; 1416 *LocStream << StringRef(Zeroes, 16); 1417 SectionOffset += 2 * 8; 1418 1419 for (std::pair<const uint64_t, std::unique_ptr<DebugLocWriter>> &Loc : 1420 LocListWritersByCU) { 1421 DebugLocWriter *LocWriter = Loc.second.get(); 1422 if (auto *LocListWriter = llvm::dyn_cast<DebugLoclistWriter>(LocWriter)) { 1423 SimpleBinaryPatcher *Patcher = 1424 getBinaryDWODebugInfoPatcher(LocListWriter->getDWOID()); 1425 LocListWriter->finalize(0, *Patcher); 1426 continue; 1427 } 1428 LocWriter->finalize(SectionOffset, DebugInfoPatcher); 1429 std::unique_ptr<DebugBufferVector> CurrCULocationLists = 1430 LocWriter->getBuffer(); 1431 *LocStream << *CurrCULocationLists; 1432 SectionOffset += CurrCULocationLists->size(); 1433 } 1434 1435 return LocBuffer; 1436 } 1437 1438 void DWARFRewriter::flushPendingRanges(SimpleBinaryPatcher &DebugInfoPatcher) { 1439 for (std::pair<const DWARFAbbreviationDeclaration *const, 1440 std::vector<std::pair<DWARFDieWrapper, DebugAddressRange>>> 1441 &I : PendingRanges) 1442 for (std::pair<DWARFDieWrapper, DebugAddressRange> &RangePair : I.second) 1443 patchLowHigh(RangePair.first, RangePair.second, DebugInfoPatcher); 1444 clearList(PendingRanges); 1445 } 1446 1447 namespace { 1448 1449 void getRangeAttrData(DWARFDie DIE, Optional<AttrInfo> &LowPCVal, 1450 Optional<AttrInfo> &HighPCVal) { 1451 LowPCVal = findAttributeInfo(DIE, dwarf::DW_AT_low_pc); 1452 HighPCVal = findAttributeInfo(DIE, dwarf::DW_AT_high_pc); 1453 uint64_t LowPCOffset = LowPCVal->Offset; 1454 uint64_t HighPCOffset = HighPCVal->Offset; 1455 dwarf::Form LowPCForm = LowPCVal->V.getForm(); 1456 dwarf::Form HighPCForm = HighPCVal->V.getForm(); 1457 1458 if (LowPCForm != dwarf::DW_FORM_addr && 1459 LowPCForm != dwarf::DW_FORM_GNU_addr_index) { 1460 errs() << "BOLT-WARNING: unexpected low_pc form value. Cannot update DIE " 1461 << "at offset 0x" << Twine::utohexstr(DIE.getOffset()) << "\n"; 1462 return; 1463 } 1464 if (HighPCForm != dwarf::DW_FORM_addr && HighPCForm != dwarf::DW_FORM_data8 && 1465 HighPCForm != dwarf::DW_FORM_data4 && 1466 HighPCForm != dwarf::DW_FORM_data2 && 1467 HighPCForm != dwarf::DW_FORM_data1 && 1468 HighPCForm != dwarf::DW_FORM_udata) { 1469 errs() << "BOLT-WARNING: unexpected high_pc form value. Cannot update DIE " 1470 << "at offset 0x" << Twine::utohexstr(DIE.getOffset()) << "\n"; 1471 return; 1472 } 1473 if ((LowPCOffset == -1U || (LowPCOffset + 8 != HighPCOffset)) && 1474 LowPCForm != dwarf::DW_FORM_GNU_addr_index) { 1475 errs() << "BOLT-WARNING: high_pc expected immediately after low_pc. " 1476 << "Cannot update DIE at offset 0x" 1477 << Twine::utohexstr(DIE.getOffset()) << '\n'; 1478 return; 1479 } 1480 } 1481 1482 } // namespace 1483 1484 void DWARFRewriter::patchLowHigh(DWARFDie DIE, DebugAddressRange Range, 1485 SimpleBinaryPatcher &DebugInfoPatcher) { 1486 Optional<AttrInfo> LowPCVal = None; 1487 Optional<AttrInfo> HighPCVal = None; 1488 getRangeAttrData(DIE, LowPCVal, HighPCVal); 1489 uint64_t LowPCOffset = LowPCVal->Offset; 1490 uint64_t HighPCOffset = HighPCVal->Offset; 1491 auto *TempDebugPatcher = &DebugInfoPatcher; 1492 if (LowPCVal->V.getForm() == dwarf::DW_FORM_GNU_addr_index) { 1493 DWARFUnit *Unit = DIE.getDwarfUnit(); 1494 assert(Unit->isDWOUnit() && "DW_FORM_GNU_addr_index not part of DWO."); 1495 uint32_t AddressIndex = 1496 AddrWriter->getIndexFromAddress(Range.LowPC, *Unit->getDWOId()); 1497 TempDebugPatcher = getBinaryDWODebugInfoPatcher(*Unit->getDWOId()); 1498 TempDebugPatcher->addUDataPatch(LowPCOffset, AddressIndex, 1499 std::abs(int(HighPCOffset - LowPCOffset))); 1500 // TODO: In DWARF5 support ULEB128 for high_pc 1501 } else { 1502 TempDebugPatcher->addLE64Patch(LowPCOffset, Range.LowPC); 1503 } 1504 1505 uint64_t HighPC = Range.HighPC; 1506 // The DW_FORM_data* is delta between high and low pc 1507 if (HighPCVal->V.getForm() != dwarf::Form::DW_FORM_addr) 1508 HighPC -= Range.LowPC; 1509 1510 if (isHighPcFormEightBytes(HighPCVal->V.getForm())) 1511 TempDebugPatcher->addLE64Patch(HighPCOffset, HighPC); 1512 else 1513 TempDebugPatcher->addLE32Patch(HighPCOffset, HighPC); 1514 } 1515 1516 void DWARFRewriter::convertToRangesPatchAbbrev( 1517 const DWARFUnit &Unit, const DWARFAbbreviationDeclaration *Abbrev, 1518 DebugAbbrevWriter &AbbrevWriter, Optional<uint64_t> RangesBase) { 1519 auto getAttributeForm = [&Abbrev](const dwarf::Attribute Attr) { 1520 Optional<uint32_t> Index = Abbrev->findAttributeIndex(Attr); 1521 assert(Index && "attribute not found"); 1522 return Abbrev->getFormByIndex(*Index); 1523 }; 1524 dwarf::Form LowPCForm = getAttributeForm(dwarf::DW_AT_low_pc); 1525 1526 // DW_FORM_GNU_addr_index is already variable encoding so nothing to do 1527 // there. 1528 if (RangesBase) { 1529 assert(LowPCForm != dwarf::DW_FORM_GNU_addr_index); 1530 AbbrevWriter.addAttributePatch(Unit, Abbrev, dwarf::DW_AT_low_pc, 1531 dwarf::DW_AT_GNU_ranges_base, 1532 dwarf::DW_FORM_sec_offset); 1533 } 1534 1535 AbbrevWriter.addAttributePatch(Unit, Abbrev, dwarf::DW_AT_high_pc, 1536 dwarf::DW_AT_ranges, 1537 dwarf::DW_FORM_sec_offset); 1538 } 1539 1540 void DWARFRewriter::convertToRangesPatchDebugInfo( 1541 DWARFDie DIE, uint64_t RangesSectionOffset, 1542 SimpleBinaryPatcher &DebugInfoPatcher, Optional<uint64_t> RangesBase) { 1543 Optional<AttrInfo> LowPCVal = None; 1544 Optional<AttrInfo> HighPCVal = None; 1545 getRangeAttrData(DIE, LowPCVal, HighPCVal); 1546 uint64_t LowPCOffset = LowPCVal->Offset; 1547 uint64_t HighPCOffset = HighPCVal->Offset; 1548 1549 std::lock_guard<std::mutex> Lock(DebugInfoPatcherMutex); 1550 uint32_t BaseOffset = 0; 1551 if (LowPCVal->V.getForm() == dwarf::DW_FORM_GNU_addr_index) { 1552 // Use ULEB128 for the value. 1553 DebugInfoPatcher.addUDataPatch(LowPCOffset, 0, 1554 std::abs(int(HighPCOffset - LowPCOffset))); 1555 // Ranges are relative to DW_AT_GNU_ranges_base. 1556 BaseOffset = DebugInfoPatcher.getRangeBase(); 1557 } else { 1558 // If case DW_AT_low_pc was converted into DW_AT_GNU_ranges_base 1559 if (RangesBase) 1560 DebugInfoPatcher.addLE32Patch(LowPCOffset, *RangesBase, 8); 1561 else 1562 DebugInfoPatcher.addLE64Patch(LowPCOffset, 0); 1563 } 1564 DebugInfoPatcher.addLE32Patch(HighPCOffset, RangesSectionOffset - BaseOffset, 1565 HighPCVal->Size); 1566 } 1567