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 (UnitsAbbrevData.find(AbbrevOffset) != UnitsAbbrevData.end()) 427 return; 428 429 AbbrevData &UnitData = UnitsAbbrevData[AbbrevOffset]; 430 UnitData.Buffer = std::make_unique<DebugBufferVector>(); 431 UnitData.Stream = std::make_unique<raw_svector_ostream>(*UnitData.Buffer); 432 433 const PatchesTy &UnitPatches = Patches[&Unit]; 434 435 raw_svector_ostream &OS = *UnitData.Stream.get(); 436 437 // Take a fast path if there are no patches to apply. Simply copy the original 438 // contents. 439 if (UnitPatches.empty()) { 440 StringRef AbbrevSectionContents = 441 Unit.isDWOUnit() ? Unit.getContext().getDWARFObj().getAbbrevDWOSection() 442 : Unit.getContext().getDWARFObj().getAbbrevSection(); 443 StringRef AbbrevContents; 444 445 const DWARFUnitIndex &CUIndex = Unit.getContext().getCUIndex(); 446 if (!CUIndex.getRows().empty()) { 447 // Handle DWP section contribution. 448 const DWARFUnitIndex::Entry *DWOEntry = 449 CUIndex.getFromHash(*Unit.getDWOId()); 450 if (!DWOEntry) 451 return; 452 453 const DWARFUnitIndex::Entry::SectionContribution *DWOContrubution = 454 DWOEntry->getContribution(DWARFSectionKind::DW_SECT_ABBREV); 455 AbbrevContents = AbbrevSectionContents.substr(DWOContrubution->Offset, 456 DWOContrubution->Length); 457 } else if (!Unit.isDWOUnit()) { 458 const uint64_t StartOffset = Unit.getAbbreviationsOffset(); 459 460 // We know where the unit's abbreviation set starts, but not where it ends 461 // as such data is not readily available. Hence, we have to build a sorted 462 // list of start addresses and find the next starting address to determine 463 // the set boundaries. 464 // 465 // FIXME: if we had a full access to DWARFDebugAbbrev::AbbrDeclSets 466 // we wouldn't have to build our own sorted list for the quick lookup. 467 if (AbbrevSetOffsets.empty()) { 468 llvm::for_each( 469 *Unit.getContext().getDebugAbbrev(), 470 [&](const std::pair<uint64_t, DWARFAbbreviationDeclarationSet> &P) { 471 AbbrevSetOffsets.push_back(P.first); 472 }); 473 llvm::sort(AbbrevSetOffsets); 474 } 475 auto It = llvm::upper_bound(AbbrevSetOffsets, StartOffset); 476 const uint64_t EndOffset = 477 It == AbbrevSetOffsets.end() ? AbbrevSectionContents.size() : *It; 478 AbbrevContents = AbbrevSectionContents.slice(StartOffset, EndOffset); 479 } else { 480 // For DWO unit outside of DWP, we expect the entire section to hold 481 // abbreviations for this unit only. 482 AbbrevContents = AbbrevSectionContents; 483 } 484 485 OS.reserveExtraSpace(AbbrevContents.size()); 486 OS << AbbrevContents; 487 488 return; 489 } 490 491 for (auto I = Abbrevs->begin(), E = Abbrevs->end(); I != E; ++I) { 492 const DWARFAbbreviationDeclaration &Abbrev = *I; 493 auto Patch = UnitPatches.find(&Abbrev); 494 495 encodeULEB128(Abbrev.getCode(), OS); 496 encodeULEB128(Abbrev.getTag(), OS); 497 encodeULEB128(Abbrev.hasChildren(), OS); 498 for (const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec : 499 Abbrev.attributes()) { 500 if (Patch != UnitPatches.end()) { 501 bool Patched = false; 502 // Patches added later take a precedence over earlier ones. 503 for (auto I = Patch->second.rbegin(), E = Patch->second.rend(); I != E; 504 ++I) { 505 if (I->OldAttr != AttrSpec.Attr) 506 continue; 507 508 encodeULEB128(I->NewAttr, OS); 509 encodeULEB128(I->NewAttrForm, OS); 510 Patched = true; 511 break; 512 } 513 if (Patched) 514 continue; 515 } 516 517 encodeULEB128(AttrSpec.Attr, OS); 518 encodeULEB128(AttrSpec.Form, OS); 519 if (AttrSpec.isImplicitConst()) 520 encodeSLEB128(AttrSpec.getImplicitConstValue(), OS); 521 } 522 523 encodeULEB128(0, OS); 524 encodeULEB128(0, OS); 525 } 526 encodeULEB128(0, OS); 527 } 528 529 std::unique_ptr<DebugBufferVector> DebugAbbrevWriter::finalize() { 530 if (DWOId) { 531 // We expect abbrev_offset to always be zero for DWO units as there 532 // should be one CU per DWO, and TUs should share the same abbreviation 533 // set with the CU. 534 // NOTE: this check could be expensive for DWPs as it iterates over 535 // all units and we invoke it for every unit. Hence only run 536 // it once per DWP. 537 bool IsDWP = !Context.getCUIndex().getRows().empty(); 538 static bool CheckedDWP = false; 539 if (!IsDWP || !CheckedDWP) { 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 if (IsDWP) 548 CheckedDWP = true; 549 } 550 551 // Issue abbreviations for the DWO CU only. 552 addUnitAbbreviations(*Context.getDWOCompileUnitForHash(*DWOId)); 553 } else { 554 // Add abbreviations from compile and type non-DWO units. 555 for (const std::unique_ptr<DWARFUnit> &Unit : Context.normal_units()) 556 addUnitAbbreviations(*Unit); 557 } 558 559 DebugBufferVector ReturnBuffer; 560 561 // Pre-calculate the total size of abbrev section. 562 uint64_t Size = 0; 563 for (const auto &KV : UnitsAbbrevData) { 564 const AbbrevData &UnitData = KV.second; 565 Size += UnitData.Buffer->size(); 566 } 567 ReturnBuffer.reserve(Size); 568 569 uint64_t Pos = 0; 570 for (auto &KV : UnitsAbbrevData) { 571 AbbrevData &UnitData = KV.second; 572 ReturnBuffer.append(*UnitData.Buffer); 573 UnitData.Offset = Pos; 574 Pos += UnitData.Buffer->size(); 575 576 UnitData.Buffer.reset(); 577 UnitData.Stream.reset(); 578 } 579 580 return std::make_unique<DebugBufferVector>(ReturnBuffer); 581 } 582 583 static void emitDwarfSetLineAddrAbs(MCStreamer &OS, 584 MCDwarfLineTableParams Params, 585 int64_t LineDelta, uint64_t Address, 586 int PointerSize) { 587 // emit the sequence to set the address 588 OS.emitIntValue(dwarf::DW_LNS_extended_op, 1); 589 OS.emitULEB128IntValue(PointerSize + 1); 590 OS.emitIntValue(dwarf::DW_LNE_set_address, 1); 591 OS.emitIntValue(Address, PointerSize); 592 593 // emit the sequence for the LineDelta (from 1) and a zero address delta. 594 MCDwarfLineAddr::Emit(&OS, Params, LineDelta, 0); 595 } 596 597 static inline void emitBinaryDwarfLineTable( 598 MCStreamer *MCOS, MCDwarfLineTableParams Params, 599 const DWARFDebugLine::LineTable *Table, 600 const std::vector<DwarfLineTable::RowSequence> &InputSequences) { 601 if (InputSequences.empty()) 602 return; 603 604 constexpr uint64_t InvalidAddress = UINT64_MAX; 605 unsigned FileNum = 1; 606 unsigned LastLine = 1; 607 unsigned Column = 0; 608 unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 609 unsigned Isa = 0; 610 unsigned Discriminator = 0; 611 uint64_t LastAddress = InvalidAddress; 612 uint64_t PrevEndOfSequence = InvalidAddress; 613 const MCAsmInfo *AsmInfo = MCOS->getContext().getAsmInfo(); 614 615 auto emitEndOfSequence = [&](uint64_t Address) { 616 MCDwarfLineAddr::Emit(MCOS, Params, INT64_MAX, Address - LastAddress); 617 FileNum = 1; 618 LastLine = 1; 619 Column = 0; 620 Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 621 Isa = 0; 622 Discriminator = 0; 623 LastAddress = InvalidAddress; 624 }; 625 626 for (const DwarfLineTable::RowSequence &Sequence : InputSequences) { 627 const uint64_t SequenceStart = 628 Table->Rows[Sequence.FirstIndex].Address.Address; 629 630 // Check if we need to mark the end of the sequence. 631 if (PrevEndOfSequence != InvalidAddress && LastAddress != InvalidAddress && 632 PrevEndOfSequence != SequenceStart) { 633 emitEndOfSequence(PrevEndOfSequence); 634 } 635 636 for (uint32_t RowIndex = Sequence.FirstIndex; 637 RowIndex <= Sequence.LastIndex; ++RowIndex) { 638 const DWARFDebugLine::Row &Row = Table->Rows[RowIndex]; 639 int64_t LineDelta = static_cast<int64_t>(Row.Line) - LastLine; 640 const uint64_t Address = Row.Address.Address; 641 642 if (FileNum != Row.File) { 643 FileNum = Row.File; 644 MCOS->emitInt8(dwarf::DW_LNS_set_file); 645 MCOS->emitULEB128IntValue(FileNum); 646 } 647 if (Column != Row.Column) { 648 Column = Row.Column; 649 MCOS->emitInt8(dwarf::DW_LNS_set_column); 650 MCOS->emitULEB128IntValue(Column); 651 } 652 if (Discriminator != Row.Discriminator && 653 MCOS->getContext().getDwarfVersion() >= 4) { 654 Discriminator = Row.Discriminator; 655 unsigned Size = getULEB128Size(Discriminator); 656 MCOS->emitInt8(dwarf::DW_LNS_extended_op); 657 MCOS->emitULEB128IntValue(Size + 1); 658 MCOS->emitInt8(dwarf::DW_LNE_set_discriminator); 659 MCOS->emitULEB128IntValue(Discriminator); 660 } 661 if (Isa != Row.Isa) { 662 Isa = Row.Isa; 663 MCOS->emitInt8(dwarf::DW_LNS_set_isa); 664 MCOS->emitULEB128IntValue(Isa); 665 } 666 if (Row.IsStmt != Flags) { 667 Flags = Row.IsStmt; 668 MCOS->emitInt8(dwarf::DW_LNS_negate_stmt); 669 } 670 if (Row.BasicBlock) 671 MCOS->emitInt8(dwarf::DW_LNS_set_basic_block); 672 if (Row.PrologueEnd) 673 MCOS->emitInt8(dwarf::DW_LNS_set_prologue_end); 674 if (Row.EpilogueBegin) 675 MCOS->emitInt8(dwarf::DW_LNS_set_epilogue_begin); 676 677 // The end of the sequence is not normal in the middle of the input 678 // sequence, but could happen, e.g. for assembly code. 679 if (Row.EndSequence) { 680 emitEndOfSequence(Address); 681 } else { 682 if (LastAddress == InvalidAddress) 683 emitDwarfSetLineAddrAbs(*MCOS, Params, LineDelta, Address, 684 AsmInfo->getCodePointerSize()); 685 else 686 MCDwarfLineAddr::Emit(MCOS, Params, LineDelta, Address - LastAddress); 687 688 LastAddress = Address; 689 LastLine = Row.Line; 690 } 691 692 Discriminator = 0; 693 } 694 PrevEndOfSequence = Sequence.EndAddress; 695 } 696 697 // Finish with the end of the sequence. 698 if (LastAddress != InvalidAddress) 699 emitEndOfSequence(PrevEndOfSequence); 700 } 701 702 // This function is similar to the one from MCDwarfLineTable, except it handles 703 // end-of-sequence entries differently by utilizing line entries with 704 // DWARF2_FLAG_END_SEQUENCE flag. 705 static inline void emitDwarfLineTable( 706 MCStreamer *MCOS, MCSection *Section, 707 const MCLineSection::MCDwarfLineEntryCollection &LineEntries) { 708 unsigned FileNum = 1; 709 unsigned LastLine = 1; 710 unsigned Column = 0; 711 unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 712 unsigned Isa = 0; 713 unsigned Discriminator = 0; 714 MCSymbol *LastLabel = nullptr; 715 const MCAsmInfo *AsmInfo = MCOS->getContext().getAsmInfo(); 716 717 // Loop through each MCDwarfLineEntry and encode the dwarf line number table. 718 for (const MCDwarfLineEntry &LineEntry : LineEntries) { 719 if (LineEntry.getFlags() & DWARF2_FLAG_END_SEQUENCE) { 720 MCOS->emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, LineEntry.getLabel(), 721 AsmInfo->getCodePointerSize()); 722 FileNum = 1; 723 LastLine = 1; 724 Column = 0; 725 Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 726 Isa = 0; 727 Discriminator = 0; 728 LastLabel = nullptr; 729 continue; 730 } 731 732 int64_t LineDelta = static_cast<int64_t>(LineEntry.getLine()) - LastLine; 733 734 if (FileNum != LineEntry.getFileNum()) { 735 FileNum = LineEntry.getFileNum(); 736 MCOS->emitInt8(dwarf::DW_LNS_set_file); 737 MCOS->emitULEB128IntValue(FileNum); 738 } 739 if (Column != LineEntry.getColumn()) { 740 Column = LineEntry.getColumn(); 741 MCOS->emitInt8(dwarf::DW_LNS_set_column); 742 MCOS->emitULEB128IntValue(Column); 743 } 744 if (Discriminator != LineEntry.getDiscriminator() && 745 MCOS->getContext().getDwarfVersion() >= 4) { 746 Discriminator = LineEntry.getDiscriminator(); 747 unsigned Size = getULEB128Size(Discriminator); 748 MCOS->emitInt8(dwarf::DW_LNS_extended_op); 749 MCOS->emitULEB128IntValue(Size + 1); 750 MCOS->emitInt8(dwarf::DW_LNE_set_discriminator); 751 MCOS->emitULEB128IntValue(Discriminator); 752 } 753 if (Isa != LineEntry.getIsa()) { 754 Isa = LineEntry.getIsa(); 755 MCOS->emitInt8(dwarf::DW_LNS_set_isa); 756 MCOS->emitULEB128IntValue(Isa); 757 } 758 if ((LineEntry.getFlags() ^ Flags) & DWARF2_FLAG_IS_STMT) { 759 Flags = LineEntry.getFlags(); 760 MCOS->emitInt8(dwarf::DW_LNS_negate_stmt); 761 } 762 if (LineEntry.getFlags() & DWARF2_FLAG_BASIC_BLOCK) 763 MCOS->emitInt8(dwarf::DW_LNS_set_basic_block); 764 if (LineEntry.getFlags() & DWARF2_FLAG_PROLOGUE_END) 765 MCOS->emitInt8(dwarf::DW_LNS_set_prologue_end); 766 if (LineEntry.getFlags() & DWARF2_FLAG_EPILOGUE_BEGIN) 767 MCOS->emitInt8(dwarf::DW_LNS_set_epilogue_begin); 768 769 MCSymbol *Label = LineEntry.getLabel(); 770 771 // At this point we want to emit/create the sequence to encode the delta 772 // in line numbers and the increment of the address from the previous 773 // Label and the current Label. 774 MCOS->emitDwarfAdvanceLineAddr(LineDelta, LastLabel, Label, 775 AsmInfo->getCodePointerSize()); 776 Discriminator = 0; 777 LastLine = LineEntry.getLine(); 778 LastLabel = Label; 779 } 780 781 assert(LastLabel == nullptr && "end of sequence expected"); 782 } 783 784 void DwarfLineTable::emitCU(MCStreamer *MCOS, MCDwarfLineTableParams Params, 785 Optional<MCDwarfLineStr> &LineStr, 786 BinaryContext &BC) const { 787 if (!RawData.empty()) { 788 assert(MCLineSections.getMCLineEntries().empty() && 789 InputSequences.empty() && 790 "cannot combine raw data with new line entries"); 791 MCOS->emitLabel(getLabel()); 792 MCOS->emitBytes(RawData); 793 794 // Emit fake relocation for RuntimeDyld to always allocate the section. 795 // 796 // FIXME: remove this once RuntimeDyld stops skipping allocatable sections 797 // without relocations. 798 MCOS->emitRelocDirective( 799 *MCConstantExpr::create(0, *BC.Ctx), "BFD_RELOC_NONE", 800 MCSymbolRefExpr::create(getLabel(), *BC.Ctx), SMLoc(), *BC.STI); 801 802 return; 803 } 804 805 MCSymbol *LineEndSym = Header.Emit(MCOS, Params, LineStr).second; 806 807 // Put out the line tables. 808 for (const auto &LineSec : MCLineSections.getMCLineEntries()) 809 emitDwarfLineTable(MCOS, LineSec.first, LineSec.second); 810 811 // Emit line tables for the original code. 812 emitBinaryDwarfLineTable(MCOS, Params, InputTable, InputSequences); 813 814 // This is the end of the section, so set the value of the symbol at the end 815 // of this section (that was used in a previous expression). 816 MCOS->emitLabel(LineEndSym); 817 } 818 819 void DwarfLineTable::emit(BinaryContext &BC, MCStreamer &Streamer) { 820 MCAssembler &Assembler = 821 static_cast<MCObjectStreamer *>(&Streamer)->getAssembler(); 822 823 MCDwarfLineTableParams Params = Assembler.getDWARFLinetableParams(); 824 825 auto &LineTables = BC.getDwarfLineTables(); 826 827 // Bail out early so we don't switch to the debug_line section needlessly and 828 // in doing so create an unnecessary (if empty) section. 829 if (LineTables.empty()) 830 return; 831 832 // In a v5 non-split line table, put the strings in a separate section. 833 Optional<MCDwarfLineStr> LineStr(None); 834 if (BC.Ctx->getDwarfVersion() >= 5) 835 LineStr = MCDwarfLineStr(*BC.Ctx); 836 837 // Switch to the section where the table will be emitted into. 838 Streamer.SwitchSection(BC.MOFI->getDwarfLineSection()); 839 840 // Handle the rest of the Compile Units. 841 for (auto &CUIDTablePair : LineTables) { 842 CUIDTablePair.second.emitCU(&Streamer, Params, LineStr, BC); 843 } 844 } 845 846 } // namespace bolt 847 } // namespace llvm 848