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