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