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/Rewrite/RewriteInstance.h" 16 #include "bolt/Utils/Utils.h" 17 #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h" 18 #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h" 19 #include "llvm/DebugInfo/DWARF/DWARFDebugAddr.h" 20 #include "llvm/MC/MCAssembler.h" 21 #include "llvm/MC/MCContext.h" 22 #include "llvm/MC/MCObjectStreamer.h" 23 #include "llvm/Support/CommandLine.h" 24 #include "llvm/Support/EndianStream.h" 25 #include "llvm/Support/LEB128.h" 26 #include "llvm/Support/SHA1.h" 27 #include <algorithm> 28 #include <cassert> 29 #include <cstdint> 30 #include <limits> 31 #include <unordered_map> 32 #include <vector> 33 34 #define DEBUG_TYPE "bolt-debug-info" 35 36 namespace opts { 37 extern llvm::cl::opt<unsigned> Verbosity; 38 } // namespace opts 39 40 namespace llvm { 41 class MCSymbol; 42 43 namespace bolt { 44 45 Optional<AttrInfo> 46 findAttributeInfo(const DWARFDie DIE, 47 const DWARFAbbreviationDeclaration *AbbrevDecl, 48 uint32_t Index) { 49 const DWARFUnit &U = *DIE.getDwarfUnit(); 50 uint64_t Offset = 51 AbbrevDecl->getAttributeOffsetFromIndex(Index, DIE.getOffset(), U); 52 Optional<DWARFFormValue> Value = 53 AbbrevDecl->getAttributeValueFromOffset(Index, Offset, U); 54 if (!Value) 55 return None; 56 // AttributeSpec 57 const DWARFAbbreviationDeclaration::AttributeSpec *AttrVal = 58 AbbrevDecl->attributes().begin() + Index; 59 uint32_t ValSize = 0; 60 Optional<int64_t> ValSizeOpt = AttrVal->getByteSize(U); 61 if (ValSizeOpt) { 62 ValSize = static_cast<uint32_t>(*ValSizeOpt); 63 } else { 64 DWARFDataExtractor DebugInfoData = U.getDebugInfoExtractor(); 65 uint64_t NewOffset = Offset; 66 DWARFFormValue::skipValue(Value->getForm(), DebugInfoData, &NewOffset, 67 U.getFormParams()); 68 // This includes entire size of the entry, which might not be just the 69 // encoding part. For example for DW_AT_loc it will include expression 70 // location. 71 ValSize = NewOffset - Offset; 72 } 73 return AttrInfo{*Value, DIE.getAbbreviationDeclarationPtr(), Offset, ValSize}; 74 } 75 76 Optional<AttrInfo> findAttributeInfo(const DWARFDie DIE, 77 dwarf::Attribute Attr) { 78 if (!DIE.isValid()) 79 return None; 80 const DWARFAbbreviationDeclaration *AbbrevDecl = 81 DIE.getAbbreviationDeclarationPtr(); 82 if (!AbbrevDecl) 83 return None; 84 Optional<uint32_t> Index = AbbrevDecl->findAttributeIndex(Attr); 85 if (!Index) 86 return None; 87 return findAttributeInfo(DIE, AbbrevDecl, *Index); 88 } 89 90 const DebugLineTableRowRef DebugLineTableRowRef::NULL_ROW{0, 0}; 91 92 namespace { 93 94 LLVM_ATTRIBUTE_UNUSED 95 static void printLE64(const std::string &S) { 96 for (uint32_t I = 0, Size = S.size(); I < Size; ++I) { 97 errs() << Twine::utohexstr(S[I]); 98 errs() << Twine::utohexstr((int8_t)S[I]); 99 } 100 errs() << "\n"; 101 } 102 103 // Writes address ranges to Writer as pairs of 64-bit (address, size). 104 // If RelativeRange is true, assumes the address range to be written must be of 105 // the form (begin address, range size), otherwise (begin address, end address). 106 // Terminates the list by writing a pair of two zeroes. 107 // Returns the number of written bytes. 108 uint64_t writeAddressRanges(raw_svector_ostream &Stream, 109 const DebugAddressRangesVector &AddressRanges, 110 const bool WriteRelativeRanges = false) { 111 for (const DebugAddressRange &Range : AddressRanges) { 112 support::endian::write(Stream, Range.LowPC, support::little); 113 support::endian::write( 114 Stream, WriteRelativeRanges ? Range.HighPC - Range.LowPC : Range.HighPC, 115 support::little); 116 } 117 // Finish with 0 entries. 118 support::endian::write(Stream, 0ULL, support::little); 119 support::endian::write(Stream, 0ULL, support::little); 120 return AddressRanges.size() * 16 + 16; 121 } 122 123 } // namespace 124 125 DebugRangesSectionWriter::DebugRangesSectionWriter() { 126 RangesBuffer = std::make_unique<DebugBufferVector>(); 127 RangesStream = std::make_unique<raw_svector_ostream>(*RangesBuffer); 128 129 // Add an empty range as the first entry; 130 SectionOffset += 131 writeAddressRanges(*RangesStream.get(), DebugAddressRangesVector{}); 132 Kind = RangesWriterKind::DebugRangesWriter; 133 } 134 135 uint64_t DebugRangesSectionWriter::addRanges( 136 DebugAddressRangesVector &&Ranges, 137 std::map<DebugAddressRangesVector, uint64_t> &CachedRanges) { 138 if (Ranges.empty()) 139 return getEmptyRangesOffset(); 140 141 const auto RI = CachedRanges.find(Ranges); 142 if (RI != CachedRanges.end()) 143 return RI->second; 144 145 const uint64_t EntryOffset = addRanges(Ranges); 146 CachedRanges.emplace(std::move(Ranges), EntryOffset); 147 148 return EntryOffset; 149 } 150 151 uint64_t 152 DebugRangesSectionWriter::addRanges(const DebugAddressRangesVector &Ranges) { 153 if (Ranges.empty()) 154 return getEmptyRangesOffset(); 155 156 // Reading the SectionOffset and updating it should be atomic to guarantee 157 // unique and correct offsets in patches. 158 std::lock_guard<std::mutex> Lock(WriterMutex); 159 const uint32_t EntryOffset = SectionOffset; 160 SectionOffset += writeAddressRanges(*RangesStream.get(), Ranges); 161 162 return EntryOffset; 163 } 164 165 uint64_t DebugRangesSectionWriter::getSectionOffset() { 166 std::lock_guard<std::mutex> Lock(WriterMutex); 167 return SectionOffset; 168 } 169 170 DebugAddrWriter *DebugRangeListsSectionWriter::AddrWriter = nullptr; 171 172 uint64_t DebugRangeListsSectionWriter::addRanges( 173 DebugAddressRangesVector &&Ranges, 174 std::map<DebugAddressRangesVector, uint64_t> &CachedRanges) { 175 return addRanges(Ranges); 176 } 177 178 struct LocListsRangelistsHeader { 179 UnitLengthType UnitLength; // Size of loclist entris section, not including 180 // size of header. 181 VersionType Version; 182 AddressSizeType AddressSize; 183 SegmentSelectorType SegmentSelector; 184 OffsetEntryCountType OffsetEntryCount; 185 }; 186 187 static std::unique_ptr<DebugBufferVector> 188 getDWARF5Header(const LocListsRangelistsHeader &Header) { 189 std::unique_ptr<DebugBufferVector> HeaderBuffer = 190 std::make_unique<DebugBufferVector>(); 191 std::unique_ptr<raw_svector_ostream> HeaderStream = 192 std::make_unique<raw_svector_ostream>(*HeaderBuffer); 193 194 // 7.29 length of the set of entries for this compilation unit, not including 195 // the length field itself 196 const uint32_t HeaderSize = 197 getDWARF5RngListLocListHeaderSize() - sizeof(UnitLengthType); 198 199 support::endian::write(*HeaderStream, Header.UnitLength + HeaderSize, 200 support::little); 201 support::endian::write(*HeaderStream, Header.Version, support::little); 202 support::endian::write(*HeaderStream, Header.AddressSize, support::little); 203 support::endian::write(*HeaderStream, Header.SegmentSelector, 204 support::little); 205 support::endian::write(*HeaderStream, Header.OffsetEntryCount, 206 support::little); 207 return HeaderBuffer; 208 } 209 210 uint64_t DebugRangeListsSectionWriter::addRanges( 211 const DebugAddressRangesVector &Ranges) { 212 std::lock_guard<std::mutex> Lock(WriterMutex); 213 214 RangeEntries.push_back(CurrentOffset); 215 for (const DebugAddressRange &Range : Ranges) { 216 support::endian::write(*CUBodyStream, 217 static_cast<uint8_t>(dwarf::DW_RLE_startx_length), 218 support::little); 219 uint32_t Index = AddrWriter->getIndexFromAddress(Range.LowPC, *CU); 220 encodeULEB128(Index, *CUBodyStream); 221 encodeULEB128(Range.HighPC - Range.LowPC, *CUBodyStream); 222 } 223 support::endian::write(*CUBodyStream, 224 static_cast<uint8_t>(dwarf::DW_RLE_end_of_list), 225 support::little); 226 CurrentOffset = CUBodyBuffer->size(); 227 return RangeEntries.size() - 1; 228 } 229 230 void DebugRangeListsSectionWriter::finalizeSection() { 231 std::unique_ptr<DebugBufferVector> CUArrayBuffer = 232 std::make_unique<DebugBufferVector>(); 233 std::unique_ptr<raw_svector_ostream> CUArrayStream = 234 std::make_unique<raw_svector_ostream>(*CUArrayBuffer); 235 constexpr uint32_t SizeOfArrayEntry = 4; 236 const uint32_t SizeOfArraySection = RangeEntries.size() * SizeOfArrayEntry; 237 for (uint32_t Offset : RangeEntries) 238 support::endian::write(*CUArrayStream, Offset + SizeOfArraySection, 239 support::little); 240 241 std::unique_ptr<DebugBufferVector> Header = getDWARF5Header( 242 {static_cast<uint32_t>(SizeOfArraySection + CUBodyBuffer.get()->size()), 243 5, 8, 0, static_cast<uint32_t>(RangeEntries.size())}); 244 *RangesStream << *Header; 245 *RangesStream << *CUArrayBuffer; 246 *RangesStream << *CUBodyBuffer; 247 SectionOffset = RangesBuffer->size(); 248 } 249 250 void DebugRangeListsSectionWriter::initSection(DWARFUnit &Unit) { 251 CUBodyBuffer = std::make_unique<DebugBufferVector>(); 252 CUBodyStream = std::make_unique<raw_svector_ostream>(*CUBodyBuffer); 253 RangeEntries.clear(); 254 CurrentOffset = 0; 255 CU = &Unit; 256 } 257 258 void DebugARangesSectionWriter::addCURanges(uint64_t CUOffset, 259 DebugAddressRangesVector &&Ranges) { 260 std::lock_guard<std::mutex> Lock(CUAddressRangesMutex); 261 CUAddressRanges.emplace(CUOffset, std::move(Ranges)); 262 } 263 264 void DebugARangesSectionWriter::writeARangesSection( 265 raw_svector_ostream &RangesStream, const CUOffsetMap &CUMap) const { 266 // For reference on the format of the .debug_aranges section, see the DWARF4 267 // specification, section 6.1.4 Lookup by Address 268 // http://www.dwarfstd.org/doc/DWARF4.pdf 269 for (const auto &CUOffsetAddressRangesPair : CUAddressRanges) { 270 const uint64_t Offset = CUOffsetAddressRangesPair.first; 271 const DebugAddressRangesVector &AddressRanges = 272 CUOffsetAddressRangesPair.second; 273 274 // Emit header. 275 276 // Size of this set: 8 (size of the header) + 4 (padding after header) 277 // + 2*sizeof(uint64_t) bytes for each of the ranges, plus an extra 278 // pair of uint64_t's for the terminating, zero-length range. 279 // Does not include size field itself. 280 uint32_t Size = 8 + 4 + 2 * sizeof(uint64_t) * (AddressRanges.size() + 1); 281 282 // Header field #1: set size. 283 support::endian::write(RangesStream, Size, support::little); 284 285 // Header field #2: version number, 2 as per the specification. 286 support::endian::write(RangesStream, static_cast<uint16_t>(2), 287 support::little); 288 289 assert(CUMap.count(Offset) && "Original CU offset is not found in CU Map"); 290 // Header field #3: debug info offset of the correspondent compile unit. 291 support::endian::write( 292 RangesStream, static_cast<uint32_t>(CUMap.find(Offset)->second.Offset), 293 support::little); 294 295 // Header field #4: address size. 296 // 8 since we only write ELF64 binaries for now. 297 RangesStream << char(8); 298 299 // Header field #5: segment size of target architecture. 300 RangesStream << char(0); 301 302 // Padding before address table - 4 bytes in the 64-bit-pointer case. 303 support::endian::write(RangesStream, static_cast<uint32_t>(0), 304 support::little); 305 306 writeAddressRanges(RangesStream, AddressRanges, true); 307 } 308 } 309 310 DebugAddrWriter::DebugAddrWriter(BinaryContext *Bc) { BC = Bc; } 311 312 void DebugAddrWriter::AddressForDWOCU::dump() { 313 std::vector<IndexAddressPair> SortedMap(indexToAddressBegin(), 314 indexToAdddessEnd()); 315 // Sorting address in increasing order of indices. 316 std::sort(SortedMap.begin(), SortedMap.end(), 317 [](const IndexAddressPair &A, const IndexAddressPair &B) { 318 return A.first < B.first; 319 }); 320 for (auto &Pair : SortedMap) 321 dbgs() << Twine::utohexstr(Pair.second) << "\t" << Pair.first << "\n"; 322 } 323 uint32_t DebugAddrWriter::getIndexFromAddress(uint64_t Address, DWARFUnit &CU) { 324 std::lock_guard<std::mutex> Lock(WriterMutex); 325 const uint64_t CUID = getCUID(CU); 326 if (!AddressMaps.count(CUID)) 327 AddressMaps[CUID] = AddressForDWOCU(); 328 329 AddressForDWOCU &Map = AddressMaps[CUID]; 330 auto Entry = Map.find(Address); 331 if (Entry == Map.end()) { 332 auto Index = Map.getNextIndex(); 333 Entry = Map.insert(Address, Index).first; 334 } 335 return Entry->second; 336 } 337 338 // Case1) Address is not in map insert in to AddresToIndex and IndexToAddres 339 // Case2) Address is in the map but Index is higher or equal. Need to update 340 // IndexToAddrss. Case3) Address is in the map but Index is lower. Need to 341 // update AddressToIndex and IndexToAddress 342 void DebugAddrWriter::addIndexAddress(uint64_t Address, uint32_t Index, 343 DWARFUnit &CU) { 344 std::lock_guard<std::mutex> Lock(WriterMutex); 345 const uint64_t CUID = getCUID(CU); 346 AddressForDWOCU &Map = AddressMaps[CUID]; 347 auto Entry = Map.find(Address); 348 if (Entry != Map.end()) { 349 if (Entry->second > Index) 350 Map.updateAddressToIndex(Address, Index); 351 Map.updateIndexToAddrss(Address, Index); 352 } else { 353 Map.insert(Address, Index); 354 } 355 } 356 357 AddressSectionBuffer DebugAddrWriter::finalize() { 358 // Need to layout all sections within .debug_addr 359 // Within each section sort Address by index. 360 AddressSectionBuffer Buffer; 361 raw_svector_ostream AddressStream(Buffer); 362 for (std::unique_ptr<DWARFUnit> &CU : BC->DwCtx->compile_units()) { 363 // Handling the case wehre debug information is a mix of Debug fission and 364 // monolitic. 365 if (!CU->getDWOId()) 366 continue; 367 const uint64_t CUID = getCUID(*CU.get()); 368 auto AM = AddressMaps.find(CUID); 369 // Adding to map even if it did not contribute to .debug_addr. 370 // The Skeleton CU might still have DW_AT_GNU_addr_base. 371 DWOIdToOffsetMap[CUID] = Buffer.size(); 372 // If does not exist this CUs DWO section didn't contribute to .debug_addr. 373 if (AM == AddressMaps.end()) 374 continue; 375 std::vector<IndexAddressPair> SortedMap(AM->second.indexToAddressBegin(), 376 AM->second.indexToAdddessEnd()); 377 // Sorting address in increasing order of indices. 378 std::sort(SortedMap.begin(), SortedMap.end(), 379 [](const IndexAddressPair &A, const IndexAddressPair &B) { 380 return A.first < B.first; 381 }); 382 383 uint8_t AddrSize = CU->getAddressByteSize(); 384 uint32_t Counter = 0; 385 auto WriteAddress = [&](uint64_t Address) -> void { 386 ++Counter; 387 switch (AddrSize) { 388 default: 389 assert(false && "Address Size is invalid."); 390 break; 391 case 4: 392 support::endian::write(AddressStream, static_cast<uint32_t>(Address), 393 support::little); 394 break; 395 case 8: 396 support::endian::write(AddressStream, Address, support::little); 397 break; 398 } 399 }; 400 401 for (const IndexAddressPair &Val : SortedMap) { 402 while (Val.first > Counter) 403 WriteAddress(0); 404 WriteAddress(Val.second); 405 } 406 } 407 408 return Buffer; 409 } 410 AddressSectionBuffer DebugAddrWriterDwarf5::finalize() { 411 // Need to layout all sections within .debug_addr 412 // Within each section sort Address by index. 413 AddressSectionBuffer Buffer; 414 raw_svector_ostream AddressStream(Buffer); 415 const endianness Endian = 416 BC->DwCtx->isLittleEndian() ? support::little : support::big; 417 const DWARFSection &AddrSec = BC->DwCtx->getDWARFObj().getAddrSection(); 418 DWARFDataExtractor AddrData(BC->DwCtx->getDWARFObj(), AddrSec, Endian, 0); 419 DWARFDebugAddrTable AddrTable; 420 DIDumpOptions DumpOpts; 421 constexpr uint32_t HeaderSize = 8; 422 for (std::unique_ptr<DWARFUnit> &CU : BC->DwCtx->compile_units()) { 423 const uint64_t CUID = getCUID(*CU.get()); 424 const uint8_t AddrSize = CU->getAddressByteSize(); 425 auto AMIter = AddressMaps.find(CUID); 426 // A case where CU has entry in .debug_addr, but we don't modify addresses 427 // for it. 428 if (AMIter == AddressMaps.end()) { 429 AMIter = AddressMaps.insert({CUID, AddressForDWOCU()}).first; 430 Optional<uint64_t> BaseOffset = CU->getAddrOffsetSectionBase(); 431 if (!BaseOffset) 432 continue; 433 // Address base offset is to the first entry. 434 // The size of header is 8 bytes. 435 uint64_t Offset = *BaseOffset - HeaderSize; 436 if (Error Err = AddrTable.extract(AddrData, &Offset, 5, AddrSize, 437 DumpOpts.WarningHandler)) { 438 DumpOpts.RecoverableErrorHandler(std::move(Err)); 439 continue; 440 } 441 uint32_t Index = 0; 442 for (uint64_t Addr : AddrTable.getAddressEntries()) 443 AMIter->second.insert(Addr, Index++); 444 } 445 446 DWOIdToOffsetMap[CUID] = Buffer.size() + HeaderSize; 447 448 std::vector<IndexAddressPair> SortedMap( 449 AMIter->second.indexToAddressBegin(), 450 AMIter->second.indexToAdddessEnd()); 451 // Sorting address in increasing order of indices. 452 std::sort(SortedMap.begin(), SortedMap.end(), 453 [](const IndexAddressPair &A, const IndexAddressPair &B) { 454 return A.first < B.first; 455 }); 456 // Writing out Header 457 const uint32_t Length = SortedMap.size() * AddrSize + 4; 458 support::endian::write(AddressStream, Length, Endian); 459 support::endian::write(AddressStream, static_cast<uint16_t>(5), Endian); 460 support::endian::write(AddressStream, static_cast<uint8_t>(AddrSize), 461 Endian); 462 support::endian::write(AddressStream, static_cast<uint8_t>(0), Endian); 463 464 uint32_t Counter = 0; 465 auto writeAddress = [&](uint64_t Address) -> void { 466 ++Counter; 467 switch (AddrSize) { 468 default: 469 llvm_unreachable("Address Size is invalid."); 470 break; 471 case 4: 472 support::endian::write(AddressStream, static_cast<uint32_t>(Address), 473 Endian); 474 break; 475 case 8: 476 support::endian::write(AddressStream, Address, Endian); 477 break; 478 } 479 }; 480 481 for (const IndexAddressPair &Val : SortedMap) { 482 while (Val.first > Counter) 483 writeAddress(0); 484 writeAddress(Val.second); 485 } 486 } 487 488 return Buffer; 489 } 490 491 uint64_t DebugAddrWriter::getOffset(DWARFUnit &Unit) { 492 const uint64_t CUID = getCUID(Unit); 493 assert(CUID && "Can't get offset, not a skeleton CU."); 494 auto Iter = DWOIdToOffsetMap.find(CUID); 495 assert(Iter != DWOIdToOffsetMap.end() && 496 "Offset in to.debug_addr was not found for DWO ID."); 497 return Iter->second; 498 } 499 500 uint64_t DebugAddrWriterDwarf5::getOffset(DWARFUnit &Unit) { 501 auto Iter = DWOIdToOffsetMap.find(getCUID(Unit)); 502 assert(Iter != DWOIdToOffsetMap.end() && 503 "Offset in to.debug_addr was not found for CU ID."); 504 return Iter->second; 505 } 506 507 void DebugLocWriter::init() { 508 LocBuffer = std::make_unique<DebugBufferVector>(); 509 LocStream = std::make_unique<raw_svector_ostream>(*LocBuffer); 510 // Writing out empty location list to which all references to empty location 511 // lists will point. 512 if (!LocSectionOffset && DwarfVersion < 5) { 513 const char Zeroes[16] = {0}; 514 *LocStream << StringRef(Zeroes, 16); 515 LocSectionOffset += 16; 516 } 517 } 518 519 uint32_t DebugLocWriter::LocSectionOffset = 0; 520 void DebugLocWriter::addList(AttrInfo &AttrVal, DebugLocationsVector &LocList, 521 DebugInfoBinaryPatcher &DebugInfoPatcher, 522 DebugAbbrevWriter &AbbrevWriter) { 523 const uint64_t AttrOffset = AttrVal.Offset; 524 if (LocList.empty()) { 525 DebugInfoPatcher.addLE32Patch(AttrOffset, DebugLocWriter::EmptyListOffset); 526 return; 527 } 528 // Since there is a separate DebugLocWriter for each thread, 529 // we don't need a lock to read the SectionOffset and update it. 530 const uint32_t EntryOffset = LocSectionOffset; 531 532 for (const DebugLocationEntry &Entry : LocList) { 533 support::endian::write(*LocStream, static_cast<uint64_t>(Entry.LowPC), 534 support::little); 535 support::endian::write(*LocStream, static_cast<uint64_t>(Entry.HighPC), 536 support::little); 537 support::endian::write(*LocStream, static_cast<uint16_t>(Entry.Expr.size()), 538 support::little); 539 *LocStream << StringRef(reinterpret_cast<const char *>(Entry.Expr.data()), 540 Entry.Expr.size()); 541 LocSectionOffset += 2 * 8 + 2 + Entry.Expr.size(); 542 } 543 LocStream->write_zeros(16); 544 LocSectionOffset += 16; 545 LocListDebugInfoPatches.push_back({AttrOffset, EntryOffset}); 546 DebugInfoPatcher.addLE32Patch(AttrOffset, EntryOffset); 547 } 548 549 std::unique_ptr<DebugBufferVector> DebugLocWriter::getBuffer() { 550 return std::move(LocBuffer); 551 } 552 553 // DWARF 4: 2.6.2 554 void DebugLocWriter::finalize(DebugInfoBinaryPatcher &DebugInfoPatcher, 555 DebugAbbrevWriter &AbbrevWriter) {} 556 557 static void writeEmptyListDwarf5(raw_svector_ostream &Stream) { 558 support::endian::write(Stream, static_cast<uint32_t>(4), support::little); 559 support::endian::write(Stream, static_cast<uint8_t>(dwarf::DW_LLE_start_end), 560 support::little); 561 562 const char Zeroes[16] = {0}; 563 Stream << StringRef(Zeroes, 16); 564 encodeULEB128(0, Stream); 565 support::endian::write( 566 Stream, static_cast<uint8_t>(dwarf::DW_LLE_end_of_list), support::little); 567 } 568 569 static void writeLegacyLocList(AttrInfo &AttrVal, DebugLocationsVector &LocList, 570 DebugInfoBinaryPatcher &DebugInfoPatcher, 571 DebugAddrWriter &AddrWriter, 572 DebugBufferVector &LocBuffer, DWARFUnit &CU, 573 raw_svector_ostream &LocStream) { 574 const uint64_t AttrOffset = AttrVal.Offset; 575 if (LocList.empty()) { 576 DebugInfoPatcher.addLE32Patch(AttrOffset, DebugLocWriter::EmptyListOffset); 577 return; 578 } 579 580 const uint32_t EntryOffset = LocBuffer.size(); 581 for (const DebugLocationEntry &Entry : LocList) { 582 support::endian::write(LocStream, 583 static_cast<uint8_t>(dwarf::DW_LLE_startx_length), 584 support::little); 585 const uint32_t Index = AddrWriter.getIndexFromAddress(Entry.LowPC, CU); 586 encodeULEB128(Index, LocStream); 587 588 support::endian::write(LocStream, 589 static_cast<uint32_t>(Entry.HighPC - Entry.LowPC), 590 support::little); 591 support::endian::write(LocStream, static_cast<uint16_t>(Entry.Expr.size()), 592 support::little); 593 LocStream << StringRef(reinterpret_cast<const char *>(Entry.Expr.data()), 594 Entry.Expr.size()); 595 } 596 support::endian::write(LocStream, 597 static_cast<uint8_t>(dwarf::DW_LLE_end_of_list), 598 support::little); 599 DebugInfoPatcher.addLE32Patch(AttrOffset, EntryOffset); 600 } 601 602 static void writeDWARF5LocList( 603 uint32_t &NumberOfEntries, AttrInfo &AttrVal, DebugLocationsVector &LocList, 604 DebugInfoBinaryPatcher &DebugInfoPatcher, DebugAbbrevWriter &AbbrevWriter, 605 DebugAddrWriter &AddrWriter, DebugBufferVector &LocBodyBuffer, 606 std::vector<uint32_t> &RelativeLocListOffsets, DWARFUnit &CU, 607 raw_svector_ostream &LocBodyStream) { 608 if (AttrVal.V.getForm() != dwarf::DW_FORM_loclistx) { 609 AbbrevWriter.addAttributePatch(CU, AttrVal.AbbrevDecl, 610 dwarf::DW_AT_location, dwarf::DW_AT_location, 611 dwarf::DW_FORM_loclistx); 612 } 613 DebugInfoPatcher.addUDataPatch(AttrVal.Offset, NumberOfEntries, AttrVal.Size); 614 RelativeLocListOffsets.push_back(LocBodyBuffer.size()); 615 ++NumberOfEntries; 616 if (LocList.empty()) { 617 writeEmptyListDwarf5(LocBodyStream); 618 return; 619 } 620 621 std::vector<uint64_t> OffsetsArray; 622 for (const DebugLocationEntry &Entry : LocList) { 623 support::endian::write(LocBodyStream, 624 static_cast<uint8_t>(dwarf::DW_LLE_startx_length), 625 support::little); 626 const uint32_t Index = AddrWriter.getIndexFromAddress(Entry.LowPC, CU); 627 encodeULEB128(Index, LocBodyStream); 628 encodeULEB128(Entry.HighPC - Entry.LowPC, LocBodyStream); 629 encodeULEB128(Entry.Expr.size(), LocBodyStream); 630 LocBodyStream << StringRef( 631 reinterpret_cast<const char *>(Entry.Expr.data()), Entry.Expr.size()); 632 } 633 support::endian::write(LocBodyStream, 634 static_cast<uint8_t>(dwarf::DW_LLE_end_of_list), 635 support::little); 636 } 637 638 void DebugLoclistWriter::addList(AttrInfo &AttrVal, 639 DebugLocationsVector &LocList, 640 DebugInfoBinaryPatcher &DebugInfoPatcher, 641 DebugAbbrevWriter &AbbrevWriter) { 642 if (DwarfVersion < 5) 643 writeLegacyLocList(AttrVal, LocList, DebugInfoPatcher, *AddrWriter, 644 *LocBuffer, CU, *LocStream); 645 else 646 writeDWARF5LocList(NumberOfEntries, AttrVal, LocList, DebugInfoPatcher, 647 AbbrevWriter, *AddrWriter, *LocBodyBuffer, 648 RelativeLocListOffsets, CU, *LocBodyStream); 649 } 650 651 uint32_t DebugLoclistWriter::LoclistBaseOffset = 0; 652 void DebugLoclistWriter::finalizeDWARF5( 653 DebugInfoBinaryPatcher &DebugInfoPatcher, DebugAbbrevWriter &AbbrevWriter) { 654 if (LocBodyBuffer->empty()) 655 return; 656 657 std::unique_ptr<DebugBufferVector> LocArrayBuffer = 658 std::make_unique<DebugBufferVector>(); 659 std::unique_ptr<raw_svector_ostream> LocArrayStream = 660 std::make_unique<raw_svector_ostream>(*LocArrayBuffer); 661 662 const uint32_t SizeOfArraySection = NumberOfEntries * sizeof(uint32_t); 663 // Write out IndexArray 664 for (uint32_t RelativeOffset : RelativeLocListOffsets) 665 support::endian::write( 666 *LocArrayStream, 667 static_cast<uint32_t>(SizeOfArraySection + RelativeOffset), 668 support::little); 669 670 std::unique_ptr<DebugBufferVector> Header = getDWARF5Header( 671 {static_cast<uint32_t>(SizeOfArraySection + LocBodyBuffer.get()->size()), 672 5, 8, 0, NumberOfEntries}); 673 *LocStream << *Header; 674 *LocStream << *LocArrayBuffer; 675 *LocStream << *LocBodyBuffer; 676 677 if (!isSplitDwarf()) { 678 if (Optional<AttrInfo> AttrInfoVal = 679 findAttributeInfo(CU.getUnitDIE(), dwarf::DW_AT_loclists_base)) 680 DebugInfoPatcher.addLE32Patch(AttrInfoVal->Offset, 681 LoclistBaseOffset + 682 getDWARF5RngListLocListHeaderSize()); 683 else { 684 AbbrevWriter.addAttribute( 685 CU, CU.getUnitDIE().getAbbreviationDeclarationPtr(), 686 dwarf::DW_AT_loclists_base, dwarf::DW_FORM_sec_offset); 687 DebugInfoPatcher.insertNewEntry(CU.getUnitDIE(), 688 LoclistBaseOffset + Header->size()); 689 } 690 LoclistBaseOffset += LocBuffer->size(); 691 } 692 clearList(RelativeLocListOffsets); 693 clearList(*LocArrayBuffer); 694 clearList(*LocBodyBuffer); 695 } 696 697 void DebugLoclistWriter::finalize(DebugInfoBinaryPatcher &DebugInfoPatcher, 698 DebugAbbrevWriter &AbbrevWriter) { 699 if (DwarfVersion >= 5) 700 finalizeDWARF5(DebugInfoPatcher, AbbrevWriter); 701 } 702 703 DebugAddrWriter *DebugLoclistWriter::AddrWriter = nullptr; 704 705 void DebugInfoBinaryPatcher::addUnitBaseOffsetLabel(uint64_t Offset) { 706 Offset -= DWPUnitOffset; 707 std::lock_guard<std::mutex> Lock(WriterMutex); 708 DebugPatches.emplace_back(new DWARFUnitOffsetBaseLabel(Offset)); 709 } 710 711 void DebugInfoBinaryPatcher::addDestinationReferenceLabel(uint64_t Offset) { 712 Offset -= DWPUnitOffset; 713 std::lock_guard<std::mutex> Lock(WriterMutex); 714 auto RetVal = DestinationLabels.insert(Offset); 715 if (!RetVal.second) 716 return; 717 718 DebugPatches.emplace_back(new DestinationReferenceLabel(Offset)); 719 } 720 721 static std::string encodeLE(size_t ByteSize, uint64_t NewValue) { 722 std::string LE64(ByteSize, 0); 723 for (size_t I = 0; I < ByteSize; ++I) { 724 LE64[I] = NewValue & 0xff; 725 NewValue >>= 8; 726 } 727 return LE64; 728 } 729 730 void DebugInfoBinaryPatcher::insertNewEntry(const DWARFDie &DIE, 731 uint32_t Value) { 732 std::string StrValue = encodeLE(4, Value); 733 insertNewEntry(DIE, std::move(StrValue)); 734 } 735 736 void DebugInfoBinaryPatcher::insertNewEntry(const DWARFDie &DIE, 737 std::string &&Value) { 738 const DWARFAbbreviationDeclaration *AbbrevDecl = 739 DIE.getAbbreviationDeclarationPtr(); 740 741 // In case this DIE has no attributes. 742 uint32_t Offset = DIE.getOffset() + 1; 743 size_t NumOfAttributes = AbbrevDecl->getNumAttributes(); 744 if (NumOfAttributes) { 745 Optional<AttrInfo> Val = 746 findAttributeInfo(DIE, AbbrevDecl, NumOfAttributes - 1); 747 assert(Val && "Invalid Value."); 748 749 Offset = Val->Offset + Val->Size - DWPUnitOffset; 750 } 751 std::lock_guard<std::mutex> Lock(WriterMutex); 752 DebugPatches.emplace_back(new NewDebugEntry(Offset, std::move(Value))); 753 } 754 755 void DebugInfoBinaryPatcher::addReferenceToPatch(uint64_t Offset, 756 uint32_t DestinationOffset, 757 uint32_t OldValueSize, 758 dwarf::Form Form) { 759 Offset -= DWPUnitOffset; 760 DestinationOffset -= DWPUnitOffset; 761 std::lock_guard<std::mutex> Lock(WriterMutex); 762 DebugPatches.emplace_back( 763 new DebugPatchReference(Offset, OldValueSize, DestinationOffset, Form)); 764 } 765 766 void DebugInfoBinaryPatcher::addUDataPatch(uint64_t Offset, uint64_t NewValue, 767 uint32_t OldValueSize) { 768 Offset -= DWPUnitOffset; 769 std::lock_guard<std::mutex> Lock(WriterMutex); 770 DebugPatches.emplace_back( 771 new DebugPatchVariableSize(Offset, OldValueSize, NewValue)); 772 } 773 774 void DebugInfoBinaryPatcher::addLE64Patch(uint64_t Offset, uint64_t NewValue) { 775 Offset -= DWPUnitOffset; 776 std::lock_guard<std::mutex> Lock(WriterMutex); 777 DebugPatches.emplace_back(new DebugPatch64(Offset, NewValue)); 778 } 779 780 void DebugInfoBinaryPatcher::addLE32Patch(uint64_t Offset, uint32_t NewValue, 781 uint32_t OldValueSize) { 782 Offset -= DWPUnitOffset; 783 std::lock_guard<std::mutex> Lock(WriterMutex); 784 if (OldValueSize == 4) 785 DebugPatches.emplace_back(new DebugPatch32(Offset, NewValue)); 786 else if (OldValueSize == 8) 787 DebugPatches.emplace_back(new DebugPatch64to32(Offset, NewValue)); 788 else 789 DebugPatches.emplace_back( 790 new DebugPatch32GenericSize(Offset, NewValue, OldValueSize)); 791 } 792 793 void SimpleBinaryPatcher::addBinaryPatch(uint64_t Offset, 794 std::string &&NewValue, 795 uint32_t OldValueSize) { 796 Patches.emplace_back(Offset, std::move(NewValue)); 797 } 798 799 void SimpleBinaryPatcher::addBytePatch(uint64_t Offset, uint8_t Value) { 800 auto Str = std::string(1, Value); 801 Patches.emplace_back(Offset, std::move(Str)); 802 } 803 804 void SimpleBinaryPatcher::addLEPatch(uint64_t Offset, uint64_t NewValue, 805 size_t ByteSize) { 806 Patches.emplace_back(Offset, encodeLE(ByteSize, NewValue)); 807 } 808 809 void SimpleBinaryPatcher::addUDataPatch(uint64_t Offset, uint64_t Value, 810 uint32_t OldValueSize) { 811 std::string Buff; 812 raw_string_ostream OS(Buff); 813 encodeULEB128(Value, OS, OldValueSize); 814 815 Patches.emplace_back(Offset, std::move(Buff)); 816 } 817 818 void SimpleBinaryPatcher::addLE64Patch(uint64_t Offset, uint64_t NewValue) { 819 addLEPatch(Offset, NewValue, 8); 820 } 821 822 void SimpleBinaryPatcher::addLE32Patch(uint64_t Offset, uint32_t NewValue, 823 uint32_t OldValueSize) { 824 addLEPatch(Offset, NewValue, 4); 825 } 826 827 std::string SimpleBinaryPatcher::patchBinary(StringRef BinaryContents) { 828 std::string BinaryContentsStr = std::string(BinaryContents); 829 for (const auto &Patch : Patches) { 830 uint32_t Offset = Patch.first; 831 const std::string &ByteSequence = Patch.second; 832 assert(Offset + ByteSequence.size() <= BinaryContents.size() && 833 "Applied patch runs over binary size."); 834 for (uint64_t I = 0, Size = ByteSequence.size(); I < Size; ++I) { 835 BinaryContentsStr[Offset + I] = ByteSequence[I]; 836 } 837 } 838 return BinaryContentsStr; 839 } 840 841 CUOffsetMap DebugInfoBinaryPatcher::computeNewOffsets(DWARFContext &DWCtx, 842 bool IsDWOContext) { 843 CUOffsetMap CUMap; 844 std::sort(DebugPatches.begin(), DebugPatches.end(), 845 [](const UniquePatchPtrType &V1, const UniquePatchPtrType &V2) { 846 if (V1.get()->Offset == V2.get()->Offset) { 847 if (V1->Kind == DebugPatchKind::NewDebugEntry && 848 V2->Kind == DebugPatchKind::NewDebugEntry) 849 return reinterpret_cast<const NewDebugEntry *>(V1.get()) 850 ->CurrentOrder < 851 reinterpret_cast<const NewDebugEntry *>(V2.get()) 852 ->CurrentOrder; 853 854 // This is a case where we are modifying first entry of next 855 // DIE, and adding a new one. 856 return V1->Kind == DebugPatchKind::NewDebugEntry; 857 } 858 return V1.get()->Offset < V2.get()->Offset; 859 }); 860 861 DWARFUnitVector::compile_unit_range CompileUnits = 862 IsDWOContext ? DWCtx.dwo_compile_units() : DWCtx.compile_units(); 863 864 for (const std::unique_ptr<DWARFUnit> &CU : CompileUnits) 865 CUMap[CU->getOffset()] = {static_cast<uint32_t>(CU->getOffset()), 866 static_cast<uint32_t>(CU->getLength())}; 867 868 // Calculating changes in .debug_info size from Patches to build a map of old 869 // to updated reference destination offsets. 870 uint32_t PreviousOffset = 0; 871 int32_t PreviousChangeInSize = 0; 872 for (UniquePatchPtrType &PatchBase : DebugPatches) { 873 Patch *P = PatchBase.get(); 874 switch (P->Kind) { 875 default: 876 continue; 877 case DebugPatchKind::PatchValue64to32: { 878 PreviousChangeInSize -= 4; 879 break; 880 } 881 case DebugPatchKind::PatchValue32GenericSize: { 882 DebugPatch32GenericSize *DPVS = 883 reinterpret_cast<DebugPatch32GenericSize *>(P); 884 PreviousChangeInSize += 4 - DPVS->OldValueSize; 885 break; 886 } 887 case DebugPatchKind::PatchValueVariable: { 888 DebugPatchVariableSize *DPV = 889 reinterpret_cast<DebugPatchVariableSize *>(P); 890 std::string Temp; 891 raw_string_ostream OS(Temp); 892 encodeULEB128(DPV->Value, OS); 893 PreviousChangeInSize += Temp.size() - DPV->OldValueSize; 894 break; 895 } 896 case DebugPatchKind::DestinationReferenceLabel: { 897 DestinationReferenceLabel *DRL = 898 reinterpret_cast<DestinationReferenceLabel *>(P); 899 OldToNewOffset[DRL->Offset] = 900 DRL->Offset + ChangeInSize + PreviousChangeInSize; 901 break; 902 } 903 case DebugPatchKind::ReferencePatchValue: { 904 // This doesn't look to be a common case, so will always encode as 4 bytes 905 // to reduce algorithmic complexity. 906 DebugPatchReference *RDP = reinterpret_cast<DebugPatchReference *>(P); 907 if (RDP->PatchInfo.IndirectRelative) { 908 PreviousChangeInSize += 4 - RDP->PatchInfo.OldValueSize; 909 assert(RDP->PatchInfo.OldValueSize <= 4 && 910 "Variable encoding reference greater than 4 bytes."); 911 } 912 break; 913 } 914 case DebugPatchKind::DWARFUnitOffsetBaseLabel: { 915 DWARFUnitOffsetBaseLabel *BaseLabel = 916 reinterpret_cast<DWARFUnitOffsetBaseLabel *>(P); 917 uint32_t CUOffset = BaseLabel->Offset; 918 ChangeInSize += PreviousChangeInSize; 919 uint32_t CUOffsetUpdate = CUOffset + ChangeInSize; 920 CUMap[CUOffset].Offset = CUOffsetUpdate; 921 CUMap[PreviousOffset].Length += PreviousChangeInSize; 922 PreviousChangeInSize = 0; 923 PreviousOffset = CUOffset; 924 break; 925 } 926 case DebugPatchKind::NewDebugEntry: { 927 NewDebugEntry *NDE = reinterpret_cast<NewDebugEntry *>(P); 928 PreviousChangeInSize += NDE->Value.size(); 929 break; 930 } 931 } 932 } 933 CUMap[PreviousOffset].Length += PreviousChangeInSize; 934 return CUMap; 935 } 936 uint32_t DebugInfoBinaryPatcher::NewDebugEntry::OrderCounter = 0; 937 938 std::string DebugInfoBinaryPatcher::patchBinary(StringRef BinaryContents) { 939 std::string NewBinaryContents; 940 NewBinaryContents.reserve(BinaryContents.size() + ChangeInSize); 941 uint32_t StartOffset = 0; 942 uint32_t DwarfUnitBaseOffset = 0; 943 uint32_t OldValueSize = 0; 944 uint32_t Offset = 0; 945 std::string ByteSequence; 946 std::vector<std::pair<uint32_t, uint32_t>> LengthPatches; 947 // Wasting one entry to avoid checks for first. 948 LengthPatches.push_back({0, 0}); 949 950 // Applying all the patches replacing current entry. 951 // This might change the size of .debug_info section. 952 for (const UniquePatchPtrType &PatchBase : DebugPatches) { 953 Patch *P = PatchBase.get(); 954 switch (P->Kind) { 955 default: 956 continue; 957 case DebugPatchKind::ReferencePatchValue: { 958 DebugPatchReference *RDP = reinterpret_cast<DebugPatchReference *>(P); 959 uint32_t DestinationOffset = RDP->DestinationOffset; 960 assert(OldToNewOffset.count(DestinationOffset) && 961 "Destination Offset for reference not updated."); 962 uint32_t UpdatedOffset = OldToNewOffset[DestinationOffset]; 963 Offset = RDP->Offset; 964 OldValueSize = RDP->PatchInfo.OldValueSize; 965 if (RDP->PatchInfo.DirectRelative) { 966 UpdatedOffset -= DwarfUnitBaseOffset; 967 ByteSequence = encodeLE(OldValueSize, UpdatedOffset); 968 // In theory reference for DW_FORM_ref{1,2,4,8} can be right on the edge 969 // and overflow if later debug information grows. 970 if (ByteSequence.size() > OldValueSize) 971 errs() << "BOLT-ERROR: Relative reference of size " 972 << Twine::utohexstr(OldValueSize) 973 << " overflows with the new encoding.\n"; 974 } else if (RDP->PatchInfo.DirectAbsolute) { 975 ByteSequence = encodeLE(OldValueSize, UpdatedOffset); 976 } else if (RDP->PatchInfo.IndirectRelative) { 977 UpdatedOffset -= DwarfUnitBaseOffset; 978 ByteSequence.clear(); 979 raw_string_ostream OS(ByteSequence); 980 encodeULEB128(UpdatedOffset, OS, 4); 981 } else { 982 llvm_unreachable("Invalid Reference form."); 983 } 984 break; 985 } 986 case DebugPatchKind::PatchValue32: { 987 DebugPatch32 *P32 = reinterpret_cast<DebugPatch32 *>(P); 988 Offset = P32->Offset; 989 OldValueSize = 4; 990 ByteSequence = encodeLE(4, P32->Value); 991 break; 992 } 993 case DebugPatchKind::PatchValue64to32: { 994 DebugPatch64to32 *P64to32 = reinterpret_cast<DebugPatch64to32 *>(P); 995 Offset = P64to32->Offset; 996 OldValueSize = 8; 997 ByteSequence = encodeLE(4, P64to32->Value); 998 break; 999 } 1000 case DebugPatchKind::PatchValue32GenericSize: { 1001 DebugPatch32GenericSize *DPVS = 1002 reinterpret_cast<DebugPatch32GenericSize *>(P); 1003 Offset = DPVS->Offset; 1004 OldValueSize = DPVS->OldValueSize; 1005 ByteSequence = encodeLE(4, DPVS->Value); 1006 break; 1007 } 1008 case DebugPatchKind::PatchValueVariable: { 1009 DebugPatchVariableSize *PV = 1010 reinterpret_cast<DebugPatchVariableSize *>(P); 1011 Offset = PV->Offset; 1012 OldValueSize = PV->OldValueSize; 1013 ByteSequence.clear(); 1014 raw_string_ostream OS(ByteSequence); 1015 encodeULEB128(PV->Value, OS); 1016 break; 1017 } 1018 case DebugPatchKind::PatchValue64: { 1019 DebugPatch64 *P64 = reinterpret_cast<DebugPatch64 *>(P); 1020 Offset = P64->Offset; 1021 OldValueSize = 8; 1022 ByteSequence = encodeLE(8, P64->Value); 1023 break; 1024 } 1025 case DebugPatchKind::DWARFUnitOffsetBaseLabel: { 1026 DWARFUnitOffsetBaseLabel *BaseLabel = 1027 reinterpret_cast<DWARFUnitOffsetBaseLabel *>(P); 1028 Offset = BaseLabel->Offset; 1029 OldValueSize = 0; 1030 ByteSequence.clear(); 1031 auto &Patch = LengthPatches.back(); 1032 // Length to copy between last patch entry and next compile unit. 1033 uint32_t RemainingLength = Offset - StartOffset; 1034 uint32_t NewCUOffset = NewBinaryContents.size() + RemainingLength; 1035 DwarfUnitBaseOffset = NewCUOffset; 1036 // Length of previous CU = This CU Offset - sizeof(length) - last CU 1037 // Offset. 1038 Patch.second = NewCUOffset - 4 - Patch.first; 1039 LengthPatches.push_back({NewCUOffset, 0}); 1040 break; 1041 } 1042 case DebugPatchKind::NewDebugEntry: { 1043 NewDebugEntry *NDE = reinterpret_cast<NewDebugEntry *>(P); 1044 Offset = NDE->Offset; 1045 OldValueSize = 0; 1046 ByteSequence = NDE->Value; 1047 break; 1048 } 1049 } 1050 1051 assert((P->Kind == DebugPatchKind::NewDebugEntry || 1052 Offset + ByteSequence.size() <= BinaryContents.size()) && 1053 "Applied patch runs over binary size."); 1054 uint32_t Length = Offset - StartOffset; 1055 NewBinaryContents.append(BinaryContents.substr(StartOffset, Length).data(), 1056 Length); 1057 NewBinaryContents.append(ByteSequence.data(), ByteSequence.size()); 1058 StartOffset = Offset + OldValueSize; 1059 } 1060 uint32_t Length = BinaryContents.size() - StartOffset; 1061 NewBinaryContents.append(BinaryContents.substr(StartOffset, Length).data(), 1062 Length); 1063 DebugPatches.clear(); 1064 1065 // Patching lengths of CUs 1066 auto &Patch = LengthPatches.back(); 1067 Patch.second = NewBinaryContents.size() - 4 - Patch.first; 1068 for (uint32_t J = 1, Size = LengthPatches.size(); J < Size; ++J) { 1069 const auto &Patch = LengthPatches[J]; 1070 ByteSequence = encodeLE(4, Patch.second); 1071 Offset = Patch.first; 1072 for (uint64_t I = 0, Size = ByteSequence.size(); I < Size; ++I) 1073 NewBinaryContents[Offset + I] = ByteSequence[I]; 1074 } 1075 1076 return NewBinaryContents; 1077 } 1078 1079 void DebugStrOffsetsWriter::initialize( 1080 const DWARFSection &StrOffsetsSection, 1081 const Optional<StrOffsetsContributionDescriptor> Contr) { 1082 if (!Contr) 1083 return; 1084 1085 const uint8_t DwarfOffsetByteSize = Contr->getDwarfOffsetByteSize(); 1086 assert(DwarfOffsetByteSize == 4 && 1087 "Dwarf String Offsets Byte Size is not supported."); 1088 uint32_t Index = 0; 1089 for (uint64_t Offset = 0; Offset < Contr->Size; Offset += DwarfOffsetByteSize) 1090 IndexToAddressMap[Index++] = *reinterpret_cast<const uint32_t *>( 1091 StrOffsetsSection.Data.data() + Contr->Base + Offset); 1092 } 1093 1094 void DebugStrOffsetsWriter::updateAddressMap(uint32_t Index, uint32_t Address) { 1095 assert(IndexToAddressMap.count(Index) > 0 && "Index is not found."); 1096 IndexToAddressMap[Index] = Address; 1097 } 1098 1099 void DebugStrOffsetsWriter::finalizeSection() { 1100 if (IndexToAddressMap.empty()) 1101 return; 1102 // Writing out the header for each section. 1103 support::endian::write(*StrOffsetsStream, CurrentSectionSize + 4, 1104 support::little); 1105 support::endian::write(*StrOffsetsStream, static_cast<uint16_t>(5), 1106 support::little); 1107 support::endian::write(*StrOffsetsStream, static_cast<uint16_t>(0), 1108 support::little); 1109 for (const auto &Entry : IndexToAddressMap) 1110 support::endian::write(*StrOffsetsStream, Entry.second, support::little); 1111 IndexToAddressMap.clear(); 1112 } 1113 1114 void DebugStrWriter::create() { 1115 StrBuffer = std::make_unique<DebugStrBufferVector>(); 1116 StrStream = std::make_unique<raw_svector_ostream>(*StrBuffer); 1117 } 1118 1119 void DebugStrWriter::initialize() { 1120 auto StrSection = BC.DwCtx->getDWARFObj().getStrSection(); 1121 (*StrStream) << StrSection; 1122 } 1123 1124 uint32_t DebugStrWriter::addString(StringRef Str) { 1125 std::lock_guard<std::mutex> Lock(WriterMutex); 1126 if (StrBuffer->empty()) 1127 initialize(); 1128 auto Offset = StrBuffer->size(); 1129 (*StrStream) << Str; 1130 StrStream->write_zeros(1); 1131 return Offset; 1132 } 1133 1134 void DebugAbbrevWriter::addUnitAbbreviations(DWARFUnit &Unit) { 1135 const DWARFAbbreviationDeclarationSet *Abbrevs = Unit.getAbbreviations(); 1136 if (!Abbrevs) 1137 return; 1138 1139 const PatchesTy &UnitPatches = Patches[&Unit]; 1140 const AbbrevEntryTy &AbbrevEntries = NewAbbrevEntries[&Unit]; 1141 1142 // We are duplicating abbrev sections, to handle the case where for one CU we 1143 // modify it, but for another we don't. 1144 auto UnitDataPtr = std::make_unique<AbbrevData>(); 1145 AbbrevData &UnitData = *UnitDataPtr.get(); 1146 UnitData.Buffer = std::make_unique<DebugBufferVector>(); 1147 UnitData.Stream = std::make_unique<raw_svector_ostream>(*UnitData.Buffer); 1148 1149 raw_svector_ostream &OS = *UnitData.Stream.get(); 1150 1151 // Returns true if AbbrevData is re-used, false otherwise. 1152 auto hashAndAddAbbrev = [&](StringRef AbbrevData) -> bool { 1153 llvm::SHA1 Hasher; 1154 Hasher.update(AbbrevData); 1155 std::array<uint8_t, 20> Hash = Hasher.final(); 1156 StringRef Key((const char *)Hash.data(), Hash.size()); 1157 auto Iter = AbbrevDataCache.find(Key); 1158 if (Iter != AbbrevDataCache.end()) { 1159 UnitsAbbrevData[&Unit] = Iter->second.get(); 1160 return true; 1161 } 1162 AbbrevDataCache[Key] = std::move(UnitDataPtr); 1163 UnitsAbbrevData[&Unit] = &UnitData; 1164 return false; 1165 }; 1166 // Take a fast path if there are no patches to apply. Simply copy the original 1167 // contents. 1168 if (UnitPatches.empty() && AbbrevEntries.empty()) { 1169 StringRef AbbrevSectionContents = 1170 Unit.isDWOUnit() ? Unit.getContext().getDWARFObj().getAbbrevDWOSection() 1171 : Unit.getContext().getDWARFObj().getAbbrevSection(); 1172 StringRef AbbrevContents; 1173 1174 const DWARFUnitIndex &CUIndex = Unit.getContext().getCUIndex(); 1175 if (!CUIndex.getRows().empty()) { 1176 // Handle DWP section contribution. 1177 const DWARFUnitIndex::Entry *DWOEntry = 1178 CUIndex.getFromHash(*Unit.getDWOId()); 1179 if (!DWOEntry) 1180 return; 1181 1182 const DWARFUnitIndex::Entry::SectionContribution *DWOContrubution = 1183 DWOEntry->getContribution(DWARFSectionKind::DW_SECT_ABBREV); 1184 AbbrevContents = AbbrevSectionContents.substr(DWOContrubution->Offset, 1185 DWOContrubution->Length); 1186 } else if (!Unit.isDWOUnit()) { 1187 const uint64_t StartOffset = Unit.getAbbreviationsOffset(); 1188 1189 // We know where the unit's abbreviation set starts, but not where it ends 1190 // as such data is not readily available. Hence, we have to build a sorted 1191 // list of start addresses and find the next starting address to determine 1192 // the set boundaries. 1193 // 1194 // FIXME: if we had a full access to DWARFDebugAbbrev::AbbrDeclSets 1195 // we wouldn't have to build our own sorted list for the quick lookup. 1196 if (AbbrevSetOffsets.empty()) { 1197 for_each( 1198 *Unit.getContext().getDebugAbbrev(), 1199 [&](const std::pair<uint64_t, DWARFAbbreviationDeclarationSet> &P) { 1200 AbbrevSetOffsets.push_back(P.first); 1201 }); 1202 sort(AbbrevSetOffsets); 1203 } 1204 auto It = upper_bound(AbbrevSetOffsets, StartOffset); 1205 const uint64_t EndOffset = 1206 It == AbbrevSetOffsets.end() ? AbbrevSectionContents.size() : *It; 1207 AbbrevContents = AbbrevSectionContents.slice(StartOffset, EndOffset); 1208 } else { 1209 // For DWO unit outside of DWP, we expect the entire section to hold 1210 // abbreviations for this unit only. 1211 AbbrevContents = AbbrevSectionContents; 1212 } 1213 1214 if (!hashAndAddAbbrev(AbbrevContents)) { 1215 OS.reserveExtraSpace(AbbrevContents.size()); 1216 OS << AbbrevContents; 1217 } 1218 return; 1219 } 1220 1221 for (auto I = Abbrevs->begin(), E = Abbrevs->end(); I != E; ++I) { 1222 const DWARFAbbreviationDeclaration &Abbrev = *I; 1223 auto Patch = UnitPatches.find(&Abbrev); 1224 1225 encodeULEB128(Abbrev.getCode(), OS); 1226 encodeULEB128(Abbrev.getTag(), OS); 1227 encodeULEB128(Abbrev.hasChildren(), OS); 1228 for (const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec : 1229 Abbrev.attributes()) { 1230 if (Patch != UnitPatches.end()) { 1231 bool Patched = false; 1232 // Patches added later take a precedence over earlier ones. 1233 for (auto I = Patch->second.rbegin(), E = Patch->second.rend(); I != E; 1234 ++I) { 1235 if (I->OldAttr != AttrSpec.Attr) 1236 continue; 1237 1238 encodeULEB128(I->NewAttr, OS); 1239 encodeULEB128(I->NewAttrForm, OS); 1240 Patched = true; 1241 break; 1242 } 1243 if (Patched) 1244 continue; 1245 } 1246 1247 encodeULEB128(AttrSpec.Attr, OS); 1248 encodeULEB128(AttrSpec.Form, OS); 1249 if (AttrSpec.isImplicitConst()) 1250 encodeSLEB128(AttrSpec.getImplicitConstValue(), OS); 1251 } 1252 const auto Entries = AbbrevEntries.find(&Abbrev); 1253 // Adding new Abbrevs for inserted entries. 1254 if (Entries != AbbrevEntries.end()) { 1255 for (const AbbrevEntry &Entry : Entries->second) { 1256 encodeULEB128(Entry.Attr, OS); 1257 encodeULEB128(Entry.Form, OS); 1258 } 1259 } 1260 encodeULEB128(0, OS); 1261 encodeULEB128(0, OS); 1262 } 1263 encodeULEB128(0, OS); 1264 1265 hashAndAddAbbrev(OS.str()); 1266 } 1267 1268 std::unique_ptr<DebugBufferVector> DebugAbbrevWriter::finalize() { 1269 // Used to create determinism for writing out abbrevs. 1270 std::vector<AbbrevData *> Abbrevs; 1271 if (DWOId) { 1272 // We expect abbrev_offset to always be zero for DWO units as there 1273 // should be one CU per DWO, and TUs should share the same abbreviation 1274 // set with the CU. 1275 // For DWP AbbreviationsOffset is an Abbrev contribution in the DWP file, so 1276 // can be none zero. Thus we are skipping the check for DWP. 1277 bool IsDWP = !Context.getCUIndex().getRows().empty(); 1278 if (!IsDWP) { 1279 for (const std::unique_ptr<DWARFUnit> &Unit : Context.dwo_units()) { 1280 if (Unit->getAbbreviationsOffset() != 0) { 1281 errs() << "BOLT-ERROR: detected DWO unit with non-zero abbr_offset. " 1282 "Unable to update debug info.\n"; 1283 exit(1); 1284 } 1285 } 1286 } 1287 1288 DWARFUnit *Unit = Context.getDWOCompileUnitForHash(*DWOId); 1289 // Issue abbreviations for the DWO CU only. 1290 addUnitAbbreviations(*Unit); 1291 AbbrevData *Abbrev = UnitsAbbrevData[Unit]; 1292 Abbrevs.push_back(Abbrev); 1293 } else { 1294 Abbrevs.reserve(Context.getNumCompileUnits() + Context.getNumTypeUnits()); 1295 std::unordered_set<AbbrevData *> ProcessedAbbrevs; 1296 // Add abbreviations from compile and type non-DWO units. 1297 for (const std::unique_ptr<DWARFUnit> &Unit : Context.normal_units()) { 1298 addUnitAbbreviations(*Unit); 1299 AbbrevData *Abbrev = UnitsAbbrevData[Unit.get()]; 1300 if (!ProcessedAbbrevs.insert(Abbrev).second) 1301 continue; 1302 Abbrevs.push_back(Abbrev); 1303 } 1304 } 1305 1306 DebugBufferVector ReturnBuffer; 1307 // Pre-calculate the total size of abbrev section. 1308 uint64_t Size = 0; 1309 for (const AbbrevData *UnitData : Abbrevs) 1310 Size += UnitData->Buffer->size(); 1311 1312 ReturnBuffer.reserve(Size); 1313 1314 uint64_t Pos = 0; 1315 for (AbbrevData *UnitData : Abbrevs) { 1316 ReturnBuffer.append(*UnitData->Buffer); 1317 UnitData->Offset = Pos; 1318 Pos += UnitData->Buffer->size(); 1319 1320 UnitData->Buffer.reset(); 1321 UnitData->Stream.reset(); 1322 } 1323 1324 return std::make_unique<DebugBufferVector>(ReturnBuffer); 1325 } 1326 1327 static void emitDwarfSetLineAddrAbs(MCStreamer &OS, 1328 MCDwarfLineTableParams Params, 1329 int64_t LineDelta, uint64_t Address, 1330 int PointerSize) { 1331 // emit the sequence to set the address 1332 OS.emitIntValue(dwarf::DW_LNS_extended_op, 1); 1333 OS.emitULEB128IntValue(PointerSize + 1); 1334 OS.emitIntValue(dwarf::DW_LNE_set_address, 1); 1335 OS.emitIntValue(Address, PointerSize); 1336 1337 // emit the sequence for the LineDelta (from 1) and a zero address delta. 1338 MCDwarfLineAddr::Emit(&OS, Params, LineDelta, 0); 1339 } 1340 1341 static inline void emitBinaryDwarfLineTable( 1342 MCStreamer *MCOS, MCDwarfLineTableParams Params, 1343 const DWARFDebugLine::LineTable *Table, 1344 const std::vector<DwarfLineTable::RowSequence> &InputSequences) { 1345 if (InputSequences.empty()) 1346 return; 1347 1348 constexpr uint64_t InvalidAddress = UINT64_MAX; 1349 unsigned FileNum = 1; 1350 unsigned LastLine = 1; 1351 unsigned Column = 0; 1352 unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 1353 unsigned Isa = 0; 1354 unsigned Discriminator = 0; 1355 uint64_t LastAddress = InvalidAddress; 1356 uint64_t PrevEndOfSequence = InvalidAddress; 1357 const MCAsmInfo *AsmInfo = MCOS->getContext().getAsmInfo(); 1358 1359 auto emitEndOfSequence = [&](uint64_t Address) { 1360 MCDwarfLineAddr::Emit(MCOS, Params, INT64_MAX, Address - LastAddress); 1361 FileNum = 1; 1362 LastLine = 1; 1363 Column = 0; 1364 Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 1365 Isa = 0; 1366 Discriminator = 0; 1367 LastAddress = InvalidAddress; 1368 }; 1369 1370 for (const DwarfLineTable::RowSequence &Sequence : InputSequences) { 1371 const uint64_t SequenceStart = 1372 Table->Rows[Sequence.FirstIndex].Address.Address; 1373 1374 // Check if we need to mark the end of the sequence. 1375 if (PrevEndOfSequence != InvalidAddress && LastAddress != InvalidAddress && 1376 PrevEndOfSequence != SequenceStart) { 1377 emitEndOfSequence(PrevEndOfSequence); 1378 } 1379 1380 for (uint32_t RowIndex = Sequence.FirstIndex; 1381 RowIndex <= Sequence.LastIndex; ++RowIndex) { 1382 const DWARFDebugLine::Row &Row = Table->Rows[RowIndex]; 1383 int64_t LineDelta = static_cast<int64_t>(Row.Line) - LastLine; 1384 const uint64_t Address = Row.Address.Address; 1385 1386 if (FileNum != Row.File) { 1387 FileNum = Row.File; 1388 MCOS->emitInt8(dwarf::DW_LNS_set_file); 1389 MCOS->emitULEB128IntValue(FileNum); 1390 } 1391 if (Column != Row.Column) { 1392 Column = Row.Column; 1393 MCOS->emitInt8(dwarf::DW_LNS_set_column); 1394 MCOS->emitULEB128IntValue(Column); 1395 } 1396 if (Discriminator != Row.Discriminator && 1397 MCOS->getContext().getDwarfVersion() >= 4) { 1398 Discriminator = Row.Discriminator; 1399 unsigned Size = getULEB128Size(Discriminator); 1400 MCOS->emitInt8(dwarf::DW_LNS_extended_op); 1401 MCOS->emitULEB128IntValue(Size + 1); 1402 MCOS->emitInt8(dwarf::DW_LNE_set_discriminator); 1403 MCOS->emitULEB128IntValue(Discriminator); 1404 } 1405 if (Isa != Row.Isa) { 1406 Isa = Row.Isa; 1407 MCOS->emitInt8(dwarf::DW_LNS_set_isa); 1408 MCOS->emitULEB128IntValue(Isa); 1409 } 1410 if (Row.IsStmt != Flags) { 1411 Flags = Row.IsStmt; 1412 MCOS->emitInt8(dwarf::DW_LNS_negate_stmt); 1413 } 1414 if (Row.BasicBlock) 1415 MCOS->emitInt8(dwarf::DW_LNS_set_basic_block); 1416 if (Row.PrologueEnd) 1417 MCOS->emitInt8(dwarf::DW_LNS_set_prologue_end); 1418 if (Row.EpilogueBegin) 1419 MCOS->emitInt8(dwarf::DW_LNS_set_epilogue_begin); 1420 1421 // The end of the sequence is not normal in the middle of the input 1422 // sequence, but could happen, e.g. for assembly code. 1423 if (Row.EndSequence) { 1424 emitEndOfSequence(Address); 1425 } else { 1426 if (LastAddress == InvalidAddress) 1427 emitDwarfSetLineAddrAbs(*MCOS, Params, LineDelta, Address, 1428 AsmInfo->getCodePointerSize()); 1429 else 1430 MCDwarfLineAddr::Emit(MCOS, Params, LineDelta, Address - LastAddress); 1431 1432 LastAddress = Address; 1433 LastLine = Row.Line; 1434 } 1435 1436 Discriminator = 0; 1437 } 1438 PrevEndOfSequence = Sequence.EndAddress; 1439 } 1440 1441 // Finish with the end of the sequence. 1442 if (LastAddress != InvalidAddress) 1443 emitEndOfSequence(PrevEndOfSequence); 1444 } 1445 1446 // This function is similar to the one from MCDwarfLineTable, except it handles 1447 // end-of-sequence entries differently by utilizing line entries with 1448 // DWARF2_FLAG_END_SEQUENCE flag. 1449 static inline void emitDwarfLineTable( 1450 MCStreamer *MCOS, MCSection *Section, 1451 const MCLineSection::MCDwarfLineEntryCollection &LineEntries) { 1452 unsigned FileNum = 1; 1453 unsigned LastLine = 1; 1454 unsigned Column = 0; 1455 unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 1456 unsigned Isa = 0; 1457 unsigned Discriminator = 0; 1458 MCSymbol *LastLabel = nullptr; 1459 const MCAsmInfo *AsmInfo = MCOS->getContext().getAsmInfo(); 1460 1461 // Loop through each MCDwarfLineEntry and encode the dwarf line number table. 1462 for (const MCDwarfLineEntry &LineEntry : LineEntries) { 1463 if (LineEntry.getFlags() & DWARF2_FLAG_END_SEQUENCE) { 1464 MCOS->emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, LineEntry.getLabel(), 1465 AsmInfo->getCodePointerSize()); 1466 FileNum = 1; 1467 LastLine = 1; 1468 Column = 0; 1469 Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 1470 Isa = 0; 1471 Discriminator = 0; 1472 LastLabel = nullptr; 1473 continue; 1474 } 1475 1476 int64_t LineDelta = static_cast<int64_t>(LineEntry.getLine()) - LastLine; 1477 1478 if (FileNum != LineEntry.getFileNum()) { 1479 FileNum = LineEntry.getFileNum(); 1480 MCOS->emitInt8(dwarf::DW_LNS_set_file); 1481 MCOS->emitULEB128IntValue(FileNum); 1482 } 1483 if (Column != LineEntry.getColumn()) { 1484 Column = LineEntry.getColumn(); 1485 MCOS->emitInt8(dwarf::DW_LNS_set_column); 1486 MCOS->emitULEB128IntValue(Column); 1487 } 1488 if (Discriminator != LineEntry.getDiscriminator() && 1489 MCOS->getContext().getDwarfVersion() >= 2) { 1490 Discriminator = LineEntry.getDiscriminator(); 1491 unsigned Size = getULEB128Size(Discriminator); 1492 MCOS->emitInt8(dwarf::DW_LNS_extended_op); 1493 MCOS->emitULEB128IntValue(Size + 1); 1494 MCOS->emitInt8(dwarf::DW_LNE_set_discriminator); 1495 MCOS->emitULEB128IntValue(Discriminator); 1496 } 1497 if (Isa != LineEntry.getIsa()) { 1498 Isa = LineEntry.getIsa(); 1499 MCOS->emitInt8(dwarf::DW_LNS_set_isa); 1500 MCOS->emitULEB128IntValue(Isa); 1501 } 1502 if ((LineEntry.getFlags() ^ Flags) & DWARF2_FLAG_IS_STMT) { 1503 Flags = LineEntry.getFlags(); 1504 MCOS->emitInt8(dwarf::DW_LNS_negate_stmt); 1505 } 1506 if (LineEntry.getFlags() & DWARF2_FLAG_BASIC_BLOCK) 1507 MCOS->emitInt8(dwarf::DW_LNS_set_basic_block); 1508 if (LineEntry.getFlags() & DWARF2_FLAG_PROLOGUE_END) 1509 MCOS->emitInt8(dwarf::DW_LNS_set_prologue_end); 1510 if (LineEntry.getFlags() & DWARF2_FLAG_EPILOGUE_BEGIN) 1511 MCOS->emitInt8(dwarf::DW_LNS_set_epilogue_begin); 1512 1513 MCSymbol *Label = LineEntry.getLabel(); 1514 1515 // At this point we want to emit/create the sequence to encode the delta 1516 // in line numbers and the increment of the address from the previous 1517 // Label and the current Label. 1518 MCOS->emitDwarfAdvanceLineAddr(LineDelta, LastLabel, Label, 1519 AsmInfo->getCodePointerSize()); 1520 Discriminator = 0; 1521 LastLine = LineEntry.getLine(); 1522 LastLabel = Label; 1523 } 1524 1525 assert(LastLabel == nullptr && "end of sequence expected"); 1526 } 1527 1528 void DwarfLineTable::emitCU(MCStreamer *MCOS, MCDwarfLineTableParams Params, 1529 Optional<MCDwarfLineStr> &LineStr, 1530 BinaryContext &BC) const { 1531 if (!RawData.empty()) { 1532 assert(MCLineSections.getMCLineEntries().empty() && 1533 InputSequences.empty() && 1534 "cannot combine raw data with new line entries"); 1535 MCOS->emitLabel(getLabel()); 1536 MCOS->emitBytes(RawData); 1537 1538 // Emit fake relocation for RuntimeDyld to always allocate the section. 1539 // 1540 // FIXME: remove this once RuntimeDyld stops skipping allocatable sections 1541 // without relocations. 1542 MCOS->emitRelocDirective( 1543 *MCConstantExpr::create(0, *BC.Ctx), "BFD_RELOC_NONE", 1544 MCSymbolRefExpr::create(getLabel(), *BC.Ctx), SMLoc(), *BC.STI); 1545 1546 return; 1547 } 1548 1549 MCSymbol *LineEndSym = Header.Emit(MCOS, Params, LineStr).second; 1550 1551 // Put out the line tables. 1552 for (const auto &LineSec : MCLineSections.getMCLineEntries()) 1553 emitDwarfLineTable(MCOS, LineSec.first, LineSec.second); 1554 1555 // Emit line tables for the original code. 1556 emitBinaryDwarfLineTable(MCOS, Params, InputTable, InputSequences); 1557 1558 // This is the end of the section, so set the value of the symbol at the end 1559 // of this section (that was used in a previous expression). 1560 MCOS->emitLabel(LineEndSym); 1561 } 1562 1563 // Helper function to parse .debug_line_str, and populate one we are using. 1564 // For functions that we do not modify we output them as raw data. 1565 // Re-constructing .debug_line_str so that offsets are correct for those 1566 // debut line tables. 1567 // Bonus is that when we output a final binary we can re-use .debug_line_str 1568 // section. So we don't have to do the SHF_ALLOC trick we did with 1569 // .debug_line. 1570 static void parseAndPopulateDebugLineStr(BinarySection &LineStrSection, 1571 MCDwarfLineStr &LineStr, 1572 BinaryContext &BC, 1573 MCStreamer &Streamer) { 1574 DataExtractor StrData(LineStrSection.getContents(), 1575 BC.DwCtx->isLittleEndian(), 0); 1576 uint64_t Offset = 0; 1577 while (StrData.isValidOffset(Offset)) { 1578 Error Err = Error::success(); 1579 const char *CStr = StrData.getCStr(&Offset, &Err); 1580 if (Err) { 1581 errs() << "BOLT-ERROR: could not extract string from .debug_line_str"; 1582 continue; 1583 } 1584 LineStr.emitRef(&Streamer, CStr); 1585 } 1586 } 1587 1588 void DwarfLineTable::emit(BinaryContext &BC, MCStreamer &Streamer) { 1589 MCAssembler &Assembler = 1590 static_cast<MCObjectStreamer *>(&Streamer)->getAssembler(); 1591 1592 MCDwarfLineTableParams Params = Assembler.getDWARFLinetableParams(); 1593 1594 auto &LineTables = BC.getDwarfLineTables(); 1595 1596 // Bail out early so we don't switch to the debug_line section needlessly and 1597 // in doing so create an unnecessary (if empty) section. 1598 if (LineTables.empty()) 1599 return; 1600 // In a v5 non-split line table, put the strings in a separate section. 1601 Optional<MCDwarfLineStr> LineStr(None); 1602 ErrorOr<BinarySection &> LineStrSection = 1603 BC.getUniqueSectionByName(".debug_line_str"); 1604 // Some versions of GCC output DWARF5 .debug_info, but DWARF4 or lower 1605 // .debug_line 1606 if (LineStrSection) { 1607 LineStr = MCDwarfLineStr(*BC.Ctx); 1608 parseAndPopulateDebugLineStr(*LineStrSection, *LineStr, BC, Streamer); 1609 } 1610 1611 // Switch to the section where the table will be emitted into. 1612 Streamer.SwitchSection(BC.MOFI->getDwarfLineSection()); 1613 1614 const uint16_t DwarfVersion = BC.Ctx->getDwarfVersion(); 1615 // Handle the rest of the Compile Units. 1616 for (auto &CUIDTablePair : LineTables) { 1617 Streamer.getContext().setDwarfVersion( 1618 CUIDTablePair.second.getDwarfVersion()); 1619 CUIDTablePair.second.emitCU(&Streamer, Params, LineStr, BC); 1620 } 1621 1622 // Resetting DWARF version for rest of the flow. 1623 BC.Ctx->setDwarfVersion(DwarfVersion); 1624 1625 // Still need to write the section out for the ExecutionEngine, and temp in 1626 // memory object we are constructing. 1627 if (LineStr) { 1628 LineStr->emitSection(&Streamer); 1629 SmallString<0> Data = LineStr->getFinalizedData(); 1630 BC.registerOrUpdateNoteSection(".debug_line_str", copyByteArray(Data.str()), 1631 Data.size()); 1632 } 1633 } 1634 1635 } // namespace bolt 1636 } // namespace llvm 1637