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 llvm::sort(SortedMap, 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 llvm::sort(SortedMap, 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 llvm::sort(SortedMap, 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 llvm::sort(DebugPatches, [](const UniquePatchPtrType &V1, 845 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())->CurrentOrder < 850 reinterpret_cast<const NewDebugEntry *>(V2.get())->CurrentOrder; 851 852 // This is a case where we are modifying first entry of next 853 // DIE, and adding a new one. 854 return V1->Kind == DebugPatchKind::NewDebugEntry; 855 } 856 return V1.get()->Offset < V2.get()->Offset; 857 }); 858 859 DWARFUnitVector::compile_unit_range CompileUnits = 860 IsDWOContext ? DWCtx.dwo_compile_units() : DWCtx.compile_units(); 861 862 for (const std::unique_ptr<DWARFUnit> &CU : CompileUnits) 863 CUMap[CU->getOffset()] = {static_cast<uint32_t>(CU->getOffset()), 864 static_cast<uint32_t>(CU->getLength())}; 865 866 // Calculating changes in .debug_info size from Patches to build a map of old 867 // to updated reference destination offsets. 868 uint32_t PreviousOffset = 0; 869 int32_t PreviousChangeInSize = 0; 870 for (UniquePatchPtrType &PatchBase : DebugPatches) { 871 Patch *P = PatchBase.get(); 872 switch (P->Kind) { 873 default: 874 continue; 875 case DebugPatchKind::PatchValue64to32: { 876 PreviousChangeInSize -= 4; 877 break; 878 } 879 case DebugPatchKind::PatchValue32GenericSize: { 880 DebugPatch32GenericSize *DPVS = 881 reinterpret_cast<DebugPatch32GenericSize *>(P); 882 PreviousChangeInSize += 4 - DPVS->OldValueSize; 883 break; 884 } 885 case DebugPatchKind::PatchValueVariable: { 886 DebugPatchVariableSize *DPV = 887 reinterpret_cast<DebugPatchVariableSize *>(P); 888 std::string Temp; 889 raw_string_ostream OS(Temp); 890 encodeULEB128(DPV->Value, OS); 891 PreviousChangeInSize += Temp.size() - DPV->OldValueSize; 892 break; 893 } 894 case DebugPatchKind::DestinationReferenceLabel: { 895 DestinationReferenceLabel *DRL = 896 reinterpret_cast<DestinationReferenceLabel *>(P); 897 OldToNewOffset[DRL->Offset] = 898 DRL->Offset + ChangeInSize + PreviousChangeInSize; 899 break; 900 } 901 case DebugPatchKind::ReferencePatchValue: { 902 // This doesn't look to be a common case, so will always encode as 4 bytes 903 // to reduce algorithmic complexity. 904 DebugPatchReference *RDP = reinterpret_cast<DebugPatchReference *>(P); 905 if (RDP->PatchInfo.IndirectRelative) { 906 PreviousChangeInSize += 4 - RDP->PatchInfo.OldValueSize; 907 assert(RDP->PatchInfo.OldValueSize <= 4 && 908 "Variable encoding reference greater than 4 bytes."); 909 } 910 break; 911 } 912 case DebugPatchKind::DWARFUnitOffsetBaseLabel: { 913 DWARFUnitOffsetBaseLabel *BaseLabel = 914 reinterpret_cast<DWARFUnitOffsetBaseLabel *>(P); 915 uint32_t CUOffset = BaseLabel->Offset; 916 ChangeInSize += PreviousChangeInSize; 917 uint32_t CUOffsetUpdate = CUOffset + ChangeInSize; 918 CUMap[CUOffset].Offset = CUOffsetUpdate; 919 CUMap[PreviousOffset].Length += PreviousChangeInSize; 920 PreviousChangeInSize = 0; 921 PreviousOffset = CUOffset; 922 break; 923 } 924 case DebugPatchKind::NewDebugEntry: { 925 NewDebugEntry *NDE = reinterpret_cast<NewDebugEntry *>(P); 926 PreviousChangeInSize += NDE->Value.size(); 927 break; 928 } 929 } 930 } 931 CUMap[PreviousOffset].Length += PreviousChangeInSize; 932 return CUMap; 933 } 934 uint32_t DebugInfoBinaryPatcher::NewDebugEntry::OrderCounter = 0; 935 936 std::string DebugInfoBinaryPatcher::patchBinary(StringRef BinaryContents) { 937 std::string NewBinaryContents; 938 NewBinaryContents.reserve(BinaryContents.size() + ChangeInSize); 939 uint32_t StartOffset = 0; 940 uint32_t DwarfUnitBaseOffset = 0; 941 uint32_t OldValueSize = 0; 942 uint32_t Offset = 0; 943 std::string ByteSequence; 944 std::vector<std::pair<uint32_t, uint32_t>> LengthPatches; 945 // Wasting one entry to avoid checks for first. 946 LengthPatches.push_back({0, 0}); 947 948 // Applying all the patches replacing current entry. 949 // This might change the size of .debug_info section. 950 for (const UniquePatchPtrType &PatchBase : DebugPatches) { 951 Patch *P = PatchBase.get(); 952 switch (P->Kind) { 953 default: 954 continue; 955 case DebugPatchKind::ReferencePatchValue: { 956 DebugPatchReference *RDP = reinterpret_cast<DebugPatchReference *>(P); 957 uint32_t DestinationOffset = RDP->DestinationOffset; 958 assert(OldToNewOffset.count(DestinationOffset) && 959 "Destination Offset for reference not updated."); 960 uint32_t UpdatedOffset = OldToNewOffset[DestinationOffset]; 961 Offset = RDP->Offset; 962 OldValueSize = RDP->PatchInfo.OldValueSize; 963 if (RDP->PatchInfo.DirectRelative) { 964 UpdatedOffset -= DwarfUnitBaseOffset; 965 ByteSequence = encodeLE(OldValueSize, UpdatedOffset); 966 // In theory reference for DW_FORM_ref{1,2,4,8} can be right on the edge 967 // and overflow if later debug information grows. 968 if (ByteSequence.size() > OldValueSize) 969 errs() << "BOLT-ERROR: Relative reference of size " 970 << Twine::utohexstr(OldValueSize) 971 << " overflows with the new encoding.\n"; 972 } else if (RDP->PatchInfo.DirectAbsolute) { 973 ByteSequence = encodeLE(OldValueSize, UpdatedOffset); 974 } else if (RDP->PatchInfo.IndirectRelative) { 975 UpdatedOffset -= DwarfUnitBaseOffset; 976 ByteSequence.clear(); 977 raw_string_ostream OS(ByteSequence); 978 encodeULEB128(UpdatedOffset, OS, 4); 979 } else { 980 llvm_unreachable("Invalid Reference form."); 981 } 982 break; 983 } 984 case DebugPatchKind::PatchValue32: { 985 DebugPatch32 *P32 = reinterpret_cast<DebugPatch32 *>(P); 986 Offset = P32->Offset; 987 OldValueSize = 4; 988 ByteSequence = encodeLE(4, P32->Value); 989 break; 990 } 991 case DebugPatchKind::PatchValue64to32: { 992 DebugPatch64to32 *P64to32 = reinterpret_cast<DebugPatch64to32 *>(P); 993 Offset = P64to32->Offset; 994 OldValueSize = 8; 995 ByteSequence = encodeLE(4, P64to32->Value); 996 break; 997 } 998 case DebugPatchKind::PatchValue32GenericSize: { 999 DebugPatch32GenericSize *DPVS = 1000 reinterpret_cast<DebugPatch32GenericSize *>(P); 1001 Offset = DPVS->Offset; 1002 OldValueSize = DPVS->OldValueSize; 1003 ByteSequence = encodeLE(4, DPVS->Value); 1004 break; 1005 } 1006 case DebugPatchKind::PatchValueVariable: { 1007 DebugPatchVariableSize *PV = 1008 reinterpret_cast<DebugPatchVariableSize *>(P); 1009 Offset = PV->Offset; 1010 OldValueSize = PV->OldValueSize; 1011 ByteSequence.clear(); 1012 raw_string_ostream OS(ByteSequence); 1013 encodeULEB128(PV->Value, OS); 1014 break; 1015 } 1016 case DebugPatchKind::PatchValue64: { 1017 DebugPatch64 *P64 = reinterpret_cast<DebugPatch64 *>(P); 1018 Offset = P64->Offset; 1019 OldValueSize = 8; 1020 ByteSequence = encodeLE(8, P64->Value); 1021 break; 1022 } 1023 case DebugPatchKind::DWARFUnitOffsetBaseLabel: { 1024 DWARFUnitOffsetBaseLabel *BaseLabel = 1025 reinterpret_cast<DWARFUnitOffsetBaseLabel *>(P); 1026 Offset = BaseLabel->Offset; 1027 OldValueSize = 0; 1028 ByteSequence.clear(); 1029 auto &Patch = LengthPatches.back(); 1030 // Length to copy between last patch entry and next compile unit. 1031 uint32_t RemainingLength = Offset - StartOffset; 1032 uint32_t NewCUOffset = NewBinaryContents.size() + RemainingLength; 1033 DwarfUnitBaseOffset = NewCUOffset; 1034 // Length of previous CU = This CU Offset - sizeof(length) - last CU 1035 // Offset. 1036 Patch.second = NewCUOffset - 4 - Patch.first; 1037 LengthPatches.push_back({NewCUOffset, 0}); 1038 break; 1039 } 1040 case DebugPatchKind::NewDebugEntry: { 1041 NewDebugEntry *NDE = reinterpret_cast<NewDebugEntry *>(P); 1042 Offset = NDE->Offset; 1043 OldValueSize = 0; 1044 ByteSequence = NDE->Value; 1045 break; 1046 } 1047 } 1048 1049 assert((P->Kind == DebugPatchKind::NewDebugEntry || 1050 Offset + ByteSequence.size() <= BinaryContents.size()) && 1051 "Applied patch runs over binary size."); 1052 uint32_t Length = Offset - StartOffset; 1053 NewBinaryContents.append(BinaryContents.substr(StartOffset, Length).data(), 1054 Length); 1055 NewBinaryContents.append(ByteSequence.data(), ByteSequence.size()); 1056 StartOffset = Offset + OldValueSize; 1057 } 1058 uint32_t Length = BinaryContents.size() - StartOffset; 1059 NewBinaryContents.append(BinaryContents.substr(StartOffset, Length).data(), 1060 Length); 1061 DebugPatches.clear(); 1062 1063 // Patching lengths of CUs 1064 auto &Patch = LengthPatches.back(); 1065 Patch.second = NewBinaryContents.size() - 4 - Patch.first; 1066 for (uint32_t J = 1, Size = LengthPatches.size(); J < Size; ++J) { 1067 const auto &Patch = LengthPatches[J]; 1068 ByteSequence = encodeLE(4, Patch.second); 1069 Offset = Patch.first; 1070 for (uint64_t I = 0, Size = ByteSequence.size(); I < Size; ++I) 1071 NewBinaryContents[Offset + I] = ByteSequence[I]; 1072 } 1073 1074 return NewBinaryContents; 1075 } 1076 1077 void DebugStrOffsetsWriter::initialize( 1078 const DWARFSection &StrOffsetsSection, 1079 const Optional<StrOffsetsContributionDescriptor> Contr) { 1080 if (!Contr) 1081 return; 1082 1083 const uint8_t DwarfOffsetByteSize = Contr->getDwarfOffsetByteSize(); 1084 assert(DwarfOffsetByteSize == 4 && 1085 "Dwarf String Offsets Byte Size is not supported."); 1086 uint32_t Index = 0; 1087 for (uint64_t Offset = 0; Offset < Contr->Size; Offset += DwarfOffsetByteSize) 1088 IndexToAddressMap[Index++] = *reinterpret_cast<const uint32_t *>( 1089 StrOffsetsSection.Data.data() + Contr->Base + Offset); 1090 } 1091 1092 void DebugStrOffsetsWriter::updateAddressMap(uint32_t Index, uint32_t Address) { 1093 assert(IndexToAddressMap.count(Index) > 0 && "Index is not found."); 1094 IndexToAddressMap[Index] = Address; 1095 } 1096 1097 void DebugStrOffsetsWriter::finalizeSection() { 1098 if (IndexToAddressMap.empty()) 1099 return; 1100 // Writing out the header for each section. 1101 support::endian::write(*StrOffsetsStream, CurrentSectionSize + 4, 1102 support::little); 1103 support::endian::write(*StrOffsetsStream, static_cast<uint16_t>(5), 1104 support::little); 1105 support::endian::write(*StrOffsetsStream, static_cast<uint16_t>(0), 1106 support::little); 1107 for (const auto &Entry : IndexToAddressMap) 1108 support::endian::write(*StrOffsetsStream, Entry.second, support::little); 1109 IndexToAddressMap.clear(); 1110 } 1111 1112 void DebugStrWriter::create() { 1113 StrBuffer = std::make_unique<DebugStrBufferVector>(); 1114 StrStream = std::make_unique<raw_svector_ostream>(*StrBuffer); 1115 } 1116 1117 void DebugStrWriter::initialize() { 1118 auto StrSection = BC.DwCtx->getDWARFObj().getStrSection(); 1119 (*StrStream) << StrSection; 1120 } 1121 1122 uint32_t DebugStrWriter::addString(StringRef Str) { 1123 std::lock_guard<std::mutex> Lock(WriterMutex); 1124 if (StrBuffer->empty()) 1125 initialize(); 1126 auto Offset = StrBuffer->size(); 1127 (*StrStream) << Str; 1128 StrStream->write_zeros(1); 1129 return Offset; 1130 } 1131 1132 void DebugAbbrevWriter::addUnitAbbreviations(DWARFUnit &Unit) { 1133 const DWARFAbbreviationDeclarationSet *Abbrevs = Unit.getAbbreviations(); 1134 if (!Abbrevs) 1135 return; 1136 1137 const PatchesTy &UnitPatches = Patches[&Unit]; 1138 const AbbrevEntryTy &AbbrevEntries = NewAbbrevEntries[&Unit]; 1139 1140 // We are duplicating abbrev sections, to handle the case where for one CU we 1141 // modify it, but for another we don't. 1142 auto UnitDataPtr = std::make_unique<AbbrevData>(); 1143 AbbrevData &UnitData = *UnitDataPtr.get(); 1144 UnitData.Buffer = std::make_unique<DebugBufferVector>(); 1145 UnitData.Stream = std::make_unique<raw_svector_ostream>(*UnitData.Buffer); 1146 1147 raw_svector_ostream &OS = *UnitData.Stream.get(); 1148 1149 // Returns true if AbbrevData is re-used, false otherwise. 1150 auto hashAndAddAbbrev = [&](StringRef AbbrevData) -> bool { 1151 llvm::SHA1 Hasher; 1152 Hasher.update(AbbrevData); 1153 std::array<uint8_t, 20> Hash = Hasher.final(); 1154 StringRef Key((const char *)Hash.data(), Hash.size()); 1155 auto Iter = AbbrevDataCache.find(Key); 1156 if (Iter != AbbrevDataCache.end()) { 1157 UnitsAbbrevData[&Unit] = Iter->second.get(); 1158 return true; 1159 } 1160 AbbrevDataCache[Key] = std::move(UnitDataPtr); 1161 UnitsAbbrevData[&Unit] = &UnitData; 1162 return false; 1163 }; 1164 // Take a fast path if there are no patches to apply. Simply copy the original 1165 // contents. 1166 if (UnitPatches.empty() && AbbrevEntries.empty()) { 1167 StringRef AbbrevSectionContents = 1168 Unit.isDWOUnit() ? Unit.getContext().getDWARFObj().getAbbrevDWOSection() 1169 : Unit.getContext().getDWARFObj().getAbbrevSection(); 1170 StringRef AbbrevContents; 1171 1172 const DWARFUnitIndex &CUIndex = Unit.getContext().getCUIndex(); 1173 if (!CUIndex.getRows().empty()) { 1174 // Handle DWP section contribution. 1175 const DWARFUnitIndex::Entry *DWOEntry = 1176 CUIndex.getFromHash(*Unit.getDWOId()); 1177 if (!DWOEntry) 1178 return; 1179 1180 const DWARFUnitIndex::Entry::SectionContribution *DWOContrubution = 1181 DWOEntry->getContribution(DWARFSectionKind::DW_SECT_ABBREV); 1182 AbbrevContents = AbbrevSectionContents.substr(DWOContrubution->Offset, 1183 DWOContrubution->Length); 1184 } else if (!Unit.isDWOUnit()) { 1185 const uint64_t StartOffset = Unit.getAbbreviationsOffset(); 1186 1187 // We know where the unit's abbreviation set starts, but not where it ends 1188 // as such data is not readily available. Hence, we have to build a sorted 1189 // list of start addresses and find the next starting address to determine 1190 // the set boundaries. 1191 // 1192 // FIXME: if we had a full access to DWARFDebugAbbrev::AbbrDeclSets 1193 // we wouldn't have to build our own sorted list for the quick lookup. 1194 if (AbbrevSetOffsets.empty()) { 1195 for_each( 1196 *Unit.getContext().getDebugAbbrev(), 1197 [&](const std::pair<uint64_t, DWARFAbbreviationDeclarationSet> &P) { 1198 AbbrevSetOffsets.push_back(P.first); 1199 }); 1200 sort(AbbrevSetOffsets); 1201 } 1202 auto It = upper_bound(AbbrevSetOffsets, StartOffset); 1203 const uint64_t EndOffset = 1204 It == AbbrevSetOffsets.end() ? AbbrevSectionContents.size() : *It; 1205 AbbrevContents = AbbrevSectionContents.slice(StartOffset, EndOffset); 1206 } else { 1207 // For DWO unit outside of DWP, we expect the entire section to hold 1208 // abbreviations for this unit only. 1209 AbbrevContents = AbbrevSectionContents; 1210 } 1211 1212 if (!hashAndAddAbbrev(AbbrevContents)) { 1213 OS.reserveExtraSpace(AbbrevContents.size()); 1214 OS << AbbrevContents; 1215 } 1216 return; 1217 } 1218 1219 for (auto I = Abbrevs->begin(), E = Abbrevs->end(); I != E; ++I) { 1220 const DWARFAbbreviationDeclaration &Abbrev = *I; 1221 auto Patch = UnitPatches.find(&Abbrev); 1222 1223 encodeULEB128(Abbrev.getCode(), OS); 1224 encodeULEB128(Abbrev.getTag(), OS); 1225 encodeULEB128(Abbrev.hasChildren(), OS); 1226 for (const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec : 1227 Abbrev.attributes()) { 1228 if (Patch != UnitPatches.end()) { 1229 bool Patched = false; 1230 // Patches added later take a precedence over earlier ones. 1231 for (auto I = Patch->second.rbegin(), E = Patch->second.rend(); I != E; 1232 ++I) { 1233 if (I->OldAttr != AttrSpec.Attr) 1234 continue; 1235 1236 encodeULEB128(I->NewAttr, OS); 1237 encodeULEB128(I->NewAttrForm, OS); 1238 Patched = true; 1239 break; 1240 } 1241 if (Patched) 1242 continue; 1243 } 1244 1245 encodeULEB128(AttrSpec.Attr, OS); 1246 encodeULEB128(AttrSpec.Form, OS); 1247 if (AttrSpec.isImplicitConst()) 1248 encodeSLEB128(AttrSpec.getImplicitConstValue(), OS); 1249 } 1250 const auto Entries = AbbrevEntries.find(&Abbrev); 1251 // Adding new Abbrevs for inserted entries. 1252 if (Entries != AbbrevEntries.end()) { 1253 for (const AbbrevEntry &Entry : Entries->second) { 1254 encodeULEB128(Entry.Attr, OS); 1255 encodeULEB128(Entry.Form, OS); 1256 } 1257 } 1258 encodeULEB128(0, OS); 1259 encodeULEB128(0, OS); 1260 } 1261 encodeULEB128(0, OS); 1262 1263 hashAndAddAbbrev(OS.str()); 1264 } 1265 1266 std::unique_ptr<DebugBufferVector> DebugAbbrevWriter::finalize() { 1267 // Used to create determinism for writing out abbrevs. 1268 std::vector<AbbrevData *> Abbrevs; 1269 if (DWOId) { 1270 // We expect abbrev_offset to always be zero for DWO units as there 1271 // should be one CU per DWO, and TUs should share the same abbreviation 1272 // set with the CU. 1273 // For DWP AbbreviationsOffset is an Abbrev contribution in the DWP file, so 1274 // can be none zero. Thus we are skipping the check for DWP. 1275 bool IsDWP = !Context.getCUIndex().getRows().empty(); 1276 if (!IsDWP) { 1277 for (const std::unique_ptr<DWARFUnit> &Unit : Context.dwo_units()) { 1278 if (Unit->getAbbreviationsOffset() != 0) { 1279 errs() << "BOLT-ERROR: detected DWO unit with non-zero abbr_offset. " 1280 "Unable to update debug info.\n"; 1281 exit(1); 1282 } 1283 } 1284 } 1285 1286 DWARFUnit *Unit = Context.getDWOCompileUnitForHash(*DWOId); 1287 // Issue abbreviations for the DWO CU only. 1288 addUnitAbbreviations(*Unit); 1289 AbbrevData *Abbrev = UnitsAbbrevData[Unit]; 1290 Abbrevs.push_back(Abbrev); 1291 } else { 1292 Abbrevs.reserve(Context.getNumCompileUnits() + Context.getNumTypeUnits()); 1293 std::unordered_set<AbbrevData *> ProcessedAbbrevs; 1294 // Add abbreviations from compile and type non-DWO units. 1295 for (const std::unique_ptr<DWARFUnit> &Unit : Context.normal_units()) { 1296 addUnitAbbreviations(*Unit); 1297 AbbrevData *Abbrev = UnitsAbbrevData[Unit.get()]; 1298 if (!ProcessedAbbrevs.insert(Abbrev).second) 1299 continue; 1300 Abbrevs.push_back(Abbrev); 1301 } 1302 } 1303 1304 DebugBufferVector ReturnBuffer; 1305 // Pre-calculate the total size of abbrev section. 1306 uint64_t Size = 0; 1307 for (const AbbrevData *UnitData : Abbrevs) 1308 Size += UnitData->Buffer->size(); 1309 1310 ReturnBuffer.reserve(Size); 1311 1312 uint64_t Pos = 0; 1313 for (AbbrevData *UnitData : Abbrevs) { 1314 ReturnBuffer.append(*UnitData->Buffer); 1315 UnitData->Offset = Pos; 1316 Pos += UnitData->Buffer->size(); 1317 1318 UnitData->Buffer.reset(); 1319 UnitData->Stream.reset(); 1320 } 1321 1322 return std::make_unique<DebugBufferVector>(ReturnBuffer); 1323 } 1324 1325 static void emitDwarfSetLineAddrAbs(MCStreamer &OS, 1326 MCDwarfLineTableParams Params, 1327 int64_t LineDelta, uint64_t Address, 1328 int PointerSize) { 1329 // emit the sequence to set the address 1330 OS.emitIntValue(dwarf::DW_LNS_extended_op, 1); 1331 OS.emitULEB128IntValue(PointerSize + 1); 1332 OS.emitIntValue(dwarf::DW_LNE_set_address, 1); 1333 OS.emitIntValue(Address, PointerSize); 1334 1335 // emit the sequence for the LineDelta (from 1) and a zero address delta. 1336 MCDwarfLineAddr::Emit(&OS, Params, LineDelta, 0); 1337 } 1338 1339 static inline void emitBinaryDwarfLineTable( 1340 MCStreamer *MCOS, MCDwarfLineTableParams Params, 1341 const DWARFDebugLine::LineTable *Table, 1342 const std::vector<DwarfLineTable::RowSequence> &InputSequences) { 1343 if (InputSequences.empty()) 1344 return; 1345 1346 constexpr uint64_t InvalidAddress = UINT64_MAX; 1347 unsigned FileNum = 1; 1348 unsigned LastLine = 1; 1349 unsigned Column = 0; 1350 unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 1351 unsigned Isa = 0; 1352 unsigned Discriminator = 0; 1353 uint64_t LastAddress = InvalidAddress; 1354 uint64_t PrevEndOfSequence = InvalidAddress; 1355 const MCAsmInfo *AsmInfo = MCOS->getContext().getAsmInfo(); 1356 1357 auto emitEndOfSequence = [&](uint64_t Address) { 1358 MCDwarfLineAddr::Emit(MCOS, Params, INT64_MAX, Address - LastAddress); 1359 FileNum = 1; 1360 LastLine = 1; 1361 Column = 0; 1362 Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 1363 Isa = 0; 1364 Discriminator = 0; 1365 LastAddress = InvalidAddress; 1366 }; 1367 1368 for (const DwarfLineTable::RowSequence &Sequence : InputSequences) { 1369 const uint64_t SequenceStart = 1370 Table->Rows[Sequence.FirstIndex].Address.Address; 1371 1372 // Check if we need to mark the end of the sequence. 1373 if (PrevEndOfSequence != InvalidAddress && LastAddress != InvalidAddress && 1374 PrevEndOfSequence != SequenceStart) { 1375 emitEndOfSequence(PrevEndOfSequence); 1376 } 1377 1378 for (uint32_t RowIndex = Sequence.FirstIndex; 1379 RowIndex <= Sequence.LastIndex; ++RowIndex) { 1380 const DWARFDebugLine::Row &Row = Table->Rows[RowIndex]; 1381 int64_t LineDelta = static_cast<int64_t>(Row.Line) - LastLine; 1382 const uint64_t Address = Row.Address.Address; 1383 1384 if (FileNum != Row.File) { 1385 FileNum = Row.File; 1386 MCOS->emitInt8(dwarf::DW_LNS_set_file); 1387 MCOS->emitULEB128IntValue(FileNum); 1388 } 1389 if (Column != Row.Column) { 1390 Column = Row.Column; 1391 MCOS->emitInt8(dwarf::DW_LNS_set_column); 1392 MCOS->emitULEB128IntValue(Column); 1393 } 1394 if (Discriminator != Row.Discriminator && 1395 MCOS->getContext().getDwarfVersion() >= 4) { 1396 Discriminator = Row.Discriminator; 1397 unsigned Size = getULEB128Size(Discriminator); 1398 MCOS->emitInt8(dwarf::DW_LNS_extended_op); 1399 MCOS->emitULEB128IntValue(Size + 1); 1400 MCOS->emitInt8(dwarf::DW_LNE_set_discriminator); 1401 MCOS->emitULEB128IntValue(Discriminator); 1402 } 1403 if (Isa != Row.Isa) { 1404 Isa = Row.Isa; 1405 MCOS->emitInt8(dwarf::DW_LNS_set_isa); 1406 MCOS->emitULEB128IntValue(Isa); 1407 } 1408 if (Row.IsStmt != Flags) { 1409 Flags = Row.IsStmt; 1410 MCOS->emitInt8(dwarf::DW_LNS_negate_stmt); 1411 } 1412 if (Row.BasicBlock) 1413 MCOS->emitInt8(dwarf::DW_LNS_set_basic_block); 1414 if (Row.PrologueEnd) 1415 MCOS->emitInt8(dwarf::DW_LNS_set_prologue_end); 1416 if (Row.EpilogueBegin) 1417 MCOS->emitInt8(dwarf::DW_LNS_set_epilogue_begin); 1418 1419 // The end of the sequence is not normal in the middle of the input 1420 // sequence, but could happen, e.g. for assembly code. 1421 if (Row.EndSequence) { 1422 emitEndOfSequence(Address); 1423 } else { 1424 if (LastAddress == InvalidAddress) 1425 emitDwarfSetLineAddrAbs(*MCOS, Params, LineDelta, Address, 1426 AsmInfo->getCodePointerSize()); 1427 else 1428 MCDwarfLineAddr::Emit(MCOS, Params, LineDelta, Address - LastAddress); 1429 1430 LastAddress = Address; 1431 LastLine = Row.Line; 1432 } 1433 1434 Discriminator = 0; 1435 } 1436 PrevEndOfSequence = Sequence.EndAddress; 1437 } 1438 1439 // Finish with the end of the sequence. 1440 if (LastAddress != InvalidAddress) 1441 emitEndOfSequence(PrevEndOfSequence); 1442 } 1443 1444 // This function is similar to the one from MCDwarfLineTable, except it handles 1445 // end-of-sequence entries differently by utilizing line entries with 1446 // DWARF2_FLAG_END_SEQUENCE flag. 1447 static inline void emitDwarfLineTable( 1448 MCStreamer *MCOS, MCSection *Section, 1449 const MCLineSection::MCDwarfLineEntryCollection &LineEntries) { 1450 unsigned FileNum = 1; 1451 unsigned LastLine = 1; 1452 unsigned Column = 0; 1453 unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 1454 unsigned Isa = 0; 1455 unsigned Discriminator = 0; 1456 MCSymbol *LastLabel = nullptr; 1457 const MCAsmInfo *AsmInfo = MCOS->getContext().getAsmInfo(); 1458 1459 // Loop through each MCDwarfLineEntry and encode the dwarf line number table. 1460 for (const MCDwarfLineEntry &LineEntry : LineEntries) { 1461 if (LineEntry.getFlags() & DWARF2_FLAG_END_SEQUENCE) { 1462 MCOS->emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, LineEntry.getLabel(), 1463 AsmInfo->getCodePointerSize()); 1464 FileNum = 1; 1465 LastLine = 1; 1466 Column = 0; 1467 Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 1468 Isa = 0; 1469 Discriminator = 0; 1470 LastLabel = nullptr; 1471 continue; 1472 } 1473 1474 int64_t LineDelta = static_cast<int64_t>(LineEntry.getLine()) - LastLine; 1475 1476 if (FileNum != LineEntry.getFileNum()) { 1477 FileNum = LineEntry.getFileNum(); 1478 MCOS->emitInt8(dwarf::DW_LNS_set_file); 1479 MCOS->emitULEB128IntValue(FileNum); 1480 } 1481 if (Column != LineEntry.getColumn()) { 1482 Column = LineEntry.getColumn(); 1483 MCOS->emitInt8(dwarf::DW_LNS_set_column); 1484 MCOS->emitULEB128IntValue(Column); 1485 } 1486 if (Discriminator != LineEntry.getDiscriminator() && 1487 MCOS->getContext().getDwarfVersion() >= 2) { 1488 Discriminator = LineEntry.getDiscriminator(); 1489 unsigned Size = getULEB128Size(Discriminator); 1490 MCOS->emitInt8(dwarf::DW_LNS_extended_op); 1491 MCOS->emitULEB128IntValue(Size + 1); 1492 MCOS->emitInt8(dwarf::DW_LNE_set_discriminator); 1493 MCOS->emitULEB128IntValue(Discriminator); 1494 } 1495 if (Isa != LineEntry.getIsa()) { 1496 Isa = LineEntry.getIsa(); 1497 MCOS->emitInt8(dwarf::DW_LNS_set_isa); 1498 MCOS->emitULEB128IntValue(Isa); 1499 } 1500 if ((LineEntry.getFlags() ^ Flags) & DWARF2_FLAG_IS_STMT) { 1501 Flags = LineEntry.getFlags(); 1502 MCOS->emitInt8(dwarf::DW_LNS_negate_stmt); 1503 } 1504 if (LineEntry.getFlags() & DWARF2_FLAG_BASIC_BLOCK) 1505 MCOS->emitInt8(dwarf::DW_LNS_set_basic_block); 1506 if (LineEntry.getFlags() & DWARF2_FLAG_PROLOGUE_END) 1507 MCOS->emitInt8(dwarf::DW_LNS_set_prologue_end); 1508 if (LineEntry.getFlags() & DWARF2_FLAG_EPILOGUE_BEGIN) 1509 MCOS->emitInt8(dwarf::DW_LNS_set_epilogue_begin); 1510 1511 MCSymbol *Label = LineEntry.getLabel(); 1512 1513 // At this point we want to emit/create the sequence to encode the delta 1514 // in line numbers and the increment of the address from the previous 1515 // Label and the current Label. 1516 MCOS->emitDwarfAdvanceLineAddr(LineDelta, LastLabel, Label, 1517 AsmInfo->getCodePointerSize()); 1518 Discriminator = 0; 1519 LastLine = LineEntry.getLine(); 1520 LastLabel = Label; 1521 } 1522 1523 assert(LastLabel == nullptr && "end of sequence expected"); 1524 } 1525 1526 void DwarfLineTable::emitCU(MCStreamer *MCOS, MCDwarfLineTableParams Params, 1527 Optional<MCDwarfLineStr> &LineStr, 1528 BinaryContext &BC) const { 1529 if (!RawData.empty()) { 1530 assert(MCLineSections.getMCLineEntries().empty() && 1531 InputSequences.empty() && 1532 "cannot combine raw data with new line entries"); 1533 MCOS->emitLabel(getLabel()); 1534 MCOS->emitBytes(RawData); 1535 1536 // Emit fake relocation for RuntimeDyld to always allocate the section. 1537 // 1538 // FIXME: remove this once RuntimeDyld stops skipping allocatable sections 1539 // without relocations. 1540 MCOS->emitRelocDirective( 1541 *MCConstantExpr::create(0, *BC.Ctx), "BFD_RELOC_NONE", 1542 MCSymbolRefExpr::create(getLabel(), *BC.Ctx), SMLoc(), *BC.STI); 1543 1544 return; 1545 } 1546 1547 MCSymbol *LineEndSym = Header.Emit(MCOS, Params, LineStr).second; 1548 1549 // Put out the line tables. 1550 for (const auto &LineSec : MCLineSections.getMCLineEntries()) 1551 emitDwarfLineTable(MCOS, LineSec.first, LineSec.second); 1552 1553 // Emit line tables for the original code. 1554 emitBinaryDwarfLineTable(MCOS, Params, InputTable, InputSequences); 1555 1556 // This is the end of the section, so set the value of the symbol at the end 1557 // of this section (that was used in a previous expression). 1558 MCOS->emitLabel(LineEndSym); 1559 } 1560 1561 // Helper function to parse .debug_line_str, and populate one we are using. 1562 // For functions that we do not modify we output them as raw data. 1563 // Re-constructing .debug_line_str so that offsets are correct for those 1564 // debut line tables. 1565 // Bonus is that when we output a final binary we can re-use .debug_line_str 1566 // section. So we don't have to do the SHF_ALLOC trick we did with 1567 // .debug_line. 1568 static void parseAndPopulateDebugLineStr(BinarySection &LineStrSection, 1569 MCDwarfLineStr &LineStr, 1570 BinaryContext &BC, 1571 MCStreamer &Streamer) { 1572 DataExtractor StrData(LineStrSection.getContents(), 1573 BC.DwCtx->isLittleEndian(), 0); 1574 uint64_t Offset = 0; 1575 while (StrData.isValidOffset(Offset)) { 1576 Error Err = Error::success(); 1577 const char *CStr = StrData.getCStr(&Offset, &Err); 1578 if (Err) { 1579 errs() << "BOLT-ERROR: could not extract string from .debug_line_str"; 1580 continue; 1581 } 1582 LineStr.emitRef(&Streamer, CStr); 1583 } 1584 } 1585 1586 void DwarfLineTable::emit(BinaryContext &BC, MCStreamer &Streamer) { 1587 MCAssembler &Assembler = 1588 static_cast<MCObjectStreamer *>(&Streamer)->getAssembler(); 1589 1590 MCDwarfLineTableParams Params = Assembler.getDWARFLinetableParams(); 1591 1592 auto &LineTables = BC.getDwarfLineTables(); 1593 1594 // Bail out early so we don't switch to the debug_line section needlessly and 1595 // in doing so create an unnecessary (if empty) section. 1596 if (LineTables.empty()) 1597 return; 1598 // In a v5 non-split line table, put the strings in a separate section. 1599 Optional<MCDwarfLineStr> LineStr(None); 1600 ErrorOr<BinarySection &> LineStrSection = 1601 BC.getUniqueSectionByName(".debug_line_str"); 1602 // Some versions of GCC output DWARF5 .debug_info, but DWARF4 or lower 1603 // .debug_line 1604 if (LineStrSection) { 1605 LineStr = MCDwarfLineStr(*BC.Ctx); 1606 parseAndPopulateDebugLineStr(*LineStrSection, *LineStr, BC, Streamer); 1607 } 1608 1609 // Switch to the section where the table will be emitted into. 1610 Streamer.switchSection(BC.MOFI->getDwarfLineSection()); 1611 1612 const uint16_t DwarfVersion = BC.Ctx->getDwarfVersion(); 1613 // Handle the rest of the Compile Units. 1614 for (auto &CUIDTablePair : LineTables) { 1615 Streamer.getContext().setDwarfVersion( 1616 CUIDTablePair.second.getDwarfVersion()); 1617 CUIDTablePair.second.emitCU(&Streamer, Params, LineStr, BC); 1618 } 1619 1620 // Resetting DWARF version for rest of the flow. 1621 BC.Ctx->setDwarfVersion(DwarfVersion); 1622 1623 // Still need to write the section out for the ExecutionEngine, and temp in 1624 // memory object we are constructing. 1625 if (LineStr) { 1626 LineStr->emitSection(&Streamer); 1627 SmallString<0> Data = LineStr->getFinalizedData(); 1628 BC.registerOrUpdateNoteSection(".debug_line_str", copyByteArray(Data.str()), 1629 Data.size()); 1630 } 1631 } 1632 1633 } // namespace bolt 1634 } // namespace llvm 1635