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/BinaryBasicBlock.h" 15 #include "bolt/Core/BinaryFunction.h" 16 #include "bolt/Utils/Utils.h" 17 #include "llvm/MC/MCObjectStreamer.h" 18 #include "llvm/MC/MCSymbol.h" 19 #include "llvm/Support/CommandLine.h" 20 #include "llvm/Support/EndianStream.h" 21 #include "llvm/Support/LEB128.h" 22 #include <algorithm> 23 #include <cassert> 24 #include <cstdint> 25 #include <limits> 26 27 #define DEBUG_TYPE "bolt-debug-info" 28 29 namespace opts { 30 extern llvm::cl::opt<unsigned> Verbosity; 31 } 32 33 namespace llvm { 34 namespace bolt { 35 36 const DebugLineTableRowRef DebugLineTableRowRef::NULL_ROW{0, 0}; 37 38 namespace { 39 40 // Writes address ranges to Writer as pairs of 64-bit (address, size). 41 // If RelativeRange is true, assumes the address range to be written must be of 42 // the form (begin address, range size), otherwise (begin address, end address). 43 // Terminates the list by writing a pair of two zeroes. 44 // Returns the number of written bytes. 45 uint64_t writeAddressRanges(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 200 AddressSectionBuffer DebugAddrWriter::finalize() { 201 // Need to layout all sections within .debug_addr 202 // Within each section sort Address by index. 203 AddressSectionBuffer Buffer; 204 raw_svector_ostream AddressStream(Buffer); 205 for (std::unique_ptr<DWARFUnit> &CU : BC->DwCtx->compile_units()) { 206 Optional<uint64_t> DWOId = CU->getDWOId(); 207 // Handling the case wehre debug information is a mix of Debug fission and 208 // monolitic. 209 if (!DWOId) 210 continue; 211 auto AM = AddressMaps.find(*DWOId); 212 // Adding to map even if it did not contribute to .debug_addr. 213 // The Skeleton CU will still have DW_AT_GNU_addr_base. 214 DWOIdToOffsetMap[*DWOId] = Buffer.size(); 215 // If does not exist this CUs DWO section didn't contribute to .debug_addr. 216 if (AM == AddressMaps.end()) 217 continue; 218 std::vector<IndexAddressPair> SortedMap(AM->second.indexToAddressBegin(), 219 AM->second.indexToAdddessEnd()); 220 // Sorting address in increasing order of indices. 221 std::sort(SortedMap.begin(), SortedMap.end(), 222 [](const IndexAddressPair &A, const IndexAddressPair &B) { 223 return A.first < B.first; 224 }); 225 226 uint8_t AddrSize = CU->getAddressByteSize(); 227 uint32_t Counter = 0; 228 auto WriteAddress = [&](uint64_t Address) -> void { 229 ++Counter; 230 switch (AddrSize) { 231 default: 232 assert(false && "Address Size is invalid."); 233 break; 234 case 4: 235 support::endian::write(AddressStream, static_cast<uint32_t>(Address), 236 support::little); 237 break; 238 case 8: 239 support::endian::write(AddressStream, Address, support::little); 240 break; 241 } 242 }; 243 244 for (const IndexAddressPair &Val : SortedMap) { 245 while (Val.first > Counter) 246 WriteAddress(0); 247 WriteAddress(Val.second); 248 } 249 } 250 251 return Buffer; 252 } 253 254 uint64_t DebugAddrWriter::getOffset(uint64_t DWOId) { 255 auto Iter = DWOIdToOffsetMap.find(DWOId); 256 assert(Iter != DWOIdToOffsetMap.end() && 257 "Offset in to.debug_addr was not found for DWO ID."); 258 return Iter->second; 259 } 260 261 DebugLocWriter::DebugLocWriter(BinaryContext *BC) { 262 LocBuffer = std::make_unique<DebugBufferVector>(); 263 LocStream = std::make_unique<raw_svector_ostream>(*LocBuffer); 264 } 265 266 void DebugLocWriter::addList(uint64_t AttrOffset, 267 DebugLocationsVector &&LocList) { 268 if (LocList.empty()) { 269 EmptyAttrLists.push_back(AttrOffset); 270 return; 271 } 272 // Since there is a separate DebugLocWriter for each thread, 273 // we don't need a lock to read the SectionOffset and update it. 274 const uint32_t EntryOffset = SectionOffset; 275 276 for (const DebugLocationEntry &Entry : LocList) { 277 support::endian::write(*LocStream, static_cast<uint64_t>(Entry.LowPC), 278 support::little); 279 support::endian::write(*LocStream, static_cast<uint64_t>(Entry.HighPC), 280 support::little); 281 support::endian::write(*LocStream, static_cast<uint16_t>(Entry.Expr.size()), 282 support::little); 283 *LocStream << StringRef(reinterpret_cast<const char *>(Entry.Expr.data()), 284 Entry.Expr.size()); 285 SectionOffset += 2 * 8 + 2 + Entry.Expr.size(); 286 } 287 LocStream->write_zeros(16); 288 SectionOffset += 16; 289 LocListDebugInfoPatches.push_back({AttrOffset, EntryOffset}); 290 } 291 292 void DebugLoclistWriter::addList(uint64_t AttrOffset, 293 DebugLocationsVector &&LocList) { 294 Patches.push_back({AttrOffset, std::move(LocList)}); 295 } 296 297 std::unique_ptr<DebugBufferVector> DebugLocWriter::getBuffer() { 298 return std::move(LocBuffer); 299 } 300 301 // DWARF 4: 2.6.2 302 void DebugLocWriter::finalize(uint64_t SectionOffset, 303 SimpleBinaryPatcher &DebugInfoPatcher) { 304 for (const auto LocListDebugInfoPatchType : LocListDebugInfoPatches) { 305 uint64_t Offset = SectionOffset + LocListDebugInfoPatchType.LocListOffset; 306 DebugInfoPatcher.addLE32Patch(LocListDebugInfoPatchType.DebugInfoAttrOffset, 307 Offset); 308 } 309 310 for (uint64_t DebugInfoAttrOffset : EmptyAttrLists) 311 DebugInfoPatcher.addLE32Patch(DebugInfoAttrOffset, 312 DebugLocWriter::EmptyListOffset); 313 } 314 315 void DebugLoclistWriter::finalize(uint64_t SectionOffset, 316 SimpleBinaryPatcher &DebugInfoPatcher) { 317 for (LocPatch &Patch : Patches) { 318 if (Patch.LocList.empty()) { 319 DebugInfoPatcher.addLE32Patch(Patch.AttrOffset, 320 DebugLocWriter::EmptyListOffset); 321 continue; 322 } 323 const uint32_t EntryOffset = LocBuffer->size(); 324 for (const DebugLocationEntry &Entry : Patch.LocList) { 325 support::endian::write(*LocStream, 326 static_cast<uint8_t>(dwarf::DW_LLE_startx_length), 327 support::little); 328 uint32_t Index = AddrWriter->getIndexFromAddress(Entry.LowPC, DWOId); 329 encodeULEB128(Index, *LocStream); 330 331 // TODO: Support DWARF5 332 support::endian::write(*LocStream, 333 static_cast<uint32_t>(Entry.HighPC - Entry.LowPC), 334 support::little); 335 support::endian::write(*LocStream, 336 static_cast<uint16_t>(Entry.Expr.size()), 337 support::little); 338 *LocStream << StringRef(reinterpret_cast<const char *>(Entry.Expr.data()), 339 Entry.Expr.size()); 340 } 341 support::endian::write(*LocStream, 342 static_cast<uint8_t>(dwarf::DW_LLE_end_of_list), 343 support::little); 344 DebugInfoPatcher.addLE32Patch(Patch.AttrOffset, EntryOffset); 345 clearList(Patch.LocList); 346 } 347 clearList(Patches); 348 } 349 350 DebugAddrWriter *DebugLoclistWriter::AddrWriter = nullptr; 351 352 void SimpleBinaryPatcher::addBinaryPatch(uint32_t Offset, 353 const std::string &NewValue) { 354 Patches.emplace_back(Offset, NewValue); 355 } 356 357 void SimpleBinaryPatcher::addBytePatch(uint32_t Offset, uint8_t Value) { 358 Patches.emplace_back(Offset, std::string(1, Value)); 359 } 360 361 void SimpleBinaryPatcher::addLEPatch(uint32_t Offset, uint64_t NewValue, 362 size_t ByteSize) { 363 std::string LE64(ByteSize, 0); 364 for (size_t I = 0; I < ByteSize; ++I) { 365 LE64[I] = NewValue & 0xff; 366 NewValue >>= 8; 367 } 368 Patches.emplace_back(Offset, LE64); 369 } 370 371 void SimpleBinaryPatcher::addUDataPatch(uint32_t Offset, uint64_t Value, 372 uint64_t Size) { 373 std::string Buff; 374 raw_string_ostream OS(Buff); 375 encodeULEB128(Value, OS, Size); 376 377 Patches.emplace_back(Offset, OS.str()); 378 } 379 380 void SimpleBinaryPatcher::addLE64Patch(uint32_t Offset, uint64_t NewValue) { 381 addLEPatch(Offset, NewValue, 8); 382 } 383 384 void SimpleBinaryPatcher::addLE32Patch(uint32_t Offset, uint32_t NewValue) { 385 addLEPatch(Offset, NewValue, 4); 386 } 387 388 void SimpleBinaryPatcher::patchBinary(std::string &BinaryContents, 389 uint32_t DWPOffset = 0) { 390 for (const auto &Patch : Patches) { 391 uint32_t Offset = Patch.first - DWPOffset; 392 const std::string &ByteSequence = Patch.second; 393 assert(Offset + ByteSequence.size() <= BinaryContents.size() && 394 "Applied patch runs over binary size."); 395 for (uint64_t I = 0, Size = ByteSequence.size(); I < Size; ++I) { 396 BinaryContents[Offset + I] = ByteSequence[I]; 397 } 398 } 399 } 400 401 void DebugStrWriter::create() { 402 StrBuffer = std::make_unique<DebugStrBufferVector>(); 403 StrStream = std::make_unique<raw_svector_ostream>(*StrBuffer); 404 } 405 406 void DebugStrWriter::initialize() { 407 auto StrSection = BC->DwCtx->getDWARFObj().getStrSection(); 408 (*StrStream) << StrSection; 409 } 410 411 uint32_t DebugStrWriter::addString(StringRef Str) { 412 if (StrBuffer->empty()) 413 initialize(); 414 auto Offset = StrBuffer->size(); 415 (*StrStream) << Str; 416 StrStream->write_zeros(1); 417 return Offset; 418 } 419 420 void DebugAbbrevWriter::addUnitAbbreviations(DWARFUnit &Unit) { 421 const DWARFAbbreviationDeclarationSet *Abbrevs = Unit.getAbbreviations(); 422 if (!Abbrevs) 423 return; 424 425 // Multiple units may share the same abbreviations. Only add abbreviations 426 // for the first unit and reuse them. 427 const uint64_t AbbrevOffset = Unit.getAbbreviationsOffset(); 428 if (UnitsAbbrevData.find(AbbrevOffset) != UnitsAbbrevData.end()) 429 return; 430 431 AbbrevData &UnitData = UnitsAbbrevData[AbbrevOffset]; 432 UnitData.Buffer = std::make_unique<DebugBufferVector>(); 433 UnitData.Stream = std::make_unique<raw_svector_ostream>(*UnitData.Buffer); 434 435 const PatchesTy &UnitPatches = Patches[&Unit]; 436 437 raw_svector_ostream &OS = *UnitData.Stream.get(); 438 439 // Take a fast path if there are no patches to apply. Simply copy the original 440 // contents. 441 if (UnitPatches.empty()) { 442 StringRef AbbrevSectionContents = 443 Unit.isDWOUnit() ? Unit.getContext().getDWARFObj().getAbbrevDWOSection() 444 : Unit.getContext().getDWARFObj().getAbbrevSection(); 445 StringRef AbbrevContents; 446 447 const DWARFUnitIndex &CUIndex = Unit.getContext().getCUIndex(); 448 if (!CUIndex.getRows().empty()) { 449 // Handle DWP section contribution. 450 const DWARFUnitIndex::Entry *DWOEntry = 451 CUIndex.getFromHash(*Unit.getDWOId()); 452 if (!DWOEntry) 453 return; 454 455 const DWARFUnitIndex::Entry::SectionContribution *DWOContrubution = 456 DWOEntry->getContribution(DWARFSectionKind::DW_SECT_ABBREV); 457 AbbrevContents = AbbrevSectionContents.substr(DWOContrubution->Offset, 458 DWOContrubution->Length); 459 } else if (!Unit.isDWOUnit()) { 460 const uint64_t StartOffset = Unit.getAbbreviationsOffset(); 461 462 // We know where the unit's abbreviation set starts, but not where it ends 463 // as such data is not readily available. Hence, we have to build a sorted 464 // list of start addresses and find the next starting address to determine 465 // the set boundaries. 466 // 467 // FIXME: if we had a full access to DWARFDebugAbbrev::AbbrDeclSets 468 // we wouldn't have to build our own sorted list for the quick lookup. 469 if (AbbrevSetOffsets.empty()) { 470 llvm::for_each( 471 *Unit.getContext().getDebugAbbrev(), 472 [&](const std::pair<uint64_t, DWARFAbbreviationDeclarationSet> &P) { 473 AbbrevSetOffsets.push_back(P.first); 474 }); 475 llvm::sort(AbbrevSetOffsets); 476 } 477 auto It = llvm::upper_bound(AbbrevSetOffsets, StartOffset); 478 const uint64_t EndOffset = 479 It == AbbrevSetOffsets.end() ? AbbrevSectionContents.size() : *It; 480 AbbrevContents = AbbrevSectionContents.slice(StartOffset, EndOffset); 481 } else { 482 // For DWO unit outside of DWP, we expect the entire section to hold 483 // abbreviations for this unit only. 484 AbbrevContents = AbbrevSectionContents; 485 } 486 487 OS.reserveExtraSpace(AbbrevContents.size()); 488 OS << AbbrevContents; 489 490 return; 491 } 492 493 for (auto I = Abbrevs->begin(), E = Abbrevs->end(); I != E; ++I) { 494 const DWARFAbbreviationDeclaration &Abbrev = *I; 495 auto Patch = UnitPatches.find(&Abbrev); 496 497 encodeULEB128(Abbrev.getCode(), OS); 498 encodeULEB128(Abbrev.getTag(), OS); 499 encodeULEB128(Abbrev.hasChildren(), OS); 500 for (const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec : 501 Abbrev.attributes()) { 502 if (Patch != UnitPatches.end()) { 503 bool Patched = false; 504 // Patches added later take a precedence over earlier ones. 505 for (auto I = Patch->second.rbegin(), E = Patch->second.rend(); I != E; 506 ++I) { 507 if (I->OldAttr != AttrSpec.Attr) 508 continue; 509 510 encodeULEB128(I->NewAttr, OS); 511 encodeULEB128(I->NewAttrForm, OS); 512 Patched = true; 513 break; 514 } 515 if (Patched) 516 continue; 517 } 518 519 encodeULEB128(AttrSpec.Attr, OS); 520 encodeULEB128(AttrSpec.Form, OS); 521 if (AttrSpec.isImplicitConst()) 522 encodeSLEB128(AttrSpec.getImplicitConstValue(), OS); 523 } 524 525 encodeULEB128(0, OS); 526 encodeULEB128(0, OS); 527 } 528 encodeULEB128(0, OS); 529 } 530 531 std::unique_ptr<DebugBufferVector> DebugAbbrevWriter::finalize() { 532 if (DWOId) { 533 // We expect abbrev_offset to always be zero for DWO units as there 534 // should be one CU per DWO, and TUs should share the same abbreviation 535 // set with the CU. 536 // For DWP AbbreviationsOffset is an Abbrev contribution in the DWP file, so 537 // can be none zero. Thus we are skipping the check for DWP. 538 bool IsDWP = !Context.getCUIndex().getRows().empty(); 539 if (!IsDWP) { 540 for (const std::unique_ptr<DWARFUnit> &Unit : Context.dwo_units()) { 541 if (Unit->getAbbreviationsOffset() != 0) { 542 errs() << "BOLT-ERROR: detected DWO unit with non-zero abbr_offset. " 543 "Unable to update debug info.\n"; 544 exit(1); 545 } 546 } 547 } 548 549 // Issue abbreviations for the DWO CU only. 550 addUnitAbbreviations(*Context.getDWOCompileUnitForHash(*DWOId)); 551 } else { 552 // Add abbreviations from compile and type non-DWO units. 553 for (const std::unique_ptr<DWARFUnit> &Unit : Context.normal_units()) 554 addUnitAbbreviations(*Unit); 555 } 556 557 DebugBufferVector ReturnBuffer; 558 559 // Pre-calculate the total size of abbrev section. 560 uint64_t Size = 0; 561 for (const auto &KV : UnitsAbbrevData) { 562 const AbbrevData &UnitData = KV.second; 563 Size += UnitData.Buffer->size(); 564 } 565 ReturnBuffer.reserve(Size); 566 567 uint64_t Pos = 0; 568 for (auto &KV : UnitsAbbrevData) { 569 AbbrevData &UnitData = KV.second; 570 ReturnBuffer.append(*UnitData.Buffer); 571 UnitData.Offset = Pos; 572 Pos += UnitData.Buffer->size(); 573 574 UnitData.Buffer.reset(); 575 UnitData.Stream.reset(); 576 } 577 578 return std::make_unique<DebugBufferVector>(ReturnBuffer); 579 } 580 581 static void emitDwarfSetLineAddrAbs(MCStreamer &OS, 582 MCDwarfLineTableParams Params, 583 int64_t LineDelta, uint64_t Address, 584 int PointerSize) { 585 // emit the sequence to set the address 586 OS.emitIntValue(dwarf::DW_LNS_extended_op, 1); 587 OS.emitULEB128IntValue(PointerSize + 1); 588 OS.emitIntValue(dwarf::DW_LNE_set_address, 1); 589 OS.emitIntValue(Address, PointerSize); 590 591 // emit the sequence for the LineDelta (from 1) and a zero address delta. 592 MCDwarfLineAddr::Emit(&OS, Params, LineDelta, 0); 593 } 594 595 static inline void emitBinaryDwarfLineTable( 596 MCStreamer *MCOS, MCDwarfLineTableParams Params, 597 const DWARFDebugLine::LineTable *Table, 598 const std::vector<DwarfLineTable::RowSequence> &InputSequences) { 599 if (InputSequences.empty()) 600 return; 601 602 constexpr uint64_t InvalidAddress = UINT64_MAX; 603 unsigned FileNum = 1; 604 unsigned LastLine = 1; 605 unsigned Column = 0; 606 unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 607 unsigned Isa = 0; 608 unsigned Discriminator = 0; 609 uint64_t LastAddress = InvalidAddress; 610 uint64_t PrevEndOfSequence = InvalidAddress; 611 const MCAsmInfo *AsmInfo = MCOS->getContext().getAsmInfo(); 612 613 auto emitEndOfSequence = [&](uint64_t Address) { 614 MCDwarfLineAddr::Emit(MCOS, Params, INT64_MAX, Address - LastAddress); 615 FileNum = 1; 616 LastLine = 1; 617 Column = 0; 618 Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 619 Isa = 0; 620 Discriminator = 0; 621 LastAddress = InvalidAddress; 622 }; 623 624 for (const DwarfLineTable::RowSequence &Sequence : InputSequences) { 625 const uint64_t SequenceStart = 626 Table->Rows[Sequence.FirstIndex].Address.Address; 627 628 // Check if we need to mark the end of the sequence. 629 if (PrevEndOfSequence != InvalidAddress && LastAddress != InvalidAddress && 630 PrevEndOfSequence != SequenceStart) { 631 emitEndOfSequence(PrevEndOfSequence); 632 } 633 634 for (uint32_t RowIndex = Sequence.FirstIndex; 635 RowIndex <= Sequence.LastIndex; ++RowIndex) { 636 const DWARFDebugLine::Row &Row = Table->Rows[RowIndex]; 637 int64_t LineDelta = static_cast<int64_t>(Row.Line) - LastLine; 638 const uint64_t Address = Row.Address.Address; 639 640 if (FileNum != Row.File) { 641 FileNum = Row.File; 642 MCOS->emitInt8(dwarf::DW_LNS_set_file); 643 MCOS->emitULEB128IntValue(FileNum); 644 } 645 if (Column != Row.Column) { 646 Column = Row.Column; 647 MCOS->emitInt8(dwarf::DW_LNS_set_column); 648 MCOS->emitULEB128IntValue(Column); 649 } 650 if (Discriminator != Row.Discriminator && 651 MCOS->getContext().getDwarfVersion() >= 4) { 652 Discriminator = Row.Discriminator; 653 unsigned Size = getULEB128Size(Discriminator); 654 MCOS->emitInt8(dwarf::DW_LNS_extended_op); 655 MCOS->emitULEB128IntValue(Size + 1); 656 MCOS->emitInt8(dwarf::DW_LNE_set_discriminator); 657 MCOS->emitULEB128IntValue(Discriminator); 658 } 659 if (Isa != Row.Isa) { 660 Isa = Row.Isa; 661 MCOS->emitInt8(dwarf::DW_LNS_set_isa); 662 MCOS->emitULEB128IntValue(Isa); 663 } 664 if (Row.IsStmt != Flags) { 665 Flags = Row.IsStmt; 666 MCOS->emitInt8(dwarf::DW_LNS_negate_stmt); 667 } 668 if (Row.BasicBlock) 669 MCOS->emitInt8(dwarf::DW_LNS_set_basic_block); 670 if (Row.PrologueEnd) 671 MCOS->emitInt8(dwarf::DW_LNS_set_prologue_end); 672 if (Row.EpilogueBegin) 673 MCOS->emitInt8(dwarf::DW_LNS_set_epilogue_begin); 674 675 // The end of the sequence is not normal in the middle of the input 676 // sequence, but could happen, e.g. for assembly code. 677 if (Row.EndSequence) { 678 emitEndOfSequence(Address); 679 } else { 680 if (LastAddress == InvalidAddress) 681 emitDwarfSetLineAddrAbs(*MCOS, Params, LineDelta, Address, 682 AsmInfo->getCodePointerSize()); 683 else 684 MCDwarfLineAddr::Emit(MCOS, Params, LineDelta, Address - LastAddress); 685 686 LastAddress = Address; 687 LastLine = Row.Line; 688 } 689 690 Discriminator = 0; 691 } 692 PrevEndOfSequence = Sequence.EndAddress; 693 } 694 695 // Finish with the end of the sequence. 696 if (LastAddress != InvalidAddress) 697 emitEndOfSequence(PrevEndOfSequence); 698 } 699 700 // This function is similar to the one from MCDwarfLineTable, except it handles 701 // end-of-sequence entries differently by utilizing line entries with 702 // DWARF2_FLAG_END_SEQUENCE flag. 703 static inline void emitDwarfLineTable( 704 MCStreamer *MCOS, MCSection *Section, 705 const MCLineSection::MCDwarfLineEntryCollection &LineEntries) { 706 unsigned FileNum = 1; 707 unsigned LastLine = 1; 708 unsigned Column = 0; 709 unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 710 unsigned Isa = 0; 711 unsigned Discriminator = 0; 712 MCSymbol *LastLabel = nullptr; 713 const MCAsmInfo *AsmInfo = MCOS->getContext().getAsmInfo(); 714 715 // Loop through each MCDwarfLineEntry and encode the dwarf line number table. 716 for (const MCDwarfLineEntry &LineEntry : LineEntries) { 717 if (LineEntry.getFlags() & DWARF2_FLAG_END_SEQUENCE) { 718 MCOS->emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, LineEntry.getLabel(), 719 AsmInfo->getCodePointerSize()); 720 FileNum = 1; 721 LastLine = 1; 722 Column = 0; 723 Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 724 Isa = 0; 725 Discriminator = 0; 726 LastLabel = nullptr; 727 continue; 728 } 729 730 int64_t LineDelta = static_cast<int64_t>(LineEntry.getLine()) - LastLine; 731 732 if (FileNum != LineEntry.getFileNum()) { 733 FileNum = LineEntry.getFileNum(); 734 MCOS->emitInt8(dwarf::DW_LNS_set_file); 735 MCOS->emitULEB128IntValue(FileNum); 736 } 737 if (Column != LineEntry.getColumn()) { 738 Column = LineEntry.getColumn(); 739 MCOS->emitInt8(dwarf::DW_LNS_set_column); 740 MCOS->emitULEB128IntValue(Column); 741 } 742 if (Discriminator != LineEntry.getDiscriminator() && 743 MCOS->getContext().getDwarfVersion() >= 4) { 744 Discriminator = LineEntry.getDiscriminator(); 745 unsigned Size = getULEB128Size(Discriminator); 746 MCOS->emitInt8(dwarf::DW_LNS_extended_op); 747 MCOS->emitULEB128IntValue(Size + 1); 748 MCOS->emitInt8(dwarf::DW_LNE_set_discriminator); 749 MCOS->emitULEB128IntValue(Discriminator); 750 } 751 if (Isa != LineEntry.getIsa()) { 752 Isa = LineEntry.getIsa(); 753 MCOS->emitInt8(dwarf::DW_LNS_set_isa); 754 MCOS->emitULEB128IntValue(Isa); 755 } 756 if ((LineEntry.getFlags() ^ Flags) & DWARF2_FLAG_IS_STMT) { 757 Flags = LineEntry.getFlags(); 758 MCOS->emitInt8(dwarf::DW_LNS_negate_stmt); 759 } 760 if (LineEntry.getFlags() & DWARF2_FLAG_BASIC_BLOCK) 761 MCOS->emitInt8(dwarf::DW_LNS_set_basic_block); 762 if (LineEntry.getFlags() & DWARF2_FLAG_PROLOGUE_END) 763 MCOS->emitInt8(dwarf::DW_LNS_set_prologue_end); 764 if (LineEntry.getFlags() & DWARF2_FLAG_EPILOGUE_BEGIN) 765 MCOS->emitInt8(dwarf::DW_LNS_set_epilogue_begin); 766 767 MCSymbol *Label = LineEntry.getLabel(); 768 769 // At this point we want to emit/create the sequence to encode the delta 770 // in line numbers and the increment of the address from the previous 771 // Label and the current Label. 772 MCOS->emitDwarfAdvanceLineAddr(LineDelta, LastLabel, Label, 773 AsmInfo->getCodePointerSize()); 774 Discriminator = 0; 775 LastLine = LineEntry.getLine(); 776 LastLabel = Label; 777 } 778 779 assert(LastLabel == nullptr && "end of sequence expected"); 780 } 781 782 void DwarfLineTable::emitCU(MCStreamer *MCOS, MCDwarfLineTableParams Params, 783 Optional<MCDwarfLineStr> &LineStr, 784 BinaryContext &BC) const { 785 if (!RawData.empty()) { 786 assert(MCLineSections.getMCLineEntries().empty() && 787 InputSequences.empty() && 788 "cannot combine raw data with new line entries"); 789 MCOS->emitLabel(getLabel()); 790 MCOS->emitBytes(RawData); 791 792 // Emit fake relocation for RuntimeDyld to always allocate the section. 793 // 794 // FIXME: remove this once RuntimeDyld stops skipping allocatable sections 795 // without relocations. 796 MCOS->emitRelocDirective( 797 *MCConstantExpr::create(0, *BC.Ctx), "BFD_RELOC_NONE", 798 MCSymbolRefExpr::create(getLabel(), *BC.Ctx), SMLoc(), *BC.STI); 799 800 return; 801 } 802 803 MCSymbol *LineEndSym = Header.Emit(MCOS, Params, LineStr).second; 804 805 // Put out the line tables. 806 for (const auto &LineSec : MCLineSections.getMCLineEntries()) 807 emitDwarfLineTable(MCOS, LineSec.first, LineSec.second); 808 809 // Emit line tables for the original code. 810 emitBinaryDwarfLineTable(MCOS, Params, InputTable, InputSequences); 811 812 // This is the end of the section, so set the value of the symbol at the end 813 // of this section (that was used in a previous expression). 814 MCOS->emitLabel(LineEndSym); 815 } 816 817 void DwarfLineTable::emit(BinaryContext &BC, MCStreamer &Streamer) { 818 MCAssembler &Assembler = 819 static_cast<MCObjectStreamer *>(&Streamer)->getAssembler(); 820 821 MCDwarfLineTableParams Params = Assembler.getDWARFLinetableParams(); 822 823 auto &LineTables = BC.getDwarfLineTables(); 824 825 // Bail out early so we don't switch to the debug_line section needlessly and 826 // in doing so create an unnecessary (if empty) section. 827 if (LineTables.empty()) 828 return; 829 830 // In a v5 non-split line table, put the strings in a separate section. 831 Optional<MCDwarfLineStr> LineStr(None); 832 if (BC.Ctx->getDwarfVersion() >= 5) 833 LineStr = MCDwarfLineStr(*BC.Ctx); 834 835 // Switch to the section where the table will be emitted into. 836 Streamer.SwitchSection(BC.MOFI->getDwarfLineSection()); 837 838 // Handle the rest of the Compile Units. 839 for (auto &CUIDTablePair : LineTables) { 840 CUIDTablePair.second.emitCU(&Streamer, Params, LineStr, BC); 841 } 842 } 843 844 } // namespace bolt 845 } // namespace llvm 846