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 StringRef Key = Hasher.final(); 824 auto Iter = AbbrevDataCache.find(Key); 825 if (Iter != AbbrevDataCache.end()) { 826 UnitsAbbrevData[&Unit] = Iter->second.get(); 827 return true; 828 } 829 AbbrevDataCache[Key] = std::move(UnitDataPtr); 830 UnitsAbbrevData[&Unit] = &UnitData; 831 return false; 832 }; 833 // Take a fast path if there are no patches to apply. Simply copy the original 834 // contents. 835 if (UnitPatches.empty() && AbbrevEntries.empty()) { 836 StringRef AbbrevSectionContents = 837 Unit.isDWOUnit() ? Unit.getContext().getDWARFObj().getAbbrevDWOSection() 838 : Unit.getContext().getDWARFObj().getAbbrevSection(); 839 StringRef AbbrevContents; 840 841 const DWARFUnitIndex &CUIndex = Unit.getContext().getCUIndex(); 842 if (!CUIndex.getRows().empty()) { 843 // Handle DWP section contribution. 844 const DWARFUnitIndex::Entry *DWOEntry = 845 CUIndex.getFromHash(*Unit.getDWOId()); 846 if (!DWOEntry) 847 return; 848 849 const DWARFUnitIndex::Entry::SectionContribution *DWOContrubution = 850 DWOEntry->getContribution(DWARFSectionKind::DW_SECT_ABBREV); 851 AbbrevContents = AbbrevSectionContents.substr(DWOContrubution->Offset, 852 DWOContrubution->Length); 853 } else if (!Unit.isDWOUnit()) { 854 const uint64_t StartOffset = Unit.getAbbreviationsOffset(); 855 856 // We know where the unit's abbreviation set starts, but not where it ends 857 // as such data is not readily available. Hence, we have to build a sorted 858 // list of start addresses and find the next starting address to determine 859 // the set boundaries. 860 // 861 // FIXME: if we had a full access to DWARFDebugAbbrev::AbbrDeclSets 862 // we wouldn't have to build our own sorted list for the quick lookup. 863 if (AbbrevSetOffsets.empty()) { 864 for_each( 865 *Unit.getContext().getDebugAbbrev(), 866 [&](const std::pair<uint64_t, DWARFAbbreviationDeclarationSet> &P) { 867 AbbrevSetOffsets.push_back(P.first); 868 }); 869 sort(AbbrevSetOffsets); 870 } 871 auto It = upper_bound(AbbrevSetOffsets, StartOffset); 872 const uint64_t EndOffset = 873 It == AbbrevSetOffsets.end() ? AbbrevSectionContents.size() : *It; 874 AbbrevContents = AbbrevSectionContents.slice(StartOffset, EndOffset); 875 } else { 876 // For DWO unit outside of DWP, we expect the entire section to hold 877 // abbreviations for this unit only. 878 AbbrevContents = AbbrevSectionContents; 879 } 880 881 if (!hashAndAddAbbrev(AbbrevContents)) { 882 OS.reserveExtraSpace(AbbrevContents.size()); 883 OS << AbbrevContents; 884 } 885 return; 886 } 887 888 for (auto I = Abbrevs->begin(), E = Abbrevs->end(); I != E; ++I) { 889 const DWARFAbbreviationDeclaration &Abbrev = *I; 890 auto Patch = UnitPatches.find(&Abbrev); 891 892 encodeULEB128(Abbrev.getCode(), OS); 893 encodeULEB128(Abbrev.getTag(), OS); 894 encodeULEB128(Abbrev.hasChildren(), OS); 895 for (const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec : 896 Abbrev.attributes()) { 897 if (Patch != UnitPatches.end()) { 898 bool Patched = false; 899 // Patches added later take a precedence over earlier ones. 900 for (auto I = Patch->second.rbegin(), E = Patch->second.rend(); I != E; 901 ++I) { 902 if (I->OldAttr != AttrSpec.Attr) 903 continue; 904 905 encodeULEB128(I->NewAttr, OS); 906 encodeULEB128(I->NewAttrForm, OS); 907 Patched = true; 908 break; 909 } 910 if (Patched) 911 continue; 912 } 913 914 encodeULEB128(AttrSpec.Attr, OS); 915 encodeULEB128(AttrSpec.Form, OS); 916 if (AttrSpec.isImplicitConst()) 917 encodeSLEB128(AttrSpec.getImplicitConstValue(), OS); 918 } 919 const auto Entries = AbbrevEntries.find(&Abbrev); 920 // Adding new Abbrevs for inserted entries. 921 if (Entries != AbbrevEntries.end()) { 922 for (const AbbrevEntry &Entry : Entries->second) { 923 encodeULEB128(Entry.Attr, OS); 924 encodeULEB128(Entry.Form, OS); 925 } 926 } 927 encodeULEB128(0, OS); 928 encodeULEB128(0, OS); 929 } 930 encodeULEB128(0, OS); 931 932 hashAndAddAbbrev(OS.str()); 933 } 934 935 std::unique_ptr<DebugBufferVector> DebugAbbrevWriter::finalize() { 936 // Used to create determinism for writing out abbrevs. 937 std::vector<AbbrevData *> Abbrevs; 938 if (DWOId) { 939 // We expect abbrev_offset to always be zero for DWO units as there 940 // should be one CU per DWO, and TUs should share the same abbreviation 941 // set with the CU. 942 // For DWP AbbreviationsOffset is an Abbrev contribution in the DWP file, so 943 // can be none zero. Thus we are skipping the check for DWP. 944 bool IsDWP = !Context.getCUIndex().getRows().empty(); 945 if (!IsDWP) { 946 for (const std::unique_ptr<DWARFUnit> &Unit : Context.dwo_units()) { 947 if (Unit->getAbbreviationsOffset() != 0) { 948 errs() << "BOLT-ERROR: detected DWO unit with non-zero abbr_offset. " 949 "Unable to update debug info.\n"; 950 exit(1); 951 } 952 } 953 } 954 955 DWARFUnit *Unit = Context.getDWOCompileUnitForHash(*DWOId); 956 // Issue abbreviations for the DWO CU only. 957 addUnitAbbreviations(*Unit); 958 AbbrevData *Abbrev = UnitsAbbrevData[Unit]; 959 Abbrevs.push_back(Abbrev); 960 } else { 961 Abbrevs.reserve(Context.getNumCompileUnits() + Context.getNumTypeUnits()); 962 std::unordered_set<AbbrevData *> ProcessedAbbrevs; 963 // Add abbreviations from compile and type non-DWO units. 964 for (const std::unique_ptr<DWARFUnit> &Unit : Context.normal_units()) { 965 addUnitAbbreviations(*Unit); 966 AbbrevData *Abbrev = UnitsAbbrevData[Unit.get()]; 967 if (!ProcessedAbbrevs.insert(Abbrev).second) 968 continue; 969 Abbrevs.push_back(Abbrev); 970 } 971 } 972 973 DebugBufferVector ReturnBuffer; 974 // Pre-calculate the total size of abbrev section. 975 uint64_t Size = 0; 976 for (const AbbrevData *UnitData : Abbrevs) 977 Size += UnitData->Buffer->size(); 978 979 ReturnBuffer.reserve(Size); 980 981 uint64_t Pos = 0; 982 for (AbbrevData *UnitData : Abbrevs) { 983 ReturnBuffer.append(*UnitData->Buffer); 984 UnitData->Offset = Pos; 985 Pos += UnitData->Buffer->size(); 986 987 UnitData->Buffer.reset(); 988 UnitData->Stream.reset(); 989 } 990 991 return std::make_unique<DebugBufferVector>(ReturnBuffer); 992 } 993 994 static void emitDwarfSetLineAddrAbs(MCStreamer &OS, 995 MCDwarfLineTableParams Params, 996 int64_t LineDelta, uint64_t Address, 997 int PointerSize) { 998 // emit the sequence to set the address 999 OS.emitIntValue(dwarf::DW_LNS_extended_op, 1); 1000 OS.emitULEB128IntValue(PointerSize + 1); 1001 OS.emitIntValue(dwarf::DW_LNE_set_address, 1); 1002 OS.emitIntValue(Address, PointerSize); 1003 1004 // emit the sequence for the LineDelta (from 1) and a zero address delta. 1005 MCDwarfLineAddr::Emit(&OS, Params, LineDelta, 0); 1006 } 1007 1008 static inline void emitBinaryDwarfLineTable( 1009 MCStreamer *MCOS, MCDwarfLineTableParams Params, 1010 const DWARFDebugLine::LineTable *Table, 1011 const std::vector<DwarfLineTable::RowSequence> &InputSequences) { 1012 if (InputSequences.empty()) 1013 return; 1014 1015 constexpr uint64_t InvalidAddress = UINT64_MAX; 1016 unsigned FileNum = 1; 1017 unsigned LastLine = 1; 1018 unsigned Column = 0; 1019 unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 1020 unsigned Isa = 0; 1021 unsigned Discriminator = 0; 1022 uint64_t LastAddress = InvalidAddress; 1023 uint64_t PrevEndOfSequence = InvalidAddress; 1024 const MCAsmInfo *AsmInfo = MCOS->getContext().getAsmInfo(); 1025 1026 auto emitEndOfSequence = [&](uint64_t Address) { 1027 MCDwarfLineAddr::Emit(MCOS, Params, INT64_MAX, Address - LastAddress); 1028 FileNum = 1; 1029 LastLine = 1; 1030 Column = 0; 1031 Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 1032 Isa = 0; 1033 Discriminator = 0; 1034 LastAddress = InvalidAddress; 1035 }; 1036 1037 for (const DwarfLineTable::RowSequence &Sequence : InputSequences) { 1038 const uint64_t SequenceStart = 1039 Table->Rows[Sequence.FirstIndex].Address.Address; 1040 1041 // Check if we need to mark the end of the sequence. 1042 if (PrevEndOfSequence != InvalidAddress && LastAddress != InvalidAddress && 1043 PrevEndOfSequence != SequenceStart) { 1044 emitEndOfSequence(PrevEndOfSequence); 1045 } 1046 1047 for (uint32_t RowIndex = Sequence.FirstIndex; 1048 RowIndex <= Sequence.LastIndex; ++RowIndex) { 1049 const DWARFDebugLine::Row &Row = Table->Rows[RowIndex]; 1050 int64_t LineDelta = static_cast<int64_t>(Row.Line) - LastLine; 1051 const uint64_t Address = Row.Address.Address; 1052 1053 if (FileNum != Row.File) { 1054 FileNum = Row.File; 1055 MCOS->emitInt8(dwarf::DW_LNS_set_file); 1056 MCOS->emitULEB128IntValue(FileNum); 1057 } 1058 if (Column != Row.Column) { 1059 Column = Row.Column; 1060 MCOS->emitInt8(dwarf::DW_LNS_set_column); 1061 MCOS->emitULEB128IntValue(Column); 1062 } 1063 if (Discriminator != Row.Discriminator && 1064 MCOS->getContext().getDwarfVersion() >= 4) { 1065 Discriminator = Row.Discriminator; 1066 unsigned Size = getULEB128Size(Discriminator); 1067 MCOS->emitInt8(dwarf::DW_LNS_extended_op); 1068 MCOS->emitULEB128IntValue(Size + 1); 1069 MCOS->emitInt8(dwarf::DW_LNE_set_discriminator); 1070 MCOS->emitULEB128IntValue(Discriminator); 1071 } 1072 if (Isa != Row.Isa) { 1073 Isa = Row.Isa; 1074 MCOS->emitInt8(dwarf::DW_LNS_set_isa); 1075 MCOS->emitULEB128IntValue(Isa); 1076 } 1077 if (Row.IsStmt != Flags) { 1078 Flags = Row.IsStmt; 1079 MCOS->emitInt8(dwarf::DW_LNS_negate_stmt); 1080 } 1081 if (Row.BasicBlock) 1082 MCOS->emitInt8(dwarf::DW_LNS_set_basic_block); 1083 if (Row.PrologueEnd) 1084 MCOS->emitInt8(dwarf::DW_LNS_set_prologue_end); 1085 if (Row.EpilogueBegin) 1086 MCOS->emitInt8(dwarf::DW_LNS_set_epilogue_begin); 1087 1088 // The end of the sequence is not normal in the middle of the input 1089 // sequence, but could happen, e.g. for assembly code. 1090 if (Row.EndSequence) { 1091 emitEndOfSequence(Address); 1092 } else { 1093 if (LastAddress == InvalidAddress) 1094 emitDwarfSetLineAddrAbs(*MCOS, Params, LineDelta, Address, 1095 AsmInfo->getCodePointerSize()); 1096 else 1097 MCDwarfLineAddr::Emit(MCOS, Params, LineDelta, Address - LastAddress); 1098 1099 LastAddress = Address; 1100 LastLine = Row.Line; 1101 } 1102 1103 Discriminator = 0; 1104 } 1105 PrevEndOfSequence = Sequence.EndAddress; 1106 } 1107 1108 // Finish with the end of the sequence. 1109 if (LastAddress != InvalidAddress) 1110 emitEndOfSequence(PrevEndOfSequence); 1111 } 1112 1113 // This function is similar to the one from MCDwarfLineTable, except it handles 1114 // end-of-sequence entries differently by utilizing line entries with 1115 // DWARF2_FLAG_END_SEQUENCE flag. 1116 static inline void emitDwarfLineTable( 1117 MCStreamer *MCOS, MCSection *Section, 1118 const MCLineSection::MCDwarfLineEntryCollection &LineEntries) { 1119 unsigned FileNum = 1; 1120 unsigned LastLine = 1; 1121 unsigned Column = 0; 1122 unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 1123 unsigned Isa = 0; 1124 unsigned Discriminator = 0; 1125 MCSymbol *LastLabel = nullptr; 1126 const MCAsmInfo *AsmInfo = MCOS->getContext().getAsmInfo(); 1127 1128 // Loop through each MCDwarfLineEntry and encode the dwarf line number table. 1129 for (const MCDwarfLineEntry &LineEntry : LineEntries) { 1130 if (LineEntry.getFlags() & DWARF2_FLAG_END_SEQUENCE) { 1131 MCOS->emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, LineEntry.getLabel(), 1132 AsmInfo->getCodePointerSize()); 1133 FileNum = 1; 1134 LastLine = 1; 1135 Column = 0; 1136 Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 1137 Isa = 0; 1138 Discriminator = 0; 1139 LastLabel = nullptr; 1140 continue; 1141 } 1142 1143 int64_t LineDelta = static_cast<int64_t>(LineEntry.getLine()) - LastLine; 1144 1145 if (FileNum != LineEntry.getFileNum()) { 1146 FileNum = LineEntry.getFileNum(); 1147 MCOS->emitInt8(dwarf::DW_LNS_set_file); 1148 MCOS->emitULEB128IntValue(FileNum); 1149 } 1150 if (Column != LineEntry.getColumn()) { 1151 Column = LineEntry.getColumn(); 1152 MCOS->emitInt8(dwarf::DW_LNS_set_column); 1153 MCOS->emitULEB128IntValue(Column); 1154 } 1155 if (Discriminator != LineEntry.getDiscriminator() && 1156 MCOS->getContext().getDwarfVersion() >= 4) { 1157 Discriminator = LineEntry.getDiscriminator(); 1158 unsigned Size = getULEB128Size(Discriminator); 1159 MCOS->emitInt8(dwarf::DW_LNS_extended_op); 1160 MCOS->emitULEB128IntValue(Size + 1); 1161 MCOS->emitInt8(dwarf::DW_LNE_set_discriminator); 1162 MCOS->emitULEB128IntValue(Discriminator); 1163 } 1164 if (Isa != LineEntry.getIsa()) { 1165 Isa = LineEntry.getIsa(); 1166 MCOS->emitInt8(dwarf::DW_LNS_set_isa); 1167 MCOS->emitULEB128IntValue(Isa); 1168 } 1169 if ((LineEntry.getFlags() ^ Flags) & DWARF2_FLAG_IS_STMT) { 1170 Flags = LineEntry.getFlags(); 1171 MCOS->emitInt8(dwarf::DW_LNS_negate_stmt); 1172 } 1173 if (LineEntry.getFlags() & DWARF2_FLAG_BASIC_BLOCK) 1174 MCOS->emitInt8(dwarf::DW_LNS_set_basic_block); 1175 if (LineEntry.getFlags() & DWARF2_FLAG_PROLOGUE_END) 1176 MCOS->emitInt8(dwarf::DW_LNS_set_prologue_end); 1177 if (LineEntry.getFlags() & DWARF2_FLAG_EPILOGUE_BEGIN) 1178 MCOS->emitInt8(dwarf::DW_LNS_set_epilogue_begin); 1179 1180 MCSymbol *Label = LineEntry.getLabel(); 1181 1182 // At this point we want to emit/create the sequence to encode the delta 1183 // in line numbers and the increment of the address from the previous 1184 // Label and the current Label. 1185 MCOS->emitDwarfAdvanceLineAddr(LineDelta, LastLabel, Label, 1186 AsmInfo->getCodePointerSize()); 1187 Discriminator = 0; 1188 LastLine = LineEntry.getLine(); 1189 LastLabel = Label; 1190 } 1191 1192 assert(LastLabel == nullptr && "end of sequence expected"); 1193 } 1194 1195 void DwarfLineTable::emitCU(MCStreamer *MCOS, MCDwarfLineTableParams Params, 1196 Optional<MCDwarfLineStr> &LineStr, 1197 BinaryContext &BC) const { 1198 if (!RawData.empty()) { 1199 assert(MCLineSections.getMCLineEntries().empty() && 1200 InputSequences.empty() && 1201 "cannot combine raw data with new line entries"); 1202 MCOS->emitLabel(getLabel()); 1203 MCOS->emitBytes(RawData); 1204 1205 // Emit fake relocation for RuntimeDyld to always allocate the section. 1206 // 1207 // FIXME: remove this once RuntimeDyld stops skipping allocatable sections 1208 // without relocations. 1209 MCOS->emitRelocDirective( 1210 *MCConstantExpr::create(0, *BC.Ctx), "BFD_RELOC_NONE", 1211 MCSymbolRefExpr::create(getLabel(), *BC.Ctx), SMLoc(), *BC.STI); 1212 1213 return; 1214 } 1215 1216 MCSymbol *LineEndSym = Header.Emit(MCOS, Params, LineStr).second; 1217 1218 // Put out the line tables. 1219 for (const auto &LineSec : MCLineSections.getMCLineEntries()) 1220 emitDwarfLineTable(MCOS, LineSec.first, LineSec.second); 1221 1222 // Emit line tables for the original code. 1223 emitBinaryDwarfLineTable(MCOS, Params, InputTable, InputSequences); 1224 1225 // This is the end of the section, so set the value of the symbol at the end 1226 // of this section (that was used in a previous expression). 1227 MCOS->emitLabel(LineEndSym); 1228 } 1229 1230 void DwarfLineTable::emit(BinaryContext &BC, MCStreamer &Streamer) { 1231 MCAssembler &Assembler = 1232 static_cast<MCObjectStreamer *>(&Streamer)->getAssembler(); 1233 1234 MCDwarfLineTableParams Params = Assembler.getDWARFLinetableParams(); 1235 1236 auto &LineTables = BC.getDwarfLineTables(); 1237 1238 // Bail out early so we don't switch to the debug_line section needlessly and 1239 // in doing so create an unnecessary (if empty) section. 1240 if (LineTables.empty()) 1241 return; 1242 1243 // In a v5 non-split line table, put the strings in a separate section. 1244 Optional<MCDwarfLineStr> LineStr(None); 1245 if (BC.Ctx->getDwarfVersion() >= 5) 1246 LineStr = MCDwarfLineStr(*BC.Ctx); 1247 1248 // Switch to the section where the table will be emitted into. 1249 Streamer.SwitchSection(BC.MOFI->getDwarfLineSection()); 1250 1251 // Handle the rest of the Compile Units. 1252 for (auto &CUIDTablePair : LineTables) { 1253 CUIDTablePair.second.emitCU(&Streamer, Params, LineStr, BC); 1254 } 1255 } 1256 1257 } // namespace bolt 1258 } // namespace llvm 1259