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