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