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