1 //===- DebugData.cpp - Representation and writing of debugging information. ==// 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 //===----------------------------------------------------------------------===// 10 11 #include "bolt/Core/DebugData.h" 12 #include "bolt/Core/BinaryBasicBlock.h" 13 #include "bolt/Core/BinaryFunction.h" 14 #include "bolt/Utils/Utils.h" 15 #include "llvm/MC/MCObjectStreamer.h" 16 #include "llvm/MC/MCSymbol.h" 17 #include "llvm/Support/CommandLine.h" 18 #include "llvm/Support/EndianStream.h" 19 #include "llvm/Support/LEB128.h" 20 #include <algorithm> 21 #include <cassert> 22 #include <cstdint> 23 #include <limits> 24 25 #undef DEBUG_TYPE 26 #define DEBUG_TYPE "bolt-debug-info" 27 28 namespace opts { 29 extern llvm::cl::opt<unsigned> Verbosity; 30 } 31 32 namespace llvm { 33 namespace bolt { 34 35 const DebugLineTableRowRef DebugLineTableRowRef::NULL_ROW{0, 0}; 36 37 namespace { 38 39 // Writes address ranges to Writer as pairs of 64-bit (address, size). 40 // If RelativeRange is true, assumes the address range to be written must be of 41 // the form (begin address, range size), otherwise (begin address, end address). 42 // Terminates the list by writing a pair of two zeroes. 43 // Returns the number of written bytes. 44 uint64_t writeAddressRanges( 45 raw_svector_ostream &Stream, 46 const DebugAddressRangesVector &AddressRanges, 47 const bool WriteRelativeRanges = false) { 48 for (const DebugAddressRange &Range : AddressRanges) { 49 support::endian::write(Stream, Range.LowPC, support::little); 50 support::endian::write( 51 Stream, WriteRelativeRanges ? Range.HighPC - Range.LowPC : Range.HighPC, 52 support::little); 53 } 54 // Finish with 0 entries. 55 support::endian::write(Stream, 0ULL, support::little); 56 support::endian::write(Stream, 0ULL, support::little); 57 return AddressRanges.size() * 16 + 16; 58 } 59 60 } // namespace 61 62 DebugRangesSectionWriter::DebugRangesSectionWriter() { 63 RangesBuffer = std::make_unique<DebugBufferVector>(); 64 RangesStream = std::make_unique<raw_svector_ostream>(*RangesBuffer); 65 66 // Add an empty range as the first entry; 67 SectionOffset += 68 writeAddressRanges(*RangesStream.get(), DebugAddressRangesVector{}); 69 } 70 71 uint64_t DebugRangesSectionWriter::addRanges( 72 DebugAddressRangesVector &&Ranges, 73 std::map<DebugAddressRangesVector, uint64_t> &CachedRanges) { 74 if (Ranges.empty()) 75 return getEmptyRangesOffset(); 76 77 const auto RI = CachedRanges.find(Ranges); 78 if (RI != CachedRanges.end()) 79 return RI->second; 80 81 const uint64_t EntryOffset = addRanges(Ranges); 82 CachedRanges.emplace(std::move(Ranges), EntryOffset); 83 84 return EntryOffset; 85 } 86 87 uint64_t 88 DebugRangesSectionWriter::addRanges(const DebugAddressRangesVector &Ranges) { 89 if (Ranges.empty()) 90 return getEmptyRangesOffset(); 91 92 // Reading the SectionOffset and updating it should be atomic to guarantee 93 // unique and correct offsets in patches. 94 std::lock_guard<std::mutex> Lock(WriterMutex); 95 const uint32_t EntryOffset = SectionOffset; 96 SectionOffset += writeAddressRanges(*RangesStream.get(), Ranges); 97 98 return EntryOffset; 99 } 100 101 uint64_t DebugRangesSectionWriter::getSectionOffset() { 102 std::lock_guard<std::mutex> Lock(WriterMutex); 103 return SectionOffset; 104 } 105 106 void DebugARangesSectionWriter::addCURanges(uint64_t CUOffset, 107 DebugAddressRangesVector &&Ranges) { 108 std::lock_guard<std::mutex> Lock(CUAddressRangesMutex); 109 CUAddressRanges.emplace(CUOffset, std::move(Ranges)); 110 } 111 112 void DebugARangesSectionWriter::writeARangesSection( 113 raw_svector_ostream &RangesStream) const { 114 // For reference on the format of the .debug_aranges section, see the DWARF4 115 // specification, section 6.1.4 Lookup by Address 116 // http://www.dwarfstd.org/doc/DWARF4.pdf 117 for (const auto &CUOffsetAddressRangesPair : CUAddressRanges) { 118 const uint64_t Offset = CUOffsetAddressRangesPair.first; 119 const DebugAddressRangesVector &AddressRanges = 120 CUOffsetAddressRangesPair.second; 121 122 // Emit header. 123 124 // Size of this set: 8 (size of the header) + 4 (padding after header) 125 // + 2*sizeof(uint64_t) bytes for each of the ranges, plus an extra 126 // pair of uint64_t's for the terminating, zero-length range. 127 // Does not include size field itself. 128 uint32_t Size = 8 + 4 + 2*sizeof(uint64_t) * (AddressRanges.size() + 1); 129 130 // Header field #1: set size. 131 support::endian::write(RangesStream, Size, support::little); 132 133 // Header field #2: version number, 2 as per the specification. 134 support::endian::write(RangesStream, static_cast<uint16_t>(2), 135 support::little); 136 137 // Header field #3: debug info offset of the correspondent compile unit. 138 support::endian::write(RangesStream, static_cast<uint32_t>(Offset), 139 support::little); 140 141 // Header field #4: address size. 142 // 8 since we only write ELF64 binaries for now. 143 RangesStream << char(8); 144 145 // Header field #5: segment size of target architecture. 146 RangesStream << char(0); 147 148 // Padding before address table - 4 bytes in the 64-bit-pointer case. 149 support::endian::write(RangesStream, static_cast<uint32_t>(0), 150 support::little); 151 152 writeAddressRanges(RangesStream, AddressRanges, true); 153 } 154 } 155 156 DebugAddrWriter::DebugAddrWriter(BinaryContext *Bc) { BC = Bc; } 157 158 void DebugAddrWriter::AddressForDWOCU::dump() { 159 std::vector<IndexAddressPair> SortedMap(indexToAddressBegin(), 160 indexToAdddessEnd()); 161 // Sorting address in increasing order of indices. 162 std::sort(SortedMap.begin(), SortedMap.end(), 163 [](const IndexAddressPair &A, const IndexAddressPair &B) { 164 return A.first < B.first; 165 }); 166 for (auto &Pair : SortedMap) 167 dbgs() << Twine::utohexstr(Pair.second) << "\t" << Pair.first << "\n"; 168 } 169 uint32_t DebugAddrWriter::getIndexFromAddress(uint64_t Address, 170 uint64_t DWOId) { 171 if (!AddressMaps.count(DWOId)) 172 AddressMaps[DWOId] = AddressForDWOCU(); 173 174 AddressForDWOCU &Map = AddressMaps[DWOId]; 175 auto Entry = Map.find(Address); 176 if (Entry == Map.end()) { 177 auto Index = Map.getNextIndex(); 178 Entry = Map.insert(Address, Index).first; 179 } 180 return Entry->second; 181 } 182 183 // Case1) Address is not in map insert in to AddresToIndex and IndexToAddres 184 // Case2) Address is in the map but Index is higher or equal. Need to update 185 // IndexToAddrss. Case3) Address is in the map but Index is lower. Need to 186 // update AddressToIndex and IndexToAddress 187 void DebugAddrWriter::addIndexAddress(uint64_t Address, uint32_t Index, 188 uint64_t DWOId) { 189 AddressForDWOCU &Map = AddressMaps[DWOId]; 190 auto Entry = Map.find(Address); 191 if (Entry != Map.end()) { 192 if (Entry->second > Index) 193 Map.updateAddressToIndex(Address, Index); 194 Map.updateIndexToAddrss(Address, Index); 195 } else 196 Map.insert(Address, Index); 197 } 198 199 AddressSectionBuffer DebugAddrWriter::finalize() { 200 // Need to layout all sections within .debug_addr 201 // Within each section sort Address by index. 202 AddressSectionBuffer Buffer; 203 raw_svector_ostream AddressStream(Buffer); 204 for (std::unique_ptr<DWARFUnit> &CU : BC->DwCtx->compile_units()) { 205 Optional<uint64_t> DWOId = CU->getDWOId(); 206 // Handling the case wehre debug information is a mix of Debug fission and 207 // monolitic. 208 if (!DWOId) 209 continue; 210 auto AM = AddressMaps.find(*DWOId); 211 // Adding to map even if it did not contribute to .debug_addr. 212 // The Skeleton CU will still have DW_AT_GNU_addr_base. 213 DWOIdToOffsetMap[*DWOId] = Buffer.size(); 214 // If does not exist this CUs DWO section didn't contribute to .debug_addr. 215 if (AM == AddressMaps.end()) 216 continue; 217 std::vector<IndexAddressPair> SortedMap(AM->second.indexToAddressBegin(), 218 AM->second.indexToAdddessEnd()); 219 // Sorting address in increasing order of indices. 220 std::sort(SortedMap.begin(), SortedMap.end(), 221 [](const IndexAddressPair &A, const IndexAddressPair &B) { 222 return A.first < B.first; 223 }); 224 225 uint8_t AddrSize = CU->getAddressByteSize(); 226 uint32_t Counter = 0; 227 auto WriteAddress = [&](uint64_t Address) -> void { 228 ++Counter; 229 switch (AddrSize) { 230 default: 231 assert(false && "Address Size is invalid."); 232 break; 233 case 4: 234 support::endian::write(AddressStream, static_cast<uint32_t>(Address), 235 support::little); 236 break; 237 case 8: 238 support::endian::write(AddressStream, Address, support::little); 239 break; 240 } 241 }; 242 243 for (const IndexAddressPair &Val : SortedMap) { 244 while (Val.first > Counter) 245 WriteAddress(0); 246 WriteAddress(Val.second); 247 } 248 } 249 250 return Buffer; 251 } 252 253 uint64_t DebugAddrWriter::getOffset(uint64_t DWOId) { 254 auto Iter = DWOIdToOffsetMap.find(DWOId); 255 assert(Iter != DWOIdToOffsetMap.end() && 256 "Offset in to.debug_addr was not found for DWO ID."); 257 return Iter->second; 258 } 259 260 DebugLocWriter::DebugLocWriter(BinaryContext *BC) { 261 LocBuffer = std::make_unique<DebugBufferVector>(); 262 LocStream = std::make_unique<raw_svector_ostream>(*LocBuffer); 263 } 264 265 void DebugLocWriter::addList(uint64_t AttrOffset, 266 DebugLocationsVector &&LocList) { 267 if (LocList.empty()) { 268 EmptyAttrLists.push_back(AttrOffset); 269 return; 270 } 271 // Since there is a separate DebugLocWriter for each thread, 272 // we don't need a lock to read the SectionOffset and update it. 273 const uint32_t EntryOffset = SectionOffset; 274 275 for (const DebugLocationEntry &Entry : LocList) { 276 support::endian::write(*LocStream, static_cast<uint64_t>(Entry.LowPC), 277 support::little); 278 support::endian::write(*LocStream, static_cast<uint64_t>(Entry.HighPC), 279 support::little); 280 support::endian::write(*LocStream, static_cast<uint16_t>(Entry.Expr.size()), 281 support::little); 282 *LocStream << StringRef(reinterpret_cast<const char *>(Entry.Expr.data()), 283 Entry.Expr.size()); 284 SectionOffset += 2 * 8 + 2 + Entry.Expr.size(); 285 } 286 LocStream->write_zeros(16); 287 SectionOffset += 16; 288 LocListDebugInfoPatches.push_back({AttrOffset, EntryOffset}); 289 } 290 291 void DebugLoclistWriter::addList(uint64_t AttrOffset, 292 DebugLocationsVector &&LocList) { 293 Patches.push_back({AttrOffset, std::move(LocList)}); 294 } 295 296 std::unique_ptr<DebugBufferVector> DebugLocWriter::getBuffer() { 297 return std::move(LocBuffer); 298 } 299 300 // DWARF 4: 2.6.2 301 void DebugLocWriter::finalize(uint64_t SectionOffset, 302 SimpleBinaryPatcher &DebugInfoPatcher) { 303 for (const auto LocListDebugInfoPatchType : LocListDebugInfoPatches) { 304 uint64_t Offset = SectionOffset + LocListDebugInfoPatchType.LocListOffset; 305 DebugInfoPatcher.addLE32Patch(LocListDebugInfoPatchType.DebugInfoAttrOffset, 306 Offset); 307 } 308 309 for (uint64_t DebugInfoAttrOffset : EmptyAttrLists) 310 DebugInfoPatcher.addLE32Patch(DebugInfoAttrOffset, 311 DebugLocWriter::EmptyListOffset); 312 } 313 314 void DebugLoclistWriter::finalize(uint64_t SectionOffset, 315 SimpleBinaryPatcher &DebugInfoPatcher) { 316 for (LocPatch &Patch : Patches) { 317 if (Patch.LocList.empty()) { 318 DebugInfoPatcher.addLE32Patch(Patch.AttrOffset, 319 DebugLocWriter::EmptyListOffset); 320 continue; 321 } 322 const uint32_t EntryOffset = LocBuffer->size(); 323 for (const DebugLocationEntry &Entry : Patch.LocList) { 324 support::endian::write(*LocStream, 325 static_cast<uint8_t>(dwarf::DW_LLE_startx_length), 326 support::little); 327 uint32_t Index = AddrWriter->getIndexFromAddress(Entry.LowPC, DWOId); 328 encodeULEB128(Index, *LocStream); 329 330 // TODO: Support DWARF5 331 support::endian::write(*LocStream, 332 static_cast<uint32_t>(Entry.HighPC - Entry.LowPC), 333 support::little); 334 support::endian::write(*LocStream, 335 static_cast<uint16_t>(Entry.Expr.size()), 336 support::little); 337 *LocStream << StringRef(reinterpret_cast<const char *>(Entry.Expr.data()), 338 Entry.Expr.size()); 339 } 340 support::endian::write(*LocStream, 341 static_cast<uint8_t>(dwarf::DW_LLE_end_of_list), 342 support::little); 343 DebugInfoPatcher.addLE32Patch(Patch.AttrOffset, EntryOffset); 344 clearList(Patch.LocList); 345 } 346 clearList(Patches); 347 } 348 349 DebugAddrWriter *DebugLoclistWriter::AddrWriter = nullptr; 350 351 void SimpleBinaryPatcher::addBinaryPatch(uint32_t Offset, 352 const std::string &NewValue) { 353 Patches.emplace_back(Offset, NewValue); 354 } 355 356 void SimpleBinaryPatcher::addBytePatch(uint32_t Offset, uint8_t Value) { 357 Patches.emplace_back(Offset, std::string(1, Value)); 358 } 359 360 void SimpleBinaryPatcher::addLEPatch(uint32_t Offset, uint64_t NewValue, 361 size_t ByteSize) { 362 std::string LE64(ByteSize, 0); 363 for (size_t I = 0; I < ByteSize; ++I) { 364 LE64[I] = NewValue & 0xff; 365 NewValue >>= 8; 366 } 367 Patches.emplace_back(Offset, LE64); 368 } 369 370 void SimpleBinaryPatcher::addUDataPatch(uint32_t Offset, uint64_t Value, uint64_t Size) { 371 std::string Buff; 372 raw_string_ostream OS(Buff); 373 encodeULEB128(Value, OS, Size); 374 375 Patches.emplace_back(Offset, OS.str()); 376 } 377 378 void SimpleBinaryPatcher::addLE64Patch(uint32_t Offset, uint64_t NewValue) { 379 addLEPatch(Offset, NewValue, 8); 380 } 381 382 void SimpleBinaryPatcher::addLE32Patch(uint32_t Offset, uint32_t NewValue) { 383 addLEPatch(Offset, NewValue, 4); 384 } 385 386 void SimpleBinaryPatcher::patchBinary(std::string &BinaryContents, 387 uint32_t DWPOffset = 0) { 388 for (const auto &Patch : Patches) { 389 uint32_t Offset = Patch.first - DWPOffset; 390 const std::string &ByteSequence = Patch.second; 391 assert(Offset + ByteSequence.size() <= BinaryContents.size() && 392 "Applied patch runs over binary size."); 393 for (uint64_t I = 0, Size = ByteSequence.size(); I < Size; ++I) { 394 BinaryContents[Offset + I] = ByteSequence[I]; 395 } 396 } 397 } 398 399 void DebugStrWriter::create() { 400 StrBuffer = std::make_unique<DebugStrBufferVector>(); 401 StrStream = std::make_unique<raw_svector_ostream>(*StrBuffer); 402 } 403 404 void DebugStrWriter::initialize() { 405 auto StrSection = BC->DwCtx->getDWARFObj().getStrSection(); 406 (*StrStream) << StrSection; 407 } 408 409 uint32_t DebugStrWriter::addString(StringRef Str) { 410 if (StrBuffer->empty()) 411 initialize(); 412 auto Offset = StrBuffer->size(); 413 (*StrStream) << Str; 414 StrStream->write_zeros(1); 415 return Offset; 416 } 417 418 void DebugAbbrevWriter::addUnitAbbreviations(DWARFUnit &Unit) { 419 const DWARFAbbreviationDeclarationSet *Abbrevs = Unit.getAbbreviations(); 420 if (!Abbrevs) 421 return; 422 423 // Multiple units may share the same abbreviations. Only add abbreviations 424 // for the first unit and reuse them. 425 const uint64_t AbbrevOffset = Unit.getAbbreviationsOffset(); 426 if (CUAbbrevData.find(AbbrevOffset) != CUAbbrevData.end()) 427 return; 428 429 std::lock_guard<std::mutex> Lock(WriterMutex); 430 AbbrevData &UnitData = CUAbbrevData[AbbrevOffset]; 431 UnitData.Buffer = std::make_unique<DebugBufferVector>(); 432 UnitData.Stream = std::make_unique<raw_svector_ostream>(*UnitData.Buffer); 433 434 const auto &UnitPatches = Patches[&Unit]; 435 436 raw_svector_ostream &OS = *UnitData.Stream.get(); 437 438 // Take a fast path if there are no patches to apply. Simply copy the original 439 // contents. 440 if (UnitPatches.empty()) { 441 StringRef AbbrevSectionContents = 442 Unit.isDWOUnit() ? Unit.getContext().getDWARFObj().getAbbrevDWOSection() 443 : Unit.getContext().getDWARFObj().getAbbrevSection(); 444 StringRef AbbrevContents; 445 446 const DWARFUnitIndex &CUIndex = Unit.getContext().getCUIndex(); 447 if (!CUIndex.getRows().empty()) { 448 // Handle DWP section contribution. 449 const DWARFUnitIndex::Entry *DWOEntry = 450 CUIndex.getFromHash(*Unit.getDWOId()); 451 if (!DWOEntry) 452 return; 453 454 const DWARFUnitIndex::Entry::SectionContribution *DWOContrubution = 455 DWOEntry->getContribution(DWARFSectionKind::DW_SECT_ABBREV); 456 AbbrevContents = AbbrevSectionContents.substr(DWOContrubution->Offset, 457 DWOContrubution->Length); 458 } else { 459 DWARFCompileUnit *NextUnit = 460 Unit.getContext().getCompileUnitForOffset(Unit.getNextUnitOffset()); 461 const uint64_t StartOffset = Unit.getAbbreviationsOffset(); 462 const uint64_t EndOffset = NextUnit ? NextUnit->getAbbreviationsOffset() 463 : AbbrevSectionContents.size(); 464 AbbrevContents = AbbrevSectionContents.slice(StartOffset, EndOffset); 465 } 466 467 OS.reserveExtraSpace(AbbrevContents.size()); 468 OS << AbbrevContents; 469 470 return; 471 } 472 473 for (auto I = Abbrevs->begin(), E = Abbrevs->end(); I != E; ++I) { 474 const DWARFAbbreviationDeclaration &Abbrev = *I; 475 auto Patch = UnitPatches.find(&Abbrev); 476 477 encodeULEB128(Abbrev.getCode(), OS); 478 encodeULEB128(Abbrev.getTag(), OS); 479 encodeULEB128(Abbrev.hasChildren(), OS); 480 for (const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec : 481 Abbrev.attributes()) { 482 if (Patch != UnitPatches.end()) { 483 bool Patched = false; 484 // Patches added later take a precedence over earlier ones. 485 for (auto I = Patch->second.rbegin(), E = Patch->second.rend(); I != E; 486 ++I) { 487 if (I->OldAttr != AttrSpec.Attr) 488 continue; 489 490 encodeULEB128(I->NewAttr, OS); 491 encodeULEB128(I->NewAttrForm, OS); 492 Patched = true; 493 break; 494 } 495 if (Patched) 496 continue; 497 } 498 499 encodeULEB128(AttrSpec.Attr, OS); 500 encodeULEB128(AttrSpec.Form, OS); 501 if (AttrSpec.isImplicitConst()) 502 encodeSLEB128(AttrSpec.getImplicitConstValue(), OS); 503 } 504 505 encodeULEB128(0, OS); 506 encodeULEB128(0, OS); 507 } 508 encodeULEB128(0, OS); 509 } 510 511 std::unique_ptr<DebugBufferVector> DebugAbbrevWriter::finalize() { 512 DebugBufferVector ReturnBuffer; 513 514 // Pre-calculate the total size of abbrev section. 515 uint64_t Size = 0; 516 for (const auto &KV : CUAbbrevData) { 517 const AbbrevData &UnitData = KV.second; 518 Size += UnitData.Buffer->size(); 519 } 520 ReturnBuffer.reserve(Size); 521 522 uint64_t Pos = 0; 523 for (auto &KV : CUAbbrevData) { 524 AbbrevData &UnitData = KV.second; 525 ReturnBuffer.append(*UnitData.Buffer); 526 UnitData.Offset = Pos; 527 Pos += UnitData.Buffer->size(); 528 529 UnitData.Buffer.reset(); 530 UnitData.Stream.reset(); 531 } 532 533 return std::make_unique<DebugBufferVector>(ReturnBuffer); 534 } 535 536 static void emitDwarfSetLineAddrAbs(MCStreamer &OS, 537 MCDwarfLineTableParams Params, 538 int64_t LineDelta, uint64_t Address, 539 int PointerSize) { 540 // emit the sequence to set the address 541 OS.emitIntValue(dwarf::DW_LNS_extended_op, 1); 542 OS.emitULEB128IntValue(PointerSize + 1); 543 OS.emitIntValue(dwarf::DW_LNE_set_address, 1); 544 OS.emitIntValue(Address, PointerSize); 545 546 // emit the sequence for the LineDelta (from 1) and a zero address delta. 547 MCDwarfLineAddr::Emit(&OS, Params, LineDelta, 0); 548 } 549 550 static inline void emitBinaryDwarfLineTable( 551 MCStreamer *MCOS, MCDwarfLineTableParams Params, 552 const DWARFDebugLine::LineTable *Table, 553 const std::vector<DwarfLineTable::RowSequence> &InputSequences) { 554 if (InputSequences.empty()) 555 return; 556 557 constexpr uint64_t InvalidAddress = UINT64_MAX; 558 unsigned FileNum = 1; 559 unsigned LastLine = 1; 560 unsigned Column = 0; 561 unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 562 unsigned Isa = 0; 563 unsigned Discriminator = 0; 564 uint64_t LastAddress = InvalidAddress; 565 uint64_t PrevEndOfSequence = InvalidAddress; 566 const MCAsmInfo *AsmInfo = MCOS->getContext().getAsmInfo(); 567 568 auto emitEndOfSequence = [&](uint64_t Address) { 569 MCDwarfLineAddr::Emit(MCOS, Params, INT64_MAX, Address - LastAddress); 570 FileNum = 1; 571 LastLine = 1; 572 Column = 0; 573 Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 574 Isa = 0; 575 Discriminator = 0; 576 LastAddress = InvalidAddress; 577 }; 578 579 for (const DwarfLineTable::RowSequence &Sequence : InputSequences) { 580 const uint64_t SequenceStart = 581 Table->Rows[Sequence.FirstIndex].Address.Address; 582 583 // Check if we need to mark the end of the sequence. 584 if (PrevEndOfSequence != InvalidAddress && LastAddress != InvalidAddress && 585 PrevEndOfSequence != SequenceStart) { 586 emitEndOfSequence(PrevEndOfSequence); 587 } 588 589 for (uint32_t RowIndex = Sequence.FirstIndex; 590 RowIndex <= Sequence.LastIndex; ++RowIndex) { 591 const DWARFDebugLine::Row &Row = Table->Rows[RowIndex]; 592 int64_t LineDelta = static_cast<int64_t>(Row.Line) - LastLine; 593 const uint64_t Address = Row.Address.Address; 594 595 if (FileNum != Row.File) { 596 FileNum = Row.File; 597 MCOS->emitInt8(dwarf::DW_LNS_set_file); 598 MCOS->emitULEB128IntValue(FileNum); 599 } 600 if (Column != Row.Column) { 601 Column = Row.Column; 602 MCOS->emitInt8(dwarf::DW_LNS_set_column); 603 MCOS->emitULEB128IntValue(Column); 604 } 605 if (Discriminator != Row.Discriminator && 606 MCOS->getContext().getDwarfVersion() >= 4) { 607 Discriminator = Row.Discriminator; 608 unsigned Size = getULEB128Size(Discriminator); 609 MCOS->emitInt8(dwarf::DW_LNS_extended_op); 610 MCOS->emitULEB128IntValue(Size + 1); 611 MCOS->emitInt8(dwarf::DW_LNE_set_discriminator); 612 MCOS->emitULEB128IntValue(Discriminator); 613 } 614 if (Isa != Row.Isa) { 615 Isa = Row.Isa; 616 MCOS->emitInt8(dwarf::DW_LNS_set_isa); 617 MCOS->emitULEB128IntValue(Isa); 618 } 619 if (Row.IsStmt != Flags) { 620 Flags = Row.IsStmt; 621 MCOS->emitInt8(dwarf::DW_LNS_negate_stmt); 622 } 623 if (Row.BasicBlock) 624 MCOS->emitInt8(dwarf::DW_LNS_set_basic_block); 625 if (Row.PrologueEnd) 626 MCOS->emitInt8(dwarf::DW_LNS_set_prologue_end); 627 if (Row.EpilogueBegin) 628 MCOS->emitInt8(dwarf::DW_LNS_set_epilogue_begin); 629 630 // The end of the sequence is not normal in the middle of the input 631 // sequence, but could happen, e.g. for assembly code. 632 if (Row.EndSequence) { 633 emitEndOfSequence(Address); 634 } else { 635 if (LastAddress == InvalidAddress) 636 emitDwarfSetLineAddrAbs(*MCOS, Params, LineDelta, Address, 637 AsmInfo->getCodePointerSize()); 638 else 639 MCDwarfLineAddr::Emit(MCOS, Params, LineDelta, Address - LastAddress); 640 641 LastAddress = Address; 642 LastLine = Row.Line; 643 } 644 645 Discriminator = 0; 646 } 647 PrevEndOfSequence = Sequence.EndAddress; 648 } 649 650 // Finish with the end of the sequence. 651 if (LastAddress != InvalidAddress) 652 emitEndOfSequence(PrevEndOfSequence); 653 } 654 655 // This function is similar to the one from MCDwarfLineTable, except it handles 656 // end-of-sequence entries differently by utilizing line entries with 657 // DWARF2_FLAG_END_SEQUENCE flag. 658 static inline void emitDwarfLineTable( 659 MCStreamer *MCOS, MCSection *Section, 660 const MCLineSection::MCDwarfLineEntryCollection &LineEntries) { 661 unsigned FileNum = 1; 662 unsigned LastLine = 1; 663 unsigned Column = 0; 664 unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 665 unsigned Isa = 0; 666 unsigned Discriminator = 0; 667 MCSymbol *LastLabel = nullptr; 668 const MCAsmInfo *AsmInfo = MCOS->getContext().getAsmInfo(); 669 670 // Loop through each MCDwarfLineEntry and encode the dwarf line number table. 671 for (const MCDwarfLineEntry &LineEntry : LineEntries) { 672 if (LineEntry.getFlags() & DWARF2_FLAG_END_SEQUENCE) { 673 MCOS->emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, LineEntry.getLabel(), 674 AsmInfo->getCodePointerSize()); 675 FileNum = 1; 676 LastLine = 1; 677 Column = 0; 678 Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 679 Isa = 0; 680 Discriminator = 0; 681 LastLabel = nullptr; 682 continue; 683 } 684 685 int64_t LineDelta = static_cast<int64_t>(LineEntry.getLine()) - LastLine; 686 687 if (FileNum != LineEntry.getFileNum()) { 688 FileNum = LineEntry.getFileNum(); 689 MCOS->emitInt8(dwarf::DW_LNS_set_file); 690 MCOS->emitULEB128IntValue(FileNum); 691 } 692 if (Column != LineEntry.getColumn()) { 693 Column = LineEntry.getColumn(); 694 MCOS->emitInt8(dwarf::DW_LNS_set_column); 695 MCOS->emitULEB128IntValue(Column); 696 } 697 if (Discriminator != LineEntry.getDiscriminator() && 698 MCOS->getContext().getDwarfVersion() >= 4) { 699 Discriminator = LineEntry.getDiscriminator(); 700 unsigned Size = getULEB128Size(Discriminator); 701 MCOS->emitInt8(dwarf::DW_LNS_extended_op); 702 MCOS->emitULEB128IntValue(Size + 1); 703 MCOS->emitInt8(dwarf::DW_LNE_set_discriminator); 704 MCOS->emitULEB128IntValue(Discriminator); 705 } 706 if (Isa != LineEntry.getIsa()) { 707 Isa = LineEntry.getIsa(); 708 MCOS->emitInt8(dwarf::DW_LNS_set_isa); 709 MCOS->emitULEB128IntValue(Isa); 710 } 711 if ((LineEntry.getFlags() ^ Flags) & DWARF2_FLAG_IS_STMT) { 712 Flags = LineEntry.getFlags(); 713 MCOS->emitInt8(dwarf::DW_LNS_negate_stmt); 714 } 715 if (LineEntry.getFlags() & DWARF2_FLAG_BASIC_BLOCK) 716 MCOS->emitInt8(dwarf::DW_LNS_set_basic_block); 717 if (LineEntry.getFlags() & DWARF2_FLAG_PROLOGUE_END) 718 MCOS->emitInt8(dwarf::DW_LNS_set_prologue_end); 719 if (LineEntry.getFlags() & DWARF2_FLAG_EPILOGUE_BEGIN) 720 MCOS->emitInt8(dwarf::DW_LNS_set_epilogue_begin); 721 722 MCSymbol *Label = LineEntry.getLabel(); 723 724 // At this point we want to emit/create the sequence to encode the delta 725 // in line numbers and the increment of the address from the previous 726 // Label and the current Label. 727 MCOS->emitDwarfAdvanceLineAddr(LineDelta, LastLabel, Label, 728 AsmInfo->getCodePointerSize()); 729 Discriminator = 0; 730 LastLine = LineEntry.getLine(); 731 LastLabel = Label; 732 } 733 734 assert(LastLabel == nullptr && "end of sequence expected"); 735 } 736 737 void DwarfLineTable::emitCU(MCStreamer *MCOS, MCDwarfLineTableParams Params, 738 Optional<MCDwarfLineStr> &LineStr) const { 739 if (!RawData.empty()) { 740 assert(MCLineSections.getMCLineEntries().empty() && 741 InputSequences.empty() && 742 "cannot combine raw data with new line entries"); 743 MCOS->emitLabel(getLabel()); 744 MCOS->emitBytes(RawData); 745 746 return; 747 } 748 749 MCSymbol *LineEndSym = Header.Emit(MCOS, Params, LineStr).second; 750 751 // Put out the line tables. 752 for (const auto &LineSec : MCLineSections.getMCLineEntries()) 753 emitDwarfLineTable(MCOS, LineSec.first, LineSec.second); 754 755 // Emit line tables for the original code. 756 emitBinaryDwarfLineTable(MCOS, Params, InputTable, InputSequences); 757 758 // This is the end of the section, so set the value of the symbol at the end 759 // of this section (that was used in a previous expression). 760 MCOS->emitLabel(LineEndSym); 761 } 762 763 void DwarfLineTable::emit(BinaryContext &BC, MCStreamer &Streamer) { 764 MCAssembler &Assembler = 765 static_cast<MCObjectStreamer *>(&Streamer)->getAssembler(); 766 767 MCDwarfLineTableParams Params = Assembler.getDWARFLinetableParams(); 768 769 auto &LineTables = BC.getDwarfLineTables(); 770 771 // Bail out early so we don't switch to the debug_line section needlessly and 772 // in doing so create an unnecessary (if empty) section. 773 if (LineTables.empty()) 774 return; 775 776 // In a v5 non-split line table, put the strings in a separate section. 777 Optional<MCDwarfLineStr> LineStr(None); 778 if (BC.Ctx->getDwarfVersion() >= 5) 779 LineStr = MCDwarfLineStr(*BC.Ctx); 780 781 // Switch to the section where the table will be emitted into. 782 Streamer.SwitchSection(BC.MOFI->getDwarfLineSection()); 783 784 // Handle the rest of the Compile Units. 785 for (auto &CUIDTablePair : LineTables) { 786 CUIDTablePair.second.emitCU(&Streamer, Params, LineStr); 787 } 788 } 789 790 } // namespace bolt 791 } // namespace llvm 792