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/BinaryContext.h"
15 #include "bolt/Rewrite/RewriteInstance.h"
16 #include "bolt/Utils/Utils.h"
17 #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
18 #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
19 #include "llvm/DebugInfo/DWARF/DWARFDebugAddr.h"
20 #include "llvm/MC/MCAssembler.h"
21 #include "llvm/MC/MCContext.h"
22 #include "llvm/MC/MCObjectStreamer.h"
23 #include "llvm/Support/CommandLine.h"
24 #include "llvm/Support/EndianStream.h"
25 #include "llvm/Support/LEB128.h"
26 #include "llvm/Support/SHA1.h"
27 #include <algorithm>
28 #include <cassert>
29 #include <cstdint>
30 #include <limits>
31 #include <unordered_map>
32 #include <vector>
33
34 #define DEBUG_TYPE "bolt-debug-info"
35
36 namespace opts {
37 extern llvm::cl::opt<unsigned> Verbosity;
38 } // namespace opts
39
40 namespace llvm {
41 class MCSymbol;
42
43 namespace bolt {
44
45 Optional<AttrInfo>
findAttributeInfo(const DWARFDie DIE,const DWARFAbbreviationDeclaration * AbbrevDecl,uint32_t Index)46 findAttributeInfo(const DWARFDie DIE,
47 const DWARFAbbreviationDeclaration *AbbrevDecl,
48 uint32_t Index) {
49 const DWARFUnit &U = *DIE.getDwarfUnit();
50 uint64_t Offset =
51 AbbrevDecl->getAttributeOffsetFromIndex(Index, DIE.getOffset(), U);
52 Optional<DWARFFormValue> Value =
53 AbbrevDecl->getAttributeValueFromOffset(Index, Offset, U);
54 if (!Value)
55 return None;
56 // AttributeSpec
57 const DWARFAbbreviationDeclaration::AttributeSpec *AttrVal =
58 AbbrevDecl->attributes().begin() + Index;
59 uint32_t ValSize = 0;
60 Optional<int64_t> ValSizeOpt = AttrVal->getByteSize(U);
61 if (ValSizeOpt) {
62 ValSize = static_cast<uint32_t>(*ValSizeOpt);
63 } else {
64 DWARFDataExtractor DebugInfoData = U.getDebugInfoExtractor();
65 uint64_t NewOffset = Offset;
66 DWARFFormValue::skipValue(Value->getForm(), DebugInfoData, &NewOffset,
67 U.getFormParams());
68 // This includes entire size of the entry, which might not be just the
69 // encoding part. For example for DW_AT_loc it will include expression
70 // location.
71 ValSize = NewOffset - Offset;
72 }
73 return AttrInfo{*Value, DIE.getAbbreviationDeclarationPtr(), Offset, ValSize};
74 }
75
findAttributeInfo(const DWARFDie DIE,dwarf::Attribute Attr)76 Optional<AttrInfo> findAttributeInfo(const DWARFDie DIE,
77 dwarf::Attribute Attr) {
78 if (!DIE.isValid())
79 return None;
80 const DWARFAbbreviationDeclaration *AbbrevDecl =
81 DIE.getAbbreviationDeclarationPtr();
82 if (!AbbrevDecl)
83 return None;
84 Optional<uint32_t> Index = AbbrevDecl->findAttributeIndex(Attr);
85 if (!Index)
86 return None;
87 return findAttributeInfo(DIE, AbbrevDecl, *Index);
88 }
89
90 const DebugLineTableRowRef DebugLineTableRowRef::NULL_ROW{0, 0};
91
92 namespace {
93
94 LLVM_ATTRIBUTE_UNUSED
printLE64(const std::string & S)95 static void printLE64(const std::string &S) {
96 for (uint32_t I = 0, Size = S.size(); I < Size; ++I) {
97 errs() << Twine::utohexstr(S[I]);
98 errs() << Twine::utohexstr((int8_t)S[I]);
99 }
100 errs() << "\n";
101 }
102
103 // Writes address ranges to Writer as pairs of 64-bit (address, size).
104 // If RelativeRange is true, assumes the address range to be written must be of
105 // the form (begin address, range size), otherwise (begin address, end address).
106 // Terminates the list by writing a pair of two zeroes.
107 // Returns the number of written bytes.
writeAddressRanges(raw_svector_ostream & Stream,const DebugAddressRangesVector & AddressRanges,const bool WriteRelativeRanges=false)108 uint64_t writeAddressRanges(raw_svector_ostream &Stream,
109 const DebugAddressRangesVector &AddressRanges,
110 const bool WriteRelativeRanges = false) {
111 for (const DebugAddressRange &Range : AddressRanges) {
112 support::endian::write(Stream, Range.LowPC, support::little);
113 support::endian::write(
114 Stream, WriteRelativeRanges ? Range.HighPC - Range.LowPC : Range.HighPC,
115 support::little);
116 }
117 // Finish with 0 entries.
118 support::endian::write(Stream, 0ULL, support::little);
119 support::endian::write(Stream, 0ULL, support::little);
120 return AddressRanges.size() * 16 + 16;
121 }
122
123 } // namespace
124
DebugRangesSectionWriter()125 DebugRangesSectionWriter::DebugRangesSectionWriter() {
126 RangesBuffer = std::make_unique<DebugBufferVector>();
127 RangesStream = std::make_unique<raw_svector_ostream>(*RangesBuffer);
128
129 // Add an empty range as the first entry;
130 SectionOffset +=
131 writeAddressRanges(*RangesStream.get(), DebugAddressRangesVector{});
132 Kind = RangesWriterKind::DebugRangesWriter;
133 }
134
addRanges(DebugAddressRangesVector && Ranges,std::map<DebugAddressRangesVector,uint64_t> & CachedRanges)135 uint64_t DebugRangesSectionWriter::addRanges(
136 DebugAddressRangesVector &&Ranges,
137 std::map<DebugAddressRangesVector, uint64_t> &CachedRanges) {
138 if (Ranges.empty())
139 return getEmptyRangesOffset();
140
141 const auto RI = CachedRanges.find(Ranges);
142 if (RI != CachedRanges.end())
143 return RI->second;
144
145 const uint64_t EntryOffset = addRanges(Ranges);
146 CachedRanges.emplace(std::move(Ranges), EntryOffset);
147
148 return EntryOffset;
149 }
150
151 uint64_t
addRanges(const DebugAddressRangesVector & Ranges)152 DebugRangesSectionWriter::addRanges(const DebugAddressRangesVector &Ranges) {
153 if (Ranges.empty())
154 return getEmptyRangesOffset();
155
156 // Reading the SectionOffset and updating it should be atomic to guarantee
157 // unique and correct offsets in patches.
158 std::lock_guard<std::mutex> Lock(WriterMutex);
159 const uint32_t EntryOffset = SectionOffset;
160 SectionOffset += writeAddressRanges(*RangesStream.get(), Ranges);
161
162 return EntryOffset;
163 }
164
getSectionOffset()165 uint64_t DebugRangesSectionWriter::getSectionOffset() {
166 std::lock_guard<std::mutex> Lock(WriterMutex);
167 return SectionOffset;
168 }
169
170 DebugAddrWriter *DebugRangeListsSectionWriter::AddrWriter = nullptr;
171
addRanges(DebugAddressRangesVector && Ranges,std::map<DebugAddressRangesVector,uint64_t> & CachedRanges)172 uint64_t DebugRangeListsSectionWriter::addRanges(
173 DebugAddressRangesVector &&Ranges,
174 std::map<DebugAddressRangesVector, uint64_t> &CachedRanges) {
175 return addRanges(Ranges);
176 }
177
178 struct LocListsRangelistsHeader {
179 UnitLengthType UnitLength; // Size of loclist entris section, not including
180 // size of header.
181 VersionType Version;
182 AddressSizeType AddressSize;
183 SegmentSelectorType SegmentSelector;
184 OffsetEntryCountType OffsetEntryCount;
185 };
186
187 static std::unique_ptr<DebugBufferVector>
getDWARF5Header(const LocListsRangelistsHeader & Header)188 getDWARF5Header(const LocListsRangelistsHeader &Header) {
189 std::unique_ptr<DebugBufferVector> HeaderBuffer =
190 std::make_unique<DebugBufferVector>();
191 std::unique_ptr<raw_svector_ostream> HeaderStream =
192 std::make_unique<raw_svector_ostream>(*HeaderBuffer);
193
194 // 7.29 length of the set of entries for this compilation unit, not including
195 // the length field itself
196 const uint32_t HeaderSize =
197 getDWARF5RngListLocListHeaderSize() - sizeof(UnitLengthType);
198
199 support::endian::write(*HeaderStream, Header.UnitLength + HeaderSize,
200 support::little);
201 support::endian::write(*HeaderStream, Header.Version, support::little);
202 support::endian::write(*HeaderStream, Header.AddressSize, support::little);
203 support::endian::write(*HeaderStream, Header.SegmentSelector,
204 support::little);
205 support::endian::write(*HeaderStream, Header.OffsetEntryCount,
206 support::little);
207 return HeaderBuffer;
208 }
209
addRanges(const DebugAddressRangesVector & Ranges)210 uint64_t DebugRangeListsSectionWriter::addRanges(
211 const DebugAddressRangesVector &Ranges) {
212 std::lock_guard<std::mutex> Lock(WriterMutex);
213
214 RangeEntries.push_back(CurrentOffset);
215 for (const DebugAddressRange &Range : Ranges) {
216 support::endian::write(*CUBodyStream,
217 static_cast<uint8_t>(dwarf::DW_RLE_startx_length),
218 support::little);
219 uint32_t Index = AddrWriter->getIndexFromAddress(Range.LowPC, *CU);
220 encodeULEB128(Index, *CUBodyStream);
221 encodeULEB128(Range.HighPC - Range.LowPC, *CUBodyStream);
222 }
223 support::endian::write(*CUBodyStream,
224 static_cast<uint8_t>(dwarf::DW_RLE_end_of_list),
225 support::little);
226 CurrentOffset = CUBodyBuffer->size();
227 return RangeEntries.size() - 1;
228 }
229
finalizeSection()230 void DebugRangeListsSectionWriter::finalizeSection() {
231 std::unique_ptr<DebugBufferVector> CUArrayBuffer =
232 std::make_unique<DebugBufferVector>();
233 std::unique_ptr<raw_svector_ostream> CUArrayStream =
234 std::make_unique<raw_svector_ostream>(*CUArrayBuffer);
235 constexpr uint32_t SizeOfArrayEntry = 4;
236 const uint32_t SizeOfArraySection = RangeEntries.size() * SizeOfArrayEntry;
237 for (uint32_t Offset : RangeEntries)
238 support::endian::write(*CUArrayStream, Offset + SizeOfArraySection,
239 support::little);
240
241 std::unique_ptr<DebugBufferVector> Header = getDWARF5Header(
242 {static_cast<uint32_t>(SizeOfArraySection + CUBodyBuffer.get()->size()),
243 5, 8, 0, static_cast<uint32_t>(RangeEntries.size())});
244 *RangesStream << *Header;
245 *RangesStream << *CUArrayBuffer;
246 *RangesStream << *CUBodyBuffer;
247 SectionOffset = RangesBuffer->size();
248 }
249
initSection(DWARFUnit & Unit)250 void DebugRangeListsSectionWriter::initSection(DWARFUnit &Unit) {
251 CUBodyBuffer = std::make_unique<DebugBufferVector>();
252 CUBodyStream = std::make_unique<raw_svector_ostream>(*CUBodyBuffer);
253 RangeEntries.clear();
254 CurrentOffset = 0;
255 CU = &Unit;
256 }
257
addCURanges(uint64_t CUOffset,DebugAddressRangesVector && Ranges)258 void DebugARangesSectionWriter::addCURanges(uint64_t CUOffset,
259 DebugAddressRangesVector &&Ranges) {
260 std::lock_guard<std::mutex> Lock(CUAddressRangesMutex);
261 CUAddressRanges.emplace(CUOffset, std::move(Ranges));
262 }
263
writeARangesSection(raw_svector_ostream & RangesStream,const CUOffsetMap & CUMap) const264 void DebugARangesSectionWriter::writeARangesSection(
265 raw_svector_ostream &RangesStream, const CUOffsetMap &CUMap) const {
266 // For reference on the format of the .debug_aranges section, see the DWARF4
267 // specification, section 6.1.4 Lookup by Address
268 // http://www.dwarfstd.org/doc/DWARF4.pdf
269 for (const auto &CUOffsetAddressRangesPair : CUAddressRanges) {
270 const uint64_t Offset = CUOffsetAddressRangesPair.first;
271 const DebugAddressRangesVector &AddressRanges =
272 CUOffsetAddressRangesPair.second;
273
274 // Emit header.
275
276 // Size of this set: 8 (size of the header) + 4 (padding after header)
277 // + 2*sizeof(uint64_t) bytes for each of the ranges, plus an extra
278 // pair of uint64_t's for the terminating, zero-length range.
279 // Does not include size field itself.
280 uint32_t Size = 8 + 4 + 2 * sizeof(uint64_t) * (AddressRanges.size() + 1);
281
282 // Header field #1: set size.
283 support::endian::write(RangesStream, Size, support::little);
284
285 // Header field #2: version number, 2 as per the specification.
286 support::endian::write(RangesStream, static_cast<uint16_t>(2),
287 support::little);
288
289 assert(CUMap.count(Offset) && "Original CU offset is not found in CU Map");
290 // Header field #3: debug info offset of the correspondent compile unit.
291 support::endian::write(
292 RangesStream, static_cast<uint32_t>(CUMap.find(Offset)->second.Offset),
293 support::little);
294
295 // Header field #4: address size.
296 // 8 since we only write ELF64 binaries for now.
297 RangesStream << char(8);
298
299 // Header field #5: segment size of target architecture.
300 RangesStream << char(0);
301
302 // Padding before address table - 4 bytes in the 64-bit-pointer case.
303 support::endian::write(RangesStream, static_cast<uint32_t>(0),
304 support::little);
305
306 writeAddressRanges(RangesStream, AddressRanges, true);
307 }
308 }
309
DebugAddrWriter(BinaryContext * Bc)310 DebugAddrWriter::DebugAddrWriter(BinaryContext *Bc) { BC = Bc; }
311
dump()312 void DebugAddrWriter::AddressForDWOCU::dump() {
313 std::vector<IndexAddressPair> SortedMap(indexToAddressBegin(),
314 indexToAdddessEnd());
315 // Sorting address in increasing order of indices.
316 llvm::sort(SortedMap, llvm::less_first());
317 for (auto &Pair : SortedMap)
318 dbgs() << Twine::utohexstr(Pair.second) << "\t" << Pair.first << "\n";
319 }
getIndexFromAddress(uint64_t Address,DWARFUnit & CU)320 uint32_t DebugAddrWriter::getIndexFromAddress(uint64_t Address, DWARFUnit &CU) {
321 std::lock_guard<std::mutex> Lock(WriterMutex);
322 const uint64_t CUID = getCUID(CU);
323 if (!AddressMaps.count(CUID))
324 AddressMaps[CUID] = AddressForDWOCU();
325
326 AddressForDWOCU &Map = AddressMaps[CUID];
327 auto Entry = Map.find(Address);
328 if (Entry == Map.end()) {
329 auto Index = Map.getNextIndex();
330 Entry = Map.insert(Address, Index).first;
331 }
332 return Entry->second;
333 }
334
335 // Case1) Address is not in map insert in to AddresToIndex and IndexToAddres
336 // Case2) Address is in the map but Index is higher or equal. Need to update
337 // IndexToAddrss. Case3) Address is in the map but Index is lower. Need to
338 // update AddressToIndex and IndexToAddress
addIndexAddress(uint64_t Address,uint32_t Index,DWARFUnit & CU)339 void DebugAddrWriter::addIndexAddress(uint64_t Address, uint32_t Index,
340 DWARFUnit &CU) {
341 std::lock_guard<std::mutex> Lock(WriterMutex);
342 const uint64_t CUID = getCUID(CU);
343 AddressForDWOCU &Map = AddressMaps[CUID];
344 auto Entry = Map.find(Address);
345 if (Entry != Map.end()) {
346 if (Entry->second > Index)
347 Map.updateAddressToIndex(Address, Index);
348 Map.updateIndexToAddrss(Address, Index);
349 } else {
350 Map.insert(Address, Index);
351 }
352 }
353
finalize()354 AddressSectionBuffer DebugAddrWriter::finalize() {
355 // Need to layout all sections within .debug_addr
356 // Within each section sort Address by index.
357 AddressSectionBuffer Buffer;
358 raw_svector_ostream AddressStream(Buffer);
359 for (std::unique_ptr<DWARFUnit> &CU : BC->DwCtx->compile_units()) {
360 // Handling the case wehre debug information is a mix of Debug fission and
361 // monolitic.
362 if (!CU->getDWOId())
363 continue;
364 const uint64_t CUID = getCUID(*CU.get());
365 auto AM = AddressMaps.find(CUID);
366 // Adding to map even if it did not contribute to .debug_addr.
367 // The Skeleton CU might still have DW_AT_GNU_addr_base.
368 DWOIdToOffsetMap[CUID] = Buffer.size();
369 // If does not exist this CUs DWO section didn't contribute to .debug_addr.
370 if (AM == AddressMaps.end())
371 continue;
372 std::vector<IndexAddressPair> SortedMap(AM->second.indexToAddressBegin(),
373 AM->second.indexToAdddessEnd());
374 // Sorting address in increasing order of indices.
375 llvm::sort(SortedMap, llvm::less_first());
376
377 uint8_t AddrSize = CU->getAddressByteSize();
378 uint32_t Counter = 0;
379 auto WriteAddress = [&](uint64_t Address) -> void {
380 ++Counter;
381 switch (AddrSize) {
382 default:
383 assert(false && "Address Size is invalid.");
384 break;
385 case 4:
386 support::endian::write(AddressStream, static_cast<uint32_t>(Address),
387 support::little);
388 break;
389 case 8:
390 support::endian::write(AddressStream, Address, support::little);
391 break;
392 }
393 };
394
395 for (const IndexAddressPair &Val : SortedMap) {
396 while (Val.first > Counter)
397 WriteAddress(0);
398 WriteAddress(Val.second);
399 }
400 }
401
402 return Buffer;
403 }
finalize()404 AddressSectionBuffer DebugAddrWriterDwarf5::finalize() {
405 // Need to layout all sections within .debug_addr
406 // Within each section sort Address by index.
407 AddressSectionBuffer Buffer;
408 raw_svector_ostream AddressStream(Buffer);
409 const endianness Endian =
410 BC->DwCtx->isLittleEndian() ? support::little : support::big;
411 const DWARFSection &AddrSec = BC->DwCtx->getDWARFObj().getAddrSection();
412 DWARFDataExtractor AddrData(BC->DwCtx->getDWARFObj(), AddrSec, Endian, 0);
413 DWARFDebugAddrTable AddrTable;
414 DIDumpOptions DumpOpts;
415 constexpr uint32_t HeaderSize = 8;
416 for (std::unique_ptr<DWARFUnit> &CU : BC->DwCtx->compile_units()) {
417 const uint64_t CUID = getCUID(*CU.get());
418 const uint8_t AddrSize = CU->getAddressByteSize();
419 auto AMIter = AddressMaps.find(CUID);
420 // A case where CU has entry in .debug_addr, but we don't modify addresses
421 // for it.
422 if (AMIter == AddressMaps.end()) {
423 AMIter = AddressMaps.insert({CUID, AddressForDWOCU()}).first;
424 Optional<uint64_t> BaseOffset = CU->getAddrOffsetSectionBase();
425 if (!BaseOffset)
426 continue;
427 // Address base offset is to the first entry.
428 // The size of header is 8 bytes.
429 uint64_t Offset = *BaseOffset - HeaderSize;
430 if (Error Err = AddrTable.extract(AddrData, &Offset, 5, AddrSize,
431 DumpOpts.WarningHandler)) {
432 DumpOpts.RecoverableErrorHandler(std::move(Err));
433 continue;
434 }
435 uint32_t Index = 0;
436 for (uint64_t Addr : AddrTable.getAddressEntries())
437 AMIter->second.insert(Addr, Index++);
438 }
439
440 DWOIdToOffsetMap[CUID] = Buffer.size() + HeaderSize;
441
442 std::vector<IndexAddressPair> SortedMap(
443 AMIter->second.indexToAddressBegin(),
444 AMIter->second.indexToAdddessEnd());
445 // Sorting address in increasing order of indices.
446 llvm::sort(SortedMap, llvm::less_first());
447 // Writing out Header
448 const uint32_t Length = SortedMap.size() * AddrSize + 4;
449 support::endian::write(AddressStream, Length, Endian);
450 support::endian::write(AddressStream, static_cast<uint16_t>(5), Endian);
451 support::endian::write(AddressStream, static_cast<uint8_t>(AddrSize),
452 Endian);
453 support::endian::write(AddressStream, static_cast<uint8_t>(0), Endian);
454
455 uint32_t Counter = 0;
456 auto writeAddress = [&](uint64_t Address) -> void {
457 ++Counter;
458 switch (AddrSize) {
459 default:
460 llvm_unreachable("Address Size is invalid.");
461 break;
462 case 4:
463 support::endian::write(AddressStream, static_cast<uint32_t>(Address),
464 Endian);
465 break;
466 case 8:
467 support::endian::write(AddressStream, Address, Endian);
468 break;
469 }
470 };
471
472 for (const IndexAddressPair &Val : SortedMap) {
473 while (Val.first > Counter)
474 writeAddress(0);
475 writeAddress(Val.second);
476 }
477 }
478
479 return Buffer;
480 }
481
getOffset(DWARFUnit & Unit)482 uint64_t DebugAddrWriter::getOffset(DWARFUnit &Unit) {
483 const uint64_t CUID = getCUID(Unit);
484 assert(CUID && "Can't get offset, not a skeleton CU.");
485 auto Iter = DWOIdToOffsetMap.find(CUID);
486 assert(Iter != DWOIdToOffsetMap.end() &&
487 "Offset in to.debug_addr was not found for DWO ID.");
488 return Iter->second;
489 }
490
getOffset(DWARFUnit & Unit)491 uint64_t DebugAddrWriterDwarf5::getOffset(DWARFUnit &Unit) {
492 auto Iter = DWOIdToOffsetMap.find(getCUID(Unit));
493 assert(Iter != DWOIdToOffsetMap.end() &&
494 "Offset in to.debug_addr was not found for CU ID.");
495 return Iter->second;
496 }
497
init()498 void DebugLocWriter::init() {
499 LocBuffer = std::make_unique<DebugBufferVector>();
500 LocStream = std::make_unique<raw_svector_ostream>(*LocBuffer);
501 // Writing out empty location list to which all references to empty location
502 // lists will point.
503 if (!LocSectionOffset && DwarfVersion < 5) {
504 const char Zeroes[16] = {0};
505 *LocStream << StringRef(Zeroes, 16);
506 LocSectionOffset += 16;
507 }
508 }
509
510 uint32_t DebugLocWriter::LocSectionOffset = 0;
addList(AttrInfo & AttrVal,DebugLocationsVector & LocList,DebugInfoBinaryPatcher & DebugInfoPatcher,DebugAbbrevWriter & AbbrevWriter)511 void DebugLocWriter::addList(AttrInfo &AttrVal, DebugLocationsVector &LocList,
512 DebugInfoBinaryPatcher &DebugInfoPatcher,
513 DebugAbbrevWriter &AbbrevWriter) {
514 const uint64_t AttrOffset = AttrVal.Offset;
515 if (LocList.empty()) {
516 DebugInfoPatcher.addLE32Patch(AttrOffset, DebugLocWriter::EmptyListOffset);
517 return;
518 }
519 // Since there is a separate DebugLocWriter for each thread,
520 // we don't need a lock to read the SectionOffset and update it.
521 const uint32_t EntryOffset = LocSectionOffset;
522
523 for (const DebugLocationEntry &Entry : LocList) {
524 support::endian::write(*LocStream, static_cast<uint64_t>(Entry.LowPC),
525 support::little);
526 support::endian::write(*LocStream, static_cast<uint64_t>(Entry.HighPC),
527 support::little);
528 support::endian::write(*LocStream, static_cast<uint16_t>(Entry.Expr.size()),
529 support::little);
530 *LocStream << StringRef(reinterpret_cast<const char *>(Entry.Expr.data()),
531 Entry.Expr.size());
532 LocSectionOffset += 2 * 8 + 2 + Entry.Expr.size();
533 }
534 LocStream->write_zeros(16);
535 LocSectionOffset += 16;
536 LocListDebugInfoPatches.push_back({AttrOffset, EntryOffset});
537 DebugInfoPatcher.addLE32Patch(AttrOffset, EntryOffset);
538 }
539
getBuffer()540 std::unique_ptr<DebugBufferVector> DebugLocWriter::getBuffer() {
541 return std::move(LocBuffer);
542 }
543
544 // DWARF 4: 2.6.2
finalize(DebugInfoBinaryPatcher & DebugInfoPatcher,DebugAbbrevWriter & AbbrevWriter)545 void DebugLocWriter::finalize(DebugInfoBinaryPatcher &DebugInfoPatcher,
546 DebugAbbrevWriter &AbbrevWriter) {}
547
writeEmptyListDwarf5(raw_svector_ostream & Stream)548 static void writeEmptyListDwarf5(raw_svector_ostream &Stream) {
549 support::endian::write(Stream, static_cast<uint32_t>(4), support::little);
550 support::endian::write(Stream, static_cast<uint8_t>(dwarf::DW_LLE_start_end),
551 support::little);
552
553 const char Zeroes[16] = {0};
554 Stream << StringRef(Zeroes, 16);
555 encodeULEB128(0, Stream);
556 support::endian::write(
557 Stream, static_cast<uint8_t>(dwarf::DW_LLE_end_of_list), support::little);
558 }
559
writeLegacyLocList(AttrInfo & AttrVal,DebugLocationsVector & LocList,DebugInfoBinaryPatcher & DebugInfoPatcher,DebugAddrWriter & AddrWriter,DebugBufferVector & LocBuffer,DWARFUnit & CU,raw_svector_ostream & LocStream)560 static void writeLegacyLocList(AttrInfo &AttrVal, DebugLocationsVector &LocList,
561 DebugInfoBinaryPatcher &DebugInfoPatcher,
562 DebugAddrWriter &AddrWriter,
563 DebugBufferVector &LocBuffer, DWARFUnit &CU,
564 raw_svector_ostream &LocStream) {
565 const uint64_t AttrOffset = AttrVal.Offset;
566 if (LocList.empty()) {
567 DebugInfoPatcher.addLE32Patch(AttrOffset, DebugLocWriter::EmptyListOffset);
568 return;
569 }
570
571 const uint32_t EntryOffset = LocBuffer.size();
572 for (const DebugLocationEntry &Entry : LocList) {
573 support::endian::write(LocStream,
574 static_cast<uint8_t>(dwarf::DW_LLE_startx_length),
575 support::little);
576 const uint32_t Index = AddrWriter.getIndexFromAddress(Entry.LowPC, CU);
577 encodeULEB128(Index, LocStream);
578
579 support::endian::write(LocStream,
580 static_cast<uint32_t>(Entry.HighPC - Entry.LowPC),
581 support::little);
582 support::endian::write(LocStream, static_cast<uint16_t>(Entry.Expr.size()),
583 support::little);
584 LocStream << StringRef(reinterpret_cast<const char *>(Entry.Expr.data()),
585 Entry.Expr.size());
586 }
587 support::endian::write(LocStream,
588 static_cast<uint8_t>(dwarf::DW_LLE_end_of_list),
589 support::little);
590 DebugInfoPatcher.addLE32Patch(AttrOffset, EntryOffset);
591 }
592
writeDWARF5LocList(uint32_t & NumberOfEntries,AttrInfo & AttrVal,DebugLocationsVector & LocList,DebugInfoBinaryPatcher & DebugInfoPatcher,DebugAbbrevWriter & AbbrevWriter,DebugAddrWriter & AddrWriter,DebugBufferVector & LocBodyBuffer,std::vector<uint32_t> & RelativeLocListOffsets,DWARFUnit & CU,raw_svector_ostream & LocBodyStream)593 static void writeDWARF5LocList(
594 uint32_t &NumberOfEntries, AttrInfo &AttrVal, DebugLocationsVector &LocList,
595 DebugInfoBinaryPatcher &DebugInfoPatcher, DebugAbbrevWriter &AbbrevWriter,
596 DebugAddrWriter &AddrWriter, DebugBufferVector &LocBodyBuffer,
597 std::vector<uint32_t> &RelativeLocListOffsets, DWARFUnit &CU,
598 raw_svector_ostream &LocBodyStream) {
599 if (AttrVal.V.getForm() != dwarf::DW_FORM_loclistx) {
600 AbbrevWriter.addAttributePatch(CU, AttrVal.AbbrevDecl,
601 dwarf::DW_AT_location, dwarf::DW_AT_location,
602 dwarf::DW_FORM_loclistx);
603 }
604 DebugInfoPatcher.addUDataPatch(AttrVal.Offset, NumberOfEntries, AttrVal.Size);
605 RelativeLocListOffsets.push_back(LocBodyBuffer.size());
606 ++NumberOfEntries;
607 if (LocList.empty()) {
608 writeEmptyListDwarf5(LocBodyStream);
609 return;
610 }
611
612 std::vector<uint64_t> OffsetsArray;
613 for (const DebugLocationEntry &Entry : LocList) {
614 support::endian::write(LocBodyStream,
615 static_cast<uint8_t>(dwarf::DW_LLE_startx_length),
616 support::little);
617 const uint32_t Index = AddrWriter.getIndexFromAddress(Entry.LowPC, CU);
618 encodeULEB128(Index, LocBodyStream);
619 encodeULEB128(Entry.HighPC - Entry.LowPC, LocBodyStream);
620 encodeULEB128(Entry.Expr.size(), LocBodyStream);
621 LocBodyStream << StringRef(
622 reinterpret_cast<const char *>(Entry.Expr.data()), Entry.Expr.size());
623 }
624 support::endian::write(LocBodyStream,
625 static_cast<uint8_t>(dwarf::DW_LLE_end_of_list),
626 support::little);
627 }
628
addList(AttrInfo & AttrVal,DebugLocationsVector & LocList,DebugInfoBinaryPatcher & DebugInfoPatcher,DebugAbbrevWriter & AbbrevWriter)629 void DebugLoclistWriter::addList(AttrInfo &AttrVal,
630 DebugLocationsVector &LocList,
631 DebugInfoBinaryPatcher &DebugInfoPatcher,
632 DebugAbbrevWriter &AbbrevWriter) {
633 if (DwarfVersion < 5)
634 writeLegacyLocList(AttrVal, LocList, DebugInfoPatcher, *AddrWriter,
635 *LocBuffer, CU, *LocStream);
636 else
637 writeDWARF5LocList(NumberOfEntries, AttrVal, LocList, DebugInfoPatcher,
638 AbbrevWriter, *AddrWriter, *LocBodyBuffer,
639 RelativeLocListOffsets, CU, *LocBodyStream);
640 }
641
642 uint32_t DebugLoclistWriter::LoclistBaseOffset = 0;
finalizeDWARF5(DebugInfoBinaryPatcher & DebugInfoPatcher,DebugAbbrevWriter & AbbrevWriter)643 void DebugLoclistWriter::finalizeDWARF5(
644 DebugInfoBinaryPatcher &DebugInfoPatcher, DebugAbbrevWriter &AbbrevWriter) {
645 if (LocBodyBuffer->empty())
646 return;
647
648 std::unique_ptr<DebugBufferVector> LocArrayBuffer =
649 std::make_unique<DebugBufferVector>();
650 std::unique_ptr<raw_svector_ostream> LocArrayStream =
651 std::make_unique<raw_svector_ostream>(*LocArrayBuffer);
652
653 const uint32_t SizeOfArraySection = NumberOfEntries * sizeof(uint32_t);
654 // Write out IndexArray
655 for (uint32_t RelativeOffset : RelativeLocListOffsets)
656 support::endian::write(
657 *LocArrayStream,
658 static_cast<uint32_t>(SizeOfArraySection + RelativeOffset),
659 support::little);
660
661 std::unique_ptr<DebugBufferVector> Header = getDWARF5Header(
662 {static_cast<uint32_t>(SizeOfArraySection + LocBodyBuffer.get()->size()),
663 5, 8, 0, NumberOfEntries});
664 *LocStream << *Header;
665 *LocStream << *LocArrayBuffer;
666 *LocStream << *LocBodyBuffer;
667
668 if (!isSplitDwarf()) {
669 if (Optional<AttrInfo> AttrInfoVal =
670 findAttributeInfo(CU.getUnitDIE(), dwarf::DW_AT_loclists_base))
671 DebugInfoPatcher.addLE32Patch(AttrInfoVal->Offset,
672 LoclistBaseOffset +
673 getDWARF5RngListLocListHeaderSize());
674 else {
675 AbbrevWriter.addAttribute(
676 CU, CU.getUnitDIE().getAbbreviationDeclarationPtr(),
677 dwarf::DW_AT_loclists_base, dwarf::DW_FORM_sec_offset);
678 DebugInfoPatcher.insertNewEntry(CU.getUnitDIE(),
679 LoclistBaseOffset + Header->size());
680 }
681 LoclistBaseOffset += LocBuffer->size();
682 }
683 clearList(RelativeLocListOffsets);
684 clearList(*LocArrayBuffer);
685 clearList(*LocBodyBuffer);
686 }
687
finalize(DebugInfoBinaryPatcher & DebugInfoPatcher,DebugAbbrevWriter & AbbrevWriter)688 void DebugLoclistWriter::finalize(DebugInfoBinaryPatcher &DebugInfoPatcher,
689 DebugAbbrevWriter &AbbrevWriter) {
690 if (DwarfVersion >= 5)
691 finalizeDWARF5(DebugInfoPatcher, AbbrevWriter);
692 }
693
694 DebugAddrWriter *DebugLoclistWriter::AddrWriter = nullptr;
695
addUnitBaseOffsetLabel(uint64_t Offset)696 void DebugInfoBinaryPatcher::addUnitBaseOffsetLabel(uint64_t Offset) {
697 Offset -= DWPUnitOffset;
698 std::lock_guard<std::mutex> Lock(WriterMutex);
699 DebugPatches.emplace_back(new DWARFUnitOffsetBaseLabel(Offset));
700 }
701
addDestinationReferenceLabel(uint64_t Offset)702 void DebugInfoBinaryPatcher::addDestinationReferenceLabel(uint64_t Offset) {
703 Offset -= DWPUnitOffset;
704 std::lock_guard<std::mutex> Lock(WriterMutex);
705 auto RetVal = DestinationLabels.insert(Offset);
706 if (!RetVal.second)
707 return;
708
709 DebugPatches.emplace_back(new DestinationReferenceLabel(Offset));
710 }
711
encodeLE(size_t ByteSize,uint64_t NewValue)712 static std::string encodeLE(size_t ByteSize, uint64_t NewValue) {
713 std::string LE64(ByteSize, 0);
714 for (size_t I = 0; I < ByteSize; ++I) {
715 LE64[I] = NewValue & 0xff;
716 NewValue >>= 8;
717 }
718 return LE64;
719 }
720
insertNewEntry(const DWARFDie & DIE,uint32_t Value)721 void DebugInfoBinaryPatcher::insertNewEntry(const DWARFDie &DIE,
722 uint32_t Value) {
723 std::string StrValue = encodeLE(4, Value);
724 insertNewEntry(DIE, std::move(StrValue));
725 }
726
insertNewEntry(const DWARFDie & DIE,std::string && Value)727 void DebugInfoBinaryPatcher::insertNewEntry(const DWARFDie &DIE,
728 std::string &&Value) {
729 const DWARFAbbreviationDeclaration *AbbrevDecl =
730 DIE.getAbbreviationDeclarationPtr();
731
732 // In case this DIE has no attributes.
733 uint32_t Offset = DIE.getOffset() + 1;
734 size_t NumOfAttributes = AbbrevDecl->getNumAttributes();
735 if (NumOfAttributes) {
736 Optional<AttrInfo> Val =
737 findAttributeInfo(DIE, AbbrevDecl, NumOfAttributes - 1);
738 assert(Val && "Invalid Value.");
739
740 Offset = Val->Offset + Val->Size - DWPUnitOffset;
741 }
742 std::lock_guard<std::mutex> Lock(WriterMutex);
743 DebugPatches.emplace_back(new NewDebugEntry(Offset, std::move(Value)));
744 }
745
addReferenceToPatch(uint64_t Offset,uint32_t DestinationOffset,uint32_t OldValueSize,dwarf::Form Form)746 void DebugInfoBinaryPatcher::addReferenceToPatch(uint64_t Offset,
747 uint32_t DestinationOffset,
748 uint32_t OldValueSize,
749 dwarf::Form Form) {
750 Offset -= DWPUnitOffset;
751 DestinationOffset -= DWPUnitOffset;
752 std::lock_guard<std::mutex> Lock(WriterMutex);
753 DebugPatches.emplace_back(
754 new DebugPatchReference(Offset, OldValueSize, DestinationOffset, Form));
755 }
756
addUDataPatch(uint64_t Offset,uint64_t NewValue,uint32_t OldValueSize)757 void DebugInfoBinaryPatcher::addUDataPatch(uint64_t Offset, uint64_t NewValue,
758 uint32_t OldValueSize) {
759 Offset -= DWPUnitOffset;
760 std::lock_guard<std::mutex> Lock(WriterMutex);
761 DebugPatches.emplace_back(
762 new DebugPatchVariableSize(Offset, OldValueSize, NewValue));
763 }
764
addLE64Patch(uint64_t Offset,uint64_t NewValue)765 void DebugInfoBinaryPatcher::addLE64Patch(uint64_t Offset, uint64_t NewValue) {
766 Offset -= DWPUnitOffset;
767 std::lock_guard<std::mutex> Lock(WriterMutex);
768 DebugPatches.emplace_back(new DebugPatch64(Offset, NewValue));
769 }
770
addLE32Patch(uint64_t Offset,uint32_t NewValue,uint32_t OldValueSize)771 void DebugInfoBinaryPatcher::addLE32Patch(uint64_t Offset, uint32_t NewValue,
772 uint32_t OldValueSize) {
773 Offset -= DWPUnitOffset;
774 std::lock_guard<std::mutex> Lock(WriterMutex);
775 if (OldValueSize == 4)
776 DebugPatches.emplace_back(new DebugPatch32(Offset, NewValue));
777 else if (OldValueSize == 8)
778 DebugPatches.emplace_back(new DebugPatch64to32(Offset, NewValue));
779 else
780 DebugPatches.emplace_back(
781 new DebugPatch32GenericSize(Offset, NewValue, OldValueSize));
782 }
783
addBinaryPatch(uint64_t Offset,std::string && NewValue,uint32_t OldValueSize)784 void SimpleBinaryPatcher::addBinaryPatch(uint64_t Offset,
785 std::string &&NewValue,
786 uint32_t OldValueSize) {
787 Patches.emplace_back(Offset, std::move(NewValue));
788 }
789
addBytePatch(uint64_t Offset,uint8_t Value)790 void SimpleBinaryPatcher::addBytePatch(uint64_t Offset, uint8_t Value) {
791 auto Str = std::string(1, Value);
792 Patches.emplace_back(Offset, std::move(Str));
793 }
794
addLEPatch(uint64_t Offset,uint64_t NewValue,size_t ByteSize)795 void SimpleBinaryPatcher::addLEPatch(uint64_t Offset, uint64_t NewValue,
796 size_t ByteSize) {
797 Patches.emplace_back(Offset, encodeLE(ByteSize, NewValue));
798 }
799
addUDataPatch(uint64_t Offset,uint64_t Value,uint32_t OldValueSize)800 void SimpleBinaryPatcher::addUDataPatch(uint64_t Offset, uint64_t Value,
801 uint32_t OldValueSize) {
802 std::string Buff;
803 raw_string_ostream OS(Buff);
804 encodeULEB128(Value, OS, OldValueSize);
805
806 Patches.emplace_back(Offset, std::move(Buff));
807 }
808
addLE64Patch(uint64_t Offset,uint64_t NewValue)809 void SimpleBinaryPatcher::addLE64Patch(uint64_t Offset, uint64_t NewValue) {
810 addLEPatch(Offset, NewValue, 8);
811 }
812
addLE32Patch(uint64_t Offset,uint32_t NewValue,uint32_t OldValueSize)813 void SimpleBinaryPatcher::addLE32Patch(uint64_t Offset, uint32_t NewValue,
814 uint32_t OldValueSize) {
815 addLEPatch(Offset, NewValue, 4);
816 }
817
patchBinary(StringRef BinaryContents)818 std::string SimpleBinaryPatcher::patchBinary(StringRef BinaryContents) {
819 std::string BinaryContentsStr = std::string(BinaryContents);
820 for (const auto &Patch : Patches) {
821 uint32_t Offset = Patch.first;
822 const std::string &ByteSequence = Patch.second;
823 assert(Offset + ByteSequence.size() <= BinaryContents.size() &&
824 "Applied patch runs over binary size.");
825 for (uint64_t I = 0, Size = ByteSequence.size(); I < Size; ++I) {
826 BinaryContentsStr[Offset + I] = ByteSequence[I];
827 }
828 }
829 return BinaryContentsStr;
830 }
831
computeNewOffsets(DWARFContext & DWCtx,bool IsDWOContext)832 CUOffsetMap DebugInfoBinaryPatcher::computeNewOffsets(DWARFContext &DWCtx,
833 bool IsDWOContext) {
834 CUOffsetMap CUMap;
835 llvm::sort(DebugPatches, [](const UniquePatchPtrType &V1,
836 const UniquePatchPtrType &V2) {
837 if (V1.get()->Offset == V2.get()->Offset) {
838 if (V1->Kind == DebugPatchKind::NewDebugEntry &&
839 V2->Kind == DebugPatchKind::NewDebugEntry)
840 return reinterpret_cast<const NewDebugEntry *>(V1.get())->CurrentOrder <
841 reinterpret_cast<const NewDebugEntry *>(V2.get())->CurrentOrder;
842
843 // This is a case where we are modifying first entry of next
844 // DIE, and adding a new one.
845 return V1->Kind == DebugPatchKind::NewDebugEntry;
846 }
847 return V1.get()->Offset < V2.get()->Offset;
848 });
849
850 DWARFUnitVector::compile_unit_range CompileUnits =
851 IsDWOContext ? DWCtx.dwo_compile_units() : DWCtx.compile_units();
852
853 for (const std::unique_ptr<DWARFUnit> &CU : CompileUnits)
854 CUMap[CU->getOffset()] = {static_cast<uint32_t>(CU->getOffset()),
855 static_cast<uint32_t>(CU->getLength())};
856
857 // Calculating changes in .debug_info size from Patches to build a map of old
858 // to updated reference destination offsets.
859 uint32_t PreviousOffset = 0;
860 int32_t PreviousChangeInSize = 0;
861 for (UniquePatchPtrType &PatchBase : DebugPatches) {
862 Patch *P = PatchBase.get();
863 switch (P->Kind) {
864 default:
865 continue;
866 case DebugPatchKind::PatchValue64to32: {
867 PreviousChangeInSize -= 4;
868 break;
869 }
870 case DebugPatchKind::PatchValue32GenericSize: {
871 DebugPatch32GenericSize *DPVS =
872 reinterpret_cast<DebugPatch32GenericSize *>(P);
873 PreviousChangeInSize += 4 - DPVS->OldValueSize;
874 break;
875 }
876 case DebugPatchKind::PatchValueVariable: {
877 DebugPatchVariableSize *DPV =
878 reinterpret_cast<DebugPatchVariableSize *>(P);
879 std::string Temp;
880 raw_string_ostream OS(Temp);
881 encodeULEB128(DPV->Value, OS);
882 PreviousChangeInSize += Temp.size() - DPV->OldValueSize;
883 break;
884 }
885 case DebugPatchKind::DestinationReferenceLabel: {
886 DestinationReferenceLabel *DRL =
887 reinterpret_cast<DestinationReferenceLabel *>(P);
888 OldToNewOffset[DRL->Offset] =
889 DRL->Offset + ChangeInSize + PreviousChangeInSize;
890 break;
891 }
892 case DebugPatchKind::ReferencePatchValue: {
893 // This doesn't look to be a common case, so will always encode as 4 bytes
894 // to reduce algorithmic complexity.
895 DebugPatchReference *RDP = reinterpret_cast<DebugPatchReference *>(P);
896 if (RDP->PatchInfo.IndirectRelative) {
897 PreviousChangeInSize += 4 - RDP->PatchInfo.OldValueSize;
898 assert(RDP->PatchInfo.OldValueSize <= 4 &&
899 "Variable encoding reference greater than 4 bytes.");
900 }
901 break;
902 }
903 case DebugPatchKind::DWARFUnitOffsetBaseLabel: {
904 DWARFUnitOffsetBaseLabel *BaseLabel =
905 reinterpret_cast<DWARFUnitOffsetBaseLabel *>(P);
906 uint32_t CUOffset = BaseLabel->Offset;
907 ChangeInSize += PreviousChangeInSize;
908 uint32_t CUOffsetUpdate = CUOffset + ChangeInSize;
909 CUMap[CUOffset].Offset = CUOffsetUpdate;
910 CUMap[PreviousOffset].Length += PreviousChangeInSize;
911 PreviousChangeInSize = 0;
912 PreviousOffset = CUOffset;
913 break;
914 }
915 case DebugPatchKind::NewDebugEntry: {
916 NewDebugEntry *NDE = reinterpret_cast<NewDebugEntry *>(P);
917 PreviousChangeInSize += NDE->Value.size();
918 break;
919 }
920 }
921 }
922 CUMap[PreviousOffset].Length += PreviousChangeInSize;
923 return CUMap;
924 }
925 uint32_t DebugInfoBinaryPatcher::NewDebugEntry::OrderCounter = 0;
926
patchBinary(StringRef BinaryContents)927 std::string DebugInfoBinaryPatcher::patchBinary(StringRef BinaryContents) {
928 std::string NewBinaryContents;
929 NewBinaryContents.reserve(BinaryContents.size() + ChangeInSize);
930 uint32_t StartOffset = 0;
931 uint32_t DwarfUnitBaseOffset = 0;
932 uint32_t OldValueSize = 0;
933 uint32_t Offset = 0;
934 std::string ByteSequence;
935 std::vector<std::pair<uint32_t, uint32_t>> LengthPatches;
936 // Wasting one entry to avoid checks for first.
937 LengthPatches.push_back({0, 0});
938
939 // Applying all the patches replacing current entry.
940 // This might change the size of .debug_info section.
941 for (const UniquePatchPtrType &PatchBase : DebugPatches) {
942 Patch *P = PatchBase.get();
943 switch (P->Kind) {
944 default:
945 continue;
946 case DebugPatchKind::ReferencePatchValue: {
947 DebugPatchReference *RDP = reinterpret_cast<DebugPatchReference *>(P);
948 uint32_t DestinationOffset = RDP->DestinationOffset;
949 assert(OldToNewOffset.count(DestinationOffset) &&
950 "Destination Offset for reference not updated.");
951 uint32_t UpdatedOffset = OldToNewOffset[DestinationOffset];
952 Offset = RDP->Offset;
953 OldValueSize = RDP->PatchInfo.OldValueSize;
954 if (RDP->PatchInfo.DirectRelative) {
955 UpdatedOffset -= DwarfUnitBaseOffset;
956 ByteSequence = encodeLE(OldValueSize, UpdatedOffset);
957 // In theory reference for DW_FORM_ref{1,2,4,8} can be right on the edge
958 // and overflow if later debug information grows.
959 if (ByteSequence.size() > OldValueSize)
960 errs() << "BOLT-ERROR: Relative reference of size "
961 << Twine::utohexstr(OldValueSize)
962 << " overflows with the new encoding.\n";
963 } else if (RDP->PatchInfo.DirectAbsolute) {
964 ByteSequence = encodeLE(OldValueSize, UpdatedOffset);
965 } else if (RDP->PatchInfo.IndirectRelative) {
966 UpdatedOffset -= DwarfUnitBaseOffset;
967 ByteSequence.clear();
968 raw_string_ostream OS(ByteSequence);
969 encodeULEB128(UpdatedOffset, OS, 4);
970 } else {
971 llvm_unreachable("Invalid Reference form.");
972 }
973 break;
974 }
975 case DebugPatchKind::PatchValue32: {
976 DebugPatch32 *P32 = reinterpret_cast<DebugPatch32 *>(P);
977 Offset = P32->Offset;
978 OldValueSize = 4;
979 ByteSequence = encodeLE(4, P32->Value);
980 break;
981 }
982 case DebugPatchKind::PatchValue64to32: {
983 DebugPatch64to32 *P64to32 = reinterpret_cast<DebugPatch64to32 *>(P);
984 Offset = P64to32->Offset;
985 OldValueSize = 8;
986 ByteSequence = encodeLE(4, P64to32->Value);
987 break;
988 }
989 case DebugPatchKind::PatchValue32GenericSize: {
990 DebugPatch32GenericSize *DPVS =
991 reinterpret_cast<DebugPatch32GenericSize *>(P);
992 Offset = DPVS->Offset;
993 OldValueSize = DPVS->OldValueSize;
994 ByteSequence = encodeLE(4, DPVS->Value);
995 break;
996 }
997 case DebugPatchKind::PatchValueVariable: {
998 DebugPatchVariableSize *PV =
999 reinterpret_cast<DebugPatchVariableSize *>(P);
1000 Offset = PV->Offset;
1001 OldValueSize = PV->OldValueSize;
1002 ByteSequence.clear();
1003 raw_string_ostream OS(ByteSequence);
1004 encodeULEB128(PV->Value, OS);
1005 break;
1006 }
1007 case DebugPatchKind::PatchValue64: {
1008 DebugPatch64 *P64 = reinterpret_cast<DebugPatch64 *>(P);
1009 Offset = P64->Offset;
1010 OldValueSize = 8;
1011 ByteSequence = encodeLE(8, P64->Value);
1012 break;
1013 }
1014 case DebugPatchKind::DWARFUnitOffsetBaseLabel: {
1015 DWARFUnitOffsetBaseLabel *BaseLabel =
1016 reinterpret_cast<DWARFUnitOffsetBaseLabel *>(P);
1017 Offset = BaseLabel->Offset;
1018 OldValueSize = 0;
1019 ByteSequence.clear();
1020 auto &Patch = LengthPatches.back();
1021 // Length to copy between last patch entry and next compile unit.
1022 uint32_t RemainingLength = Offset - StartOffset;
1023 uint32_t NewCUOffset = NewBinaryContents.size() + RemainingLength;
1024 DwarfUnitBaseOffset = NewCUOffset;
1025 // Length of previous CU = This CU Offset - sizeof(length) - last CU
1026 // Offset.
1027 Patch.second = NewCUOffset - 4 - Patch.first;
1028 LengthPatches.push_back({NewCUOffset, 0});
1029 break;
1030 }
1031 case DebugPatchKind::NewDebugEntry: {
1032 NewDebugEntry *NDE = reinterpret_cast<NewDebugEntry *>(P);
1033 Offset = NDE->Offset;
1034 OldValueSize = 0;
1035 ByteSequence = NDE->Value;
1036 break;
1037 }
1038 }
1039
1040 assert((P->Kind == DebugPatchKind::NewDebugEntry ||
1041 Offset + ByteSequence.size() <= BinaryContents.size()) &&
1042 "Applied patch runs over binary size.");
1043 uint32_t Length = Offset - StartOffset;
1044 NewBinaryContents.append(BinaryContents.substr(StartOffset, Length).data(),
1045 Length);
1046 NewBinaryContents.append(ByteSequence.data(), ByteSequence.size());
1047 StartOffset = Offset + OldValueSize;
1048 }
1049 uint32_t Length = BinaryContents.size() - StartOffset;
1050 NewBinaryContents.append(BinaryContents.substr(StartOffset, Length).data(),
1051 Length);
1052 DebugPatches.clear();
1053
1054 // Patching lengths of CUs
1055 auto &Patch = LengthPatches.back();
1056 Patch.second = NewBinaryContents.size() - 4 - Patch.first;
1057 for (uint32_t J = 1, Size = LengthPatches.size(); J < Size; ++J) {
1058 const auto &Patch = LengthPatches[J];
1059 ByteSequence = encodeLE(4, Patch.second);
1060 Offset = Patch.first;
1061 for (uint64_t I = 0, Size = ByteSequence.size(); I < Size; ++I)
1062 NewBinaryContents[Offset + I] = ByteSequence[I];
1063 }
1064
1065 return NewBinaryContents;
1066 }
1067
initialize(const DWARFSection & StrOffsetsSection,const Optional<StrOffsetsContributionDescriptor> Contr)1068 void DebugStrOffsetsWriter::initialize(
1069 const DWARFSection &StrOffsetsSection,
1070 const Optional<StrOffsetsContributionDescriptor> Contr) {
1071 if (!Contr)
1072 return;
1073
1074 const uint8_t DwarfOffsetByteSize = Contr->getDwarfOffsetByteSize();
1075 assert(DwarfOffsetByteSize == 4 &&
1076 "Dwarf String Offsets Byte Size is not supported.");
1077 uint32_t Index = 0;
1078 for (uint64_t Offset = 0; Offset < Contr->Size; Offset += DwarfOffsetByteSize)
1079 IndexToAddressMap[Index++] = *reinterpret_cast<const uint32_t *>(
1080 StrOffsetsSection.Data.data() + Contr->Base + Offset);
1081 }
1082
updateAddressMap(uint32_t Index,uint32_t Address)1083 void DebugStrOffsetsWriter::updateAddressMap(uint32_t Index, uint32_t Address) {
1084 assert(IndexToAddressMap.count(Index) > 0 && "Index is not found.");
1085 IndexToAddressMap[Index] = Address;
1086 }
1087
finalizeSection()1088 void DebugStrOffsetsWriter::finalizeSection() {
1089 if (IndexToAddressMap.empty())
1090 return;
1091 // Writing out the header for each section.
1092 support::endian::write(*StrOffsetsStream, CurrentSectionSize + 4,
1093 support::little);
1094 support::endian::write(*StrOffsetsStream, static_cast<uint16_t>(5),
1095 support::little);
1096 support::endian::write(*StrOffsetsStream, static_cast<uint16_t>(0),
1097 support::little);
1098 for (const auto &Entry : IndexToAddressMap)
1099 support::endian::write(*StrOffsetsStream, Entry.second, support::little);
1100 IndexToAddressMap.clear();
1101 }
1102
create()1103 void DebugStrWriter::create() {
1104 StrBuffer = std::make_unique<DebugStrBufferVector>();
1105 StrStream = std::make_unique<raw_svector_ostream>(*StrBuffer);
1106 }
1107
initialize()1108 void DebugStrWriter::initialize() {
1109 auto StrSection = BC.DwCtx->getDWARFObj().getStrSection();
1110 (*StrStream) << StrSection;
1111 }
1112
addString(StringRef Str)1113 uint32_t DebugStrWriter::addString(StringRef Str) {
1114 std::lock_guard<std::mutex> Lock(WriterMutex);
1115 if (StrBuffer->empty())
1116 initialize();
1117 auto Offset = StrBuffer->size();
1118 (*StrStream) << Str;
1119 StrStream->write_zeros(1);
1120 return Offset;
1121 }
1122
addUnitAbbreviations(DWARFUnit & Unit)1123 void DebugAbbrevWriter::addUnitAbbreviations(DWARFUnit &Unit) {
1124 const DWARFAbbreviationDeclarationSet *Abbrevs = Unit.getAbbreviations();
1125 if (!Abbrevs)
1126 return;
1127
1128 const PatchesTy &UnitPatches = Patches[&Unit];
1129 const AbbrevEntryTy &AbbrevEntries = NewAbbrevEntries[&Unit];
1130
1131 // We are duplicating abbrev sections, to handle the case where for one CU we
1132 // modify it, but for another we don't.
1133 auto UnitDataPtr = std::make_unique<AbbrevData>();
1134 AbbrevData &UnitData = *UnitDataPtr.get();
1135 UnitData.Buffer = std::make_unique<DebugBufferVector>();
1136 UnitData.Stream = std::make_unique<raw_svector_ostream>(*UnitData.Buffer);
1137
1138 raw_svector_ostream &OS = *UnitData.Stream.get();
1139
1140 // Returns true if AbbrevData is re-used, false otherwise.
1141 auto hashAndAddAbbrev = [&](StringRef AbbrevData) -> bool {
1142 llvm::SHA1 Hasher;
1143 Hasher.update(AbbrevData);
1144 std::array<uint8_t, 20> Hash = Hasher.final();
1145 StringRef Key((const char *)Hash.data(), Hash.size());
1146 auto Iter = AbbrevDataCache.find(Key);
1147 if (Iter != AbbrevDataCache.end()) {
1148 UnitsAbbrevData[&Unit] = Iter->second.get();
1149 return true;
1150 }
1151 AbbrevDataCache[Key] = std::move(UnitDataPtr);
1152 UnitsAbbrevData[&Unit] = &UnitData;
1153 return false;
1154 };
1155 // Take a fast path if there are no patches to apply. Simply copy the original
1156 // contents.
1157 if (UnitPatches.empty() && AbbrevEntries.empty()) {
1158 StringRef AbbrevSectionContents =
1159 Unit.isDWOUnit() ? Unit.getContext().getDWARFObj().getAbbrevDWOSection()
1160 : Unit.getContext().getDWARFObj().getAbbrevSection();
1161 StringRef AbbrevContents;
1162
1163 const DWARFUnitIndex &CUIndex = Unit.getContext().getCUIndex();
1164 if (!CUIndex.getRows().empty()) {
1165 // Handle DWP section contribution.
1166 const DWARFUnitIndex::Entry *DWOEntry =
1167 CUIndex.getFromHash(*Unit.getDWOId());
1168 if (!DWOEntry)
1169 return;
1170
1171 const DWARFUnitIndex::Entry::SectionContribution *DWOContrubution =
1172 DWOEntry->getContribution(DWARFSectionKind::DW_SECT_ABBREV);
1173 AbbrevContents = AbbrevSectionContents.substr(DWOContrubution->Offset,
1174 DWOContrubution->Length);
1175 } else if (!Unit.isDWOUnit()) {
1176 const uint64_t StartOffset = Unit.getAbbreviationsOffset();
1177
1178 // We know where the unit's abbreviation set starts, but not where it ends
1179 // as such data is not readily available. Hence, we have to build a sorted
1180 // list of start addresses and find the next starting address to determine
1181 // the set boundaries.
1182 //
1183 // FIXME: if we had a full access to DWARFDebugAbbrev::AbbrDeclSets
1184 // we wouldn't have to build our own sorted list for the quick lookup.
1185 if (AbbrevSetOffsets.empty()) {
1186 for_each(
1187 *Unit.getContext().getDebugAbbrev(),
1188 [&](const std::pair<uint64_t, DWARFAbbreviationDeclarationSet> &P) {
1189 AbbrevSetOffsets.push_back(P.first);
1190 });
1191 sort(AbbrevSetOffsets);
1192 }
1193 auto It = upper_bound(AbbrevSetOffsets, StartOffset);
1194 const uint64_t EndOffset =
1195 It == AbbrevSetOffsets.end() ? AbbrevSectionContents.size() : *It;
1196 AbbrevContents = AbbrevSectionContents.slice(StartOffset, EndOffset);
1197 } else {
1198 // For DWO unit outside of DWP, we expect the entire section to hold
1199 // abbreviations for this unit only.
1200 AbbrevContents = AbbrevSectionContents;
1201 }
1202
1203 if (!hashAndAddAbbrev(AbbrevContents)) {
1204 OS.reserveExtraSpace(AbbrevContents.size());
1205 OS << AbbrevContents;
1206 }
1207 return;
1208 }
1209
1210 for (auto I = Abbrevs->begin(), E = Abbrevs->end(); I != E; ++I) {
1211 const DWARFAbbreviationDeclaration &Abbrev = *I;
1212 auto Patch = UnitPatches.find(&Abbrev);
1213
1214 encodeULEB128(Abbrev.getCode(), OS);
1215 encodeULEB128(Abbrev.getTag(), OS);
1216 encodeULEB128(Abbrev.hasChildren(), OS);
1217 for (const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec :
1218 Abbrev.attributes()) {
1219 if (Patch != UnitPatches.end()) {
1220 bool Patched = false;
1221 // Patches added later take a precedence over earlier ones.
1222 for (auto I = Patch->second.rbegin(), E = Patch->second.rend(); I != E;
1223 ++I) {
1224 if (I->OldAttr != AttrSpec.Attr)
1225 continue;
1226
1227 encodeULEB128(I->NewAttr, OS);
1228 encodeULEB128(I->NewAttrForm, OS);
1229 Patched = true;
1230 break;
1231 }
1232 if (Patched)
1233 continue;
1234 }
1235
1236 encodeULEB128(AttrSpec.Attr, OS);
1237 encodeULEB128(AttrSpec.Form, OS);
1238 if (AttrSpec.isImplicitConst())
1239 encodeSLEB128(AttrSpec.getImplicitConstValue(), OS);
1240 }
1241 const auto Entries = AbbrevEntries.find(&Abbrev);
1242 // Adding new Abbrevs for inserted entries.
1243 if (Entries != AbbrevEntries.end()) {
1244 for (const AbbrevEntry &Entry : Entries->second) {
1245 encodeULEB128(Entry.Attr, OS);
1246 encodeULEB128(Entry.Form, OS);
1247 }
1248 }
1249 encodeULEB128(0, OS);
1250 encodeULEB128(0, OS);
1251 }
1252 encodeULEB128(0, OS);
1253
1254 hashAndAddAbbrev(OS.str());
1255 }
1256
finalize()1257 std::unique_ptr<DebugBufferVector> DebugAbbrevWriter::finalize() {
1258 // Used to create determinism for writing out abbrevs.
1259 std::vector<AbbrevData *> Abbrevs;
1260 if (DWOId) {
1261 // We expect abbrev_offset to always be zero for DWO units as there
1262 // should be one CU per DWO, and TUs should share the same abbreviation
1263 // set with the CU.
1264 // For DWP AbbreviationsOffset is an Abbrev contribution in the DWP file, so
1265 // can be none zero. Thus we are skipping the check for DWP.
1266 bool IsDWP = !Context.getCUIndex().getRows().empty();
1267 if (!IsDWP) {
1268 for (const std::unique_ptr<DWARFUnit> &Unit : Context.dwo_units()) {
1269 if (Unit->getAbbreviationsOffset() != 0) {
1270 errs() << "BOLT-ERROR: detected DWO unit with non-zero abbr_offset. "
1271 "Unable to update debug info.\n";
1272 exit(1);
1273 }
1274 }
1275 }
1276
1277 DWARFUnit *Unit = Context.getDWOCompileUnitForHash(*DWOId);
1278 // Issue abbreviations for the DWO CU only.
1279 addUnitAbbreviations(*Unit);
1280 AbbrevData *Abbrev = UnitsAbbrevData[Unit];
1281 Abbrevs.push_back(Abbrev);
1282 } else {
1283 Abbrevs.reserve(Context.getNumCompileUnits() + Context.getNumTypeUnits());
1284 std::unordered_set<AbbrevData *> ProcessedAbbrevs;
1285 // Add abbreviations from compile and type non-DWO units.
1286 for (const std::unique_ptr<DWARFUnit> &Unit : Context.normal_units()) {
1287 addUnitAbbreviations(*Unit);
1288 AbbrevData *Abbrev = UnitsAbbrevData[Unit.get()];
1289 if (!ProcessedAbbrevs.insert(Abbrev).second)
1290 continue;
1291 Abbrevs.push_back(Abbrev);
1292 }
1293 }
1294
1295 DebugBufferVector ReturnBuffer;
1296 // Pre-calculate the total size of abbrev section.
1297 uint64_t Size = 0;
1298 for (const AbbrevData *UnitData : Abbrevs)
1299 Size += UnitData->Buffer->size();
1300
1301 ReturnBuffer.reserve(Size);
1302
1303 uint64_t Pos = 0;
1304 for (AbbrevData *UnitData : Abbrevs) {
1305 ReturnBuffer.append(*UnitData->Buffer);
1306 UnitData->Offset = Pos;
1307 Pos += UnitData->Buffer->size();
1308
1309 UnitData->Buffer.reset();
1310 UnitData->Stream.reset();
1311 }
1312
1313 return std::make_unique<DebugBufferVector>(ReturnBuffer);
1314 }
1315
emitDwarfSetLineAddrAbs(MCStreamer & OS,MCDwarfLineTableParams Params,int64_t LineDelta,uint64_t Address,int PointerSize)1316 static void emitDwarfSetLineAddrAbs(MCStreamer &OS,
1317 MCDwarfLineTableParams Params,
1318 int64_t LineDelta, uint64_t Address,
1319 int PointerSize) {
1320 // emit the sequence to set the address
1321 OS.emitIntValue(dwarf::DW_LNS_extended_op, 1);
1322 OS.emitULEB128IntValue(PointerSize + 1);
1323 OS.emitIntValue(dwarf::DW_LNE_set_address, 1);
1324 OS.emitIntValue(Address, PointerSize);
1325
1326 // emit the sequence for the LineDelta (from 1) and a zero address delta.
1327 MCDwarfLineAddr::Emit(&OS, Params, LineDelta, 0);
1328 }
1329
emitBinaryDwarfLineTable(MCStreamer * MCOS,MCDwarfLineTableParams Params,const DWARFDebugLine::LineTable * Table,const std::vector<DwarfLineTable::RowSequence> & InputSequences)1330 static inline void emitBinaryDwarfLineTable(
1331 MCStreamer *MCOS, MCDwarfLineTableParams Params,
1332 const DWARFDebugLine::LineTable *Table,
1333 const std::vector<DwarfLineTable::RowSequence> &InputSequences) {
1334 if (InputSequences.empty())
1335 return;
1336
1337 constexpr uint64_t InvalidAddress = UINT64_MAX;
1338 unsigned FileNum = 1;
1339 unsigned LastLine = 1;
1340 unsigned Column = 0;
1341 unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
1342 unsigned Isa = 0;
1343 unsigned Discriminator = 0;
1344 uint64_t LastAddress = InvalidAddress;
1345 uint64_t PrevEndOfSequence = InvalidAddress;
1346 const MCAsmInfo *AsmInfo = MCOS->getContext().getAsmInfo();
1347
1348 auto emitEndOfSequence = [&](uint64_t Address) {
1349 MCDwarfLineAddr::Emit(MCOS, Params, INT64_MAX, Address - LastAddress);
1350 FileNum = 1;
1351 LastLine = 1;
1352 Column = 0;
1353 Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
1354 Isa = 0;
1355 Discriminator = 0;
1356 LastAddress = InvalidAddress;
1357 };
1358
1359 for (const DwarfLineTable::RowSequence &Sequence : InputSequences) {
1360 const uint64_t SequenceStart =
1361 Table->Rows[Sequence.FirstIndex].Address.Address;
1362
1363 // Check if we need to mark the end of the sequence.
1364 if (PrevEndOfSequence != InvalidAddress && LastAddress != InvalidAddress &&
1365 PrevEndOfSequence != SequenceStart) {
1366 emitEndOfSequence(PrevEndOfSequence);
1367 }
1368
1369 for (uint32_t RowIndex = Sequence.FirstIndex;
1370 RowIndex <= Sequence.LastIndex; ++RowIndex) {
1371 const DWARFDebugLine::Row &Row = Table->Rows[RowIndex];
1372 int64_t LineDelta = static_cast<int64_t>(Row.Line) - LastLine;
1373 const uint64_t Address = Row.Address.Address;
1374
1375 if (FileNum != Row.File) {
1376 FileNum = Row.File;
1377 MCOS->emitInt8(dwarf::DW_LNS_set_file);
1378 MCOS->emitULEB128IntValue(FileNum);
1379 }
1380 if (Column != Row.Column) {
1381 Column = Row.Column;
1382 MCOS->emitInt8(dwarf::DW_LNS_set_column);
1383 MCOS->emitULEB128IntValue(Column);
1384 }
1385 if (Discriminator != Row.Discriminator &&
1386 MCOS->getContext().getDwarfVersion() >= 4) {
1387 Discriminator = Row.Discriminator;
1388 unsigned Size = getULEB128Size(Discriminator);
1389 MCOS->emitInt8(dwarf::DW_LNS_extended_op);
1390 MCOS->emitULEB128IntValue(Size + 1);
1391 MCOS->emitInt8(dwarf::DW_LNE_set_discriminator);
1392 MCOS->emitULEB128IntValue(Discriminator);
1393 }
1394 if (Isa != Row.Isa) {
1395 Isa = Row.Isa;
1396 MCOS->emitInt8(dwarf::DW_LNS_set_isa);
1397 MCOS->emitULEB128IntValue(Isa);
1398 }
1399 if (Row.IsStmt != Flags) {
1400 Flags = Row.IsStmt;
1401 MCOS->emitInt8(dwarf::DW_LNS_negate_stmt);
1402 }
1403 if (Row.BasicBlock)
1404 MCOS->emitInt8(dwarf::DW_LNS_set_basic_block);
1405 if (Row.PrologueEnd)
1406 MCOS->emitInt8(dwarf::DW_LNS_set_prologue_end);
1407 if (Row.EpilogueBegin)
1408 MCOS->emitInt8(dwarf::DW_LNS_set_epilogue_begin);
1409
1410 // The end of the sequence is not normal in the middle of the input
1411 // sequence, but could happen, e.g. for assembly code.
1412 if (Row.EndSequence) {
1413 emitEndOfSequence(Address);
1414 } else {
1415 if (LastAddress == InvalidAddress)
1416 emitDwarfSetLineAddrAbs(*MCOS, Params, LineDelta, Address,
1417 AsmInfo->getCodePointerSize());
1418 else
1419 MCDwarfLineAddr::Emit(MCOS, Params, LineDelta, Address - LastAddress);
1420
1421 LastAddress = Address;
1422 LastLine = Row.Line;
1423 }
1424
1425 Discriminator = 0;
1426 }
1427 PrevEndOfSequence = Sequence.EndAddress;
1428 }
1429
1430 // Finish with the end of the sequence.
1431 if (LastAddress != InvalidAddress)
1432 emitEndOfSequence(PrevEndOfSequence);
1433 }
1434
1435 // This function is similar to the one from MCDwarfLineTable, except it handles
1436 // end-of-sequence entries differently by utilizing line entries with
1437 // DWARF2_FLAG_END_SEQUENCE flag.
emitDwarfLineTable(MCStreamer * MCOS,MCSection * Section,const MCLineSection::MCDwarfLineEntryCollection & LineEntries)1438 static inline void emitDwarfLineTable(
1439 MCStreamer *MCOS, MCSection *Section,
1440 const MCLineSection::MCDwarfLineEntryCollection &LineEntries) {
1441 unsigned FileNum = 1;
1442 unsigned LastLine = 1;
1443 unsigned Column = 0;
1444 unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
1445 unsigned Isa = 0;
1446 unsigned Discriminator = 0;
1447 MCSymbol *LastLabel = nullptr;
1448 const MCAsmInfo *AsmInfo = MCOS->getContext().getAsmInfo();
1449
1450 // Loop through each MCDwarfLineEntry and encode the dwarf line number table.
1451 for (const MCDwarfLineEntry &LineEntry : LineEntries) {
1452 if (LineEntry.getFlags() & DWARF2_FLAG_END_SEQUENCE) {
1453 MCOS->emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, LineEntry.getLabel(),
1454 AsmInfo->getCodePointerSize());
1455 FileNum = 1;
1456 LastLine = 1;
1457 Column = 0;
1458 Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
1459 Isa = 0;
1460 Discriminator = 0;
1461 LastLabel = nullptr;
1462 continue;
1463 }
1464
1465 int64_t LineDelta = static_cast<int64_t>(LineEntry.getLine()) - LastLine;
1466
1467 if (FileNum != LineEntry.getFileNum()) {
1468 FileNum = LineEntry.getFileNum();
1469 MCOS->emitInt8(dwarf::DW_LNS_set_file);
1470 MCOS->emitULEB128IntValue(FileNum);
1471 }
1472 if (Column != LineEntry.getColumn()) {
1473 Column = LineEntry.getColumn();
1474 MCOS->emitInt8(dwarf::DW_LNS_set_column);
1475 MCOS->emitULEB128IntValue(Column);
1476 }
1477 if (Discriminator != LineEntry.getDiscriminator() &&
1478 MCOS->getContext().getDwarfVersion() >= 2) {
1479 Discriminator = LineEntry.getDiscriminator();
1480 unsigned Size = getULEB128Size(Discriminator);
1481 MCOS->emitInt8(dwarf::DW_LNS_extended_op);
1482 MCOS->emitULEB128IntValue(Size + 1);
1483 MCOS->emitInt8(dwarf::DW_LNE_set_discriminator);
1484 MCOS->emitULEB128IntValue(Discriminator);
1485 }
1486 if (Isa != LineEntry.getIsa()) {
1487 Isa = LineEntry.getIsa();
1488 MCOS->emitInt8(dwarf::DW_LNS_set_isa);
1489 MCOS->emitULEB128IntValue(Isa);
1490 }
1491 if ((LineEntry.getFlags() ^ Flags) & DWARF2_FLAG_IS_STMT) {
1492 Flags = LineEntry.getFlags();
1493 MCOS->emitInt8(dwarf::DW_LNS_negate_stmt);
1494 }
1495 if (LineEntry.getFlags() & DWARF2_FLAG_BASIC_BLOCK)
1496 MCOS->emitInt8(dwarf::DW_LNS_set_basic_block);
1497 if (LineEntry.getFlags() & DWARF2_FLAG_PROLOGUE_END)
1498 MCOS->emitInt8(dwarf::DW_LNS_set_prologue_end);
1499 if (LineEntry.getFlags() & DWARF2_FLAG_EPILOGUE_BEGIN)
1500 MCOS->emitInt8(dwarf::DW_LNS_set_epilogue_begin);
1501
1502 MCSymbol *Label = LineEntry.getLabel();
1503
1504 // At this point we want to emit/create the sequence to encode the delta
1505 // in line numbers and the increment of the address from the previous
1506 // Label and the current Label.
1507 MCOS->emitDwarfAdvanceLineAddr(LineDelta, LastLabel, Label,
1508 AsmInfo->getCodePointerSize());
1509 Discriminator = 0;
1510 LastLine = LineEntry.getLine();
1511 LastLabel = Label;
1512 }
1513
1514 assert(LastLabel == nullptr && "end of sequence expected");
1515 }
1516
emitCU(MCStreamer * MCOS,MCDwarfLineTableParams Params,Optional<MCDwarfLineStr> & LineStr,BinaryContext & BC) const1517 void DwarfLineTable::emitCU(MCStreamer *MCOS, MCDwarfLineTableParams Params,
1518 Optional<MCDwarfLineStr> &LineStr,
1519 BinaryContext &BC) const {
1520 if (!RawData.empty()) {
1521 assert(MCLineSections.getMCLineEntries().empty() &&
1522 InputSequences.empty() &&
1523 "cannot combine raw data with new line entries");
1524 MCOS->emitLabel(getLabel());
1525 MCOS->emitBytes(RawData);
1526
1527 // Emit fake relocation for RuntimeDyld to always allocate the section.
1528 //
1529 // FIXME: remove this once RuntimeDyld stops skipping allocatable sections
1530 // without relocations.
1531 MCOS->emitRelocDirective(
1532 *MCConstantExpr::create(0, *BC.Ctx), "BFD_RELOC_NONE",
1533 MCSymbolRefExpr::create(getLabel(), *BC.Ctx), SMLoc(), *BC.STI);
1534
1535 return;
1536 }
1537
1538 MCSymbol *LineEndSym = Header.Emit(MCOS, Params, LineStr).second;
1539
1540 // Put out the line tables.
1541 for (const auto &LineSec : MCLineSections.getMCLineEntries())
1542 emitDwarfLineTable(MCOS, LineSec.first, LineSec.second);
1543
1544 // Emit line tables for the original code.
1545 emitBinaryDwarfLineTable(MCOS, Params, InputTable, InputSequences);
1546
1547 // This is the end of the section, so set the value of the symbol at the end
1548 // of this section (that was used in a previous expression).
1549 MCOS->emitLabel(LineEndSym);
1550 }
1551
1552 // Helper function to parse .debug_line_str, and populate one we are using.
1553 // For functions that we do not modify we output them as raw data.
1554 // Re-constructing .debug_line_str so that offsets are correct for those
1555 // debut line tables.
1556 // Bonus is that when we output a final binary we can re-use .debug_line_str
1557 // section. So we don't have to do the SHF_ALLOC trick we did with
1558 // .debug_line.
parseAndPopulateDebugLineStr(BinarySection & LineStrSection,MCDwarfLineStr & LineStr,BinaryContext & BC,MCStreamer & Streamer)1559 static void parseAndPopulateDebugLineStr(BinarySection &LineStrSection,
1560 MCDwarfLineStr &LineStr,
1561 BinaryContext &BC,
1562 MCStreamer &Streamer) {
1563 DataExtractor StrData(LineStrSection.getContents(),
1564 BC.DwCtx->isLittleEndian(), 0);
1565 uint64_t Offset = 0;
1566 while (StrData.isValidOffset(Offset)) {
1567 Error Err = Error::success();
1568 const char *CStr = StrData.getCStr(&Offset, &Err);
1569 if (Err) {
1570 errs() << "BOLT-ERROR: could not extract string from .debug_line_str";
1571 continue;
1572 }
1573 LineStr.emitRef(&Streamer, CStr);
1574 }
1575 }
1576
emit(BinaryContext & BC,MCStreamer & Streamer)1577 void DwarfLineTable::emit(BinaryContext &BC, MCStreamer &Streamer) {
1578 MCAssembler &Assembler =
1579 static_cast<MCObjectStreamer *>(&Streamer)->getAssembler();
1580
1581 MCDwarfLineTableParams Params = Assembler.getDWARFLinetableParams();
1582
1583 auto &LineTables = BC.getDwarfLineTables();
1584
1585 // Bail out early so we don't switch to the debug_line section needlessly and
1586 // in doing so create an unnecessary (if empty) section.
1587 if (LineTables.empty())
1588 return;
1589 // In a v5 non-split line table, put the strings in a separate section.
1590 Optional<MCDwarfLineStr> LineStr(None);
1591 ErrorOr<BinarySection &> LineStrSection =
1592 BC.getUniqueSectionByName(".debug_line_str");
1593 // Some versions of GCC output DWARF5 .debug_info, but DWARF4 or lower
1594 // .debug_line
1595 if (LineStrSection) {
1596 LineStr.emplace(*BC.Ctx);
1597 parseAndPopulateDebugLineStr(*LineStrSection, *LineStr, BC, Streamer);
1598 }
1599
1600 // Switch to the section where the table will be emitted into.
1601 Streamer.switchSection(BC.MOFI->getDwarfLineSection());
1602
1603 const uint16_t DwarfVersion = BC.Ctx->getDwarfVersion();
1604 // Handle the rest of the Compile Units.
1605 for (auto &CUIDTablePair : LineTables) {
1606 Streamer.getContext().setDwarfVersion(
1607 CUIDTablePair.second.getDwarfVersion());
1608 CUIDTablePair.second.emitCU(&Streamer, Params, LineStr, BC);
1609 }
1610
1611 // Resetting DWARF version for rest of the flow.
1612 BC.Ctx->setDwarfVersion(DwarfVersion);
1613
1614 // Still need to write the section out for the ExecutionEngine, and temp in
1615 // memory object we are constructing.
1616 if (LineStr) {
1617 LineStr->emitSection(&Streamer);
1618 SmallString<0> Data = LineStr->getFinalizedData();
1619 BC.registerOrUpdateNoteSection(".debug_line_str", copyByteArray(Data.str()),
1620 Data.size());
1621 }
1622 }
1623
1624 } // namespace bolt
1625 } // namespace llvm
1626