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 Offset = AddrWriter->getOffset(*CU); 1004 1005 if (AttrValGnu) { 1006 AttrOffset = AttrValGnu->Offset; 1007 Size = AttrValGnu->Size; 1008 } 1009 1010 if (AttrVal) { 1011 AttrOffset = AttrVal->Offset; 1012 Size = AttrVal->Size; 1013 } 1014 1015 if (AttrValGnu || AttrVal) { 1016 DebugInfoPatcher.addLE32Patch(AttrOffset, static_cast<int32_t>(Offset), 1017 Size); 1018 } else if (CU->getVersion() >= 5) { 1019 // A case where we were not using .debug_addr section, but after update 1020 // now using it. 1021 const DWARFAbbreviationDeclaration *Abbrev = 1022 DIE.getAbbreviationDeclarationPtr(); 1023 AbbrevWriter->addAttribute(*CU, Abbrev, dwarf::DW_AT_addr_base, 1024 dwarf::DW_FORM_sec_offset); 1025 DebugInfoPatcher.insertNewEntry(DIE, static_cast<int32_t>(Offset)); 1026 } else 1027 llvm_unreachable( 1028 "DWO CU uses .debug_address, but DW_AT_GNU_addr_base is missing."); 1029 } 1030 } 1031 1032 std::unique_ptr<DebugBufferVector> AbbrevSectionContents = 1033 AbbrevWriter->finalize(); 1034 BC.registerOrUpdateNoteSection(".debug_abbrev", 1035 copyByteArray(*AbbrevSectionContents), 1036 AbbrevSectionContents->size()); 1037 1038 // Update abbreviation offsets for CUs/TUs if they were changed. 1039 SimpleBinaryPatcher *DebugTypesPatcher = nullptr; 1040 for (auto &Unit : BC.DwCtx->normal_units()) { 1041 const uint64_t NewAbbrevOffset = 1042 AbbrevWriter->getAbbreviationsOffsetForUnit(*Unit); 1043 if (Unit->getAbbreviationsOffset() == NewAbbrevOffset) 1044 continue; 1045 1046 // DWARFv4 or earlier 1047 // unit_length - 4 bytes 1048 // version - 2 bytes 1049 // So + 6 to patch debug_abbrev_offset 1050 constexpr uint64_t AbbrevFieldOffsetLegacy = 6; 1051 // DWARFv5 1052 // unit_length - 4 bytes 1053 // version - 2 bytes 1054 // unit_type - 1 byte 1055 // address_size - 1 byte 1056 // So + 8 to patch debug_abbrev_offset 1057 constexpr uint64_t AbbrevFieldOffsetV5 = 8; 1058 uint64_t AbbrevOffset = 1059 Unit->getVersion() >= 5 ? AbbrevFieldOffsetV5 : AbbrevFieldOffsetLegacy; 1060 if (!Unit->isTypeUnit() || Unit->getVersion() >= 5) { 1061 DebugInfoPatcher.addLE32Patch(Unit->getOffset() + AbbrevOffset, 1062 static_cast<uint32_t>(NewAbbrevOffset)); 1063 continue; 1064 } 1065 1066 if (!DebugTypesPatcher) { 1067 ErrorOr<BinarySection &> DebugTypes = 1068 BC.getUniqueSectionByName(".debug_types"); 1069 DebugTypes->registerPatcher(std::make_unique<SimpleBinaryPatcher>()); 1070 DebugTypesPatcher = 1071 static_cast<SimpleBinaryPatcher *>(DebugTypes->getPatcher()); 1072 } 1073 DebugTypesPatcher->addLE32Patch(Unit->getOffset() + AbbrevOffset, 1074 static_cast<uint32_t>(NewAbbrevOffset)); 1075 } 1076 1077 // No more creating new DebugInfoPatches. 1078 CUOffsetMap CUMap = 1079 DebugInfoPatcher.computeNewOffsets(*BC.DwCtx.get(), false); 1080 1081 // Skip .debug_aranges if we are re-generating .gdb_index. 1082 if (opts::KeepARanges || !BC.getGdbIndexSection()) { 1083 SmallVector<char, 16> ARangesBuffer; 1084 raw_svector_ostream OS(ARangesBuffer); 1085 1086 auto MAB = std::unique_ptr<MCAsmBackend>( 1087 BC.TheTarget->createMCAsmBackend(*BC.STI, *BC.MRI, MCTargetOptions())); 1088 1089 ARangesSectionWriter->writeARangesSection(OS, CUMap); 1090 const StringRef &ARangesContents = OS.str(); 1091 1092 BC.registerOrUpdateNoteSection(".debug_aranges", 1093 copyByteArray(ARangesContents), 1094 ARangesContents.size()); 1095 } 1096 return CUMap; 1097 } 1098 1099 // Creates all the data structures necessary for creating MCStreamer. 1100 // They are passed by reference because they need to be kept around. 1101 // Also creates known debug sections. These are sections handled by 1102 // handleDebugDataPatching. 1103 using KnownSectionsEntry = std::pair<MCSection *, DWARFSectionKind>; 1104 namespace { 1105 1106 std::unique_ptr<BinaryContext> 1107 createDwarfOnlyBC(const object::ObjectFile &File) { 1108 return cantFail(BinaryContext::createBinaryContext( 1109 &File, false, 1110 DWARFContext::create(File, DWARFContext::ProcessDebugRelocations::Ignore, 1111 nullptr, "", WithColor::defaultErrorHandler, 1112 WithColor::defaultWarningHandler))); 1113 } 1114 1115 StringMap<KnownSectionsEntry> 1116 createKnownSectionsMap(const MCObjectFileInfo &MCOFI) { 1117 StringMap<KnownSectionsEntry> KnownSectionsTemp = { 1118 {"debug_info.dwo", {MCOFI.getDwarfInfoDWOSection(), DW_SECT_INFO}}, 1119 {"debug_types.dwo", {MCOFI.getDwarfTypesDWOSection(), DW_SECT_EXT_TYPES}}, 1120 {"debug_str_offsets.dwo", 1121 {MCOFI.getDwarfStrOffDWOSection(), DW_SECT_STR_OFFSETS}}, 1122 {"debug_str.dwo", {MCOFI.getDwarfStrDWOSection(), DW_SECT_EXT_unknown}}, 1123 {"debug_loc.dwo", {MCOFI.getDwarfLocDWOSection(), DW_SECT_EXT_LOC}}, 1124 {"debug_abbrev.dwo", {MCOFI.getDwarfAbbrevDWOSection(), DW_SECT_ABBREV}}, 1125 {"debug_line.dwo", {MCOFI.getDwarfLineDWOSection(), DW_SECT_LINE}}, 1126 {"debug_loclists.dwo", 1127 {MCOFI.getDwarfLoclistsDWOSection(), DW_SECT_LOCLISTS}}, 1128 {"debug_rnglists.dwo", 1129 {MCOFI.getDwarfRnglistsDWOSection(), DW_SECT_RNGLISTS}}}; 1130 return KnownSectionsTemp; 1131 } 1132 1133 StringRef getSectionName(const SectionRef &Section) { 1134 Expected<StringRef> SectionName = Section.getName(); 1135 assert(SectionName && "Invalid section name."); 1136 StringRef Name = *SectionName; 1137 Name = Name.substr(Name.find_first_not_of("._")); 1138 return Name; 1139 } 1140 1141 // Exctracts an appropriate slice if input is DWP. 1142 // Applies patches or overwrites the section. 1143 Optional<StringRef> 1144 updateDebugData(DWARFContext &DWCtx, std::string &Storage, 1145 StringRef SectionName, StringRef SectionContents, 1146 const StringMap<KnownSectionsEntry> &KnownSections, 1147 MCStreamer &Streamer, DWARFRewriter &Writer, 1148 const DWARFUnitIndex::Entry *DWOEntry, uint64_t DWOId, 1149 std::unique_ptr<DebugBufferVector> &OutputBuffer, 1150 DebugRangeListsSectionWriter *RangeListsWriter) { 1151 auto applyPatch = [&](DebugInfoBinaryPatcher *Patcher, 1152 StringRef Data) -> StringRef { 1153 Patcher->computeNewOffsets(DWCtx, true); 1154 Storage = Patcher->patchBinary(Data); 1155 return StringRef(Storage.c_str(), Storage.size()); 1156 }; 1157 1158 using DWOSectionContribution = 1159 const DWARFUnitIndex::Entry::SectionContribution; 1160 auto getSliceData = [&](const DWARFUnitIndex::Entry *DWOEntry, 1161 StringRef OutData, DWARFSectionKind Sec, 1162 uint32_t &DWPOffset) -> StringRef { 1163 if (DWOEntry) { 1164 DWOSectionContribution *DWOContrubution = DWOEntry->getContribution(Sec); 1165 DWPOffset = DWOContrubution->Offset; 1166 OutData = OutData.substr(DWPOffset, DWOContrubution->Length); 1167 } 1168 return OutData; 1169 }; 1170 1171 auto SectionIter = KnownSections.find(SectionName); 1172 if (SectionIter == KnownSections.end()) 1173 return None; 1174 Streamer.SwitchSection(SectionIter->second.first); 1175 StringRef OutData = SectionContents; 1176 uint32_t DWPOffset = 0; 1177 1178 switch (SectionIter->second.second) { 1179 default: { 1180 if (!SectionName.equals("debug_str.dwo")) 1181 errs() << "BOLT-WARNING: unsupported debug section: " << SectionName 1182 << "\n"; 1183 return OutData; 1184 } 1185 case DWARFSectionKind::DW_SECT_INFO: { 1186 OutData = getSliceData(DWOEntry, OutData, DWARFSectionKind::DW_SECT_INFO, 1187 DWPOffset); 1188 DebugInfoBinaryPatcher *Patcher = llvm::cast<DebugInfoBinaryPatcher>( 1189 Writer.getBinaryDWODebugInfoPatcher(DWOId)); 1190 return applyPatch(Patcher, OutData); 1191 } 1192 case DWARFSectionKind::DW_SECT_EXT_TYPES: { 1193 return getSliceData(DWOEntry, OutData, DWARFSectionKind::DW_SECT_EXT_TYPES, 1194 DWPOffset); 1195 } 1196 case DWARFSectionKind::DW_SECT_STR_OFFSETS: { 1197 return getSliceData(DWOEntry, OutData, 1198 DWARFSectionKind::DW_SECT_STR_OFFSETS, DWPOffset); 1199 } 1200 case DWARFSectionKind::DW_SECT_ABBREV: { 1201 DebugAbbrevWriter *AbbrevWriter = Writer.getBinaryDWOAbbrevWriter(DWOId); 1202 OutputBuffer = AbbrevWriter->finalize(); 1203 // Creating explicit StringRef here, otherwise 1204 // with impicit conversion it will take null byte as end of 1205 // string. 1206 return StringRef(reinterpret_cast<const char *>(OutputBuffer->data()), 1207 OutputBuffer->size()); 1208 } 1209 case DWARFSectionKind::DW_SECT_EXT_LOC: 1210 case DWARFSectionKind::DW_SECT_LOCLISTS: { 1211 DebugLocWriter *LocWriter = Writer.getDebugLocWriter(DWOId); 1212 OutputBuffer = LocWriter->getBuffer(); 1213 // Creating explicit StringRef here, otherwise 1214 // with impicit conversion it will take null byte as end of 1215 // string. 1216 return StringRef(reinterpret_cast<const char *>(OutputBuffer->data()), 1217 OutputBuffer->size()); 1218 } 1219 case DWARFSectionKind::DW_SECT_LINE: { 1220 return getSliceData(DWOEntry, OutData, DWARFSectionKind::DW_SECT_LINE, 1221 DWPOffset); 1222 } 1223 case DWARFSectionKind::DW_SECT_RNGLISTS: { 1224 OutputBuffer = RangeListsWriter->releaseBuffer(); 1225 return StringRef(reinterpret_cast<const char *>(OutputBuffer->data()), 1226 OutputBuffer->size()); 1227 } 1228 } 1229 } 1230 1231 } // namespace 1232 1233 void DWARFRewriter::writeDWP( 1234 std::unordered_map<uint64_t, std::string> &DWOIdToName) { 1235 SmallString<0> OutputNameStr; 1236 StringRef OutputName; 1237 if (opts::DwarfOutputPath.empty()) { 1238 OutputName = 1239 Twine(opts::OutputFilename).concat(".dwp").toStringRef(OutputNameStr); 1240 } else { 1241 StringRef ExeFileName = llvm::sys::path::filename(opts::OutputFilename); 1242 OutputName = Twine(opts::DwarfOutputPath) 1243 .concat("/") 1244 .concat(ExeFileName) 1245 .concat(".dwp") 1246 .toStringRef(OutputNameStr); 1247 errs() << "BOLT-WARNING: dwarf-output-path is in effect and .dwp file will " 1248 "possibly be written to another location that is not the same as " 1249 "the executable\n"; 1250 } 1251 std::error_code EC; 1252 std::unique_ptr<ToolOutputFile> Out = 1253 std::make_unique<ToolOutputFile>(OutputName, EC, sys::fs::OF_None); 1254 1255 const object::ObjectFile *File = BC.DwCtx->getDWARFObj().getFile(); 1256 std::unique_ptr<BinaryContext> TmpBC = createDwarfOnlyBC(*File); 1257 std::unique_ptr<MCStreamer> Streamer = TmpBC->createStreamer(Out->os()); 1258 const MCObjectFileInfo &MCOFI = *Streamer->getContext().getObjectFileInfo(); 1259 StringMap<KnownSectionsEntry> KnownSections = createKnownSectionsMap(MCOFI); 1260 MCSection *const StrSection = MCOFI.getDwarfStrDWOSection(); 1261 MCSection *const StrOffsetSection = MCOFI.getDwarfStrOffDWOSection(); 1262 1263 // Data Structures for DWP book keeping 1264 // Size of array corresponds to the number of sections supported by DWO format 1265 // in DWARF4/5. 1266 uint32_t ContributionOffsets[8] = {}; 1267 std::deque<SmallString<32>> UncompressedSections; 1268 DWPStringPool Strings(*Streamer, StrSection); 1269 MapVector<uint64_t, UnitIndexEntry> IndexEntries; 1270 constexpr uint32_t IndexVersion = 2; 1271 1272 // Setup DWP code once. 1273 DWARFContext *DWOCtx = BC.getDWOContext(); 1274 const DWARFUnitIndex *CUIndex = nullptr; 1275 bool IsDWP = false; 1276 if (DWOCtx) { 1277 CUIndex = &DWOCtx->getCUIndex(); 1278 IsDWP = !CUIndex->getRows().empty(); 1279 } 1280 1281 for (const std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units()) { 1282 Optional<uint64_t> DWOId = CU->getDWOId(); 1283 if (!DWOId) 1284 continue; 1285 1286 // Skipping CUs that we failed to load. 1287 Optional<DWARFUnit *> DWOCU = BC.getDWOCU(*DWOId); 1288 if (!DWOCU) 1289 continue; 1290 1291 assert(CU->getVersion() <= 4 && "For DWP output only DWARF4 is supported"); 1292 UnitIndexEntry CurEntry = {}; 1293 CurEntry.DWOName = 1294 dwarf::toString(CU->getUnitDIE().find( 1295 {dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name}), 1296 ""); 1297 const char *Name = CU->getUnitDIE().getShortName(); 1298 if (Name) 1299 CurEntry.Name = Name; 1300 StringRef CurStrSection; 1301 StringRef CurStrOffsetSection; 1302 1303 // This maps each section contained in this file to its length. 1304 // This information is later on used to calculate the contributions, 1305 // i.e. offset and length, of each compile/type unit to a section. 1306 std::vector<std::pair<DWARFSectionKind, uint32_t>> SectionLength; 1307 1308 const DWARFUnitIndex::Entry *DWOEntry = nullptr; 1309 if (IsDWP) 1310 DWOEntry = CUIndex->getFromHash(*DWOId); 1311 1312 bool StrSectionWrittenOut = false; 1313 const object::ObjectFile *DWOFile = 1314 (*DWOCU)->getContext().getDWARFObj().getFile(); 1315 1316 DebugRangeListsSectionWriter *RangeListssWriter = nullptr; 1317 if (CU->getVersion() == 5) { 1318 assert(RangeListsWritersByCU.count(*DWOId) != 0 && 1319 "No RangeListsWriter for DWO ID."); 1320 RangeListssWriter = RangeListsWritersByCU[*DWOId].get(); 1321 } 1322 for (const SectionRef &Section : DWOFile->sections()) { 1323 std::string Storage = ""; 1324 std::unique_ptr<DebugBufferVector> OutputData; 1325 StringRef SectionName = getSectionName(Section); 1326 Expected<StringRef> Contents = Section.getContents(); 1327 assert(Contents && "Invalid contents."); 1328 Optional<StringRef> TOutData = 1329 updateDebugData((*DWOCU)->getContext(), Storage, SectionName, 1330 *Contents, KnownSections, *Streamer, *this, DWOEntry, 1331 *DWOId, OutputData, RangeListssWriter); 1332 if (!TOutData) 1333 continue; 1334 1335 StringRef OutData = *TOutData; 1336 StringRef Name = getSectionName(Section); 1337 if (Name.equals("debug_str.dwo")) { 1338 CurStrSection = OutData; 1339 } else { 1340 // Since handleDebugDataPatching returned true, we already know this is 1341 // a known section. 1342 auto SectionIter = KnownSections.find(Name); 1343 if (SectionIter->second.second == DWARFSectionKind::DW_SECT_STR_OFFSETS) 1344 CurStrOffsetSection = OutData; 1345 else 1346 Streamer->emitBytes(OutData); 1347 auto Index = 1348 getContributionIndex(SectionIter->second.second, IndexVersion); 1349 CurEntry.Contributions[Index].Offset = ContributionOffsets[Index]; 1350 CurEntry.Contributions[Index].Length = OutData.size(); 1351 ContributionOffsets[Index] += CurEntry.Contributions[Index].Length; 1352 } 1353 1354 // Strings are combined in to a new string section, and de-duplicated 1355 // based on hash. 1356 if (!StrSectionWrittenOut && !CurStrOffsetSection.empty() && 1357 !CurStrSection.empty()) { 1358 writeStringsAndOffsets(*Streamer.get(), Strings, StrOffsetSection, 1359 CurStrSection, CurStrOffsetSection, 1360 CU->getVersion()); 1361 StrSectionWrittenOut = true; 1362 } 1363 } 1364 CompileUnitIdentifiers CUI{*DWOId, CurEntry.Name.c_str(), 1365 CurEntry.DWOName.c_str()}; 1366 auto P = IndexEntries.insert(std::make_pair(CUI.Signature, CurEntry)); 1367 if (!P.second) { 1368 Error Err = buildDuplicateError(*P.first, CUI, ""); 1369 errs() << "BOLT-ERROR: " << toString(std::move(Err)) << "\n"; 1370 return; 1371 } 1372 } 1373 1374 // Lie about the type contribution for DWARF < 5. In DWARFv5 the type 1375 // section does not exist, so no need to do anything about this. 1376 ContributionOffsets[getContributionIndex(DW_SECT_EXT_TYPES, 2)] = 0; 1377 writeIndex(*Streamer.get(), MCOFI.getDwarfCUIndexSection(), 1378 ContributionOffsets, IndexEntries, IndexVersion); 1379 1380 Streamer->Finish(); 1381 Out->keep(); 1382 } 1383 1384 void DWARFRewriter::writeDWOFiles( 1385 std::unordered_map<uint64_t, std::string> &DWOIdToName) { 1386 // Setup DWP code once. 1387 DWARFContext *DWOCtx = BC.getDWOContext(); 1388 const DWARFUnitIndex *CUIndex = nullptr; 1389 bool IsDWP = false; 1390 if (DWOCtx) { 1391 CUIndex = &DWOCtx->getCUIndex(); 1392 IsDWP = !CUIndex->getRows().empty(); 1393 } 1394 1395 for (const std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units()) { 1396 Optional<uint64_t> DWOId = CU->getDWOId(); 1397 if (!DWOId) 1398 continue; 1399 1400 // Skipping CUs that we failed to load. 1401 Optional<DWARFUnit *> DWOCU = BC.getDWOCU(*DWOId); 1402 if (!DWOCU) 1403 continue; 1404 1405 std::string CompDir = opts::DwarfOutputPath.empty() 1406 ? CU->getCompilationDir() 1407 : opts::DwarfOutputPath.c_str(); 1408 std::string ObjectName = getDWOName(*CU.get(), nullptr, DWOIdToName); 1409 auto FullPath = CompDir.append("/").append(ObjectName); 1410 1411 std::error_code EC; 1412 std::unique_ptr<ToolOutputFile> TempOut = 1413 std::make_unique<ToolOutputFile>(FullPath, EC, sys::fs::OF_None); 1414 1415 const DWARFUnitIndex::Entry *DWOEntry = nullptr; 1416 if (IsDWP) 1417 DWOEntry = CUIndex->getFromHash(*DWOId); 1418 1419 const object::ObjectFile *File = 1420 (*DWOCU)->getContext().getDWARFObj().getFile(); 1421 std::unique_ptr<BinaryContext> TmpBC = createDwarfOnlyBC(*File); 1422 std::unique_ptr<MCStreamer> Streamer = TmpBC->createStreamer(TempOut->os()); 1423 StringMap<KnownSectionsEntry> KnownSections = 1424 createKnownSectionsMap(*Streamer->getContext().getObjectFileInfo()); 1425 1426 DebugRangeListsSectionWriter *RangeListssWriter = nullptr; 1427 if (CU->getVersion() == 5) { 1428 assert(RangeListsWritersByCU.count(*DWOId) != 0 && 1429 "No RangeListsWriter for DWO ID."); 1430 RangeListssWriter = RangeListsWritersByCU[*DWOId].get(); 1431 1432 // Handling .debug_rnglists.dwo seperatly. The original .o/.dwo might not 1433 // have .debug_rnglists so won't be part of the loop below. 1434 if (!RangeListssWriter->empty()) { 1435 std::string Storage = ""; 1436 std::unique_ptr<DebugBufferVector> OutputData; 1437 if (Optional<StringRef> OutData = updateDebugData( 1438 (*DWOCU)->getContext(), Storage, "debug_rnglists.dwo", "", 1439 KnownSections, *Streamer, *this, DWOEntry, *DWOId, OutputData, 1440 RangeListssWriter)) 1441 Streamer->emitBytes(*OutData); 1442 } 1443 } 1444 for (const SectionRef &Section : File->sections()) { 1445 std::string Storage = ""; 1446 std::unique_ptr<DebugBufferVector> OutputData; 1447 StringRef SectionName = getSectionName(Section); 1448 if (SectionName == "debug_rnglists.dwo") 1449 continue; 1450 Expected<StringRef> Contents = Section.getContents(); 1451 assert(Contents && "Invalid contents."); 1452 if (Optional<StringRef> OutData = 1453 updateDebugData((*DWOCU)->getContext(), Storage, SectionName, 1454 *Contents, KnownSections, *Streamer, *this, 1455 DWOEntry, *DWOId, OutputData, RangeListssWriter)) 1456 Streamer->emitBytes(*OutData); 1457 } 1458 Streamer->Finish(); 1459 TempOut->keep(); 1460 } 1461 } 1462 1463 void DWARFRewriter::updateGdbIndexSection(CUOffsetMap &CUMap) { 1464 if (!BC.getGdbIndexSection()) 1465 return; 1466 1467 // See https://sourceware.org/gdb/onlinedocs/gdb/Index-Section-Format.html 1468 // for .gdb_index section format. 1469 1470 StringRef GdbIndexContents = BC.getGdbIndexSection()->getContents(); 1471 1472 const char *Data = GdbIndexContents.data(); 1473 1474 // Parse the header. 1475 const uint32_t Version = read32le(Data); 1476 if (Version != 7 && Version != 8) { 1477 errs() << "BOLT-ERROR: can only process .gdb_index versions 7 and 8\n"; 1478 exit(1); 1479 } 1480 1481 // Some .gdb_index generators use file offsets while others use section 1482 // offsets. Hence we can only rely on offsets relative to each other, 1483 // and ignore their absolute values. 1484 const uint32_t CUListOffset = read32le(Data + 4); 1485 const uint32_t CUTypesOffset = read32le(Data + 8); 1486 const uint32_t AddressTableOffset = read32le(Data + 12); 1487 const uint32_t SymbolTableOffset = read32le(Data + 16); 1488 const uint32_t ConstantPoolOffset = read32le(Data + 20); 1489 Data += 24; 1490 1491 // Map CUs offsets to indices and verify existing index table. 1492 std::map<uint32_t, uint32_t> OffsetToIndexMap; 1493 const uint32_t CUListSize = CUTypesOffset - CUListOffset; 1494 const unsigned NumCUs = BC.DwCtx->getNumCompileUnits(); 1495 if (CUListSize != NumCUs * 16) { 1496 errs() << "BOLT-ERROR: .gdb_index: CU count mismatch\n"; 1497 exit(1); 1498 } 1499 for (unsigned Index = 0; Index < NumCUs; ++Index, Data += 16) { 1500 const DWARFUnit *CU = BC.DwCtx->getUnitAtIndex(Index); 1501 const uint64_t Offset = read64le(Data); 1502 if (CU->getOffset() != Offset) { 1503 errs() << "BOLT-ERROR: .gdb_index CU offset mismatch\n"; 1504 exit(1); 1505 } 1506 1507 OffsetToIndexMap[Offset] = Index; 1508 } 1509 1510 // Ignore old address table. 1511 const uint32_t OldAddressTableSize = SymbolTableOffset - AddressTableOffset; 1512 // Move Data to the beginning of symbol table. 1513 Data += SymbolTableOffset - CUTypesOffset; 1514 1515 // Calculate the size of the new address table. 1516 uint32_t NewAddressTableSize = 0; 1517 for (const auto &CURangesPair : ARangesSectionWriter->getCUAddressRanges()) { 1518 const SmallVector<DebugAddressRange, 2> &Ranges = CURangesPair.second; 1519 NewAddressTableSize += Ranges.size() * 20; 1520 } 1521 1522 // Difference between old and new table (and section) sizes. 1523 // Could be negative. 1524 int32_t Delta = NewAddressTableSize - OldAddressTableSize; 1525 1526 size_t NewGdbIndexSize = GdbIndexContents.size() + Delta; 1527 1528 // Free'd by ExecutableFileMemoryManager. 1529 auto *NewGdbIndexContents = new uint8_t[NewGdbIndexSize]; 1530 uint8_t *Buffer = NewGdbIndexContents; 1531 1532 write32le(Buffer, Version); 1533 write32le(Buffer + 4, CUListOffset); 1534 write32le(Buffer + 8, CUTypesOffset); 1535 write32le(Buffer + 12, AddressTableOffset); 1536 write32le(Buffer + 16, SymbolTableOffset + Delta); 1537 write32le(Buffer + 20, ConstantPoolOffset + Delta); 1538 Buffer += 24; 1539 1540 // Writing out CU List <Offset, Size> 1541 for (auto &CUInfo : CUMap) { 1542 write64le(Buffer, CUInfo.second.Offset); 1543 // Length encoded in CU doesn't contain first 4 bytes that encode length. 1544 write64le(Buffer + 8, CUInfo.second.Length + 4); 1545 Buffer += 16; 1546 } 1547 1548 // Copy over types CU list 1549 // Spec says " triplet, the first value is the CU offset, the second value is 1550 // the type offset in the CU, and the third value is the type signature" 1551 // Looking at what is being generated by gdb-add-index. The first entry is TU 1552 // offset, second entry is offset from it, and third entry is the type 1553 // signature. 1554 memcpy(Buffer, GdbIndexContents.data() + CUTypesOffset, 1555 AddressTableOffset - CUTypesOffset); 1556 Buffer += AddressTableOffset - CUTypesOffset; 1557 1558 // Generate new address table. 1559 for (const std::pair<const uint64_t, DebugAddressRangesVector> &CURangesPair : 1560 ARangesSectionWriter->getCUAddressRanges()) { 1561 const uint32_t CUIndex = OffsetToIndexMap[CURangesPair.first]; 1562 const DebugAddressRangesVector &Ranges = CURangesPair.second; 1563 for (const DebugAddressRange &Range : Ranges) { 1564 write64le(Buffer, Range.LowPC); 1565 write64le(Buffer + 8, Range.HighPC); 1566 write32le(Buffer + 16, CUIndex); 1567 Buffer += 20; 1568 } 1569 } 1570 1571 const size_t TrailingSize = 1572 GdbIndexContents.data() + GdbIndexContents.size() - Data; 1573 assert(Buffer + TrailingSize == NewGdbIndexContents + NewGdbIndexSize && 1574 "size calculation error"); 1575 1576 // Copy over the rest of the original data. 1577 memcpy(Buffer, Data, TrailingSize); 1578 1579 // Register the new section. 1580 BC.registerOrUpdateNoteSection(".gdb_index", NewGdbIndexContents, 1581 NewGdbIndexSize); 1582 } 1583 1584 std::unique_ptr<DebugBufferVector> 1585 DWARFRewriter::makeFinalLocListsSection(SimpleBinaryPatcher &DebugInfoPatcher, 1586 DWARFVersion Version) { 1587 auto LocBuffer = std::make_unique<DebugBufferVector>(); 1588 auto LocStream = std::make_unique<raw_svector_ostream>(*LocBuffer); 1589 auto Writer = 1590 std::unique_ptr<MCObjectWriter>(BC.createObjectWriter(*LocStream)); 1591 1592 uint64_t SectionOffset = 0; 1593 // Add an empty list as the first entry; 1594 if (LocListWritersByCU.empty() || 1595 LocListWritersByCU.begin()->second.get()->getDwarfVersion() < 5) { 1596 // Should be fine for both DWARF4 and DWARF5? 1597 const char Zeroes[16] = {0}; 1598 *LocStream << StringRef(Zeroes, 16); 1599 SectionOffset += 2 * 8; 1600 } 1601 1602 for (std::pair<const uint64_t, std::unique_ptr<DebugLocWriter>> &Loc : 1603 LocListWritersByCU) { 1604 DebugLocWriter *LocWriter = Loc.second.get(); 1605 auto *LocListWriter = llvm::dyn_cast<DebugLoclistWriter>(LocWriter); 1606 1607 if (Version == DWARFVersion::DWARF5 && 1608 (!LocListWriter || LocListWriter->getDwarfVersion() <= 4)) 1609 continue; 1610 1611 if (Version == DWARFVersion::DWARFLegacy && 1612 (LocListWriter && LocListWriter->getDwarfVersion() >= 5)) 1613 continue; 1614 if (LocListWriter && (LocListWriter->getDwarfVersion() <= 4 || 1615 (LocListWriter->getDwarfVersion() >= 5 && 1616 LocListWriter->isSplitDwarf()))) { 1617 SimpleBinaryPatcher *Patcher = 1618 getBinaryDWODebugInfoPatcher(LocListWriter->getCUID()); 1619 LocListWriter->finalize(0, *Patcher); 1620 continue; 1621 } 1622 LocWriter->finalize(SectionOffset, DebugInfoPatcher); 1623 std::unique_ptr<DebugBufferVector> CurrCULocationLists = 1624 LocWriter->getBuffer(); 1625 *LocStream << *CurrCULocationLists; 1626 SectionOffset += CurrCULocationLists->size(); 1627 } 1628 1629 return LocBuffer; 1630 } 1631 1632 namespace { 1633 1634 void getRangeAttrData(DWARFDie DIE, Optional<AttrInfo> &LowPCVal, 1635 Optional<AttrInfo> &HighPCVal) { 1636 LowPCVal = findAttributeInfo(DIE, dwarf::DW_AT_low_pc); 1637 HighPCVal = findAttributeInfo(DIE, dwarf::DW_AT_high_pc); 1638 uint64_t LowPCOffset = LowPCVal->Offset; 1639 uint64_t HighPCOffset = HighPCVal->Offset; 1640 dwarf::Form LowPCForm = LowPCVal->V.getForm(); 1641 dwarf::Form HighPCForm = HighPCVal->V.getForm(); 1642 1643 if (LowPCForm != dwarf::DW_FORM_addr && 1644 LowPCForm != dwarf::DW_FORM_GNU_addr_index && 1645 LowPCForm != dwarf::DW_FORM_addrx) { 1646 errs() << "BOLT-WARNING: unexpected low_pc form value. Cannot update DIE " 1647 << "at offset 0x" << Twine::utohexstr(DIE.getOffset()) << "\n"; 1648 return; 1649 } 1650 if (HighPCForm != dwarf::DW_FORM_addr && HighPCForm != dwarf::DW_FORM_data8 && 1651 HighPCForm != dwarf::DW_FORM_data4 && 1652 HighPCForm != dwarf::DW_FORM_data2 && 1653 HighPCForm != dwarf::DW_FORM_data1 && 1654 HighPCForm != dwarf::DW_FORM_udata) { 1655 errs() << "BOLT-WARNING: unexpected high_pc form value. Cannot update DIE " 1656 << "at offset 0x" << Twine::utohexstr(DIE.getOffset()) << "\n"; 1657 return; 1658 } 1659 if ((LowPCOffset == -1U || (LowPCOffset + 8 != HighPCOffset)) && 1660 LowPCForm != dwarf::DW_FORM_GNU_addr_index && 1661 LowPCForm != dwarf::DW_FORM_addrx) { 1662 errs() << "BOLT-WARNING: high_pc expected immediately after low_pc. " 1663 << "Cannot update DIE at offset 0x" 1664 << Twine::utohexstr(DIE.getOffset()) << '\n'; 1665 return; 1666 } 1667 } 1668 1669 } // namespace 1670 1671 void DWARFRewriter::convertToRangesPatchAbbrev( 1672 const DWARFUnit &Unit, const DWARFAbbreviationDeclaration *Abbrev, 1673 DebugAbbrevWriter &AbbrevWriter, Optional<uint64_t> RangesBase) { 1674 1675 dwarf::Attribute RangeBaseAttribute = dwarf::DW_AT_GNU_ranges_base; 1676 dwarf::Form RangesForm = dwarf::DW_FORM_sec_offset; 1677 1678 if (Unit.getVersion() >= 5) { 1679 RangeBaseAttribute = dwarf::DW_AT_rnglists_base; 1680 RangesForm = dwarf::DW_FORM_rnglistx; 1681 } 1682 // If we hit this point it means we converted subprogram DIEs from 1683 // low_pc/high_pc into ranges. The CU originally didn't have DW_AT_*_base, so 1684 // we are adding it here. 1685 if (RangesBase) 1686 AbbrevWriter.addAttribute(Unit, Abbrev, RangeBaseAttribute, 1687 dwarf::DW_FORM_sec_offset); 1688 1689 // Converting DW_AT_high_pc into DW_AT_ranges. 1690 // For DWARF4 it's DW_FORM_sec_offset. 1691 // For DWARF5 it can be either DW_FORM_sec_offset or DW_FORM_rnglistx. 1692 // For consistency for DWARF5 we always use DW_FORM_rnglistx. 1693 AbbrevWriter.addAttributePatch(Unit, Abbrev, dwarf::DW_AT_high_pc, 1694 dwarf::DW_AT_ranges, RangesForm); 1695 } 1696 1697 void DWARFRewriter::convertToRangesPatchDebugInfo( 1698 DWARFDie DIE, uint64_t RangesSectionOffset, 1699 SimpleBinaryPatcher &DebugInfoPatcher, Optional<uint64_t> RangesBase) { 1700 Optional<AttrInfo> LowPCVal = None; 1701 Optional<AttrInfo> HighPCVal = None; 1702 getRangeAttrData(DIE, LowPCVal, HighPCVal); 1703 uint64_t LowPCOffset = LowPCVal->Offset; 1704 uint64_t HighPCOffset = HighPCVal->Offset; 1705 1706 std::lock_guard<std::mutex> Lock(DebugInfoPatcherMutex); 1707 uint32_t BaseOffset = 0; 1708 dwarf::Form LowForm = LowPCVal->V.getForm(); 1709 1710 // In DWARF4 for DW_AT_low_pc in binary DW_FORM_addr is used. In the DWO 1711 // section DW_FORM_GNU_addr_index is used. So for if we are converting 1712 // DW_AT_low_pc/DW_AT_high_pc and see DW_FORM_GNU_addr_index. We are 1713 // converting in DWO section, and DW_AT_ranges [DW_FORM_sec_offset] is 1714 // relative to DW_AT_GNU_ranges_base. 1715 if (LowForm == dwarf::DW_FORM_GNU_addr_index) { 1716 // Use ULEB128 for the value. 1717 DebugInfoPatcher.addUDataPatch(LowPCOffset, 0, LowPCVal->Size); 1718 // Ranges are relative to DW_AT_GNU_ranges_base. 1719 BaseOffset = DebugInfoPatcher.getRangeBase(); 1720 } else { 1721 // In DWARF 5 we can have DW_AT_low_pc either as DW_FORM_addr, or 1722 // DW_FORM_addrx. Former is when DW_AT_rnglists_base is present. Latter is 1723 // when it's absent. 1724 if (LowForm == dwarf::DW_FORM_addrx) { 1725 const uint32_t Index = 1726 AddrWriter->getIndexFromAddress(0, *DIE.getDwarfUnit()); 1727 DebugInfoPatcher.addUDataPatch(LowPCOffset, Index, LowPCVal->Size); 1728 } else 1729 DebugInfoPatcher.addLE64Patch(LowPCOffset, 0); 1730 1731 // Original CU didn't have DW_AT_*_base. We converted it's children (or 1732 // dwo), so need to insert it into CU. 1733 if (RangesBase) 1734 reinterpret_cast<DebugInfoBinaryPatcher &>(DebugInfoPatcher) 1735 .insertNewEntry(DIE, *RangesBase); 1736 } 1737 1738 // HighPC was conveted into DW_AT_ranges. 1739 // For DWARF5 we only access ranges throught index. 1740 if (DIE.getDwarfUnit()->getVersion() >= 5) 1741 DebugInfoPatcher.addUDataPatch(HighPCOffset, RangesSectionOffset, 1742 HighPCVal->Size); 1743 else 1744 DebugInfoPatcher.addLE32Patch( 1745 HighPCOffset, RangesSectionOffset - BaseOffset, HighPCVal->Size); 1746 } 1747