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