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 // For DWP AbbreviationsOffset is an Abbrev contribution in the DWP file, so 535 // can be none zero. Thus we are skipping the check for DWP. 536 bool IsDWP = !Context.getCUIndex().getRows().empty(); 537 if (!IsDWP) { 538 for (const std::unique_ptr<DWARFUnit> &Unit : Context.dwo_units()) { 539 if (Unit->getAbbreviationsOffset() != 0) { 540 errs() << "BOLT-ERROR: detected DWO unit with non-zero abbr_offset. " 541 "Unable to update debug info.\n"; 542 exit(1); 543 } 544 } 545 } 546 547 // Issue abbreviations for the DWO CU only. 548 addUnitAbbreviations(*Context.getDWOCompileUnitForHash(*DWOId)); 549 } else { 550 // Add abbreviations from compile and type non-DWO units. 551 for (const std::unique_ptr<DWARFUnit> &Unit : Context.normal_units()) 552 addUnitAbbreviations(*Unit); 553 } 554 555 DebugBufferVector ReturnBuffer; 556 557 // Pre-calculate the total size of abbrev section. 558 uint64_t Size = 0; 559 for (const auto &KV : UnitsAbbrevData) { 560 const AbbrevData &UnitData = KV.second; 561 Size += UnitData.Buffer->size(); 562 } 563 ReturnBuffer.reserve(Size); 564 565 uint64_t Pos = 0; 566 for (auto &KV : UnitsAbbrevData) { 567 AbbrevData &UnitData = KV.second; 568 ReturnBuffer.append(*UnitData.Buffer); 569 UnitData.Offset = Pos; 570 Pos += UnitData.Buffer->size(); 571 572 UnitData.Buffer.reset(); 573 UnitData.Stream.reset(); 574 } 575 576 return std::make_unique<DebugBufferVector>(ReturnBuffer); 577 } 578 579 static void emitDwarfSetLineAddrAbs(MCStreamer &OS, 580 MCDwarfLineTableParams Params, 581 int64_t LineDelta, uint64_t Address, 582 int PointerSize) { 583 // emit the sequence to set the address 584 OS.emitIntValue(dwarf::DW_LNS_extended_op, 1); 585 OS.emitULEB128IntValue(PointerSize + 1); 586 OS.emitIntValue(dwarf::DW_LNE_set_address, 1); 587 OS.emitIntValue(Address, PointerSize); 588 589 // emit the sequence for the LineDelta (from 1) and a zero address delta. 590 MCDwarfLineAddr::Emit(&OS, Params, LineDelta, 0); 591 } 592 593 static inline void emitBinaryDwarfLineTable( 594 MCStreamer *MCOS, MCDwarfLineTableParams Params, 595 const DWARFDebugLine::LineTable *Table, 596 const std::vector<DwarfLineTable::RowSequence> &InputSequences) { 597 if (InputSequences.empty()) 598 return; 599 600 constexpr uint64_t InvalidAddress = UINT64_MAX; 601 unsigned FileNum = 1; 602 unsigned LastLine = 1; 603 unsigned Column = 0; 604 unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 605 unsigned Isa = 0; 606 unsigned Discriminator = 0; 607 uint64_t LastAddress = InvalidAddress; 608 uint64_t PrevEndOfSequence = InvalidAddress; 609 const MCAsmInfo *AsmInfo = MCOS->getContext().getAsmInfo(); 610 611 auto emitEndOfSequence = [&](uint64_t Address) { 612 MCDwarfLineAddr::Emit(MCOS, Params, INT64_MAX, Address - LastAddress); 613 FileNum = 1; 614 LastLine = 1; 615 Column = 0; 616 Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 617 Isa = 0; 618 Discriminator = 0; 619 LastAddress = InvalidAddress; 620 }; 621 622 for (const DwarfLineTable::RowSequence &Sequence : InputSequences) { 623 const uint64_t SequenceStart = 624 Table->Rows[Sequence.FirstIndex].Address.Address; 625 626 // Check if we need to mark the end of the sequence. 627 if (PrevEndOfSequence != InvalidAddress && LastAddress != InvalidAddress && 628 PrevEndOfSequence != SequenceStart) { 629 emitEndOfSequence(PrevEndOfSequence); 630 } 631 632 for (uint32_t RowIndex = Sequence.FirstIndex; 633 RowIndex <= Sequence.LastIndex; ++RowIndex) { 634 const DWARFDebugLine::Row &Row = Table->Rows[RowIndex]; 635 int64_t LineDelta = static_cast<int64_t>(Row.Line) - LastLine; 636 const uint64_t Address = Row.Address.Address; 637 638 if (FileNum != Row.File) { 639 FileNum = Row.File; 640 MCOS->emitInt8(dwarf::DW_LNS_set_file); 641 MCOS->emitULEB128IntValue(FileNum); 642 } 643 if (Column != Row.Column) { 644 Column = Row.Column; 645 MCOS->emitInt8(dwarf::DW_LNS_set_column); 646 MCOS->emitULEB128IntValue(Column); 647 } 648 if (Discriminator != Row.Discriminator && 649 MCOS->getContext().getDwarfVersion() >= 4) { 650 Discriminator = Row.Discriminator; 651 unsigned Size = getULEB128Size(Discriminator); 652 MCOS->emitInt8(dwarf::DW_LNS_extended_op); 653 MCOS->emitULEB128IntValue(Size + 1); 654 MCOS->emitInt8(dwarf::DW_LNE_set_discriminator); 655 MCOS->emitULEB128IntValue(Discriminator); 656 } 657 if (Isa != Row.Isa) { 658 Isa = Row.Isa; 659 MCOS->emitInt8(dwarf::DW_LNS_set_isa); 660 MCOS->emitULEB128IntValue(Isa); 661 } 662 if (Row.IsStmt != Flags) { 663 Flags = Row.IsStmt; 664 MCOS->emitInt8(dwarf::DW_LNS_negate_stmt); 665 } 666 if (Row.BasicBlock) 667 MCOS->emitInt8(dwarf::DW_LNS_set_basic_block); 668 if (Row.PrologueEnd) 669 MCOS->emitInt8(dwarf::DW_LNS_set_prologue_end); 670 if (Row.EpilogueBegin) 671 MCOS->emitInt8(dwarf::DW_LNS_set_epilogue_begin); 672 673 // The end of the sequence is not normal in the middle of the input 674 // sequence, but could happen, e.g. for assembly code. 675 if (Row.EndSequence) { 676 emitEndOfSequence(Address); 677 } else { 678 if (LastAddress == InvalidAddress) 679 emitDwarfSetLineAddrAbs(*MCOS, Params, LineDelta, Address, 680 AsmInfo->getCodePointerSize()); 681 else 682 MCDwarfLineAddr::Emit(MCOS, Params, LineDelta, Address - LastAddress); 683 684 LastAddress = Address; 685 LastLine = Row.Line; 686 } 687 688 Discriminator = 0; 689 } 690 PrevEndOfSequence = Sequence.EndAddress; 691 } 692 693 // Finish with the end of the sequence. 694 if (LastAddress != InvalidAddress) 695 emitEndOfSequence(PrevEndOfSequence); 696 } 697 698 // This function is similar to the one from MCDwarfLineTable, except it handles 699 // end-of-sequence entries differently by utilizing line entries with 700 // DWARF2_FLAG_END_SEQUENCE flag. 701 static inline void emitDwarfLineTable( 702 MCStreamer *MCOS, MCSection *Section, 703 const MCLineSection::MCDwarfLineEntryCollection &LineEntries) { 704 unsigned FileNum = 1; 705 unsigned LastLine = 1; 706 unsigned Column = 0; 707 unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 708 unsigned Isa = 0; 709 unsigned Discriminator = 0; 710 MCSymbol *LastLabel = nullptr; 711 const MCAsmInfo *AsmInfo = MCOS->getContext().getAsmInfo(); 712 713 // Loop through each MCDwarfLineEntry and encode the dwarf line number table. 714 for (const MCDwarfLineEntry &LineEntry : LineEntries) { 715 if (LineEntry.getFlags() & DWARF2_FLAG_END_SEQUENCE) { 716 MCOS->emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, LineEntry.getLabel(), 717 AsmInfo->getCodePointerSize()); 718 FileNum = 1; 719 LastLine = 1; 720 Column = 0; 721 Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 722 Isa = 0; 723 Discriminator = 0; 724 LastLabel = nullptr; 725 continue; 726 } 727 728 int64_t LineDelta = static_cast<int64_t>(LineEntry.getLine()) - LastLine; 729 730 if (FileNum != LineEntry.getFileNum()) { 731 FileNum = LineEntry.getFileNum(); 732 MCOS->emitInt8(dwarf::DW_LNS_set_file); 733 MCOS->emitULEB128IntValue(FileNum); 734 } 735 if (Column != LineEntry.getColumn()) { 736 Column = LineEntry.getColumn(); 737 MCOS->emitInt8(dwarf::DW_LNS_set_column); 738 MCOS->emitULEB128IntValue(Column); 739 } 740 if (Discriminator != LineEntry.getDiscriminator() && 741 MCOS->getContext().getDwarfVersion() >= 4) { 742 Discriminator = LineEntry.getDiscriminator(); 743 unsigned Size = getULEB128Size(Discriminator); 744 MCOS->emitInt8(dwarf::DW_LNS_extended_op); 745 MCOS->emitULEB128IntValue(Size + 1); 746 MCOS->emitInt8(dwarf::DW_LNE_set_discriminator); 747 MCOS->emitULEB128IntValue(Discriminator); 748 } 749 if (Isa != LineEntry.getIsa()) { 750 Isa = LineEntry.getIsa(); 751 MCOS->emitInt8(dwarf::DW_LNS_set_isa); 752 MCOS->emitULEB128IntValue(Isa); 753 } 754 if ((LineEntry.getFlags() ^ Flags) & DWARF2_FLAG_IS_STMT) { 755 Flags = LineEntry.getFlags(); 756 MCOS->emitInt8(dwarf::DW_LNS_negate_stmt); 757 } 758 if (LineEntry.getFlags() & DWARF2_FLAG_BASIC_BLOCK) 759 MCOS->emitInt8(dwarf::DW_LNS_set_basic_block); 760 if (LineEntry.getFlags() & DWARF2_FLAG_PROLOGUE_END) 761 MCOS->emitInt8(dwarf::DW_LNS_set_prologue_end); 762 if (LineEntry.getFlags() & DWARF2_FLAG_EPILOGUE_BEGIN) 763 MCOS->emitInt8(dwarf::DW_LNS_set_epilogue_begin); 764 765 MCSymbol *Label = LineEntry.getLabel(); 766 767 // At this point we want to emit/create the sequence to encode the delta 768 // in line numbers and the increment of the address from the previous 769 // Label and the current Label. 770 MCOS->emitDwarfAdvanceLineAddr(LineDelta, LastLabel, Label, 771 AsmInfo->getCodePointerSize()); 772 Discriminator = 0; 773 LastLine = LineEntry.getLine(); 774 LastLabel = Label; 775 } 776 777 assert(LastLabel == nullptr && "end of sequence expected"); 778 } 779 780 void DwarfLineTable::emitCU(MCStreamer *MCOS, MCDwarfLineTableParams Params, 781 Optional<MCDwarfLineStr> &LineStr, 782 BinaryContext &BC) const { 783 if (!RawData.empty()) { 784 assert(MCLineSections.getMCLineEntries().empty() && 785 InputSequences.empty() && 786 "cannot combine raw data with new line entries"); 787 MCOS->emitLabel(getLabel()); 788 MCOS->emitBytes(RawData); 789 790 // Emit fake relocation for RuntimeDyld to always allocate the section. 791 // 792 // FIXME: remove this once RuntimeDyld stops skipping allocatable sections 793 // without relocations. 794 MCOS->emitRelocDirective( 795 *MCConstantExpr::create(0, *BC.Ctx), "BFD_RELOC_NONE", 796 MCSymbolRefExpr::create(getLabel(), *BC.Ctx), SMLoc(), *BC.STI); 797 798 return; 799 } 800 801 MCSymbol *LineEndSym = Header.Emit(MCOS, Params, LineStr).second; 802 803 // Put out the line tables. 804 for (const auto &LineSec : MCLineSections.getMCLineEntries()) 805 emitDwarfLineTable(MCOS, LineSec.first, LineSec.second); 806 807 // Emit line tables for the original code. 808 emitBinaryDwarfLineTable(MCOS, Params, InputTable, InputSequences); 809 810 // This is the end of the section, so set the value of the symbol at the end 811 // of this section (that was used in a previous expression). 812 MCOS->emitLabel(LineEndSym); 813 } 814 815 void DwarfLineTable::emit(BinaryContext &BC, MCStreamer &Streamer) { 816 MCAssembler &Assembler = 817 static_cast<MCObjectStreamer *>(&Streamer)->getAssembler(); 818 819 MCDwarfLineTableParams Params = Assembler.getDWARFLinetableParams(); 820 821 auto &LineTables = BC.getDwarfLineTables(); 822 823 // Bail out early so we don't switch to the debug_line section needlessly and 824 // in doing so create an unnecessary (if empty) section. 825 if (LineTables.empty()) 826 return; 827 828 // In a v5 non-split line table, put the strings in a separate section. 829 Optional<MCDwarfLineStr> LineStr(None); 830 if (BC.Ctx->getDwarfVersion() >= 5) 831 LineStr = MCDwarfLineStr(*BC.Ctx); 832 833 // Switch to the section where the table will be emitted into. 834 Streamer.SwitchSection(BC.MOFI->getDwarfLineSection()); 835 836 // Handle the rest of the Compile Units. 837 for (auto &CUIDTablePair : LineTables) { 838 CUIDTablePair.second.emitCU(&Streamer, Params, LineStr, BC); 839 } 840 } 841 842 } // namespace bolt 843 } // namespace llvm 844