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