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