1 //===- bolt/Core/DebugData.cpp - Debugging information handling -----------===// 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 // This file implements functions and classes for handling debug info. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "bolt/Core/DebugData.h" 14 #include "bolt/Core/BinaryBasicBlock.h" 15 #include "bolt/Core/BinaryFunction.h" 16 #include "bolt/Utils/Utils.h" 17 #include "llvm/MC/MCObjectStreamer.h" 18 #include "llvm/MC/MCSymbol.h" 19 #include "llvm/Support/CommandLine.h" 20 #include "llvm/Support/EndianStream.h" 21 #include "llvm/Support/LEB128.h" 22 #include <algorithm> 23 #include <cassert> 24 #include <cstdint> 25 #include <limits> 26 #include <unordered_map> 27 28 #define DEBUG_TYPE "bolt-debug-info" 29 30 namespace opts { 31 extern llvm::cl::opt<unsigned> Verbosity; 32 } // namespace opts 33 34 namespace llvm { 35 namespace bolt { 36 37 const DebugLineTableRowRef DebugLineTableRowRef::NULL_ROW{0, 0}; 38 39 namespace { 40 41 LLVM_ATTRIBUTE_UNUSED 42 static void printLE64(const std::string &S) { 43 for (uint32_t I = 0, Size = S.size(); I < Size; ++I) { 44 errs() << Twine::utohexstr(S[I]); 45 errs() << Twine::utohexstr((int8_t)S[I]); 46 } 47 errs() << "\n"; 48 } 49 50 // Writes address ranges to Writer as pairs of 64-bit (address, size). 51 // If RelativeRange is true, assumes the address range to be written must be of 52 // the form (begin address, range size), otherwise (begin address, end address). 53 // Terminates the list by writing a pair of two zeroes. 54 // Returns the number of written bytes. 55 uint64_t writeAddressRanges(raw_svector_ostream &Stream, 56 const DebugAddressRangesVector &AddressRanges, 57 const bool WriteRelativeRanges = false) { 58 for (const DebugAddressRange &Range : AddressRanges) { 59 support::endian::write(Stream, Range.LowPC, support::little); 60 support::endian::write( 61 Stream, WriteRelativeRanges ? Range.HighPC - Range.LowPC : Range.HighPC, 62 support::little); 63 } 64 // Finish with 0 entries. 65 support::endian::write(Stream, 0ULL, support::little); 66 support::endian::write(Stream, 0ULL, support::little); 67 return AddressRanges.size() * 16 + 16; 68 } 69 70 } // namespace 71 72 DebugRangesSectionWriter::DebugRangesSectionWriter() { 73 RangesBuffer = std::make_unique<DebugBufferVector>(); 74 RangesStream = std::make_unique<raw_svector_ostream>(*RangesBuffer); 75 76 // Add an empty range as the first entry; 77 SectionOffset += 78 writeAddressRanges(*RangesStream.get(), DebugAddressRangesVector{}); 79 } 80 81 uint64_t DebugRangesSectionWriter::addRanges( 82 DebugAddressRangesVector &&Ranges, 83 std::map<DebugAddressRangesVector, uint64_t> &CachedRanges) { 84 if (Ranges.empty()) 85 return getEmptyRangesOffset(); 86 87 const auto RI = CachedRanges.find(Ranges); 88 if (RI != CachedRanges.end()) 89 return RI->second; 90 91 const uint64_t EntryOffset = addRanges(Ranges); 92 CachedRanges.emplace(std::move(Ranges), EntryOffset); 93 94 return EntryOffset; 95 } 96 97 uint64_t 98 DebugRangesSectionWriter::addRanges(const DebugAddressRangesVector &Ranges) { 99 if (Ranges.empty()) 100 return getEmptyRangesOffset(); 101 102 // Reading the SectionOffset and updating it should be atomic to guarantee 103 // unique and correct offsets in patches. 104 std::lock_guard<std::mutex> Lock(WriterMutex); 105 const uint32_t EntryOffset = SectionOffset; 106 SectionOffset += writeAddressRanges(*RangesStream.get(), Ranges); 107 108 return EntryOffset; 109 } 110 111 uint64_t DebugRangesSectionWriter::getSectionOffset() { 112 std::lock_guard<std::mutex> Lock(WriterMutex); 113 return SectionOffset; 114 } 115 116 void DebugARangesSectionWriter::addCURanges(uint64_t CUOffset, 117 DebugAddressRangesVector &&Ranges) { 118 std::lock_guard<std::mutex> Lock(CUAddressRangesMutex); 119 CUAddressRanges.emplace(CUOffset, std::move(Ranges)); 120 } 121 122 void DebugARangesSectionWriter::writeARangesSection( 123 raw_svector_ostream &RangesStream, 124 const std::unordered_map<uint32_t, uint32_t> CUMap) const { 125 // For reference on the format of the .debug_aranges section, see the DWARF4 126 // specification, section 6.1.4 Lookup by Address 127 // http://www.dwarfstd.org/doc/DWARF4.pdf 128 for (const auto &CUOffsetAddressRangesPair : CUAddressRanges) { 129 const uint64_t Offset = CUOffsetAddressRangesPair.first; 130 const DebugAddressRangesVector &AddressRanges = 131 CUOffsetAddressRangesPair.second; 132 133 // Emit header. 134 135 // Size of this set: 8 (size of the header) + 4 (padding after header) 136 // + 2*sizeof(uint64_t) bytes for each of the ranges, plus an extra 137 // pair of uint64_t's for the terminating, zero-length range. 138 // Does not include size field itself. 139 uint32_t Size = 8 + 4 + 2 * sizeof(uint64_t) * (AddressRanges.size() + 1); 140 141 // Header field #1: set size. 142 support::endian::write(RangesStream, Size, support::little); 143 144 // Header field #2: version number, 2 as per the specification. 145 support::endian::write(RangesStream, static_cast<uint16_t>(2), 146 support::little); 147 148 assert(CUMap.count(Offset) && "Original CU offset is not found in CU Map"); 149 // Header field #3: debug info offset of the correspondent compile unit. 150 support::endian::write(RangesStream, 151 static_cast<uint32_t>(CUMap.find(Offset)->second), 152 support::little); 153 154 // Header field #4: address size. 155 // 8 since we only write ELF64 binaries for now. 156 RangesStream << char(8); 157 158 // Header field #5: segment size of target architecture. 159 RangesStream << char(0); 160 161 // Padding before address table - 4 bytes in the 64-bit-pointer case. 162 support::endian::write(RangesStream, static_cast<uint32_t>(0), 163 support::little); 164 165 writeAddressRanges(RangesStream, AddressRanges, true); 166 } 167 } 168 169 DebugAddrWriter::DebugAddrWriter(BinaryContext *Bc) { BC = Bc; } 170 171 void DebugAddrWriter::AddressForDWOCU::dump() { 172 std::vector<IndexAddressPair> SortedMap(indexToAddressBegin(), 173 indexToAdddessEnd()); 174 // Sorting address in increasing order of indices. 175 std::sort(SortedMap.begin(), SortedMap.end(), 176 [](const IndexAddressPair &A, const IndexAddressPair &B) { 177 return A.first < B.first; 178 }); 179 for (auto &Pair : SortedMap) 180 dbgs() << Twine::utohexstr(Pair.second) << "\t" << Pair.first << "\n"; 181 } 182 uint32_t DebugAddrWriter::getIndexFromAddress(uint64_t Address, 183 uint64_t DWOId) { 184 std::lock_guard<std::mutex> Lock(WriterMutex); 185 if (!AddressMaps.count(DWOId)) 186 AddressMaps[DWOId] = AddressForDWOCU(); 187 188 AddressForDWOCU &Map = AddressMaps[DWOId]; 189 auto Entry = Map.find(Address); 190 if (Entry == Map.end()) { 191 auto Index = Map.getNextIndex(); 192 Entry = Map.insert(Address, Index).first; 193 } 194 return Entry->second; 195 } 196 197 // Case1) Address is not in map insert in to AddresToIndex and IndexToAddres 198 // Case2) Address is in the map but Index is higher or equal. Need to update 199 // IndexToAddrss. Case3) Address is in the map but Index is lower. Need to 200 // update AddressToIndex and IndexToAddress 201 void DebugAddrWriter::addIndexAddress(uint64_t Address, uint32_t Index, 202 uint64_t DWOId) { 203 std::lock_guard<std::mutex> Lock(WriterMutex); 204 AddressForDWOCU &Map = AddressMaps[DWOId]; 205 auto Entry = Map.find(Address); 206 if (Entry != Map.end()) { 207 if (Entry->second > Index) 208 Map.updateAddressToIndex(Address, Index); 209 Map.updateIndexToAddrss(Address, Index); 210 } else { 211 Map.insert(Address, Index); 212 } 213 } 214 215 AddressSectionBuffer DebugAddrWriter::finalize() { 216 // Need to layout all sections within .debug_addr 217 // Within each section sort Address by index. 218 AddressSectionBuffer Buffer; 219 raw_svector_ostream AddressStream(Buffer); 220 for (std::unique_ptr<DWARFUnit> &CU : BC->DwCtx->compile_units()) { 221 Optional<uint64_t> DWOId = CU->getDWOId(); 222 // Handling the case wehre debug information is a mix of Debug fission and 223 // monolitic. 224 if (!DWOId) 225 continue; 226 auto AM = AddressMaps.find(*DWOId); 227 // Adding to map even if it did not contribute to .debug_addr. 228 // The Skeleton CU will still have DW_AT_GNU_addr_base. 229 DWOIdToOffsetMap[*DWOId] = Buffer.size(); 230 // If does not exist this CUs DWO section didn't contribute to .debug_addr. 231 if (AM == AddressMaps.end()) 232 continue; 233 std::vector<IndexAddressPair> SortedMap(AM->second.indexToAddressBegin(), 234 AM->second.indexToAdddessEnd()); 235 // Sorting address in increasing order of indices. 236 std::sort(SortedMap.begin(), SortedMap.end(), 237 [](const IndexAddressPair &A, const IndexAddressPair &B) { 238 return A.first < B.first; 239 }); 240 241 uint8_t AddrSize = CU->getAddressByteSize(); 242 uint32_t Counter = 0; 243 auto WriteAddress = [&](uint64_t Address) -> void { 244 ++Counter; 245 switch (AddrSize) { 246 default: 247 assert(false && "Address Size is invalid."); 248 break; 249 case 4: 250 support::endian::write(AddressStream, static_cast<uint32_t>(Address), 251 support::little); 252 break; 253 case 8: 254 support::endian::write(AddressStream, Address, support::little); 255 break; 256 } 257 }; 258 259 for (const IndexAddressPair &Val : SortedMap) { 260 while (Val.first > Counter) 261 WriteAddress(0); 262 WriteAddress(Val.second); 263 } 264 } 265 266 return Buffer; 267 } 268 269 uint64_t DebugAddrWriter::getOffset(uint64_t DWOId) { 270 auto Iter = DWOIdToOffsetMap.find(DWOId); 271 assert(Iter != DWOIdToOffsetMap.end() && 272 "Offset in to.debug_addr was not found for DWO ID."); 273 return Iter->second; 274 } 275 276 DebugLocWriter::DebugLocWriter(BinaryContext *BC) { 277 LocBuffer = std::make_unique<DebugBufferVector>(); 278 LocStream = std::make_unique<raw_svector_ostream>(*LocBuffer); 279 } 280 281 void DebugLocWriter::addList(uint64_t AttrOffset, 282 DebugLocationsVector &&LocList) { 283 if (LocList.empty()) { 284 EmptyAttrLists.push_back(AttrOffset); 285 return; 286 } 287 // Since there is a separate DebugLocWriter for each thread, 288 // we don't need a lock to read the SectionOffset and update it. 289 const uint32_t EntryOffset = SectionOffset; 290 291 for (const DebugLocationEntry &Entry : LocList) { 292 support::endian::write(*LocStream, static_cast<uint64_t>(Entry.LowPC), 293 support::little); 294 support::endian::write(*LocStream, static_cast<uint64_t>(Entry.HighPC), 295 support::little); 296 support::endian::write(*LocStream, static_cast<uint16_t>(Entry.Expr.size()), 297 support::little); 298 *LocStream << StringRef(reinterpret_cast<const char *>(Entry.Expr.data()), 299 Entry.Expr.size()); 300 SectionOffset += 2 * 8 + 2 + Entry.Expr.size(); 301 } 302 LocStream->write_zeros(16); 303 SectionOffset += 16; 304 LocListDebugInfoPatches.push_back({AttrOffset, EntryOffset}); 305 } 306 307 void DebugLoclistWriter::addList(uint64_t AttrOffset, 308 DebugLocationsVector &&LocList) { 309 Patches.push_back({AttrOffset, std::move(LocList)}); 310 } 311 312 std::unique_ptr<DebugBufferVector> DebugLocWriter::getBuffer() { 313 return std::move(LocBuffer); 314 } 315 316 // DWARF 4: 2.6.2 317 void DebugLocWriter::finalize(uint64_t SectionOffset, 318 SimpleBinaryPatcher &DebugInfoPatcher) { 319 for (const auto LocListDebugInfoPatchType : LocListDebugInfoPatches) { 320 uint64_t Offset = SectionOffset + LocListDebugInfoPatchType.LocListOffset; 321 DebugInfoPatcher.addLE32Patch(LocListDebugInfoPatchType.DebugInfoAttrOffset, 322 Offset); 323 } 324 325 for (uint64_t DebugInfoAttrOffset : EmptyAttrLists) 326 DebugInfoPatcher.addLE32Patch(DebugInfoAttrOffset, 327 DebugLocWriter::EmptyListOffset); 328 } 329 330 void DebugLoclistWriter::finalize(uint64_t SectionOffset, 331 SimpleBinaryPatcher &DebugInfoPatcher) { 332 for (LocPatch &Patch : Patches) { 333 if (Patch.LocList.empty()) { 334 DebugInfoPatcher.addLE32Patch(Patch.AttrOffset, 335 DebugLocWriter::EmptyListOffset); 336 continue; 337 } 338 const uint32_t EntryOffset = LocBuffer->size(); 339 for (const DebugLocationEntry &Entry : Patch.LocList) { 340 support::endian::write(*LocStream, 341 static_cast<uint8_t>(dwarf::DW_LLE_startx_length), 342 support::little); 343 uint32_t Index = AddrWriter->getIndexFromAddress(Entry.LowPC, DWOId); 344 encodeULEB128(Index, *LocStream); 345 346 // TODO: Support DWARF5 347 support::endian::write(*LocStream, 348 static_cast<uint32_t>(Entry.HighPC - Entry.LowPC), 349 support::little); 350 support::endian::write(*LocStream, 351 static_cast<uint16_t>(Entry.Expr.size()), 352 support::little); 353 *LocStream << StringRef(reinterpret_cast<const char *>(Entry.Expr.data()), 354 Entry.Expr.size()); 355 } 356 support::endian::write(*LocStream, 357 static_cast<uint8_t>(dwarf::DW_LLE_end_of_list), 358 support::little); 359 DebugInfoPatcher.addLE32Patch(Patch.AttrOffset, EntryOffset); 360 clearList(Patch.LocList); 361 } 362 clearList(Patches); 363 } 364 365 DebugAddrWriter *DebugLoclistWriter::AddrWriter = nullptr; 366 367 void DebugInfoBinaryPatcher::addUnitBaseOffsetLabel(uint64_t Offset) { 368 Offset -= DWPUnitOffset; 369 std::lock_guard<std::mutex> Lock(WriterMutex); 370 DebugPatches.emplace_back(std::make_unique<DWARFUnitOffsetBaseLabel>(Offset)); 371 } 372 373 void DebugInfoBinaryPatcher::addDestinationReferenceLabel(uint64_t Offset) { 374 Offset -= DWPUnitOffset; 375 std::lock_guard<std::mutex> Lock(WriterMutex); 376 auto RetVal = DestinationLabels.insert(Offset); 377 if (!RetVal.second) 378 return; 379 380 DebugPatches.emplace_back( 381 std::make_unique<DestinationReferenceLabel>(Offset)); 382 } 383 384 void DebugInfoBinaryPatcher::addReferenceToPatch(uint64_t Offset, 385 uint32_t DestinationOffset, 386 uint32_t OldValueSize, 387 dwarf::Form Form) { 388 Offset -= DWPUnitOffset; 389 DestinationOffset -= DWPUnitOffset; 390 std::lock_guard<std::mutex> Lock(WriterMutex); 391 DebugPatches.emplace_back(std::make_unique<DebugPatchReference>( 392 Offset, OldValueSize, DestinationOffset, Form)); 393 } 394 395 void DebugInfoBinaryPatcher::addUDataPatch(uint64_t Offset, uint64_t NewValue, 396 uint32_t OldValueSize) { 397 Offset -= DWPUnitOffset; 398 std::lock_guard<std::mutex> Lock(WriterMutex); 399 DebugPatches.emplace_back( 400 std::make_unique<DebugPatchVariableSize>(Offset, OldValueSize, NewValue)); 401 } 402 403 void DebugInfoBinaryPatcher::addLE64Patch(uint64_t Offset, uint64_t NewValue) { 404 Offset -= DWPUnitOffset; 405 std::lock_guard<std::mutex> Lock(WriterMutex); 406 DebugPatches.emplace_back(std::make_unique<DebugPatch64>(Offset, NewValue)); 407 } 408 409 void DebugInfoBinaryPatcher::addLE32Patch(uint64_t Offset, uint32_t NewValue, 410 uint32_t OldValueSize) { 411 Offset -= DWPUnitOffset; 412 std::lock_guard<std::mutex> Lock(WriterMutex); 413 if (OldValueSize == 4) 414 DebugPatches.emplace_back(std::make_unique<DebugPatch32>(Offset, NewValue)); 415 else 416 DebugPatches.emplace_back( 417 std::make_unique<DebugPatch64to32>(Offset, NewValue)); 418 } 419 420 void SimpleBinaryPatcher::addBinaryPatch(uint64_t Offset, 421 std::string &&NewValue, 422 uint32_t OldValueSize) { 423 Patches.emplace_back(Offset, std::move(NewValue)); 424 } 425 426 void SimpleBinaryPatcher::addBytePatch(uint64_t Offset, uint8_t Value) { 427 auto Str = std::string(1, Value); 428 Patches.emplace_back(Offset, std::move(Str)); 429 } 430 431 static std::string encodeLE(size_t ByteSize, uint64_t NewValue) { 432 std::string LE64(ByteSize, 0); 433 for (size_t I = 0; I < ByteSize; ++I) { 434 LE64[I] = NewValue & 0xff; 435 NewValue >>= 8; 436 } 437 return LE64; 438 } 439 440 void SimpleBinaryPatcher::addLEPatch(uint64_t Offset, uint64_t NewValue, 441 size_t ByteSize) { 442 Patches.emplace_back(Offset, encodeLE(ByteSize, NewValue)); 443 } 444 445 void SimpleBinaryPatcher::addUDataPatch(uint64_t Offset, uint64_t Value, 446 uint32_t OldValueSize) { 447 std::string Buff; 448 raw_string_ostream OS(Buff); 449 encodeULEB128(Value, OS, OldValueSize); 450 451 Patches.emplace_back(Offset, std::move(Buff)); 452 } 453 454 void SimpleBinaryPatcher::addLE64Patch(uint64_t Offset, uint64_t NewValue) { 455 addLEPatch(Offset, NewValue, 8); 456 } 457 458 void SimpleBinaryPatcher::addLE32Patch(uint64_t Offset, uint32_t NewValue, 459 uint32_t OldValueSize) { 460 addLEPatch(Offset, NewValue, 4); 461 } 462 463 std::string SimpleBinaryPatcher::patchBinary(StringRef BinaryContents) { 464 std::string BinaryContentsStr = std::string(BinaryContents); 465 for (const auto &Patch : Patches) { 466 uint32_t Offset = Patch.first; 467 const std::string &ByteSequence = Patch.second; 468 assert(Offset + ByteSequence.size() <= BinaryContents.size() && 469 "Applied patch runs over binary size."); 470 for (uint64_t I = 0, Size = ByteSequence.size(); I < Size; ++I) { 471 BinaryContentsStr[Offset + I] = ByteSequence[I]; 472 } 473 } 474 return BinaryContentsStr; 475 } 476 477 std::unordered_map<uint32_t, uint32_t> 478 DebugInfoBinaryPatcher::computeNewOffsets() { 479 std::unordered_map<uint32_t, uint32_t> CUMap; 480 std::sort( 481 DebugPatches.begin(), DebugPatches.end(), 482 [](const std::unique_ptr<Patch> &V1, const std::unique_ptr<Patch> &V2) { 483 return V1.get()->Offset < V2.get()->Offset; 484 }); 485 486 // Calculating changes in .debug_info size from Patches to build a map of old 487 // to updated reference destination offsets. 488 for (std::unique_ptr<Patch> &PatchBase : DebugPatches) { 489 Patch *P = PatchBase.get(); 490 switch (P->Kind) { 491 default: 492 continue; 493 case DebugPatchKind::PatchValue64to32: { 494 ChangeInSize -= 4; 495 break; 496 } 497 case DebugPatchKind::PatchValueVariable: { 498 DebugPatchVariableSize *DPV = 499 reinterpret_cast<DebugPatchVariableSize *>(P); 500 std::string Temp; 501 raw_string_ostream OS(Temp); 502 encodeULEB128(DPV->Value, OS); 503 ChangeInSize += Temp.size() - DPV->OldValueSize; 504 break; 505 } 506 case DebugPatchKind::DestinationReferenceLabel: { 507 DestinationReferenceLabel *DRL = 508 reinterpret_cast<DestinationReferenceLabel *>(P); 509 OldToNewOffset[DRL->Offset] = DRL->Offset + ChangeInSize; 510 break; 511 } 512 case DebugPatchKind::ReferencePatchValue: { 513 // This doesn't look to be a common case, so will always encode as 4 bytes 514 // to reduce algorithmic complexity. 515 DebugPatchReference *RDP = reinterpret_cast<DebugPatchReference *>(P); 516 if (RDP->PatchInfo.IndirectRelative) { 517 ChangeInSize += 4 - RDP->PatchInfo.OldValueSize; 518 assert(RDP->PatchInfo.OldValueSize <= 4 && 519 "Variable encoding reference greater than 4 bytes."); 520 } 521 break; 522 } 523 case DebugPatchKind::DWARFUnitOffsetBaseLabel: { 524 DWARFUnitOffsetBaseLabel *BaseLabel = 525 reinterpret_cast<DWARFUnitOffsetBaseLabel *>(P); 526 uint32_t CUOffset = BaseLabel->Offset; 527 uint32_t CUOffsetUpdate = CUOffset + ChangeInSize; 528 CUMap[CUOffset] = CUOffsetUpdate; 529 } 530 } 531 } 532 return CUMap; 533 } 534 535 std::string DebugInfoBinaryPatcher::patchBinary(StringRef BinaryContents) { 536 std::string NewBinaryContents; 537 NewBinaryContents.reserve(BinaryContents.size() + ChangeInSize); 538 uint32_t StartOffset = 0; 539 uint32_t DwarfUnitBaseOffset = 0; 540 uint32_t OldValueSize = 0; 541 uint32_t Offset = 0; 542 std::string ByteSequence; 543 std::vector<std::pair<uint32_t, uint32_t>> LengthPatches; 544 // Wasting one entry to avoid checks for first. 545 LengthPatches.push_back({0, 0}); 546 547 // Applying all the patches replacing current entry. 548 // This might change the size of .debug_info section. 549 for (const std::unique_ptr<Patch> &PatchBase : DebugPatches) { 550 Patch *P = PatchBase.get(); 551 switch (P->Kind) { 552 default: 553 continue; 554 case DebugPatchKind::ReferencePatchValue: { 555 DebugPatchReference *RDP = reinterpret_cast<DebugPatchReference *>(P); 556 uint32_t DestinationOffset = RDP->DestinationOffset; 557 assert(OldToNewOffset.count(DestinationOffset) && 558 "Destination Offset for reference not updated."); 559 uint32_t UpdatedOffset = OldToNewOffset[DestinationOffset]; 560 Offset = RDP->Offset; 561 OldValueSize = RDP->PatchInfo.OldValueSize; 562 if (RDP->PatchInfo.DirectRelative) { 563 UpdatedOffset -= DwarfUnitBaseOffset; 564 ByteSequence = encodeLE(OldValueSize, UpdatedOffset); 565 // In theory reference for DW_FORM_ref{1,2,4,8} can be right on the edge 566 // and overflow if later debug information grows. 567 if (ByteSequence.size() > OldValueSize) 568 errs() << "BOLT-ERROR: Relative reference of size " 569 << Twine::utohexstr(OldValueSize) 570 << " overflows with the new encoding.\n"; 571 } else if (RDP->PatchInfo.DirectAbsolute) { 572 ByteSequence = encodeLE(OldValueSize, UpdatedOffset); 573 } else if (RDP->PatchInfo.IndirectRelative) { 574 UpdatedOffset -= DwarfUnitBaseOffset; 575 ByteSequence.clear(); 576 raw_string_ostream OS(ByteSequence); 577 encodeULEB128(UpdatedOffset, OS, 4); 578 } else { 579 llvm_unreachable("Invalid Reference form."); 580 } 581 break; 582 } 583 case DebugPatchKind::PatchValue32: { 584 DebugPatch32 *P32 = reinterpret_cast<DebugPatch32 *>(P); 585 Offset = P32->Offset; 586 OldValueSize = 4; 587 ByteSequence = encodeLE(4, P32->Value); 588 break; 589 } 590 case DebugPatchKind::PatchValue64to32: { 591 DebugPatch64to32 *P64to32 = reinterpret_cast<DebugPatch64to32 *>(P); 592 Offset = P64to32->Offset; 593 OldValueSize = 8; 594 ByteSequence = encodeLE(4, P64to32->Value); 595 break; 596 } 597 case DebugPatchKind::PatchValueVariable: { 598 DebugPatchVariableSize *PV = 599 reinterpret_cast<DebugPatchVariableSize *>(P); 600 Offset = PV->Offset; 601 OldValueSize = PV->OldValueSize; 602 ByteSequence.clear(); 603 raw_string_ostream OS(ByteSequence); 604 encodeULEB128(PV->Value, OS); 605 break; 606 } 607 case DebugPatchKind::PatchValue64: { 608 DebugPatch64 *P64 = reinterpret_cast<DebugPatch64 *>(P); 609 Offset = P64->Offset; 610 OldValueSize = 8; 611 ByteSequence = encodeLE(8, P64->Value); 612 break; 613 } 614 case DebugPatchKind::DWARFUnitOffsetBaseLabel: { 615 DWARFUnitOffsetBaseLabel *BaseLabel = 616 reinterpret_cast<DWARFUnitOffsetBaseLabel *>(P); 617 Offset = BaseLabel->Offset; 618 OldValueSize = 0; 619 ByteSequence.clear(); 620 auto &Patch = LengthPatches.back(); 621 // Length to copy between last patch entry and next compile unit. 622 uint32_t RemainingLength = Offset - StartOffset; 623 uint32_t NewCUOffset = NewBinaryContents.size() + RemainingLength; 624 DwarfUnitBaseOffset = NewCUOffset; 625 // Length of previous CU = This CU Offset - sizeof(length) - last CU 626 // Offset. 627 Patch.second = NewCUOffset - 4 - Patch.first; 628 LengthPatches.push_back({NewCUOffset, 0}); 629 break; 630 } 631 } 632 633 assert(Offset + ByteSequence.size() <= BinaryContents.size() && 634 "Applied patch runs over binary size."); 635 uint32_t Length = Offset - StartOffset; 636 NewBinaryContents.append(BinaryContents.substr(StartOffset, Length).data(), 637 Length); 638 NewBinaryContents.append(ByteSequence.data(), ByteSequence.size()); 639 StartOffset = Offset + OldValueSize; 640 } 641 uint32_t Length = BinaryContents.size() - StartOffset; 642 NewBinaryContents.append(BinaryContents.substr(StartOffset, Length).data(), 643 Length); 644 DebugPatches.clear(); 645 646 // Patching lengths of CUs 647 auto &Patch = LengthPatches.back(); 648 Patch.second = NewBinaryContents.size() - 4 - Patch.first; 649 for (uint32_t J = 1, Size = LengthPatches.size(); J < Size; ++J) { 650 const auto &Patch = LengthPatches[J]; 651 ByteSequence = encodeLE(4, Patch.second); 652 Offset = Patch.first; 653 for (uint64_t I = 0, Size = ByteSequence.size(); I < Size; ++I) 654 NewBinaryContents[Offset + I] = ByteSequence[I]; 655 } 656 657 return NewBinaryContents; 658 } 659 660 void DebugStrWriter::create() { 661 StrBuffer = std::make_unique<DebugStrBufferVector>(); 662 StrStream = std::make_unique<raw_svector_ostream>(*StrBuffer); 663 } 664 665 void DebugStrWriter::initialize() { 666 auto StrSection = BC->DwCtx->getDWARFObj().getStrSection(); 667 (*StrStream) << StrSection; 668 } 669 670 uint32_t DebugStrWriter::addString(StringRef Str) { 671 std::lock_guard<std::mutex> Lock(WriterMutex); 672 if (StrBuffer->empty()) 673 initialize(); 674 auto Offset = StrBuffer->size(); 675 (*StrStream) << Str; 676 StrStream->write_zeros(1); 677 return Offset; 678 } 679 680 void DebugAbbrevWriter::addUnitAbbreviations(DWARFUnit &Unit) { 681 const DWARFAbbreviationDeclarationSet *Abbrevs = Unit.getAbbreviations(); 682 if (!Abbrevs) 683 return; 684 685 // Multiple units may share the same abbreviations. Only add abbreviations 686 // for the first unit and reuse them. 687 const uint64_t AbbrevOffset = Unit.getAbbreviationsOffset(); 688 if (UnitsAbbrevData.find(AbbrevOffset) != UnitsAbbrevData.end()) 689 return; 690 691 AbbrevData &UnitData = UnitsAbbrevData[AbbrevOffset]; 692 UnitData.Buffer = std::make_unique<DebugBufferVector>(); 693 UnitData.Stream = std::make_unique<raw_svector_ostream>(*UnitData.Buffer); 694 695 const PatchesTy &UnitPatches = Patches[&Unit]; 696 697 raw_svector_ostream &OS = *UnitData.Stream.get(); 698 699 // Take a fast path if there are no patches to apply. Simply copy the original 700 // contents. 701 if (UnitPatches.empty()) { 702 StringRef AbbrevSectionContents = 703 Unit.isDWOUnit() ? Unit.getContext().getDWARFObj().getAbbrevDWOSection() 704 : Unit.getContext().getDWARFObj().getAbbrevSection(); 705 StringRef AbbrevContents; 706 707 const DWARFUnitIndex &CUIndex = Unit.getContext().getCUIndex(); 708 if (!CUIndex.getRows().empty()) { 709 // Handle DWP section contribution. 710 const DWARFUnitIndex::Entry *DWOEntry = 711 CUIndex.getFromHash(*Unit.getDWOId()); 712 if (!DWOEntry) 713 return; 714 715 const DWARFUnitIndex::Entry::SectionContribution *DWOContrubution = 716 DWOEntry->getContribution(DWARFSectionKind::DW_SECT_ABBREV); 717 AbbrevContents = AbbrevSectionContents.substr(DWOContrubution->Offset, 718 DWOContrubution->Length); 719 } else if (!Unit.isDWOUnit()) { 720 const uint64_t StartOffset = Unit.getAbbreviationsOffset(); 721 722 // We know where the unit's abbreviation set starts, but not where it ends 723 // as such data is not readily available. Hence, we have to build a sorted 724 // list of start addresses and find the next starting address to determine 725 // the set boundaries. 726 // 727 // FIXME: if we had a full access to DWARFDebugAbbrev::AbbrDeclSets 728 // we wouldn't have to build our own sorted list for the quick lookup. 729 if (AbbrevSetOffsets.empty()) { 730 for_each( 731 *Unit.getContext().getDebugAbbrev(), 732 [&](const std::pair<uint64_t, DWARFAbbreviationDeclarationSet> &P) { 733 AbbrevSetOffsets.push_back(P.first); 734 }); 735 sort(AbbrevSetOffsets); 736 } 737 auto It = upper_bound(AbbrevSetOffsets, StartOffset); 738 const uint64_t EndOffset = 739 It == AbbrevSetOffsets.end() ? AbbrevSectionContents.size() : *It; 740 AbbrevContents = AbbrevSectionContents.slice(StartOffset, EndOffset); 741 } else { 742 // For DWO unit outside of DWP, we expect the entire section to hold 743 // abbreviations for this unit only. 744 AbbrevContents = AbbrevSectionContents; 745 } 746 747 OS.reserveExtraSpace(AbbrevContents.size()); 748 OS << AbbrevContents; 749 750 return; 751 } 752 753 for (auto I = Abbrevs->begin(), E = Abbrevs->end(); I != E; ++I) { 754 const DWARFAbbreviationDeclaration &Abbrev = *I; 755 auto Patch = UnitPatches.find(&Abbrev); 756 757 encodeULEB128(Abbrev.getCode(), OS); 758 encodeULEB128(Abbrev.getTag(), OS); 759 encodeULEB128(Abbrev.hasChildren(), OS); 760 for (const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec : 761 Abbrev.attributes()) { 762 if (Patch != UnitPatches.end()) { 763 bool Patched = false; 764 // Patches added later take a precedence over earlier ones. 765 for (auto I = Patch->second.rbegin(), E = Patch->second.rend(); I != E; 766 ++I) { 767 if (I->OldAttr != AttrSpec.Attr) 768 continue; 769 770 encodeULEB128(I->NewAttr, OS); 771 encodeULEB128(I->NewAttrForm, OS); 772 Patched = true; 773 break; 774 } 775 if (Patched) 776 continue; 777 } 778 779 encodeULEB128(AttrSpec.Attr, OS); 780 encodeULEB128(AttrSpec.Form, OS); 781 if (AttrSpec.isImplicitConst()) 782 encodeSLEB128(AttrSpec.getImplicitConstValue(), OS); 783 } 784 785 encodeULEB128(0, OS); 786 encodeULEB128(0, OS); 787 } 788 encodeULEB128(0, OS); 789 } 790 791 std::unique_ptr<DebugBufferVector> DebugAbbrevWriter::finalize() { 792 if (DWOId) { 793 // We expect abbrev_offset to always be zero for DWO units as there 794 // should be one CU per DWO, and TUs should share the same abbreviation 795 // set with the CU. 796 // For DWP AbbreviationsOffset is an Abbrev contribution in the DWP file, so 797 // can be none zero. Thus we are skipping the check for DWP. 798 bool IsDWP = !Context.getCUIndex().getRows().empty(); 799 if (!IsDWP) { 800 for (const std::unique_ptr<DWARFUnit> &Unit : Context.dwo_units()) { 801 if (Unit->getAbbreviationsOffset() != 0) { 802 errs() << "BOLT-ERROR: detected DWO unit with non-zero abbr_offset. " 803 "Unable to update debug info.\n"; 804 exit(1); 805 } 806 } 807 } 808 809 // Issue abbreviations for the DWO CU only. 810 addUnitAbbreviations(*Context.getDWOCompileUnitForHash(*DWOId)); 811 } else { 812 // Add abbreviations from compile and type non-DWO units. 813 for (const std::unique_ptr<DWARFUnit> &Unit : Context.normal_units()) 814 addUnitAbbreviations(*Unit); 815 } 816 817 DebugBufferVector ReturnBuffer; 818 819 // Pre-calculate the total size of abbrev section. 820 uint64_t Size = 0; 821 for (const auto &KV : UnitsAbbrevData) { 822 const AbbrevData &UnitData = KV.second; 823 Size += UnitData.Buffer->size(); 824 } 825 ReturnBuffer.reserve(Size); 826 827 uint64_t Pos = 0; 828 for (auto &KV : UnitsAbbrevData) { 829 AbbrevData &UnitData = KV.second; 830 ReturnBuffer.append(*UnitData.Buffer); 831 UnitData.Offset = Pos; 832 Pos += UnitData.Buffer->size(); 833 834 UnitData.Buffer.reset(); 835 UnitData.Stream.reset(); 836 } 837 838 return std::make_unique<DebugBufferVector>(ReturnBuffer); 839 } 840 841 static void emitDwarfSetLineAddrAbs(MCStreamer &OS, 842 MCDwarfLineTableParams Params, 843 int64_t LineDelta, uint64_t Address, 844 int PointerSize) { 845 // emit the sequence to set the address 846 OS.emitIntValue(dwarf::DW_LNS_extended_op, 1); 847 OS.emitULEB128IntValue(PointerSize + 1); 848 OS.emitIntValue(dwarf::DW_LNE_set_address, 1); 849 OS.emitIntValue(Address, PointerSize); 850 851 // emit the sequence for the LineDelta (from 1) and a zero address delta. 852 MCDwarfLineAddr::Emit(&OS, Params, LineDelta, 0); 853 } 854 855 static inline void emitBinaryDwarfLineTable( 856 MCStreamer *MCOS, MCDwarfLineTableParams Params, 857 const DWARFDebugLine::LineTable *Table, 858 const std::vector<DwarfLineTable::RowSequence> &InputSequences) { 859 if (InputSequences.empty()) 860 return; 861 862 constexpr uint64_t InvalidAddress = UINT64_MAX; 863 unsigned FileNum = 1; 864 unsigned LastLine = 1; 865 unsigned Column = 0; 866 unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 867 unsigned Isa = 0; 868 unsigned Discriminator = 0; 869 uint64_t LastAddress = InvalidAddress; 870 uint64_t PrevEndOfSequence = InvalidAddress; 871 const MCAsmInfo *AsmInfo = MCOS->getContext().getAsmInfo(); 872 873 auto emitEndOfSequence = [&](uint64_t Address) { 874 MCDwarfLineAddr::Emit(MCOS, Params, INT64_MAX, Address - LastAddress); 875 FileNum = 1; 876 LastLine = 1; 877 Column = 0; 878 Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 879 Isa = 0; 880 Discriminator = 0; 881 LastAddress = InvalidAddress; 882 }; 883 884 for (const DwarfLineTable::RowSequence &Sequence : InputSequences) { 885 const uint64_t SequenceStart = 886 Table->Rows[Sequence.FirstIndex].Address.Address; 887 888 // Check if we need to mark the end of the sequence. 889 if (PrevEndOfSequence != InvalidAddress && LastAddress != InvalidAddress && 890 PrevEndOfSequence != SequenceStart) { 891 emitEndOfSequence(PrevEndOfSequence); 892 } 893 894 for (uint32_t RowIndex = Sequence.FirstIndex; 895 RowIndex <= Sequence.LastIndex; ++RowIndex) { 896 const DWARFDebugLine::Row &Row = Table->Rows[RowIndex]; 897 int64_t LineDelta = static_cast<int64_t>(Row.Line) - LastLine; 898 const uint64_t Address = Row.Address.Address; 899 900 if (FileNum != Row.File) { 901 FileNum = Row.File; 902 MCOS->emitInt8(dwarf::DW_LNS_set_file); 903 MCOS->emitULEB128IntValue(FileNum); 904 } 905 if (Column != Row.Column) { 906 Column = Row.Column; 907 MCOS->emitInt8(dwarf::DW_LNS_set_column); 908 MCOS->emitULEB128IntValue(Column); 909 } 910 if (Discriminator != Row.Discriminator && 911 MCOS->getContext().getDwarfVersion() >= 4) { 912 Discriminator = Row.Discriminator; 913 unsigned Size = getULEB128Size(Discriminator); 914 MCOS->emitInt8(dwarf::DW_LNS_extended_op); 915 MCOS->emitULEB128IntValue(Size + 1); 916 MCOS->emitInt8(dwarf::DW_LNE_set_discriminator); 917 MCOS->emitULEB128IntValue(Discriminator); 918 } 919 if (Isa != Row.Isa) { 920 Isa = Row.Isa; 921 MCOS->emitInt8(dwarf::DW_LNS_set_isa); 922 MCOS->emitULEB128IntValue(Isa); 923 } 924 if (Row.IsStmt != Flags) { 925 Flags = Row.IsStmt; 926 MCOS->emitInt8(dwarf::DW_LNS_negate_stmt); 927 } 928 if (Row.BasicBlock) 929 MCOS->emitInt8(dwarf::DW_LNS_set_basic_block); 930 if (Row.PrologueEnd) 931 MCOS->emitInt8(dwarf::DW_LNS_set_prologue_end); 932 if (Row.EpilogueBegin) 933 MCOS->emitInt8(dwarf::DW_LNS_set_epilogue_begin); 934 935 // The end of the sequence is not normal in the middle of the input 936 // sequence, but could happen, e.g. for assembly code. 937 if (Row.EndSequence) { 938 emitEndOfSequence(Address); 939 } else { 940 if (LastAddress == InvalidAddress) 941 emitDwarfSetLineAddrAbs(*MCOS, Params, LineDelta, Address, 942 AsmInfo->getCodePointerSize()); 943 else 944 MCDwarfLineAddr::Emit(MCOS, Params, LineDelta, Address - LastAddress); 945 946 LastAddress = Address; 947 LastLine = Row.Line; 948 } 949 950 Discriminator = 0; 951 } 952 PrevEndOfSequence = Sequence.EndAddress; 953 } 954 955 // Finish with the end of the sequence. 956 if (LastAddress != InvalidAddress) 957 emitEndOfSequence(PrevEndOfSequence); 958 } 959 960 // This function is similar to the one from MCDwarfLineTable, except it handles 961 // end-of-sequence entries differently by utilizing line entries with 962 // DWARF2_FLAG_END_SEQUENCE flag. 963 static inline void emitDwarfLineTable( 964 MCStreamer *MCOS, MCSection *Section, 965 const MCLineSection::MCDwarfLineEntryCollection &LineEntries) { 966 unsigned FileNum = 1; 967 unsigned LastLine = 1; 968 unsigned Column = 0; 969 unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 970 unsigned Isa = 0; 971 unsigned Discriminator = 0; 972 MCSymbol *LastLabel = nullptr; 973 const MCAsmInfo *AsmInfo = MCOS->getContext().getAsmInfo(); 974 975 // Loop through each MCDwarfLineEntry and encode the dwarf line number table. 976 for (const MCDwarfLineEntry &LineEntry : LineEntries) { 977 if (LineEntry.getFlags() & DWARF2_FLAG_END_SEQUENCE) { 978 MCOS->emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, LineEntry.getLabel(), 979 AsmInfo->getCodePointerSize()); 980 FileNum = 1; 981 LastLine = 1; 982 Column = 0; 983 Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 984 Isa = 0; 985 Discriminator = 0; 986 LastLabel = nullptr; 987 continue; 988 } 989 990 int64_t LineDelta = static_cast<int64_t>(LineEntry.getLine()) - LastLine; 991 992 if (FileNum != LineEntry.getFileNum()) { 993 FileNum = LineEntry.getFileNum(); 994 MCOS->emitInt8(dwarf::DW_LNS_set_file); 995 MCOS->emitULEB128IntValue(FileNum); 996 } 997 if (Column != LineEntry.getColumn()) { 998 Column = LineEntry.getColumn(); 999 MCOS->emitInt8(dwarf::DW_LNS_set_column); 1000 MCOS->emitULEB128IntValue(Column); 1001 } 1002 if (Discriminator != LineEntry.getDiscriminator() && 1003 MCOS->getContext().getDwarfVersion() >= 4) { 1004 Discriminator = LineEntry.getDiscriminator(); 1005 unsigned Size = getULEB128Size(Discriminator); 1006 MCOS->emitInt8(dwarf::DW_LNS_extended_op); 1007 MCOS->emitULEB128IntValue(Size + 1); 1008 MCOS->emitInt8(dwarf::DW_LNE_set_discriminator); 1009 MCOS->emitULEB128IntValue(Discriminator); 1010 } 1011 if (Isa != LineEntry.getIsa()) { 1012 Isa = LineEntry.getIsa(); 1013 MCOS->emitInt8(dwarf::DW_LNS_set_isa); 1014 MCOS->emitULEB128IntValue(Isa); 1015 } 1016 if ((LineEntry.getFlags() ^ Flags) & DWARF2_FLAG_IS_STMT) { 1017 Flags = LineEntry.getFlags(); 1018 MCOS->emitInt8(dwarf::DW_LNS_negate_stmt); 1019 } 1020 if (LineEntry.getFlags() & DWARF2_FLAG_BASIC_BLOCK) 1021 MCOS->emitInt8(dwarf::DW_LNS_set_basic_block); 1022 if (LineEntry.getFlags() & DWARF2_FLAG_PROLOGUE_END) 1023 MCOS->emitInt8(dwarf::DW_LNS_set_prologue_end); 1024 if (LineEntry.getFlags() & DWARF2_FLAG_EPILOGUE_BEGIN) 1025 MCOS->emitInt8(dwarf::DW_LNS_set_epilogue_begin); 1026 1027 MCSymbol *Label = LineEntry.getLabel(); 1028 1029 // At this point we want to emit/create the sequence to encode the delta 1030 // in line numbers and the increment of the address from the previous 1031 // Label and the current Label. 1032 MCOS->emitDwarfAdvanceLineAddr(LineDelta, LastLabel, Label, 1033 AsmInfo->getCodePointerSize()); 1034 Discriminator = 0; 1035 LastLine = LineEntry.getLine(); 1036 LastLabel = Label; 1037 } 1038 1039 assert(LastLabel == nullptr && "end of sequence expected"); 1040 } 1041 1042 void DwarfLineTable::emitCU(MCStreamer *MCOS, MCDwarfLineTableParams Params, 1043 Optional<MCDwarfLineStr> &LineStr, 1044 BinaryContext &BC) const { 1045 if (!RawData.empty()) { 1046 assert(MCLineSections.getMCLineEntries().empty() && 1047 InputSequences.empty() && 1048 "cannot combine raw data with new line entries"); 1049 MCOS->emitLabel(getLabel()); 1050 MCOS->emitBytes(RawData); 1051 1052 // Emit fake relocation for RuntimeDyld to always allocate the section. 1053 // 1054 // FIXME: remove this once RuntimeDyld stops skipping allocatable sections 1055 // without relocations. 1056 MCOS->emitRelocDirective( 1057 *MCConstantExpr::create(0, *BC.Ctx), "BFD_RELOC_NONE", 1058 MCSymbolRefExpr::create(getLabel(), *BC.Ctx), SMLoc(), *BC.STI); 1059 1060 return; 1061 } 1062 1063 MCSymbol *LineEndSym = Header.Emit(MCOS, Params, LineStr).second; 1064 1065 // Put out the line tables. 1066 for (const auto &LineSec : MCLineSections.getMCLineEntries()) 1067 emitDwarfLineTable(MCOS, LineSec.first, LineSec.second); 1068 1069 // Emit line tables for the original code. 1070 emitBinaryDwarfLineTable(MCOS, Params, InputTable, InputSequences); 1071 1072 // This is the end of the section, so set the value of the symbol at the end 1073 // of this section (that was used in a previous expression). 1074 MCOS->emitLabel(LineEndSym); 1075 } 1076 1077 void DwarfLineTable::emit(BinaryContext &BC, MCStreamer &Streamer) { 1078 MCAssembler &Assembler = 1079 static_cast<MCObjectStreamer *>(&Streamer)->getAssembler(); 1080 1081 MCDwarfLineTableParams Params = Assembler.getDWARFLinetableParams(); 1082 1083 auto &LineTables = BC.getDwarfLineTables(); 1084 1085 // Bail out early so we don't switch to the debug_line section needlessly and 1086 // in doing so create an unnecessary (if empty) section. 1087 if (LineTables.empty()) 1088 return; 1089 1090 // In a v5 non-split line table, put the strings in a separate section. 1091 Optional<MCDwarfLineStr> LineStr(None); 1092 if (BC.Ctx->getDwarfVersion() >= 5) 1093 LineStr = MCDwarfLineStr(*BC.Ctx); 1094 1095 // Switch to the section where the table will be emitted into. 1096 Streamer.SwitchSection(BC.MOFI->getDwarfLineSection()); 1097 1098 // Handle the rest of the Compile Units. 1099 for (auto &CUIDTablePair : LineTables) { 1100 CUIDTablePair.second.emitCU(&Streamer, Params, LineStr, BC); 1101 } 1102 } 1103 1104 } // namespace bolt 1105 } // namespace llvm 1106