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