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