LLVM 24.0.0git
MCDwarf.cpp
Go to the documentation of this file.
1//===- lib/MC/MCDwarf.cpp - MCDwarf implementation ------------------------===//
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#include "llvm/MC/MCDwarf.h"
10#include "llvm/ADT/ArrayRef.h"
11#include "llvm/ADT/STLExtras.h"
14#include "llvm/ADT/StringRef.h"
15#include "llvm/ADT/Twine.h"
17#include "llvm/Config/config.h"
18#include "llvm/MC/MCAsmInfo.h"
19#include "llvm/MC/MCContext.h"
20#include "llvm/MC/MCExpr.h"
24#include "llvm/MC/MCSection.h"
25#include "llvm/MC/MCStreamer.h"
26#include "llvm/MC/MCSymbol.h"
30#include "llvm/Support/LEB128.h"
32#include "llvm/Support/Path.h"
35#include <cassert>
36#include <cstdint>
37#include <optional>
38#include <string>
39#include <utility>
40#include <vector>
41
42using namespace llvm;
43
45 MCSymbol *Start = S.getContext().createTempSymbol("debug_list_header_start");
46 MCSymbol *End = S.getContext().createTempSymbol("debug_list_header_end");
47 auto DwarfFormat = S.getContext().getDwarfFormat();
48 if (DwarfFormat == dwarf::DWARF64) {
49 S.AddComment("DWARF64 mark");
51 }
52 S.AddComment("Length");
53 S.emitAbsoluteSymbolDiff(End, Start,
55 S.emitLabel(Start);
56 S.AddComment("Version");
58 S.AddComment("Address size");
60 S.AddComment("Segment selector size");
61 S.emitInt8(0);
62 return End;
63}
64
65static inline uint64_t ScaleAddrDelta(MCContext &Context, uint64_t AddrDelta) {
66 unsigned MinInsnLength = Context.getAsmInfo().getMinInstAlignment();
67 if (MinInsnLength == 1)
68 return AddrDelta;
69 if (AddrDelta % MinInsnLength != 0) {
70 // TODO: report this error, but really only once.
71 ;
72 }
73 return AddrDelta / MinInsnLength;
74}
75
77 UseRelocs = Ctx.getAsmInfo().doesDwarfUseRelocationsAcrossSections();
78 if (UseRelocs) {
79 MCSection *DwarfLineStrSection =
80 Ctx.getObjectFileInfo()->getDwarfLineStrSection();
81 assert(DwarfLineStrSection && "DwarfLineStrSection must not be NULL");
82 LineStrLabel = DwarfLineStrSection->getBeginSymbol();
83 }
84}
85
86//
87// This is called when an instruction is assembled into the specified section
88// and if there is information from the last .loc directive that has yet to have
89// a line entry made for it is made.
90//
92 if (!MCOS->getContext().getDwarfLocSeen())
93 return;
94
95 // Create a symbol at in the current section for use in the line entry.
96 MCSymbol *LineSym = MCOS->getContext().createTempSymbol();
97 // Set the value of the symbol to use for the MCDwarfLineEntry.
98 MCOS->emitLabel(LineSym);
99
100 // Get the current .loc info saved in the context.
101 const MCDwarfLoc &DwarfLoc = MCOS->getContext().getCurrentDwarfLoc();
102
103 // Create a (local) line entry with the symbol and the current .loc info.
104 MCDwarfLineEntry LineEntry(LineSym, DwarfLoc);
105
106 // clear DwarfLocSeen saying the current .loc info is now used.
108
109 // Add the line entry to this section's entries.
110 MCOS->getContext()
113 .addLineEntry(LineEntry, Section);
114}
115
116//
117// This helper routine returns an expression of End - Start - IntVal .
118//
119static inline const MCExpr *makeEndMinusStartExpr(MCContext &Ctx,
120 const MCSymbol &Start,
121 const MCSymbol &End,
122 int IntVal) {
123 const MCExpr *Res = MCSymbolRefExpr::create(&End, Ctx);
124 const MCExpr *RHS = MCSymbolRefExpr::create(&Start, Ctx);
125 const MCExpr *Res1 = MCBinaryExpr::create(MCBinaryExpr::Sub, Res, RHS, Ctx);
126 const MCExpr *Res2 = MCConstantExpr::create(IntVal, Ctx);
127 const MCExpr *Res3 = MCBinaryExpr::create(MCBinaryExpr::Sub, Res1, Res2, Ctx);
128 return Res3;
129}
130
131//
132// This helper routine returns an expression of Start + IntVal .
133//
134static inline const MCExpr *
135makeStartPlusIntExpr(MCContext &Ctx, const MCSymbol &Start, int IntVal) {
136 const MCExpr *LHS = MCSymbolRefExpr::create(&Start, Ctx);
137 const MCExpr *RHS = MCConstantExpr::create(IntVal, Ctx);
139 return Res;
140}
141
143 auto *Sec = &EndLabel->getSection();
144 // The line table may be empty, which we should skip adding an end entry.
145 // There are three cases:
146 // (1) MCAsmStreamer - emitDwarfLocDirective emits a location directive in
147 // place instead of adding a line entry.
148 // (2) MCObjectStreamer - if a function has incomplete debug info where
149 // instructions don't have DILocations, the line entries are missing.
150 // (3) It's also possible that there are no prior line entries if the section
151 // itself is empty before this end label.
152 auto I = MCLineDivisions.find(Sec);
153 if (I == MCLineDivisions.end()) // If section not found, do nothing.
154 return;
155
156 auto &Entries = I->second;
157 // If no entries in this section's list, nothing to base the end entry on.
158 if (Entries.empty())
159 return;
160
161 // Create the end entry based on the last existing entry.
162 MCDwarfLineEntry EndEntry = Entries.back();
163
164 // An end entry is just for marking the end of a sequence of code locations.
165 // It should not carry forward a LineStreamLabel from a previous special entry
166 // if Entries.back() happened to be such an entry. So here we clear
167 // LineStreamLabel.
168 EndEntry.LineStreamLabel = nullptr;
169 EndEntry.setEndLabel(EndLabel);
170 Entries.push_back(EndEntry);
171}
172
173//
174// This emits the Dwarf line table for the specified section from the entries
175// in the LineSection.
176//
178 MCStreamer *MCOS, MCSection *Section,
180
181 unsigned FileNum, LastLine, Column, Flags, Isa, Discriminator;
182 bool IsAtStartSeq;
183 MCSymbol *PrevLabel;
184 auto init = [&]() {
185 FileNum = 1;
186 LastLine = 1;
187 Column = 0;
189 Isa = 0;
190 Discriminator = 0;
191 PrevLabel = nullptr;
192 IsAtStartSeq = true;
193 };
194 init();
195
196 // Loop through each MCDwarfLineEntry and encode the dwarf line number table.
197 bool EndEntryEmitted = false;
198 for (auto It = LineEntries.begin(); It != LineEntries.end(); ++It) {
199 auto LineEntry = *It;
200 MCSymbol *CurrLabel = LineEntry.getLabel();
201 const MCAsmInfo &asmInfo = MCOS->getContext().getAsmInfo();
202
203 if (LineEntry.LineStreamLabel) {
204 if (!IsAtStartSeq) {
205 auto *Label = CurrLabel;
206 auto NextIt = It + 1;
207 // LineEntry with a null Label is probably a fake LineEntry we added
208 // when `-emit-func-debug-line-table-offsets` in order to terminate the
209 // sequence. Look for the next Label if possible, otherwise we will set
210 // the PC to the end of the section.
211 if (!Label && NextIt != LineEntries.end()) {
212 Label = NextIt->getLabel();
213 }
214 MCOS->emitDwarfLineEndEntry(Section, PrevLabel,
215 /*EndLabel =*/Label);
216 init();
217 }
218 MCOS->emitLabel(LineEntry.LineStreamLabel, LineEntry.StreamLabelDefLoc);
219 continue;
220 }
221
222 if (LineEntry.IsEndEntry) {
223 MCOS->emitDwarfAdvanceLineAddr(INT64_MAX, PrevLabel, CurrLabel,
224 asmInfo.getCodePointerSize());
225 init();
226 EndEntryEmitted = true;
227 continue;
228 }
229
230 int64_t LineDelta = static_cast<int64_t>(LineEntry.getLine()) - LastLine;
231
232 if (FileNum != LineEntry.getFileNum()) {
233 FileNum = LineEntry.getFileNum();
234 MCOS->emitInt8(dwarf::DW_LNS_set_file);
235 MCOS->emitULEB128IntValue(FileNum);
236 }
237 if (Column != LineEntry.getColumn()) {
238 Column = LineEntry.getColumn();
239 MCOS->emitInt8(dwarf::DW_LNS_set_column);
240 MCOS->emitULEB128IntValue(Column);
241 }
242 if (Discriminator != LineEntry.getDiscriminator() &&
243 MCOS->getContext().getDwarfVersion() >= 4) {
244 Discriminator = LineEntry.getDiscriminator();
245 unsigned Size = getULEB128Size(Discriminator);
246 MCOS->emitInt8(dwarf::DW_LNS_extended_op);
247 MCOS->emitULEB128IntValue(Size + 1);
248 MCOS->emitInt8(dwarf::DW_LNE_set_discriminator);
249 MCOS->emitULEB128IntValue(Discriminator);
250 }
251 if (Isa != LineEntry.getIsa()) {
252 Isa = LineEntry.getIsa();
253 MCOS->emitInt8(dwarf::DW_LNS_set_isa);
254 MCOS->emitULEB128IntValue(Isa);
255 }
256 if ((LineEntry.getFlags() ^ Flags) & DWARF2_FLAG_IS_STMT) {
257 Flags = LineEntry.getFlags();
258 MCOS->emitInt8(dwarf::DW_LNS_negate_stmt);
259 }
260 if (LineEntry.getFlags() & DWARF2_FLAG_BASIC_BLOCK)
261 MCOS->emitInt8(dwarf::DW_LNS_set_basic_block);
262 if (LineEntry.getFlags() & DWARF2_FLAG_PROLOGUE_END)
263 MCOS->emitInt8(dwarf::DW_LNS_set_prologue_end);
264 if (LineEntry.getFlags() & DWARF2_FLAG_EPILOGUE_BEGIN)
265 MCOS->emitInt8(dwarf::DW_LNS_set_epilogue_begin);
266
267 // At this point we want to emit/create the sequence to encode the delta in
268 // line numbers and the increment of the address from the previous Label
269 // and the current Label.
270 MCOS->emitDwarfAdvanceLineAddr(LineDelta, PrevLabel, CurrLabel,
271 asmInfo.getCodePointerSize());
272
273 Discriminator = 0;
274 LastLine = LineEntry.getLine();
275 PrevLabel = CurrLabel;
276 IsAtStartSeq = false;
277 }
278
279 // Generate DWARF line end entry.
280 // We do not need this for DwarfDebug that explicitly terminates the line
281 // table using ranges whenever CU or section changes. However, the MC path
282 // does not track ranges nor terminate the line table. In that case,
283 // conservatively use the section end symbol to end the line table.
284 if (!EndEntryEmitted && !IsAtStartSeq)
285 MCOS->emitDwarfLineEndEntry(Section, PrevLabel);
286}
287
289 SMLoc DefLoc,
290 StringRef Name) {
291 auto &ctx = MCOS->getContext();
292 auto *LineStreamLabel = ctx.getOrCreateSymbol(Name);
293 auto *LineSym = ctx.createTempSymbol();
294 MCOS->emitLabel(LineSym);
295 const MCDwarfLoc &DwarfLoc = ctx.getCurrentDwarfLoc();
296
297 // Create a 'fake' line entry by having LineStreamLabel be non-null. This
298 // won't actually emit any line information, it will reset the line table
299 // sequence and emit a label at the start of the new line table sequence.
300 MCDwarfLineEntry LineEntry(LineSym, DwarfLoc, LineStreamLabel, DefLoc);
302}
303
304//
305// This emits the Dwarf file and the line tables.
306//
308 MCContext &context = MCOS->getContext();
309
310 auto &LineTables = context.getMCDwarfLineTables();
311
312 // Bail out early so we don't switch to the debug_line section needlessly and
313 // in doing so create an unnecessary (if empty) section.
314 if (LineTables.empty())
315 return;
316
317 // In a v5 non-split line table, put the strings in a separate section.
318 std::optional<MCDwarfLineStr> LineStr;
319 if (context.getDwarfVersion() >= 5)
320 LineStr.emplace(context);
321
322 // Switch to the section where the table will be emitted into.
324
325 // Handle the rest of the Compile Units.
326 for (const auto &CUIDTablePair : LineTables) {
327 CUIDTablePair.second.emitCU(MCOS, Params, LineStr);
328 }
329
330 if (LineStr)
331 LineStr->emitSection(MCOS);
332}
333
335 MCSection *Section) const {
336 if (!HasSplitLineTable)
337 return;
338 std::optional<MCDwarfLineStr> NoLineStr(std::nullopt);
339 MCOS.switchSection(Section);
340 MCOS.emitLabel(Header.Emit(&MCOS, Params, {}, NoLineStr).second);
341}
342
343std::pair<MCSymbol *, MCSymbol *>
345 std::optional<MCDwarfLineStr> &LineStr) const {
346 static const char StandardOpcodeLengths[] = {
347 0, // length of DW_LNS_copy
348 1, // length of DW_LNS_advance_pc
349 1, // length of DW_LNS_advance_line
350 1, // length of DW_LNS_set_file
351 1, // length of DW_LNS_set_column
352 0, // length of DW_LNS_negate_stmt
353 0, // length of DW_LNS_set_basic_block
354 0, // length of DW_LNS_const_add_pc
355 1, // length of DW_LNS_fixed_advance_pc
356 0, // length of DW_LNS_set_prologue_end
357 0, // length of DW_LNS_set_epilogue_begin
358 1 // DW_LNS_set_isa
359 };
360 assert(std::size(StandardOpcodeLengths) >=
361 (Params.DWARF2LineOpcodeBase - 1U));
362 return Emit(MCOS, Params,
363 ArrayRef(StandardOpcodeLengths, Params.DWARF2LineOpcodeBase - 1),
364 LineStr);
365}
366
367static const MCExpr *forceExpAbs(MCStreamer &OS, const MCExpr* Expr) {
368 MCContext &Context = OS.getContext();
370 if (!Context.getAsmInfo().doesSetDirectiveSuppressReloc())
371 return Expr;
372
373 // On Mach-O, try to avoid a relocation by using a set directive.
374 MCSymbol *ABS = Context.createTempSymbol();
375 OS.emitAssignment(ABS, Expr);
376 return MCSymbolRefExpr::create(ABS, Context);
377}
378
379static void emitAbsValue(MCStreamer &OS, const MCExpr *Value, unsigned Size) {
380 const MCExpr *ABS = forceExpAbs(OS, Value);
381 OS.emitValue(ABS, Size);
382}
383
385 // Switch to the .debug_line_str section.
386 MCOS->switchSection(
389 MCOS->emitBinaryData(Data.str());
390}
391
393 // Emit the strings without perturbing the offsets we used.
394 if (!LineStrings.isFinalized())
395 LineStrings.finalizeInOrder();
397 Data.resize(LineStrings.getSize());
398 LineStrings.write((uint8_t *)Data.data());
399 return Data;
400}
401
403 return LineStrings.add(Path);
404}
405
407 int RefSize =
409 size_t Offset = addString(Path);
410 if (UseRelocs) {
411 MCContext &Ctx = MCOS->getContext();
412 if (Ctx.getAsmInfo().needsDwarfSectionOffsetDirective()) {
413 MCOS->emitCOFFSecRel32(LineStrLabel, Offset);
414 } else {
415 MCOS->emitValue(makeStartPlusIntExpr(Ctx, *LineStrLabel, Offset),
416 RefSize);
417 }
418 } else
419 MCOS->emitIntValue(Offset, RefSize);
420}
421
422void MCDwarfLineTableHeader::emitV2FileDirTables(MCStreamer *MCOS) const {
423 // First the directory table.
424 for (auto &Dir : MCDwarfDirs) {
425 MCOS->emitBytes(Dir); // The DirectoryName, and...
426 MCOS->emitBytes(StringRef("\0", 1)); // its null terminator.
427 }
428 MCOS->emitInt8(0); // Terminate the directory list.
429
430 // Second the file table.
431 for (unsigned i = 1; i < MCDwarfFiles.size(); i++) {
432 assert(!MCDwarfFiles[i].Name.empty());
433 MCOS->emitBytes(MCDwarfFiles[i].Name); // FileName and...
434 MCOS->emitBytes(StringRef("\0", 1)); // its null terminator.
435 MCOS->emitULEB128IntValue(MCDwarfFiles[i].DirIndex); // Directory number.
436 MCOS->emitInt8(0); // Last modification timestamp (always 0).
437 MCOS->emitInt8(0); // File size (always 0).
438 }
439 MCOS->emitInt8(0); // Terminate the file list.
440}
441
443 bool EmitMD5, bool HasAnySource,
444 std::optional<MCDwarfLineStr> &LineStr) {
445 assert(!DwarfFile.Name.empty());
446 if (LineStr)
447 LineStr->emitRef(MCOS, DwarfFile.Name);
448 else {
449 MCOS->emitBytes(DwarfFile.Name); // FileName and...
450 MCOS->emitBytes(StringRef("\0", 1)); // its null terminator.
451 }
452 MCOS->emitULEB128IntValue(DwarfFile.DirIndex); // Directory number.
453 if (EmitMD5) {
454 const MD5::MD5Result &Cksum = *DwarfFile.Checksum;
455 MCOS->emitBinaryData(
456 StringRef(reinterpret_cast<const char *>(Cksum.data()), Cksum.size()));
457 }
458 if (HasAnySource) {
459 // From https://dwarfstd.org/issues/180201.1.html
460 // * The value is an empty null-terminated string if no source is available
461 StringRef Source = DwarfFile.Source.value_or(StringRef());
462 // * If the source is available but is an empty file then the value is a
463 // null-terminated single "\n".
464 if (DwarfFile.Source && DwarfFile.Source->empty())
465 Source = "\n";
466 if (LineStr)
467 LineStr->emitRef(MCOS, Source);
468 else {
469 MCOS->emitBytes(Source); // Source and...
470 MCOS->emitBytes(StringRef("\0", 1)); // its null terminator.
471 }
472 }
473}
474
475void MCDwarfLineTableHeader::emitV5FileDirTables(
476 MCStreamer *MCOS, std::optional<MCDwarfLineStr> &LineStr) const {
477 // The directory format, which is just a list of the directory paths. In a
478 // non-split object, these are references to .debug_line_str; in a split
479 // object, they are inline strings.
480 MCOS->emitInt8(1);
481 MCOS->emitULEB128IntValue(dwarf::DW_LNCT_path);
482 MCOS->emitULEB128IntValue(LineStr ? dwarf::DW_FORM_line_strp
483 : dwarf::DW_FORM_string);
484 MCOS->emitULEB128IntValue(MCDwarfDirs.size() + 1);
485 // Try not to emit an empty compilation directory.
486 SmallString<256> Dir;
487 StringRef CompDir = MCOS->getContext().getCompilationDir();
488 if (!CompilationDir.empty()) {
489 Dir = CompilationDir;
490 MCOS->getContext().remapDebugPath(Dir);
491 CompDir = Dir.str();
492 if (LineStr)
493 CompDir = LineStr->getSaver().save(CompDir);
494 }
495 if (LineStr) {
496 // Record path strings, emit references here.
497 LineStr->emitRef(MCOS, CompDir);
498 for (const auto &Dir : MCDwarfDirs)
499 LineStr->emitRef(MCOS, Dir);
500 } else {
501 // The list of directory paths. Compilation directory comes first.
502 MCOS->emitBytes(CompDir);
503 MCOS->emitBytes(StringRef("\0", 1));
504 for (const auto &Dir : MCDwarfDirs) {
505 MCOS->emitBytes(Dir); // The DirectoryName, and...
506 MCOS->emitBytes(StringRef("\0", 1)); // its null terminator.
507 }
508 }
509
510 // The file format, which is the inline null-terminated filename and a
511 // directory index. We don't track file size/timestamp so don't emit them
512 // in the v5 table. Emit MD5 checksums and source if we have them.
513 uint64_t Entries = 2;
514 if (HasAllMD5)
515 Entries += 1;
516 if (HasAnySource)
517 Entries += 1;
518 MCOS->emitInt8(Entries);
519 MCOS->emitULEB128IntValue(dwarf::DW_LNCT_path);
520 MCOS->emitULEB128IntValue(LineStr ? dwarf::DW_FORM_line_strp
521 : dwarf::DW_FORM_string);
522 MCOS->emitULEB128IntValue(dwarf::DW_LNCT_directory_index);
523 MCOS->emitULEB128IntValue(dwarf::DW_FORM_udata);
524 if (HasAllMD5) {
525 MCOS->emitULEB128IntValue(dwarf::DW_LNCT_MD5);
526 MCOS->emitULEB128IntValue(dwarf::DW_FORM_data16);
527 }
528 if (HasAnySource) {
529 MCOS->emitULEB128IntValue(dwarf::DW_LNCT_LLVM_source);
530 MCOS->emitULEB128IntValue(LineStr ? dwarf::DW_FORM_line_strp
531 : dwarf::DW_FORM_string);
532 }
533 // Then the counted list of files. The root file is file #0, then emit the
534 // files as provide by .file directives.
535 // MCDwarfFiles has an unused element [0] so use size() not size()+1.
536 // But sometimes MCDwarfFiles is empty, in which case we still emit one file.
537 MCOS->emitULEB128IntValue(MCDwarfFiles.empty() ? 1 : MCDwarfFiles.size());
538 // To accommodate assembler source written for DWARF v4 but trying to emit
539 // v5: If we didn't see a root file explicitly, replicate file #1.
540 assert((!RootFile.Name.empty() || MCDwarfFiles.size() >= 1) &&
541 "No root file and no .file directives");
542 emitOneV5FileEntry(MCOS, RootFile.Name.empty() ? MCDwarfFiles[1] : RootFile,
543 HasAllMD5, HasAnySource, LineStr);
544 for (unsigned i = 1; i < MCDwarfFiles.size(); ++i)
545 emitOneV5FileEntry(MCOS, MCDwarfFiles[i], HasAllMD5, HasAnySource, LineStr);
546}
547
548std::pair<MCSymbol *, MCSymbol *>
550 ArrayRef<char> StandardOpcodeLengths,
551 std::optional<MCDwarfLineStr> &LineStr) const {
552 MCContext &context = MCOS->getContext();
553
554 // Create a symbol at the beginning of the line table.
555 MCSymbol *LineStartSym = Label;
556 if (!LineStartSym)
557 LineStartSym = context.createTempSymbol();
558
559 // Set the value of the symbol, as we are at the start of the line table.
560 MCOS->emitDwarfLineStartLabel(LineStartSym);
561
562 unsigned OffsetSize = dwarf::getDwarfOffsetByteSize(context.getDwarfFormat());
563
564 MCSymbol *LineEndSym = MCOS->emitDwarfUnitLength("debug_line", "unit length");
565
566 // Next 2 bytes is the Version.
567 unsigned LineTableVersion = context.getDwarfVersion();
568 MCOS->emitInt16(LineTableVersion);
569
570 // In v5, we get address info next.
571 if (LineTableVersion >= 5) {
572 MCOS->emitInt8(context.getAsmInfo().getCodePointerSize());
573 MCOS->emitInt8(0); // Segment selector; same as EmitGenDwarfAranges.
574 }
575
576 // Create symbols for the start/end of the prologue.
577 MCSymbol *ProStartSym = context.createTempSymbol("prologue_start");
578 MCSymbol *ProEndSym = context.createTempSymbol("prologue_end");
579
580 // Length of the prologue, is the next 4 bytes (8 bytes for DWARF64). This is
581 // actually the length from after the length word, to the end of the prologue.
582 MCOS->emitAbsoluteSymbolDiff(ProEndSym, ProStartSym, OffsetSize);
583
584 MCOS->emitLabel(ProStartSym);
585
586 // Parameters of the state machine, are next.
587 MCOS->emitInt8(context.getAsmInfo().getMinInstAlignment());
588 // maximum_operations_per_instruction
589 // For non-VLIW architectures this field is always 1.
590 // FIXME: VLIW architectures need to update this field accordingly.
591 if (LineTableVersion >= 4)
592 MCOS->emitInt8(1);
594 MCOS->emitInt8(Params.DWARF2LineBase);
595 MCOS->emitInt8(Params.DWARF2LineRange);
596 MCOS->emitInt8(StandardOpcodeLengths.size() + 1);
597
598 // Standard opcode lengths
599 for (char Length : StandardOpcodeLengths)
600 MCOS->emitInt8(Length);
601
602 // Put out the directory and file tables. The formats vary depending on
603 // the version.
604 if (LineTableVersion >= 5)
605 emitV5FileDirTables(MCOS, LineStr);
606 else
607 emitV2FileDirTables(MCOS);
608
609 // This is the end of the prologue, so set the value of the symbol at the
610 // end of the prologue (that was used in a previous expression).
611 MCOS->emitLabel(ProEndSym);
612
613 return std::make_pair(LineStartSym, LineEndSym);
614}
615
617 std::optional<MCDwarfLineStr> &LineStr) const {
618 MCSymbol *LineEndSym = Header.Emit(MCOS, Params, LineStr).second;
619
620 // Put out the line tables.
621 for (const auto &LineSec : MCLineSections.getMCLineEntries())
622 emitOne(MCOS, LineSec.first, LineSec.second);
623
624 // This is the end of the section, so set the value of the symbol at the end
625 // of this section (that was used in a previous expression).
626 MCOS->emitLabel(LineEndSym);
627}
628
631 std::optional<MD5::MD5Result> Checksum,
632 std::optional<StringRef> Source,
633 uint16_t DwarfVersion, unsigned FileNumber) {
634 return Header.tryGetFile(Directory, FileName, Checksum, Source, DwarfVersion,
635 FileNumber);
636}
637
638static bool isRootFile(const MCDwarfFile &RootFile, StringRef &Directory,
639 StringRef &FileName,
640 std::optional<MD5::MD5Result> Checksum) {
641 if (RootFile.Name.empty() || StringRef(RootFile.Name) != FileName)
642 return false;
643 return RootFile.Checksum == Checksum;
644}
645
648 std::optional<MD5::MD5Result> Checksum,
649 std::optional<StringRef> Source,
650 uint16_t DwarfVersion, unsigned FileNumber) {
651 if (Directory == CompilationDir)
652 Directory = "";
653 if (FileName.empty()) {
654 FileName = "<stdin>";
655 Directory = "";
656 }
657 assert(!FileName.empty());
658 // Keep track of whether any or all files have an MD5 checksum.
659 // If any files have embedded source, they all must.
660 if (MCDwarfFiles.empty()) {
661 trackMD5Usage(Checksum.has_value());
662 HasAnySource |= Source.has_value();
663 }
664 if (DwarfVersion >= 5 && isRootFile(RootFile, Directory, FileName, Checksum))
665 return 0;
666 if (FileNumber == 0) {
667 // File numbers start with 1 and/or after any file numbers
668 // allocated by inline-assembler .file directives.
669 FileNumber = MCDwarfFiles.empty() ? 1 : MCDwarfFiles.size();
670 SmallString<256> Buffer;
671 auto IterBool = SourceIdMap.insert(
672 std::make_pair((Directory + Twine('\0') + FileName).toStringRef(Buffer),
673 FileNumber));
674 if (!IterBool.second)
675 return IterBool.first->second;
676 }
677 // Make space for this FileNumber in the MCDwarfFiles vector if needed.
678 if (FileNumber >= MCDwarfFiles.size())
679 MCDwarfFiles.resize(FileNumber + 1);
680
681 // Get the new MCDwarfFile slot for this FileNumber.
682 MCDwarfFile &File = MCDwarfFiles[FileNumber];
683
684 // It is an error to see the same number more than once.
685 if (!File.Name.empty())
686 return make_error<StringError>("file number already allocated",
688
689 if (Directory.empty()) {
690 // Separate the directory part from the basename of the FileName.
691 StringRef tFileName = sys::path::filename(FileName);
692 if (!tFileName.empty()) {
693 Directory = sys::path::parent_path(FileName);
694 if (!Directory.empty())
695 FileName = tFileName;
696 }
697 }
698
699 // Find or make an entry in the MCDwarfDirs vector for this Directory.
700 // Capture directory name.
701 unsigned DirIndex;
702 if (Directory.empty()) {
703 // For FileNames with no directories a DirIndex of 0 is used.
704 DirIndex = 0;
705 } else {
706 DirIndex = llvm::find(MCDwarfDirs, Directory) - MCDwarfDirs.begin();
707 if (DirIndex >= MCDwarfDirs.size())
708 MCDwarfDirs.push_back(std::string(Directory));
709 // The DirIndex is one based, as DirIndex of 0 is used for FileNames with
710 // no directories. MCDwarfDirs[] is unlike MCDwarfFiles[] in that the
711 // directory names are stored at MCDwarfDirs[DirIndex-1] where FileNames
712 // are stored at MCDwarfFiles[FileNumber].Name .
713 DirIndex++;
714 }
715
716 File.Name = std::string(FileName);
717 File.DirIndex = DirIndex;
718 File.Checksum = Checksum;
719 trackMD5Usage(Checksum.has_value());
720 File.Source = Source;
721 if (Source.has_value())
722 HasAnySource = true;
723
724 // return the allocated FileNumber.
725 return FileNumber;
726}
727
728/// Utility function to emit the encoding to a streamer.
730 int64_t LineDelta, uint64_t AddrDelta) {
731 MCContext &Context = MCOS->getContext();
733 MCDwarfLineAddr::encode(Context, Params, LineDelta, AddrDelta, Tmp);
734 MCOS->emitBytes(Tmp);
735}
736
737/// Given a special op, return the address skip amount (in units of
738/// DWARF2_LINE_MIN_INSN_LENGTH).
740 return (op - Params.DWARF2LineOpcodeBase) / Params.DWARF2LineRange;
741}
742
743/// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas.
745 int64_t LineDelta, uint64_t AddrDelta,
747 uint64_t Temp, Opcode;
748 bool NeedCopy = false;
749
750 // The maximum address skip amount that can be encoded with a special op.
751 uint64_t MaxSpecialAddrDelta = SpecialAddr(Params, 255);
752
753 // Scale the address delta by the minimum instruction length.
754 AddrDelta = ScaleAddrDelta(Context, AddrDelta);
755
756 // A LineDelta of INT64_MAX is a signal that this is actually a
757 // DW_LNE_end_sequence. We cannot use special opcodes here, since we want the
758 // end_sequence to emit the matrix entry.
759 if (LineDelta == INT64_MAX) {
760 if (AddrDelta == MaxSpecialAddrDelta)
761 Out.push_back(dwarf::DW_LNS_const_add_pc);
762 else if (AddrDelta) {
763 Out.push_back(dwarf::DW_LNS_advance_pc);
765 }
766 Out.push_back(dwarf::DW_LNS_extended_op);
767 Out.push_back(1);
768 Out.push_back(dwarf::DW_LNE_end_sequence);
769 return;
770 }
771
772 // Bias the line delta by the base.
773 Temp = LineDelta - Params.DWARF2LineBase;
774
775 // If the line increment is out of range of a special opcode, we must encode
776 // it with DW_LNS_advance_line.
777 if (Temp >= Params.DWARF2LineRange ||
778 Temp + Params.DWARF2LineOpcodeBase > 255) {
779 Out.push_back(dwarf::DW_LNS_advance_line);
780 appendLEB128<LEB128Sign::Signed>(Out, LineDelta);
781
782 LineDelta = 0;
783 Temp = 0 - Params.DWARF2LineBase;
784 NeedCopy = true;
785 }
786
787 // Use DW_LNS_copy instead of a "line +0, addr +0" special opcode.
788 if (LineDelta == 0 && AddrDelta == 0) {
789 Out.push_back(dwarf::DW_LNS_copy);
790 return;
791 }
792
793 // Bias the opcode by the special opcode base.
794 Temp += Params.DWARF2LineOpcodeBase;
795
796 // Avoid overflow when addr_delta is large.
797 if (AddrDelta < 256 + MaxSpecialAddrDelta) {
798 // Try using a special opcode.
799 Opcode = Temp + AddrDelta * Params.DWARF2LineRange;
800 if (Opcode <= 255) {
801 Out.push_back(Opcode);
802 return;
803 }
804
805 // Try using DW_LNS_const_add_pc followed by special op.
806 Opcode = Temp + (AddrDelta - MaxSpecialAddrDelta) * Params.DWARF2LineRange;
807 if (Opcode <= 255) {
808 Out.push_back(dwarf::DW_LNS_const_add_pc);
809 Out.push_back(Opcode);
810 return;
811 }
812 }
813
814 // Otherwise use DW_LNS_advance_pc.
815 Out.push_back(dwarf::DW_LNS_advance_pc);
817
818 if (NeedCopy)
819 Out.push_back(dwarf::DW_LNS_copy);
820 else {
821 assert(Temp <= 255 && "Buggy special opcode encoding.");
822 Out.push_back(Temp);
823 }
824}
825
826// Utility function to write a tuple for .debug_abbrev.
827static void EmitAbbrev(MCStreamer *MCOS, uint64_t Name, uint64_t Form) {
828 MCOS->emitULEB128IntValue(Name);
829 MCOS->emitULEB128IntValue(Form);
830}
831
832// When generating dwarf for assembly source files this emits
833// the data for .debug_abbrev section which contains three DIEs.
834static void EmitGenDwarfAbbrev(MCStreamer *MCOS) {
835 MCContext &context = MCOS->getContext();
837
838 // DW_TAG_compile_unit DIE abbrev (1).
839 MCOS->emitULEB128IntValue(1);
840 MCOS->emitULEB128IntValue(dwarf::DW_TAG_compile_unit);
842 dwarf::Form SecOffsetForm =
843 context.getDwarfVersion() >= 4
844 ? dwarf::DW_FORM_sec_offset
845 : (context.getDwarfFormat() == dwarf::DWARF64 ? dwarf::DW_FORM_data8
846 : dwarf::DW_FORM_data4);
847 EmitAbbrev(MCOS, dwarf::DW_AT_stmt_list, SecOffsetForm);
848 if (context.getGenDwarfSectionSyms().size() > 1 &&
849 context.getDwarfVersion() >= 3) {
850 EmitAbbrev(MCOS, dwarf::DW_AT_ranges, SecOffsetForm);
851 } else {
852 EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
853 EmitAbbrev(MCOS, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr);
854 }
855 EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
856 if (!context.getCompilationDir().empty())
857 EmitAbbrev(MCOS, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string);
858 StringRef DwarfDebugFlags = context.getDwarfDebugFlags();
859 if (!DwarfDebugFlags.empty())
860 EmitAbbrev(MCOS, dwarf::DW_AT_APPLE_flags, dwarf::DW_FORM_string);
861 EmitAbbrev(MCOS, dwarf::DW_AT_producer, dwarf::DW_FORM_string);
862
863 if (context.getDwarfVersion() >= 6)
864 EmitAbbrev(MCOS, dwarf::DW_AT_language_name, dwarf::DW_FORM_data2);
865 else
866 EmitAbbrev(MCOS, dwarf::DW_AT_language, dwarf::DW_FORM_data2);
867
868 EmitAbbrev(MCOS, 0, 0);
869
870 // DW_TAG_label DIE abbrev (2).
871 MCOS->emitULEB128IntValue(2);
872 MCOS->emitULEB128IntValue(dwarf::DW_TAG_label);
874 EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
875 EmitAbbrev(MCOS, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data4);
876 EmitAbbrev(MCOS, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data4);
877 EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
878 EmitAbbrev(MCOS, 0, 0);
879
880 // Terminate the abbreviations for this compilation unit.
881 MCOS->emitInt8(0);
882}
883
884// When generating dwarf for assembly source files this emits the data for
885// .debug_aranges section. This section contains a header and a table of pairs
886// of PointerSize'ed values for the address and size of section(s) with line
887// table entries.
889 const MCSymbol *InfoSectionSymbol) {
890 MCContext &context = MCOS->getContext();
891
892 auto &Sections = context.getGenDwarfSectionSyms();
893
895
896 unsigned UnitLengthBytes =
898 unsigned OffsetSize = dwarf::getDwarfOffsetByteSize(context.getDwarfFormat());
899
900 // This will be the length of the .debug_aranges section, first account for
901 // the size of each item in the header (see below where we emit these items).
902 int Length = UnitLengthBytes + 2 + OffsetSize + 1 + 1;
903
904 // Figure the padding after the header before the table of address and size
905 // pairs who's values are PointerSize'ed.
906 const MCAsmInfo &asmInfo = context.getAsmInfo();
907 int AddrSize = asmInfo.getCodePointerSize();
908 int Pad = 2 * AddrSize - (Length & (2 * AddrSize - 1));
909 if (Pad == 2 * AddrSize)
910 Pad = 0;
911 Length += Pad;
912
913 // Add the size of the pair of PointerSize'ed values for the address and size
914 // of each section we have in the table.
915 Length += 2 * AddrSize * Sections.size();
916 // And the pair of terminating zeros.
917 Length += 2 * AddrSize;
918
919 // Emit the header for this section.
920 if (context.getDwarfFormat() == dwarf::DWARF64)
921 // The DWARF64 mark.
923 // The 4 (8 for DWARF64) byte length not including the length of the unit
924 // length field itself.
925 MCOS->emitIntValue(Length - UnitLengthBytes, OffsetSize);
926 // The 2 byte version, which is 2.
927 MCOS->emitInt16(2);
928 // The 4 (8 for DWARF64) byte offset to the compile unit in the .debug_info
929 // from the start of the .debug_info.
930 if (InfoSectionSymbol)
931 MCOS->emitSymbolValue(InfoSectionSymbol, OffsetSize,
933 else
934 MCOS->emitIntValue(0, OffsetSize);
935 // The 1 byte size of an address.
936 MCOS->emitInt8(AddrSize);
937 // The 1 byte size of a segment descriptor, we use a value of zero.
938 MCOS->emitInt8(0);
939 // Align the header with the padding if needed, before we put out the table.
940 for(int i = 0; i < Pad; i++)
941 MCOS->emitInt8(0);
942
943 // Now emit the table of pairs of PointerSize'ed values for the section
944 // addresses and sizes.
945 for (MCSection *Sec : Sections) {
946 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
947 MCSymbol *EndSymbol = Sec->getEndSymbol(context);
948 assert(StartSymbol && "StartSymbol must not be NULL");
949 assert(EndSymbol && "EndSymbol must not be NULL");
950
951 const MCExpr *Addr = MCSymbolRefExpr::create(StartSymbol, context);
952 const MCExpr *Size =
953 makeEndMinusStartExpr(context, *StartSymbol, *EndSymbol, 0);
954 MCOS->emitValue(Addr, AddrSize);
955 emitAbsValue(*MCOS, Size, AddrSize);
956 }
957
958 // And finally the pair of terminating zeros.
959 MCOS->emitIntValue(0, AddrSize);
960 MCOS->emitIntValue(0, AddrSize);
961}
962
963// When generating dwarf for assembly source files this emits the data for
964// .debug_info section which contains three parts. The header, the compile_unit
965// DIE and a list of label DIEs.
966static void EmitGenDwarfInfo(MCStreamer *MCOS,
967 const MCSymbol *AbbrevSectionSymbol,
968 const MCSymbol *LineSectionSymbol,
969 const MCSymbol *RangesSymbol) {
970 MCContext &context = MCOS->getContext();
971
973
974 // Create a symbol at the start and end of this section used in here for the
975 // expression to calculate the length in the header.
976 MCSymbol *InfoStart = context.createTempSymbol();
977 MCOS->emitLabel(InfoStart);
978 MCSymbol *InfoEnd = context.createTempSymbol();
979
980 // First part: the header.
981
982 unsigned UnitLengthBytes =
984 unsigned OffsetSize = dwarf::getDwarfOffsetByteSize(context.getDwarfFormat());
985
986 if (context.getDwarfFormat() == dwarf::DWARF64)
987 // Emit DWARF64 mark.
989
990 // The 4 (8 for DWARF64) byte total length of the information for this
991 // compilation unit, not including the unit length field itself.
992 const MCExpr *Length =
993 makeEndMinusStartExpr(context, *InfoStart, *InfoEnd, UnitLengthBytes);
994 emitAbsValue(*MCOS, Length, OffsetSize);
995
996 // The 2 byte DWARF version.
997 MCOS->emitInt16(context.getDwarfVersion());
998
999 // The DWARF v5 header has unit type, address size, abbrev offset.
1000 // Earlier versions have abbrev offset, address size.
1001 const MCAsmInfo &AsmInfo = context.getAsmInfo();
1002 int AddrSize = AsmInfo.getCodePointerSize();
1003 if (context.getDwarfVersion() >= 5) {
1004 MCOS->emitInt8(dwarf::DW_UT_compile);
1005 MCOS->emitInt8(AddrSize);
1006 }
1007 // The 4 (8 for DWARF64) byte offset to the debug abbrevs from the start of
1008 // the .debug_abbrev.
1009 if (AbbrevSectionSymbol)
1010 MCOS->emitSymbolValue(AbbrevSectionSymbol, OffsetSize,
1012 else
1013 // Since the abbrevs are at the start of the section, the offset is zero.
1014 MCOS->emitIntValue(0, OffsetSize);
1015 if (context.getDwarfVersion() <= 4)
1016 MCOS->emitInt8(AddrSize);
1017
1018 // Second part: the compile_unit DIE.
1019
1020 // The DW_TAG_compile_unit DIE abbrev (1).
1021 MCOS->emitULEB128IntValue(1);
1022
1023 // DW_AT_stmt_list, a 4 (8 for DWARF64) byte offset from the start of the
1024 // .debug_line section.
1025 if (LineSectionSymbol)
1026 MCOS->emitSymbolValue(LineSectionSymbol, OffsetSize,
1028 else
1029 // The line table is at the start of the section, so the offset is zero.
1030 MCOS->emitIntValue(0, OffsetSize);
1031
1032 if (RangesSymbol) {
1033 // There are multiple sections containing code, so we must use
1034 // .debug_ranges/.debug_rnglists. AT_ranges, the 4/8 byte offset from the
1035 // start of the .debug_ranges/.debug_rnglists.
1036 MCOS->emitSymbolValue(RangesSymbol, OffsetSize);
1037 } else {
1038 // If we only have one non-empty code section, we can use the simpler
1039 // AT_low_pc and AT_high_pc attributes.
1040
1041 // Find the first (and only) non-empty text section
1042 auto &Sections = context.getGenDwarfSectionSyms();
1043 const auto TextSection = Sections.begin();
1044 assert(TextSection != Sections.end() && "No text section found");
1045
1046 MCSymbol *StartSymbol = (*TextSection)->getBeginSymbol();
1047 MCSymbol *EndSymbol = (*TextSection)->getEndSymbol(context);
1048 assert(StartSymbol && "StartSymbol must not be NULL");
1049 assert(EndSymbol && "EndSymbol must not be NULL");
1050
1051 // AT_low_pc, the first address of the default .text section.
1052 const MCExpr *Start = MCSymbolRefExpr::create(StartSymbol, context);
1053 MCOS->emitValue(Start, AddrSize);
1054
1055 // AT_high_pc, the last address of the default .text section.
1056 const MCExpr *End = MCSymbolRefExpr::create(EndSymbol, context);
1057 MCOS->emitValue(End, AddrSize);
1058 }
1059
1060 // AT_name, the name of the source file. Reconstruct from the first directory
1061 // and file table entries.
1062 const SmallVectorImpl<std::string> &MCDwarfDirs = context.getMCDwarfDirs();
1063 if (MCDwarfDirs.size() > 0) {
1064 MCOS->emitBytes(MCDwarfDirs[0]);
1066 }
1067 const SmallVectorImpl<MCDwarfFile> &MCDwarfFiles = context.getMCDwarfFiles();
1068 // MCDwarfFiles might be empty if we have an empty source file.
1069 // If it's not empty, [0] is unused and [1] is the first actual file.
1070 assert(MCDwarfFiles.empty() || MCDwarfFiles.size() >= 2);
1071 const MCDwarfFile &RootFile =
1072 MCDwarfFiles.empty()
1073 ? context.getMCDwarfLineTable(/*CUID=*/0).getRootFile()
1074 : MCDwarfFiles[1];
1075 MCOS->emitBytes(RootFile.Name);
1076 MCOS->emitInt8(0); // NULL byte to terminate the string.
1077
1078 // AT_comp_dir, the working directory the assembly was done in.
1079 if (!context.getCompilationDir().empty()) {
1080 MCOS->emitBytes(context.getCompilationDir());
1081 MCOS->emitInt8(0); // NULL byte to terminate the string.
1082 }
1083
1084 // AT_APPLE_flags, the command line arguments of the assembler tool.
1085 StringRef DwarfDebugFlags = context.getDwarfDebugFlags();
1086 if (!DwarfDebugFlags.empty()){
1087 MCOS->emitBytes(DwarfDebugFlags);
1088 MCOS->emitInt8(0); // NULL byte to terminate the string.
1089 }
1090
1091 // AT_producer, the version of the assembler tool.
1092 StringRef DwarfDebugProducer = context.getDwarfDebugProducer();
1093 if (!DwarfDebugProducer.empty())
1094 MCOS->emitBytes(DwarfDebugProducer);
1095 else
1096 MCOS->emitBytes(StringRef("llvm-mc (based on LLVM " PACKAGE_VERSION ")"));
1097 MCOS->emitInt8(0); // NULL byte to terminate the string.
1098
1099 if (context.getDwarfVersion() >= 6) {
1100 // AT_language_name, a 4 byte value.
1101 MCOS->emitInt16(dwarf::DW_LNAME_Assembly);
1102 } else {
1103 // AT_language, a 4 byte value. We use DW_LANG_Mips_Assembler as the dwarf2
1104 // draft has no standard code for assembler.
1105 // FIXME: dwarf4 has DW_LANG_Assembly which we could use instead.
1106 MCOS->emitInt16(dwarf::DW_LANG_Mips_Assembler);
1107 }
1108
1109 // Third part: the list of label DIEs.
1110
1111 // Loop on saved info for dwarf labels and create the DIEs for them.
1112 const std::vector<MCGenDwarfLabelEntry> &Entries =
1114 for (const auto &Entry : Entries) {
1115 // The DW_TAG_label DIE abbrev (2).
1116 MCOS->emitULEB128IntValue(2);
1117
1118 // AT_name, of the label without any leading underbar.
1119 MCOS->emitBytes(Entry.getName());
1120 MCOS->emitInt8(0); // NULL byte to terminate the string.
1121
1122 // AT_decl_file, index into the file table.
1123 MCOS->emitInt32(Entry.getFileNumber());
1124
1125 // AT_decl_line, source line number.
1126 MCOS->emitInt32(Entry.getLineNumber());
1127
1128 // AT_low_pc, start address of the label.
1129 const auto *AT_low_pc = MCSymbolRefExpr::create(Entry.getLabel(), context);
1130 MCOS->emitValue(AT_low_pc, AddrSize);
1131 }
1132
1133 // Add the NULL DIE terminating the Compile Unit DIE's.
1134 MCOS->emitInt8(0);
1135
1136 // Now set the value of the symbol at the end of the info section.
1137 MCOS->emitLabel(InfoEnd);
1138}
1139
1140// When generating dwarf for assembly source files this emits the data for
1141// .debug_ranges section. We only emit one range list, which spans all of the
1142// executable sections of this file.
1144 MCContext &context = MCOS->getContext();
1145 auto &Sections = context.getGenDwarfSectionSyms();
1146
1147 const MCAsmInfo &AsmInfo = context.getAsmInfo();
1148 int AddrSize = AsmInfo.getCodePointerSize();
1149 MCSymbol *RangesSymbol;
1150
1151 if (MCOS->getContext().getDwarfVersion() >= 5) {
1153 MCSymbol *EndSymbol = mcdwarf::emitListsTableHeaderStart(*MCOS);
1154 MCOS->AddComment("Offset entry count");
1155 MCOS->emitInt32(0);
1156 RangesSymbol = context.createTempSymbol("debug_rnglist0_start");
1157 MCOS->emitLabel(RangesSymbol);
1158 for (MCSection *Sec : Sections) {
1159 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
1160 const MCSymbol *EndSymbol = Sec->getEndSymbol(context);
1161 const MCExpr *SectionStartAddr =
1162 MCSymbolRefExpr::create(StartSymbol, context);
1163 const MCExpr *SectionSize =
1164 makeEndMinusStartExpr(context, *StartSymbol, *EndSymbol, 0);
1165 MCOS->emitInt8(dwarf::DW_RLE_start_length);
1166 MCOS->emitValue(SectionStartAddr, AddrSize);
1167 MCOS->emitULEB128Value(SectionSize);
1168 }
1169 MCOS->emitInt8(dwarf::DW_RLE_end_of_list);
1170 MCOS->emitLabel(EndSymbol);
1171 } else {
1173 RangesSymbol = context.createTempSymbol("debug_ranges_start");
1174 MCOS->emitLabel(RangesSymbol);
1175 for (MCSection *Sec : Sections) {
1176 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
1177 const MCSymbol *EndSymbol = Sec->getEndSymbol(context);
1178
1179 // Emit a base address selection entry for the section start.
1180 const MCExpr *SectionStartAddr =
1181 MCSymbolRefExpr::create(StartSymbol, context);
1182 MCOS->emitFill(AddrSize, 0xFF);
1183 MCOS->emitValue(SectionStartAddr, AddrSize);
1184
1185 // Emit a range list entry spanning this section.
1186 const MCExpr *SectionSize =
1187 makeEndMinusStartExpr(context, *StartSymbol, *EndSymbol, 0);
1188 MCOS->emitIntValue(0, AddrSize);
1189 emitAbsValue(*MCOS, SectionSize, AddrSize);
1190 }
1191
1192 // Emit end of list entry
1193 MCOS->emitIntValue(0, AddrSize);
1194 MCOS->emitIntValue(0, AddrSize);
1195 }
1196
1197 return RangesSymbol;
1198}
1199
1200//
1201// When generating dwarf for assembly source files this emits the Dwarf
1202// sections.
1203//
1205 MCContext &context = MCOS->getContext();
1206
1207 // Create the dwarf sections in this order (.debug_line already created).
1208 const MCAsmInfo &AsmInfo = context.getAsmInfo();
1209 bool CreateDwarfSectionSymbols =
1211 MCSymbol *LineSectionSymbol = nullptr;
1212 if (CreateDwarfSectionSymbols)
1213 LineSectionSymbol = MCOS->getDwarfLineTableSymbol(0);
1214 MCSymbol *AbbrevSectionSymbol = nullptr;
1215 MCSymbol *InfoSectionSymbol = nullptr;
1216 MCSymbol *RangesSymbol = nullptr;
1217
1218 // Create end symbols for each section, and remove empty sections
1219 MCOS->getContext().finalizeDwarfSections(*MCOS);
1220
1221 // If there are no sections to generate debug info for, we don't need
1222 // to do anything
1223 if (MCOS->getContext().getGenDwarfSectionSyms().empty())
1224 return;
1225
1226 // We only use the .debug_ranges section if we have multiple code sections,
1227 // and we are emitting a DWARF version which supports it.
1228 const bool UseRangesSection =
1229 MCOS->getContext().getGenDwarfSectionSyms().size() > 1 &&
1230 MCOS->getContext().getDwarfVersion() >= 3;
1231 CreateDwarfSectionSymbols |= UseRangesSection;
1232
1234 if (CreateDwarfSectionSymbols) {
1235 InfoSectionSymbol = context.createTempSymbol();
1236 MCOS->emitLabel(InfoSectionSymbol);
1237 }
1239 if (CreateDwarfSectionSymbols) {
1240 AbbrevSectionSymbol = context.createTempSymbol();
1241 MCOS->emitLabel(AbbrevSectionSymbol);
1242 }
1243
1245
1246 // Output the data for .debug_aranges section.
1247 EmitGenDwarfAranges(MCOS, InfoSectionSymbol);
1248
1249 if (UseRangesSection) {
1250 RangesSymbol = emitGenDwarfRanges(MCOS);
1251 assert(RangesSymbol);
1252 }
1253
1254 // Output the data for .debug_abbrev section.
1255 EmitGenDwarfAbbrev(MCOS);
1256
1257 // Output the data for .debug_info section.
1258 EmitGenDwarfInfo(MCOS, AbbrevSectionSymbol, LineSectionSymbol, RangesSymbol);
1259}
1260
1261//
1262// When generating dwarf for assembly source files this is called when symbol
1263// for a label is created. If this symbol is not a temporary and is in the
1264// section that dwarf is being generated for, save the needed info to create
1265// a dwarf label.
1266//
1269 // We won't create dwarf labels for temporary symbols.
1270 if (Symbol->isTemporary())
1271 return;
1272 MCContext &context = MCOS->getContext();
1273 // We won't create dwarf labels for symbols in sections that we are not
1274 // generating debug info for.
1275 if (!context.getGenDwarfSectionSyms().count(MCOS->getCurrentSectionOnly()))
1276 return;
1277
1278 // The dwarf label's name does not have the symbol name's leading
1279 // underbar if any.
1280 StringRef Name = Symbol->getName();
1281 if (Name.starts_with("_"))
1282 Name = Name.substr(1, Name.size()-1);
1283
1284 // Get the dwarf file number to be used for the dwarf label.
1285 unsigned FileNumber = context.getGenDwarfFileNumber();
1286
1287 // Finding the line number is the expensive part which is why we just don't
1288 // pass it in as for some symbols we won't create a dwarf label.
1289 unsigned CurBuffer = SrcMgr.FindBufferContainingLoc(Loc);
1290 unsigned LineNumber = SrcMgr.FindLineNumber(Loc, CurBuffer);
1291
1292 // We create a temporary symbol for use for the AT_high_pc and AT_low_pc
1293 // values so that they don't have things like an ARM thumb bit from the
1294 // original symbol. So when used they won't get a low bit set after
1295 // relocation.
1296 MCSymbol *Label = context.createTempSymbol();
1297 MCOS->emitLabel(Label);
1298
1299 // Create and entry for the info and add it to the other entries.
1301 MCGenDwarfLabelEntry(Name, FileNumber, LineNumber, Label));
1302}
1303
1304void MCCFIInstruction::replaceRegister(unsigned FromReg, unsigned ToReg) {
1305 auto ReplaceReg = [=](unsigned &Reg) {
1306 if (Reg == FromReg)
1307 Reg = ToReg;
1308 };
1309 auto Visitor = makeVisitor(
1310 [=](CommonFields &F) {
1311 ReplaceReg(F.Register);
1312 ReplaceReg(F.Register2);
1313 },
1314 [](EscapeFields &) {}, [](LabelFields &) {},
1315 [=](RegisterPairFields &F) {
1316 ReplaceReg(F.Register);
1317 ReplaceReg(F.Reg1);
1318 ReplaceReg(F.Reg2);
1319 },
1320 [=](VectorRegistersFields &F) {
1321 ReplaceReg(F.Register);
1322 for (VectorRegisterWithLane &VRL : F.VectorRegisters)
1323 ReplaceReg(VRL.Register);
1324 },
1325 [=](VectorOffsetFields &F) {
1326 ReplaceReg(F.Register);
1327 ReplaceReg(F.MaskRegister);
1328 },
1330 ReplaceReg(F.Register);
1331 ReplaceReg(F.SpillRegister);
1332 ReplaceReg(F.MaskRegister);
1333 },
1334 [](LLVMSetRAStateFields &) {
1335 llvm_unreachable(".cfi_set_ra_state does not have registers");
1336 });
1337 std::visit(Visitor, ExtraFields);
1338}
1339
1340static int getDataAlignmentFactor(MCStreamer &streamer) {
1341 MCContext &context = streamer.getContext();
1342 const MCAsmInfo &asmInfo = context.getAsmInfo();
1343 int size = asmInfo.getCalleeSaveStackSlotSize();
1344 if (asmInfo.isStackGrowthDirectionUp())
1345 return size;
1346 else
1347 return -size;
1348}
1349
1350static unsigned getSizeForEncoding(MCStreamer &streamer,
1351 unsigned symbolEncoding) {
1352 MCContext &context = streamer.getContext();
1353 unsigned format = symbolEncoding & 0x0f;
1354 switch (format) {
1355 default: llvm_unreachable("Unknown Encoding");
1358 return context.getAsmInfo().getCodePointerSize();
1361 return 2;
1364 return 4;
1367 return 8;
1368 }
1369}
1370
1371static void emitFDESymbol(MCObjectStreamer &streamer, const MCSymbol &symbol,
1372 unsigned symbolEncoding, bool isEH) {
1373 MCContext &context = streamer.getContext();
1374 const MCAsmInfo &asmInfo = context.getAsmInfo();
1375 const MCExpr *v =
1376 asmInfo.getExprForFDESymbol(&symbol, symbolEncoding, streamer);
1377 unsigned size = getSizeForEncoding(streamer, symbolEncoding);
1378 if (asmInfo.doDwarfFDESymbolsUseAbsDiff() && isEH)
1379 emitAbsValue(streamer, v, size);
1380 else
1381 streamer.emitValue(v, size);
1382}
1383
1384static void EmitPersonality(MCStreamer &streamer, const MCSymbol &symbol,
1385 unsigned symbolEncoding) {
1386 MCContext &context = streamer.getContext();
1387 const MCAsmInfo &asmInfo = context.getAsmInfo();
1388 const MCExpr *v =
1389 asmInfo.getExprForPersonalitySymbol(&symbol, symbolEncoding, streamer);
1390 unsigned size = getSizeForEncoding(streamer, symbolEncoding);
1391 streamer.emitValue(v, size);
1392}
1393
1394namespace {
1395
1396class FrameEmitterImpl {
1397 int64_t CFAOffset = 0;
1398 int64_t InitialCFAOffset = 0;
1399 bool IsEH;
1400 MCObjectStreamer &Streamer;
1401
1402public:
1403 FrameEmitterImpl(bool IsEH, MCObjectStreamer &Streamer)
1404 : IsEH(IsEH), Streamer(Streamer) {}
1405
1406 /// Emit the unwind information in a compact way.
1407 void EmitCompactUnwind(const MCDwarfFrameInfo &frame);
1408
1409 const MCSymbol &EmitCIE(const MCDwarfFrameInfo &F);
1410 void EmitFDE(const MCSymbol &cieStart, const MCDwarfFrameInfo &frame,
1411 bool LastInSection, const MCSymbol &SectionStart);
1412 void emitCFIInstructions(ArrayRef<MCCFIInstruction> Instrs,
1413 MCSymbol *BaseLabel);
1414 void emitCFIInstruction(const MCCFIInstruction &Instr);
1415};
1416
1417} // end anonymous namespace
1418
1419static void emitEncodingByte(MCObjectStreamer &Streamer, unsigned Encoding) {
1420 Streamer.emitInt8(Encoding);
1421}
1422
1423static void encodeDwarfRegisterLocation(int DwarfReg, raw_ostream &OS) {
1424 assert(DwarfReg >= 0);
1425 if (DwarfReg < 32) {
1426 OS << uint8_t(dwarf::DW_OP_reg0 + DwarfReg);
1427 } else {
1428 OS << uint8_t(dwarf::DW_OP_regx);
1429 encodeULEB128(DwarfReg, OS);
1430 }
1431}
1432
1433void FrameEmitterImpl::emitCFIInstruction(const MCCFIInstruction &Instr) {
1434 int dataAlignmentFactor = getDataAlignmentFactor(Streamer);
1435 auto *MRI = Streamer.getContext().getRegisterInfo();
1436
1437 switch (Instr.getOperation()) {
1439 unsigned Reg1 = Instr.getRegister();
1440 unsigned Reg2 = Instr.getRegister2();
1441 if (!IsEH) {
1442 Reg1 = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg1);
1443 Reg2 = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg2);
1444 }
1445 Streamer.emitInt8(dwarf::DW_CFA_register);
1446 Streamer.emitULEB128IntValue(Reg1);
1447 Streamer.emitULEB128IntValue(Reg2);
1448 return;
1449 }
1451 Streamer.emitInt8(dwarf::DW_CFA_GNU_window_save);
1452 return;
1453
1455 Streamer.emitInt8(dwarf::DW_CFA_AARCH64_negate_ra_state);
1456 return;
1457
1459 Streamer.emitInt8(dwarf::DW_CFA_AARCH64_negate_ra_state_with_pc);
1460 return;
1461
1463 Streamer.emitInt8(dwarf::DW_CFA_AARCH64_set_ra_state);
1464 Streamer.emitULEB128IntValue(Instr.getRASignState());
1465 if (MCSymbol *PACSym = Instr.getRASignSymbol()) {
1466 MCContext &Ctx = Streamer.getContext();
1467 const MCExpr *Diff = MCBinaryExpr::createSub(
1468 MCSymbolRefExpr::create(PACSym, Ctx),
1469 MCSymbolRefExpr::create(Instr.getLabel(), Ctx), Ctx);
1470 const MCExpr *Factored = MCBinaryExpr::createDiv(
1471 Diff,
1473 Ctx);
1474 Streamer.emitSLEB128Value(Factored);
1475 } else {
1476 Streamer.emitSLEB128IntValue(Instr.getRASignOffset());
1477 }
1478 return;
1479 }
1481 unsigned Reg = Instr.getRegister();
1482 Streamer.emitInt8(dwarf::DW_CFA_undefined);
1483 Streamer.emitULEB128IntValue(Reg);
1484 return;
1485 }
1488 const bool IsRelative =
1490
1491 Streamer.emitInt8(dwarf::DW_CFA_def_cfa_offset);
1492
1493 if (IsRelative)
1494 CFAOffset += Instr.getOffset();
1495 else
1496 CFAOffset = Instr.getOffset();
1497
1498 Streamer.emitULEB128IntValue(CFAOffset);
1499
1500 return;
1501 }
1503 unsigned Reg = Instr.getRegister();
1504 if (!IsEH)
1505 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1506 Streamer.emitInt8(dwarf::DW_CFA_def_cfa);
1507 Streamer.emitULEB128IntValue(Reg);
1508 CFAOffset = Instr.getOffset();
1509 Streamer.emitULEB128IntValue(CFAOffset);
1510
1511 return;
1512 }
1514 unsigned Reg = Instr.getRegister();
1515 if (!IsEH)
1516 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1517 Streamer.emitInt8(dwarf::DW_CFA_def_cfa_register);
1518 Streamer.emitULEB128IntValue(Reg);
1519
1520 return;
1521 }
1522 // TODO: Implement `_sf` variants if/when they need to be emitted.
1524 unsigned Reg = Instr.getRegister();
1525 if (!IsEH)
1526 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1527 Streamer.emitIntValue(dwarf::DW_CFA_LLVM_def_aspace_cfa, 1);
1528 Streamer.emitULEB128IntValue(Reg);
1529 CFAOffset = Instr.getOffset();
1530 Streamer.emitULEB128IntValue(CFAOffset);
1531 Streamer.emitULEB128IntValue(Instr.getAddressSpace());
1532
1533 return;
1534 }
1537 const bool IsRelative =
1538 Instr.getOperation() == MCCFIInstruction::OpRelOffset;
1539
1540 unsigned Reg = Instr.getRegister();
1541 if (!IsEH)
1542 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1543
1544 int64_t Offset = Instr.getOffset();
1545 if (IsRelative)
1546 Offset -= CFAOffset;
1547 Offset = Offset / dataAlignmentFactor;
1548
1549 if (Offset < 0) {
1550 Streamer.emitInt8(dwarf::DW_CFA_offset_extended_sf);
1551 Streamer.emitULEB128IntValue(Reg);
1552 Streamer.emitSLEB128IntValue(Offset);
1553 } else if (Reg < 64) {
1554 Streamer.emitInt8(dwarf::DW_CFA_offset + Reg);
1555 Streamer.emitULEB128IntValue(Offset);
1556 } else {
1557 Streamer.emitInt8(dwarf::DW_CFA_offset_extended);
1558 Streamer.emitULEB128IntValue(Reg);
1559 Streamer.emitULEB128IntValue(Offset);
1560 }
1561 return;
1562 }
1564 Streamer.emitInt8(dwarf::DW_CFA_remember_state);
1565 return;
1567 Streamer.emitInt8(dwarf::DW_CFA_restore_state);
1568 return;
1570 unsigned Reg = Instr.getRegister();
1571 Streamer.emitInt8(dwarf::DW_CFA_same_value);
1572 Streamer.emitULEB128IntValue(Reg);
1573 return;
1574 }
1576 unsigned Reg = Instr.getRegister();
1577 if (!IsEH)
1578 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1579 if (Reg < 64) {
1580 Streamer.emitInt8(dwarf::DW_CFA_restore | Reg);
1581 } else {
1582 Streamer.emitInt8(dwarf::DW_CFA_restore_extended);
1583 Streamer.emitULEB128IntValue(Reg);
1584 }
1585 return;
1586 }
1588 Streamer.emitInt8(dwarf::DW_CFA_GNU_args_size);
1589 Streamer.emitULEB128IntValue(Instr.getOffset());
1590 return;
1591
1593 Streamer.emitBytes(Instr.getValues());
1594 return;
1595
1597 Streamer.emitLabel(Instr.getCfiLabel(), Instr.getLoc());
1598 return;
1600 unsigned Reg = Instr.getRegister();
1601 if (!IsEH)
1602 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1603
1604 int Offset = Instr.getOffset();
1605 Offset = Offset / dataAlignmentFactor;
1606
1607 if (Offset < 0) {
1608 Streamer.emitInt8(dwarf::DW_CFA_val_offset_sf);
1609 Streamer.emitULEB128IntValue(Reg);
1610 Streamer.emitSLEB128IntValue(Offset);
1611 } else {
1612 Streamer.emitInt8(dwarf::DW_CFA_val_offset);
1613 Streamer.emitULEB128IntValue(Reg);
1614 Streamer.emitULEB128IntValue(Offset);
1615 }
1616 return;
1617 }
1619 // CFI for a register spilled to a pair of SGPRs is implemented as an
1620 // expression(E) rule where E is a composite location description with
1621 // multiple parts each referencing SGPR register location storage with a bit
1622 // offset of 0. In other words we generate the following DWARF:
1623 //
1624 // DW_CFA_expression: <Reg>,
1625 // (DW_OP_regx <SGPRPair[0]>) (DW_OP_piece <Size>)
1626 // (DW_OP_regx <SGPRPair[1]>) (DW_OP_piece <Size>)
1627 //
1628 // The memory location description for the current CFA is pushed on the
1629 // stack before E is evaluated, but we choose not to drop it as it would
1630 // require a longer expression E and DWARF defines the result of the
1631 // evaulation to be the location description on the top of the stack (i.e.
1632 // the implictly pushed one is just ignored.)
1633
1634 const auto &Fields =
1636
1638 raw_svector_ostream OSBlock(Block);
1639 encodeDwarfRegisterLocation(Fields.Reg1, OSBlock);
1640 if (Fields.Reg1SizeInBits % 8 == 0) {
1641 OSBlock << uint8_t(dwarf::DW_OP_piece);
1642 encodeULEB128(Fields.Reg1SizeInBits / 8, OSBlock);
1643 } else {
1644 OSBlock << uint8_t(dwarf::DW_OP_bit_piece);
1645 encodeULEB128(Fields.Reg1SizeInBits, OSBlock);
1646 encodeULEB128(0, OSBlock);
1647 }
1648 encodeDwarfRegisterLocation(Fields.Reg2, OSBlock);
1649 if (Fields.Reg2SizeInBits % 8 == 0) {
1650 OSBlock << uint8_t(dwarf::DW_OP_piece);
1651 encodeULEB128(Fields.Reg2SizeInBits / 8, OSBlock);
1652 } else {
1653 OSBlock << uint8_t(dwarf::DW_OP_bit_piece);
1654 encodeULEB128(Fields.Reg2SizeInBits, OSBlock);
1655 encodeULEB128(0, OSBlock);
1656 }
1657
1658 Streamer.emitInt8(dwarf::DW_CFA_expression);
1659 Streamer.emitULEB128IntValue(Fields.Register);
1660 Streamer.emitULEB128IntValue(Block.size());
1661 Streamer.emitBinaryData(StringRef(&Block[0], Block.size()));
1662 return;
1663 }
1665 // CFI for an SGPR spilled to a multiple lanes of VGPRs is implemented as an
1666 // expression(E) rule where E is a composite location description with
1667 // multiple parts each referencing VGPR register location storage with a bit
1668 // offset of the lane index multiplied by the size of a lane. In other words
1669 // we generate the following DWARF:
1670 //
1671 // DW_CFA_expression: <SGPR>,
1672 // (DW_OP_regx <VGPR[0]>) (DW_OP_bit_piece <Size>, <Lane[0]>*<Size>)
1673 // (DW_OP_regx <VGPR[1]>) (DW_OP_bit_piece <Size>, <Lane[1]>*<Size>)
1674 // ...
1675 // (DW_OP_regx <VGPR[N]>) (DW_OP_bit_piece <Size>, <Lane[N]>*<Size>)
1676 //
1677 // However if we're only using a single lane then we can emit a slightly
1678 // more optimal form:
1679 //
1680 // DW_CFA_expression: <SGPR>,
1681 // (DW_OP_regx <VGPR[0]>) (DW_OP_LLVM_offset_uconst <Lane[0]>*<Size>)
1682 //
1683 // The memory location description for the current CFA is pushed on the
1684 // stack before E is evaluated, but we choose not to drop it as it would
1685 // require a longer expression E and DWARF defines the result of the
1686 // evaulation to be the location description on the top of the stack (i.e.
1687 // the implictly pushed one is just ignored.)
1688
1689 const auto &Fields =
1691 auto &VRs = Fields.VectorRegisters;
1692
1694 raw_svector_ostream OSBlock(Block);
1695
1696 if (VRs.size() == 1 && VRs[0].SizeInBits % 8 == 0) {
1697 encodeDwarfRegisterLocation(VRs[0].Register, OSBlock);
1698 OSBlock << uint8_t(dwarf::DW_OP_LLVM_user)
1699 << uint8_t(dwarf::DW_OP_LLVM_offset_uconst);
1700 encodeULEB128((VRs[0].SizeInBits / 8) * VRs[0].Lane, OSBlock);
1701 } else {
1702 for (const auto &VR : VRs) {
1703 // TODO: Detect when we can merge multiple adjacent pieces, or even
1704 // reduce this to a register location description (when all pieces are
1705 // adjacent).
1706 encodeDwarfRegisterLocation(VR.Register, OSBlock);
1707 OSBlock << uint8_t(dwarf::DW_OP_bit_piece);
1708 encodeULEB128(VR.SizeInBits, OSBlock);
1709 encodeULEB128(VR.SizeInBits * VR.Lane, OSBlock);
1710 }
1711 }
1712
1713 Streamer.emitInt8(dwarf::DW_CFA_expression);
1714 Streamer.emitULEB128IntValue(Fields.Register);
1715 Streamer.emitULEB128IntValue(Block.size());
1716 Streamer.emitBinaryData(StringRef(&Block[0], Block.size()));
1717 return;
1718 }
1720 // CFI for a vector register spilled to memory is implemented as an
1721 // expression(E) rule where E is a location description.
1722 //
1723 // DW_CFA_expression: <VGPR>,
1724 // (DW_OP_regx <VGPR>)
1725 // (DW_OP_swap)
1726 // (DW_OP_LLVM_offset_uconst <Offset>)
1727 // (DW_OP_LLVM_call_frame_entry_reg <Mask>)
1728 // (DW_OP_deref_size <MaskSize>)
1729 // (DW_OP_LLVM_select_bit_piece <VGPRSize> <MaskSize>)
1730
1731 const auto &Fields =
1733
1735 raw_svector_ostream OSBlock(Block);
1736 encodeDwarfRegisterLocation(Fields.Register, OSBlock);
1737 OSBlock << uint8_t(dwarf::DW_OP_swap);
1738 OSBlock << uint8_t(dwarf::DW_OP_LLVM_user)
1739 << uint8_t(dwarf::DW_OP_LLVM_offset_uconst);
1740 encodeULEB128(Fields.Offset, OSBlock);
1741 OSBlock << uint8_t(dwarf::DW_OP_LLVM_user)
1742 << uint8_t(dwarf::DW_OP_LLVM_call_frame_entry_reg);
1743 encodeULEB128(Fields.MaskRegister, OSBlock);
1744 OSBlock << uint8_t(dwarf::DW_OP_deref_size);
1745 OSBlock << uint8_t(Fields.MaskRegisterSizeInBits / 8);
1746 OSBlock << uint8_t(dwarf::DW_OP_LLVM_user)
1747 << uint8_t(dwarf::DW_OP_LLVM_select_bit_piece);
1748 encodeULEB128(Fields.RegisterSizeInBits, OSBlock);
1749 encodeULEB128(Fields.MaskRegisterSizeInBits, OSBlock);
1750
1751 Streamer.emitInt8(dwarf::DW_CFA_expression);
1752 Streamer.emitULEB128IntValue(Fields.Register);
1753 Streamer.emitULEB128IntValue(Block.size());
1754 Streamer.emitBinaryData(StringRef(&Block[0], Block.size()));
1755 return;
1756 }
1758 // CFI for a VGPR/AGPR partially spilled to another VGPR/AGPR dependent on
1759 // an EXEC mask is implemented as an expression(E) rule where E is a
1760 // location description.
1761 //
1762 // DW_CFA_expression: <GPR>,
1763 // (DW_OP_regx <GPR>)
1764 // (DW_OP_regx <Spill GPR>)
1765 // (DW_OP_LLVM_call_frame_entry_reg <Mask>)
1766 // (DW_OP_deref_size <MaskSize>)
1767 // (DW_OP_LLVM_select_bit_piece <GPR lane size> <MaskSize>)
1768
1769 const auto Fields =
1771
1773 raw_svector_ostream OSBlock(Block);
1774 encodeDwarfRegisterLocation(Fields.Register, OSBlock);
1775 encodeDwarfRegisterLocation(Fields.SpillRegister, OSBlock);
1776 OSBlock << uint8_t(dwarf::DW_OP_LLVM_user)
1777 << uint8_t(dwarf::DW_OP_LLVM_call_frame_entry_reg);
1778 encodeULEB128(Fields.MaskRegister, OSBlock);
1779 OSBlock << uint8_t(dwarf::DW_OP_deref_size)
1780 << uint8_t(Fields.MaskRegisterSizeInBits / 8);
1781 OSBlock << uint8_t(dwarf::DW_OP_LLVM_user)
1782 << uint8_t(dwarf::DW_OP_LLVM_select_bit_piece);
1783 encodeULEB128(Fields.SpillRegisterLaneSizeInBits, OSBlock);
1784 encodeULEB128(Fields.MaskRegisterSizeInBits, OSBlock);
1785
1786 Streamer.emitInt8(dwarf::DW_CFA_expression);
1787 Streamer.emitULEB128IntValue(Fields.Register);
1788 Streamer.emitULEB128IntValue(Block.size());
1789 Streamer.emitBinaryData(StringRef(&Block[0], Block.size()));
1790 return;
1791 }
1792 }
1793
1794 llvm_unreachable("Unhandled case in switch");
1795}
1796
1797/// Emit frame instructions to describe the layout of the frame.
1798void FrameEmitterImpl::emitCFIInstructions(ArrayRef<MCCFIInstruction> Instrs,
1799 MCSymbol *BaseLabel) {
1800 for (const MCCFIInstruction &Instr : Instrs) {
1801 MCSymbol *Label = Instr.getLabel();
1802 // Throw out move if the label is invalid.
1803 if (Label && !Label->isDefined()) continue; // Not emitted, in dead code.
1804
1805 // Advance row if new location.
1806 if (BaseLabel && Label) {
1807 MCSymbol *ThisSym = Label;
1808 if (ThisSym != BaseLabel) {
1809 Streamer.emitDwarfAdvanceFrameAddr(BaseLabel, ThisSym, Instr.getLoc());
1810 BaseLabel = ThisSym;
1811 }
1812 }
1813
1814 emitCFIInstruction(Instr);
1815 }
1816}
1817
1818/// Emit the unwind information in a compact way.
1819void FrameEmitterImpl::EmitCompactUnwind(const MCDwarfFrameInfo &Frame) {
1820 MCContext &Context = Streamer.getContext();
1821 const MCObjectFileInfo *MOFI = Context.getObjectFileInfo();
1822
1823 // range-start range-length compact-unwind-enc personality-func lsda
1824 // _foo LfooEnd-_foo 0x00000023 0 0
1825 // _bar LbarEnd-_bar 0x00000025 __gxx_personality except_tab1
1826 //
1827 // .section __LD,__compact_unwind,regular,debug
1828 //
1829 // # compact unwind for _foo
1830 // .quad _foo
1831 // .set L1,LfooEnd-_foo
1832 // .long L1
1833 // .long 0x01010001
1834 // .quad 0
1835 // .quad 0
1836 //
1837 // # compact unwind for _bar
1838 // .quad _bar
1839 // .set L2,LbarEnd-_bar
1840 // .long L2
1841 // .long 0x01020011
1842 // .quad __gxx_personality
1843 // .quad except_tab1
1844
1845 uint32_t Encoding = Frame.CompactUnwindEncoding;
1846 if (!Encoding) return;
1847 bool DwarfEHFrameOnly = (Encoding == MOFI->getCompactUnwindDwarfEHFrameOnly());
1848
1849 // The encoding needs to know we have an LSDA.
1850 if (!DwarfEHFrameOnly && Frame.Lsda)
1851 Encoding |= 0x40000000;
1852
1853 // Range Start
1854 unsigned FDEEncoding = MOFI->getFDEEncoding();
1855 unsigned Size = getSizeForEncoding(Streamer, FDEEncoding);
1856 Streamer.emitSymbolValue(Frame.Begin, Size);
1857
1858 // Range Length
1859 const MCExpr *Range =
1860 makeEndMinusStartExpr(Context, *Frame.Begin, *Frame.End, 0);
1861 emitAbsValue(Streamer, Range, 4);
1862
1863 // Compact Encoding
1865 Streamer.emitIntValue(Encoding, Size);
1866
1867 // Personality Function
1869 if (!DwarfEHFrameOnly && Frame.Personality)
1870 Streamer.emitSymbolValue(Frame.Personality, Size);
1871 else
1872 Streamer.emitIntValue(0, Size); // No personality fn
1873
1874 // LSDA
1875 Size = getSizeForEncoding(Streamer, Frame.LsdaEncoding);
1876 if (!DwarfEHFrameOnly && Frame.Lsda)
1877 Streamer.emitSymbolValue(Frame.Lsda, Size);
1878 else
1879 Streamer.emitIntValue(0, Size); // No LSDA
1880}
1881
1882static unsigned getCIEVersion(bool IsEH, unsigned DwarfVersion) {
1883 if (IsEH)
1884 return 1;
1885 switch (DwarfVersion) {
1886 case 2:
1887 return 1;
1888 case 3:
1889 return 3;
1890 case 4:
1891 case 5:
1892 return 4;
1893 }
1894 llvm_unreachable("Unknown version");
1895}
1896
1897const MCSymbol &FrameEmitterImpl::EmitCIE(const MCDwarfFrameInfo &Frame) {
1898 MCContext &context = Streamer.getContext();
1899 const MCRegisterInfo *MRI = context.getRegisterInfo();
1900 const MCObjectFileInfo *MOFI = context.getObjectFileInfo();
1901
1902 MCSymbol *sectionStart = context.createTempSymbol();
1903 Streamer.emitLabel(sectionStart);
1904
1905 MCSymbol *sectionEnd = context.createTempSymbol();
1906
1908 unsigned UnitLengthBytes = dwarf::getUnitLengthFieldByteSize(Format);
1909 unsigned OffsetSize = dwarf::getDwarfOffsetByteSize(Format);
1910 bool IsDwarf64 = Format == dwarf::DWARF64;
1911
1912 if (IsDwarf64)
1913 // DWARF64 mark
1914 Streamer.emitInt32(dwarf::DW_LENGTH_DWARF64);
1915
1916 // Length
1917 const MCExpr *Length = makeEndMinusStartExpr(context, *sectionStart,
1918 *sectionEnd, UnitLengthBytes);
1919 emitAbsValue(Streamer, Length, OffsetSize);
1920
1921 // CIE ID
1922 uint64_t CIE_ID =
1923 IsEH ? 0 : (IsDwarf64 ? dwarf::DW64_CIE_ID : dwarf::DW_CIE_ID);
1924 Streamer.emitIntValue(CIE_ID, OffsetSize);
1925
1926 // Version
1927 uint8_t CIEVersion = getCIEVersion(IsEH, context.getDwarfVersion());
1928 Streamer.emitInt8(CIEVersion);
1929
1930 if (IsEH) {
1931 SmallString<8> Augmentation;
1932 Augmentation += "z";
1933 if (Frame.Personality)
1934 Augmentation += "P";
1935 if (Frame.Lsda)
1936 Augmentation += "L";
1937 Augmentation += "R";
1938 if (Frame.IsSignalFrame)
1939 Augmentation += "S";
1940 if (Frame.IsBKeyFrame)
1941 Augmentation += "B";
1942 if (Frame.IsMTETaggedFrame)
1943 Augmentation += "G";
1944 Streamer.emitBytes(Augmentation);
1945 }
1946 Streamer.emitInt8(0);
1947
1948 if (CIEVersion >= 4) {
1949 // Address Size
1950 Streamer.emitInt8(context.getAsmInfo().getCodePointerSize());
1951
1952 // Segment Descriptor Size
1953 Streamer.emitInt8(0);
1954 }
1955
1956 // Code Alignment Factor
1957 Streamer.emitULEB128IntValue(context.getAsmInfo().getMinInstAlignment());
1958
1959 // Data Alignment Factor
1960 Streamer.emitSLEB128IntValue(getDataAlignmentFactor(Streamer));
1961
1962 // Return Address Register
1963 unsigned RAReg = Frame.RAReg;
1964 if (RAReg == static_cast<unsigned>(INT_MAX))
1965 RAReg = MRI->getDwarfRegNum(MRI->getRARegister(), IsEH);
1966
1967 if (CIEVersion == 1) {
1968 assert(RAReg <= 255 &&
1969 "DWARF 2 encodes return_address_register in one byte");
1970 Streamer.emitInt8(RAReg);
1971 } else {
1972 Streamer.emitULEB128IntValue(RAReg);
1973 }
1974
1975 // Augmentation Data Length (optional)
1976 unsigned augmentationLength = 0;
1977 if (IsEH) {
1978 if (Frame.Personality) {
1979 // Personality Encoding
1980 augmentationLength += 1;
1981 // Personality
1982 augmentationLength +=
1983 getSizeForEncoding(Streamer, Frame.PersonalityEncoding);
1984 }
1985 if (Frame.Lsda)
1986 augmentationLength += 1;
1987 // Encoding of the FDE pointers
1988 augmentationLength += 1;
1989
1990 Streamer.emitULEB128IntValue(augmentationLength);
1991
1992 // Augmentation Data (optional)
1993 if (Frame.Personality) {
1994 // Personality Encoding
1995 emitEncodingByte(Streamer, Frame.PersonalityEncoding);
1996 // Personality
1997 EmitPersonality(Streamer, *Frame.Personality, Frame.PersonalityEncoding);
1998 }
1999
2000 if (Frame.Lsda)
2001 emitEncodingByte(Streamer, Frame.LsdaEncoding);
2002
2003 // Encoding of the FDE pointers
2004 emitEncodingByte(Streamer, MOFI->getFDEEncoding());
2005 }
2006
2007 // Initial Instructions
2008
2009 const MCAsmInfo &MAI = context.getAsmInfo();
2010 if (!Frame.IsSimple) {
2011 const std::vector<MCCFIInstruction> &Instructions =
2013 emitCFIInstructions(Instructions, nullptr);
2014 }
2015
2016 InitialCFAOffset = CFAOffset;
2017
2018 // Padding
2019 Streamer.emitValueToAlignment(Align(IsEH ? 4 : MAI.getCodePointerSize()));
2020
2021 Streamer.emitLabel(sectionEnd);
2022 return *sectionStart;
2023}
2024
2025void FrameEmitterImpl::EmitFDE(const MCSymbol &cieStart,
2026 const MCDwarfFrameInfo &frame,
2027 bool LastInSection,
2028 const MCSymbol &SectionStart) {
2029 MCContext &context = Streamer.getContext();
2030 MCSymbol *fdeStart = context.createTempSymbol();
2031 MCSymbol *fdeEnd = context.createTempSymbol();
2032 const MCObjectFileInfo *MOFI = context.getObjectFileInfo();
2033
2034 CFAOffset = InitialCFAOffset;
2035
2037 unsigned OffsetSize = dwarf::getDwarfOffsetByteSize(Format);
2038
2039 if (Format == dwarf::DWARF64)
2040 // DWARF64 mark
2041 Streamer.emitInt32(dwarf::DW_LENGTH_DWARF64);
2042
2043 // Length
2044 const MCExpr *Length = makeEndMinusStartExpr(context, *fdeStart, *fdeEnd, 0);
2045 emitAbsValue(Streamer, Length, OffsetSize);
2046
2047 Streamer.emitLabel(fdeStart);
2048
2049 // CIE Pointer
2050 const MCAsmInfo &asmInfo = context.getAsmInfo();
2051 if (IsEH) {
2052 const MCExpr *offset =
2053 makeEndMinusStartExpr(context, cieStart, *fdeStart, 0);
2054 emitAbsValue(Streamer, offset, OffsetSize);
2055 } else if (!asmInfo.doesDwarfUseRelocationsAcrossSections()) {
2056 const MCExpr *offset =
2057 makeEndMinusStartExpr(context, SectionStart, cieStart, 0);
2058 emitAbsValue(Streamer, offset, OffsetSize);
2059 } else {
2060 Streamer.emitSymbolValue(&cieStart, OffsetSize,
2062 }
2063
2064 // PC Begin
2065 unsigned PCEncoding =
2066 IsEH ? MOFI->getFDEEncoding() : (unsigned)dwarf::DW_EH_PE_absptr;
2067 unsigned PCSize = getSizeForEncoding(Streamer, PCEncoding);
2068 emitFDESymbol(Streamer, *frame.Begin, PCEncoding, IsEH);
2069
2070 // PC Range
2071 const MCExpr *Range =
2072 makeEndMinusStartExpr(context, *frame.Begin, *frame.End, 0);
2073 emitAbsValue(Streamer, Range, PCSize);
2074
2075 if (IsEH) {
2076 // Augmentation Data Length
2077 unsigned augmentationLength = 0;
2078
2079 if (frame.Lsda)
2080 augmentationLength += getSizeForEncoding(Streamer, frame.LsdaEncoding);
2081
2082 Streamer.emitULEB128IntValue(augmentationLength);
2083
2084 // Augmentation Data
2085 if (frame.Lsda)
2086 emitFDESymbol(Streamer, *frame.Lsda, frame.LsdaEncoding, true);
2087 }
2088
2089 // Call Frame Instructions
2090 emitCFIInstructions(frame.Instructions, frame.Begin);
2091
2092 // Padding
2093 // The size of a .eh_frame section has to be a multiple of the alignment
2094 // since a null CIE is interpreted as the end. Old systems overaligned
2095 // .eh_frame, so we do too and account for it in the last FDE.
2096 unsigned Alignment = LastInSection ? asmInfo.getCodePointerSize() : PCSize;
2097 Streamer.emitValueToAlignment(Align(Alignment));
2098
2099 Streamer.emitLabel(fdeEnd);
2100}
2101
2102namespace {
2103
2104struct CIEKey {
2105 CIEKey() = default;
2106
2107 explicit CIEKey(const MCDwarfFrameInfo &Frame, bool IsEH)
2108 : Personality(Frame.Personality),
2109 PersonalityEncoding(Frame.PersonalityEncoding),
2110 LsdaEncoding(Frame.LsdaEncoding), IsSignalFrame(Frame.IsSignalFrame),
2111 IsSimple(Frame.IsSimple), RAReg(Frame.RAReg),
2112 IsBKeyFrame(Frame.IsBKeyFrame),
2113 IsMTETaggedFrame(Frame.IsMTETaggedFrame), IsEH(IsEH) {}
2114
2115 StringRef PersonalityName() const {
2116 if (!Personality)
2117 return StringRef();
2118 return Personality->getName();
2119 }
2120
2121 bool operator<(const CIEKey &Other) const {
2122 assert(IsEH == Other.IsEH);
2123 if (!IsEH)
2124 return std::make_tuple(RAReg, IsSimple) <
2125 std::make_tuple(Other.RAReg, Other.IsSimple);
2126
2127 return std::make_tuple(PersonalityName(), PersonalityEncoding, LsdaEncoding,
2128 IsSignalFrame, IsSimple, RAReg, IsBKeyFrame,
2129 IsMTETaggedFrame) <
2130 std::make_tuple(Other.PersonalityName(), Other.PersonalityEncoding,
2131 Other.LsdaEncoding, Other.IsSignalFrame,
2132 Other.IsSimple, Other.RAReg, Other.IsBKeyFrame,
2133 Other.IsMTETaggedFrame);
2134 }
2135
2136 bool operator==(const CIEKey &Other) const {
2137 assert(IsEH == Other.IsEH);
2138 if (!IsEH)
2139 return RAReg == Other.RAReg && IsSimple == Other.IsSimple;
2140
2141 return Personality == Other.Personality &&
2142 PersonalityEncoding == Other.PersonalityEncoding &&
2143 LsdaEncoding == Other.LsdaEncoding &&
2144 IsSignalFrame == Other.IsSignalFrame && IsSimple == Other.IsSimple &&
2145 RAReg == Other.RAReg && IsBKeyFrame == Other.IsBKeyFrame &&
2146 IsMTETaggedFrame == Other.IsMTETaggedFrame;
2147 }
2148 bool operator!=(const CIEKey &Other) const { return !(*this == Other); }
2149
2150 const MCSymbol *Personality = nullptr;
2151 unsigned PersonalityEncoding = 0;
2152 unsigned LsdaEncoding = -1;
2153 bool IsSignalFrame = false;
2154 bool IsSimple = false;
2155 unsigned RAReg = UINT_MAX;
2156 bool IsBKeyFrame = false;
2157 bool IsMTETaggedFrame = false;
2158 bool IsEH = false;
2159};
2160
2161} // end anonymous namespace
2162
2164 MCContext &Context = Streamer.getContext();
2165 const MCObjectFileInfo *MOFI = Context.getObjectFileInfo();
2166 const MCAsmInfo &AsmInfo = Context.getAsmInfo();
2167 FrameEmitterImpl Emitter(IsEH, Streamer);
2168 ArrayRef<MCDwarfFrameInfo> FrameArray = Streamer.getDwarfFrameInfos();
2169
2170 // Emit the compact unwind info if available.
2171 bool NeedsEHFrameSection = !MOFI->getSupportsCompactUnwindWithoutEHFrame();
2172 if (IsEH && MOFI->getCompactUnwindSection()) {
2174 bool SectionEmitted = false;
2175 for (const MCDwarfFrameInfo &Frame : FrameArray) {
2176 if (Frame.CompactUnwindEncoding == 0) continue;
2177 if (!SectionEmitted) {
2178 Streamer.switchSection(MOFI->getCompactUnwindSection());
2179 Streamer.emitValueToAlignment(Align(AsmInfo.getCodePointerSize()));
2180 SectionEmitted = true;
2181 }
2182 NeedsEHFrameSection |=
2183 Frame.CompactUnwindEncoding ==
2185 Emitter.EmitCompactUnwind(Frame);
2186 }
2187 }
2188
2189 // Compact unwind information can be emitted in the eh_frame section or the
2190 // debug_frame section. Skip emitting FDEs and CIEs when the compact unwind
2191 // doesn't need an eh_frame section and the emission location is the eh_frame
2192 // section.
2193 if (!NeedsEHFrameSection && IsEH) return;
2194
2195 MCSection &Section =
2196 IsEH ? *const_cast<MCObjectFileInfo *>(MOFI)->getEHFrameSection()
2197 : *MOFI->getDwarfFrameSection();
2198
2199 Streamer.switchSection(&Section);
2200 MCSymbol *SectionStart = Context.createTempSymbol();
2201 Streamer.emitLabel(SectionStart);
2202
2203 bool CanOmitDwarf = MOFI->getOmitDwarfIfHaveCompactUnwind();
2204 // Sort the FDEs by their corresponding CIE before we emit them.
2205 // This isn't technically necessary according to the DWARF standard,
2206 // but the Android libunwindstack rejects eh_frame sections where
2207 // an FDE refers to a CIE other than the closest previous CIE.
2208 std::vector<MCDwarfFrameInfo> FrameArrayX(FrameArray.begin(), FrameArray.end());
2209 llvm::stable_sort(FrameArrayX, [IsEH](const MCDwarfFrameInfo &X,
2210 const MCDwarfFrameInfo &Y) {
2211 return CIEKey(X, IsEH) < CIEKey(Y, IsEH);
2212 });
2213 CIEKey LastKey;
2214 const MCSymbol *LastCIEStart = nullptr;
2215 for (auto I = FrameArrayX.begin(), E = FrameArrayX.end(); I != E;) {
2216 const MCDwarfFrameInfo &Frame = *I;
2217 ++I;
2218 if (CanOmitDwarf && Frame.CompactUnwindEncoding !=
2219 MOFI->getCompactUnwindDwarfEHFrameOnly() && IsEH)
2220 // CIEs and FDEs can be emitted in either the eh_frame section or the
2221 // debug_frame section, on some platforms (e.g. AArch64) the target object
2222 // file supports emitting a compact_unwind section without an associated
2223 // eh_frame section. If the eh_frame section is not needed, and the
2224 // location where the CIEs and FDEs are to be emitted is the eh_frame
2225 // section, do not emit anything.
2226 continue;
2227
2228 CIEKey Key(Frame, IsEH);
2229 if (!LastCIEStart || Key != LastKey) {
2230 LastKey = Key;
2231 LastCIEStart = &Emitter.EmitCIE(Frame);
2232 }
2233
2234 Emitter.EmitFDE(*LastCIEStart, Frame, I == E, *SectionStart);
2235 }
2236}
2237
2239 uint64_t AddrDelta,
2240 SmallVectorImpl<char> &Out) {
2241 // Scale the address delta by the minimum instruction length.
2242 AddrDelta = ScaleAddrDelta(Context, AddrDelta);
2243 if (AddrDelta == 0)
2244 return;
2245
2246 llvm::endianness E = Context.getAsmInfo().isLittleEndian()
2249
2250 if (isUIntN(6, AddrDelta)) {
2251 uint8_t Opcode = dwarf::DW_CFA_advance_loc | AddrDelta;
2252 Out.push_back(Opcode);
2253 } else if (isUInt<8>(AddrDelta)) {
2254 Out.push_back(dwarf::DW_CFA_advance_loc1);
2255 Out.push_back(AddrDelta);
2256 } else if (isUInt<16>(AddrDelta)) {
2257 Out.push_back(dwarf::DW_CFA_advance_loc2);
2258 support::endian::write<uint16_t>(Out, AddrDelta, E);
2259 } else {
2260 assert(isUInt<32>(AddrDelta));
2261 Out.push_back(dwarf::DW_CFA_advance_loc4);
2262 support::endian::write<uint32_t>(Out, AddrDelta, E);
2263 }
2264}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define X(NUM, ENUM, NAME)
Definition ELF.h:856
dxil DXContainer Global Emitter
This file contains constants used for implementing Dwarf debug support.
#define op(i)
static void emitFDESymbol(MCObjectStreamer &streamer, const MCSymbol &symbol, unsigned symbolEncoding, bool isEH)
Definition MCDwarf.cpp:1371
static uint64_t SpecialAddr(MCDwarfLineTableParams Params, uint64_t op)
Given a special op, return the address skip amount (in units of DWARF2_LINE_MIN_INSN_LENGTH).
Definition MCDwarf.cpp:739
static void EmitGenDwarfAranges(MCStreamer *MCOS, const MCSymbol *InfoSectionSymbol)
Definition MCDwarf.cpp:888
static bool isRootFile(const MCDwarfFile &RootFile, StringRef &Directory, StringRef &FileName, std::optional< MD5::MD5Result > Checksum)
Definition MCDwarf.cpp:638
static uint64_t ScaleAddrDelta(MCContext &Context, uint64_t AddrDelta)
Definition MCDwarf.cpp:65
static const MCExpr * forceExpAbs(MCStreamer &OS, const MCExpr *Expr)
Definition MCDwarf.cpp:367
static void emitAbsValue(MCStreamer &OS, const MCExpr *Value, unsigned Size)
Definition MCDwarf.cpp:379
static void encodeDwarfRegisterLocation(int DwarfReg, raw_ostream &OS)
Definition MCDwarf.cpp:1423
static void emitOneV5FileEntry(MCStreamer *MCOS, const MCDwarfFile &DwarfFile, bool EmitMD5, bool HasAnySource, std::optional< MCDwarfLineStr > &LineStr)
Definition MCDwarf.cpp:442
static const MCExpr * makeEndMinusStartExpr(MCContext &Ctx, const MCSymbol &Start, const MCSymbol &End, int IntVal)
Definition MCDwarf.cpp:119
static unsigned getCIEVersion(bool IsEH, unsigned DwarfVersion)
Definition MCDwarf.cpp:1882
static void EmitGenDwarfInfo(MCStreamer *MCOS, const MCSymbol *AbbrevSectionSymbol, const MCSymbol *LineSectionSymbol, const MCSymbol *RangesSymbol)
Definition MCDwarf.cpp:966
static void EmitAbbrev(MCStreamer *MCOS, uint64_t Name, uint64_t Form)
Definition MCDwarf.cpp:827
static void EmitPersonality(MCStreamer &streamer, const MCSymbol &symbol, unsigned symbolEncoding)
Definition MCDwarf.cpp:1384
static void emitEncodingByte(MCObjectStreamer &Streamer, unsigned Encoding)
Definition MCDwarf.cpp:1419
static int getDataAlignmentFactor(MCStreamer &streamer)
Definition MCDwarf.cpp:1340
static MCSymbol * emitGenDwarfRanges(MCStreamer *MCOS)
Definition MCDwarf.cpp:1143
static const MCExpr * makeStartPlusIntExpr(MCContext &Ctx, const MCSymbol &Start, int IntVal)
Definition MCDwarf.cpp:135
static void EmitGenDwarfAbbrev(MCStreamer *MCOS)
Definition MCDwarf.cpp:834
static unsigned getSizeForEncoding(MCStreamer &streamer, unsigned symbolEncoding)
Definition MCDwarf.cpp:1350
#define DWARF2_FLAG_IS_STMT
Definition MCDwarf.h:119
#define DWARF2_FLAG_BASIC_BLOCK
Definition MCDwarf.h:120
#define DWARF2_LINE_DEFAULT_IS_STMT
Definition MCDwarf.h:117
#define DWARF2_FLAG_PROLOGUE_END
Definition MCDwarf.h:121
#define DWARF2_FLAG_EPILOGUE_BEGIN
Definition MCDwarf.h:122
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
static constexpr MCPhysReg RAReg
This file contains some templates that are useful if you are working with the STL at all.
This file defines the SmallString class.
This file defines the SmallVector class.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
Value * RHS
Value * LHS
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
iterator end() const
Definition ArrayRef.h:130
size_t size() const
Get the array size.
Definition ArrayRef.h:141
iterator begin() const
Definition ArrayRef.h:129
Tagged union holding either a T or a Error.
Definition Error.h:485
This class is intended to be used as a base class for asm properties and features specific to the tar...
Definition MCAsmInfo.h:67
unsigned getMinInstAlignment() const
Definition MCAsmInfo.h:549
const std::vector< MCCFIInstruction > & getInitialFrameState() const
Definition MCAsmInfo.h:699
bool needsDwarfSectionOffsetDirective() const
Definition MCAsmInfo.h:531
bool doesDwarfUseRelocationsAcrossSections() const
Definition MCAsmInfo.h:681
const MCExpr * getExprForFDESymbol(const MCSymbol *Sym, unsigned Encoding, MCStreamer &Streamer) const
Definition MCAsmInfo.cpp:65
bool isStackGrowthDirectionUp() const
True if target stack grow up.
Definition MCAsmInfo.h:466
unsigned getCalleeSaveStackSlotSize() const
Get the callee-saved register stack slot size in bytes.
Definition MCAsmInfo.h:458
bool doDwarfFDESymbolsUseAbsDiff() const
Definition MCAsmInfo.h:685
virtual const MCExpr * getExprForPersonalitySymbol(const MCSymbol *Sym, unsigned Encoding, MCStreamer &Streamer) const
Definition MCAsmInfo.cpp:59
unsigned getCodePointerSize() const
Get the code pointer size in bytes.
Definition MCAsmInfo.h:454
static const MCBinaryExpr * createDiv(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition MCExpr.h:352
static LLVM_ABI const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.cpp:201
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition MCExpr.h:427
@ Sub
Subtraction.
Definition MCExpr.h:323
@ Add
Addition.
Definition MCExpr.h:301
LLVM_ABI void replaceRegister(unsigned FromReg, unsigned ToReg)
Replaces in place all references to FromReg with ToReg.
Definition MCDwarf.cpp:1304
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition MCExpr.cpp:212
Context object for machine code objects.
Definition MCContext.h:83
const MCObjectFileInfo * getObjectFileInfo() const
Definition MCContext.h:413
LLVM_ABI void remapDebugPath(SmallVectorImpl< char > &Path)
Remap one path in-place as per the debug prefix map.
const SetVector< MCSection * > & getGenDwarfSectionSyms()
Definition MCContext.h:786
const SmallVectorImpl< std::string > & getMCDwarfDirs(unsigned CUID=0)
Definition MCContext.h:728
StringRef getDwarfDebugProducer()
Definition MCContext.h:808
StringRef getDwarfDebugFlags()
Definition MCContext.h:805
bool getDwarfLocSeen()
Definition MCContext.h:769
LLVM_ABI MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
StringRef getCompilationDir() const
Get the compilation directory for DW_AT_comp_dir The compilation directory should be set with setComp...
Definition MCContext.h:679
void clearDwarfLocSeen()
Definition MCContext.h:767
MCDwarfLineTable & getMCDwarfLineTable(unsigned CUID)
Definition MCContext.h:714
unsigned getDwarfCompileUnitID()
Definition MCContext.h:732
const MCRegisterInfo * getRegisterInfo() const
Definition MCContext.h:411
const SmallVectorImpl< MCDwarfFile > & getMCDwarfFiles(unsigned CUID=0)
Definition MCContext.h:724
const std::map< unsigned, MCDwarfLineTable > & getMCDwarfLineTables() const
Definition MCContext.h:710
unsigned getGenDwarfFileNumber()
Definition MCContext.h:774
uint16_t getDwarfVersion() const
Definition MCContext.h:814
LLVM_ABI void finalizeDwarfSections(MCStreamer &MCOS)
Remove empty sections from SectionsForRanges, to avoid generating useless debug info for them.
void addMCGenDwarfLabelEntry(const MCGenDwarfLabelEntry &E)
Definition MCContext.h:800
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
const MCDwarfLoc & getCurrentDwarfLoc()
Definition MCContext.h:770
dwarf::DwarfFormat getDwarfFormat() const
Definition MCContext.h:811
const MCAsmInfo & getAsmInfo() const
Definition MCContext.h:409
const std::vector< MCGenDwarfLabelEntry > & getMCGenDwarfLabelEntries() const
Definition MCContext.h:796
LLVM_ABI void Emit(MCStreamer &MCOS, MCDwarfLineTableParams Params, MCSection *Section) const
Definition MCDwarf.cpp:334
static LLVM_ABI void emit(MCObjectStreamer &streamer, bool isEH)
Definition MCDwarf.cpp:2163
static LLVM_ABI void encodeAdvanceLoc(MCContext &Context, uint64_t AddrDelta, SmallVectorImpl< char > &OS)
Definition MCDwarf.cpp:2238
static LLVM_ABI void Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params, int64_t LineDelta, uint64_t AddrDelta)
Utility function to emit the encoding to a streamer.
Definition MCDwarf.cpp:729
static LLVM_ABI void encode(MCContext &Context, MCDwarfLineTableParams Params, int64_t LineDelta, uint64_t AddrDelta, SmallVectorImpl< char > &OS)
Utility function to encode a Dwarf pair of LineDelta and AddrDeltas.
Definition MCDwarf.cpp:744
Instances of this class represent the line information for the dwarf line table entries.
Definition MCDwarf.h:190
void setEndLabel(MCSymbol *EndLabel)
Definition MCDwarf.h:220
MCDwarfLineEntry(MCSymbol *label, const MCDwarfLoc loc, MCSymbol *lineStreamLabel=nullptr, SMLoc streamLabelDefLoc={})
Definition MCDwarf.h:199
MCSymbol * LineStreamLabel
Definition MCDwarf.h:210
static LLVM_ABI void make(MCStreamer *MCOS, MCSection *Section)
Definition MCDwarf.cpp:91
LLVM_ABI void emitSection(MCStreamer *MCOS)
Emit the .debug_line_str section if appropriate.
Definition MCDwarf.cpp:384
LLVM_ABI MCDwarfLineStr(MCContext &Ctx)
Construct an instance that can emit .debug_line_str (for use in a normal v5 line table).
Definition MCDwarf.cpp:76
LLVM_ABI SmallString< 0 > getFinalizedData()
Returns finalized section.
Definition MCDwarf.cpp:392
LLVM_ABI void emitRef(MCStreamer *MCOS, StringRef Path)
Emit a reference to the string.
Definition MCDwarf.cpp:406
LLVM_ABI size_t addString(StringRef Path)
Adds path Path to the line string.
Definition MCDwarf.cpp:402
LLVM_ABI void endCurrentSeqAndEmitLineStreamLabel(MCStreamer *MCOS, SMLoc DefLoc, StringRef Name)
Definition MCDwarf.cpp:288
MCDwarfFile & getRootFile()
Definition MCDwarf.h:421
const MCLineSection & getMCLineSections() const
Definition MCDwarf.h:451
static LLVM_ABI void emit(MCStreamer *MCOS, MCDwarfLineTableParams Params)
Definition MCDwarf.cpp:307
static LLVM_ABI void emitOne(MCStreamer *MCOS, MCSection *Section, const MCLineSection::MCDwarfLineEntryCollection &LineEntries)
Definition MCDwarf.cpp:177
LLVM_ABI Expected< unsigned > tryGetFile(StringRef &Directory, StringRef &FileName, std::optional< MD5::MD5Result > Checksum, std::optional< StringRef > Source, uint16_t DwarfVersion, unsigned FileNumber=0)
Definition MCDwarf.cpp:630
LLVM_ABI void emitCU(MCStreamer *MCOS, MCDwarfLineTableParams Params, std::optional< MCDwarfLineStr > &LineStr) const
Definition MCDwarf.cpp:616
Instances of this class represent the information from a dwarf .loc directive.
Definition MCDwarf.h:107
Base class for the full range of assembler expressions which are needed for parsing.
Definition MCExpr.h:34
static LLVM_ABI void Emit(MCStreamer *MCOS)
Definition MCDwarf.cpp:1204
MCGenDwarfLabelEntry(StringRef name, unsigned fileNumber, unsigned lineNumber, MCSymbol *label)
Definition MCDwarf.h:494
static LLVM_ABI void Make(MCSymbol *Symbol, MCStreamer *MCOS, SourceMgr &SrcMgr, SMLoc &Loc)
Definition MCDwarf.cpp:1267
LLVM_ABI void addEndEntry(MCSymbol *EndLabel)
Definition MCDwarf.cpp:142
void addLineEntry(const MCDwarfLineEntry &LineEntry, MCSection *Sec)
Definition MCDwarf.h:241
std::vector< MCDwarfLineEntry > MCDwarfLineEntryCollection
Definition MCDwarf.h:249
MCSection * getDwarfRangesSection() const
bool getSupportsCompactUnwindWithoutEHFrame() const
MCSection * getDwarfLineStrSection() const
unsigned getCompactUnwindDwarfEHFrameOnly() const
MCSection * getDwarfRnglistsSection() const
MCSection * getDwarfLineSection() const
MCSection * getDwarfInfoSection() const
MCSection * getDwarfFrameSection() const
unsigned getFDEEncoding() const
MCSection * getDwarfAbbrevSection() const
bool getOmitDwarfIfHaveCompactUnwind() const
MCSection * getDwarfARangesSection() const
MCSection * getCompactUnwindSection() const
Streaming object file generation interface.
void emitValueToAlignment(Align Alignment, int64_t Fill=0, uint8_t FillLen=1, unsigned MaxBytesToEmit=0) override
Emit some number of copies of Value until the byte alignment ByteAlignment is reached.
void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc()) override
Emit a label for Symbol into the current section.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
MCRegister getRARegister() const
This method should return the register where the return address can be found.
virtual int64_t getDwarfRegNum(MCRegister Reg, bool isEH) const
Map a target register to an equivalent dwarf register number.
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition MCSection.h:573
MCSymbol * getBeginSymbol()
Definition MCSection.h:646
Streaming machine code generation interface.
Definition MCStreamer.h:222
virtual void emitAssignment(MCSymbol *Symbol, const MCExpr *Value)
Emit an assignment of Value to Symbol.
virtual void emitBinaryData(StringRef Data)
Functionally identical to EmitBytes.
virtual void emitDwarfUnitLength(uint64_t Length, const Twine &Comment)
Emit a unit length field.
MCContext & getContext() const
Definition MCStreamer.h:326
virtual void AddComment(const Twine &T, bool EOL=true)
Add a textual comment.
Definition MCStreamer.h:404
virtual void emitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset)
Emits a COFF section relative relocation.
void emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())
void emitSymbolValue(const MCSymbol *Sym, unsigned Size, bool IsSectionRelative=false)
Special case of EmitValue that avoids the client having to pass in a MCExpr for MCSymbols.
virtual void emitDwarfLineStartLabel(MCSymbol *StartSym)
Emit the debug line start label.
virtual void emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo, unsigned Size)
Emit the absolute difference between two symbols.
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
virtual void emitIntValue(uint64_t Value, unsigned Size)
Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers.
virtual void emitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel, const MCSymbol *Label, unsigned PointerSize)
If targets does not support representing debug line section by .loc/.file directives in assembly outp...
void emitInt16(uint64_t Value)
Definition MCStreamer.h:766
virtual MCSymbol * getDwarfLineTableSymbol(unsigned CUID)
unsigned emitULEB128IntValue(uint64_t Value, unsigned PadTo=0)
Special case of EmitULEB128Value that avoids the client having to pass in a MCExpr for constant integ...
virtual void emitULEB128Value(const MCExpr *Value)
ArrayRef< MCDwarfFrameInfo > getDwarfFrameInfos() const
virtual void switchSection(MCSection *Section, uint32_t Subsec=0)
Set the current section where code is being emitted to Section.
void emitInt32(uint64_t Value)
Definition MCStreamer.h:767
MCSection * getCurrentSectionOnly() const
Definition MCStreamer.h:438
virtual void emitDwarfLineEndEntry(MCSection *Section, MCSymbol *LastLabel, MCSymbol *EndLabel=nullptr)
Emit the debug line end entry.
void emitInt8(uint64_t Value)
Definition MCStreamer.h:765
void emitFill(uint64_t NumBytes, uint8_t FillValue)
Emit NumBytes bytes worth of the value specified by FillValue.
virtual void emitBytes(StringRef Data)
Emit the bytes in Data into the output.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:213
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition MCSymbol.h:42
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
Definition MCSymbol.h:251
Wrapper class representing virtual and physical registers.
Definition Register.h:20
Represents a location in source code.
Definition SMLoc.h:22
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
StringRef str() const
Explicit conversion to StringRef.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This owns the files read by a parser, handles include stacks, and handles diagnostic wrangling.
Definition SourceMgr.h:37
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition StringRef.h:597
constexpr bool empty() const
Check if the string is empty.
Definition StringRef.h:141
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
LLVM Value Representation.
Definition Value.h:75
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
A raw_ostream that writes to an SmallVector or SmallString.
#define INT64_MAX
Definition DataTypes.h:71
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const uint32_t DW_CIE_ID
Special ID values that distinguish a CIE from a FDE in DWARF CFI.
Definition Dwarf.h:98
uint8_t getUnitLengthFieldByteSize(DwarfFormat Format)
Get the byte size of the unit length field depending on the DWARF format.
Definition Dwarf.h:1228
const uint64_t DW64_CIE_ID
Definition Dwarf.h:99
DwarfFormat
Constants that define the DWARF format as 32 or 64 bit.
Definition Dwarf.h:93
@ DWARF64
Definition Dwarf.h:93
@ DWARF32
Definition Dwarf.h:93
uint8_t getDwarfOffsetByteSize(DwarfFormat Format)
The size of a reference determined by the DWARF 32/64-bit format.
Definition Dwarf.h:1186
@ DW_CHILDREN_no
Definition Dwarf.h:948
@ DW_EH_PE_signed
Definition Dwarf.h:961
@ DW_CHILDREN_yes
Definition Dwarf.h:949
@ DW_EH_PE_sdata4
Definition Dwarf.h:959
@ DW_EH_PE_udata2
Definition Dwarf.h:954
@ DW_EH_PE_sdata8
Definition Dwarf.h:960
@ DW_EH_PE_absptr
Definition Dwarf.h:951
@ DW_EH_PE_sdata2
Definition Dwarf.h:958
@ DW_EH_PE_udata4
Definition Dwarf.h:955
@ DW_EH_PE_udata8
Definition Dwarf.h:956
@ DW_LENGTH_DWARF64
Indicator of 64-bit DWARF format.
Definition Dwarf.h:57
LLVM_ABI MCSymbol * emitListsTableHeaderStart(MCStreamer &S)
Definition MCDwarf.cpp:44
NodeAddr< InstrNode * > Instr
Definition RDFGraph.h:389
void write(void *memory, value_type value, endianness endian)
Write a value to memory with a particular endianness.
Definition Endian.h:96
LLVM_ABI StringRef get_separator(Style style=Style::native)
Return the preferred separator for this platform.
Definition Path.cpp:626
LLVM_ABI StringRef parent_path(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get parent path.
Definition Path.cpp:478
LLVM_ABI StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get filename.
Definition Path.cpp:594
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:578
@ Length
Definition DWP.cpp:578
bool operator<(int64_t V1, const APSInt &V2)
Definition APSInt.h:360
void stable_sort(R &&Range)
Definition STLExtras.h:2116
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1765
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition STLExtras.h:1669
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition Error.cpp:94
bool operator!=(uint64_t V1, const APInt &V2)
Definition APInt.h:2144
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
Definition MathExtras.h:244
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
LLVM_ABI SourceMgr SrcMgr
Definition Error.cpp:24
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:190
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition Format.h:94
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
Definition Error.h:340
@ Other
Any other memory.
Definition ModRef.h:68
LLVM_ABI unsigned getULEB128Size(uint64_t Value)
Utility function to get the size of the ULEB128-encoded value.
Definition LEB128.cpp:19
ArrayRef(const T &OneElt) -> ArrayRef< T >
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
Definition LEB128.h:79
void appendLEB128(SmallVectorImpl< U > &Buffer, T Value)
Definition LEB128.h:246
constexpr decltype(auto) makeVisitor(CallableTs &&...Callables)
Returns an opaquely-typed Callable object whose operator() overload set is the sum of the operator() ...
Definition STLExtras.h:1519
endianness
Definition bit.h:71
StringRef toStringRef(bool B)
Construct a string ref from a boolean.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Held in ExtraFields when OpLLVMSetRAState.
Definition MCDwarf.h:599
Held in ExtraFields when OpLLVMRegisterPair.
Definition MCDwarf.h:567
Held in ExtraFields when OpLLVMVectorOffset.
Definition MCDwarf.h:583
Held in ExtraFields when OpLLVMVectorRegisterMask.
Definition MCDwarf.h:591
Held in ExtraFields when OpLLVMVectorRegisters.
Definition MCDwarf.h:578
std::vector< VectorRegisterWithLane > VectorRegisters
Definition MCDwarf.h:580
Instances of this class represent the name of the dwarf .file directive and its associated dwarf file...
Definition MCDwarf.h:89
std::optional< MD5::MD5Result > Checksum
The MD5 checksum, if there is one.
Definition MCDwarf.h:98
std::string Name
Definition MCDwarf.h:91
const MCSymbol * Personality
Definition MCDwarf.h:904
unsigned PersonalityEncoding
Definition MCDwarf.h:908
uint64_t CompactUnwindEncoding
Definition MCDwarf.h:910
std::vector< MCCFIInstruction > Instructions
Definition MCDwarf.h:906
const MCSymbol * Lsda
Definition MCDwarf.h:905
void trackMD5Usage(bool MD5Used)
Definition MCDwarf.h:311
SmallVector< MCDwarfFile, 3 > MCDwarfFiles
Definition MCDwarf.h:281
SmallVector< std::string, 3 > MCDwarfDirs
Definition MCDwarf.h:280
LLVM_ABI std::pair< MCSymbol *, MCSymbol * > Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params, std::optional< MCDwarfLineStr > &LineStr) const
Definition MCDwarf.cpp:344
StringMap< unsigned > SourceIdMap
Definition MCDwarf.h:282
LLVM_ABI Expected< unsigned > tryGetFile(StringRef &Directory, StringRef &FileName, std::optional< MD5::MD5Result > Checksum, std::optional< StringRef > Source, uint16_t DwarfVersion, unsigned FileNumber=0)
Definition MCDwarf.cpp:647
uint8_t DWARF2LineOpcodeBase
First special line opcode - leave room for the standard opcodes.
Definition MCDwarf.h:270
uint8_t DWARF2LineRange
Range of line offsets in a special line info. opcode.
Definition MCDwarf.h:275
int8_t DWARF2LineBase
Minimum line offset in a special line info.
Definition MCDwarf.h:273