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