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