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");
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 (FileNumber == 0) {
665 if (DwarfVersion >= 5 &&
666 isRootFile(RootFile, Directory, FileName, Checksum))
667 return 0;
668 // File numbers start with 1 and/or after any file numbers
669 // allocated by inline-assembler .file directives.
670 FileNumber = MCDwarfFiles.empty() ? 1 : MCDwarfFiles.size();
671 SmallString<256> Buffer;
672 auto IterBool = SourceIdMap.insert(
673 std::make_pair((Directory + Twine('\0') + FileName).toStringRef(Buffer),
674 FileNumber));
675 if (!IterBool.second)
676 return IterBool.first->second;
677 }
678 // Make space for this FileNumber in the MCDwarfFiles vector if needed.
679 if (FileNumber >= MCDwarfFiles.size())
680 MCDwarfFiles.resize(FileNumber + 1);
681
682 // Get the new MCDwarfFile slot for this FileNumber.
683 MCDwarfFile &File = MCDwarfFiles[FileNumber];
684
685 // It is an error to see the same number more than once.
686 if (!File.Name.empty())
687 return make_error<StringError>("file number already allocated",
689
690 if (Directory.empty()) {
691 // Separate the directory part from the basename of the FileName.
692 StringRef tFileName = sys::path::filename(FileName);
693 if (!tFileName.empty()) {
694 Directory = sys::path::parent_path(FileName);
695 if (!Directory.empty())
696 FileName = tFileName;
697 }
698 }
699
700 // Find or make an entry in the MCDwarfDirs vector for this Directory.
701 // Capture directory name.
702 unsigned DirIndex;
703 if (Directory.empty()) {
704 // For FileNames with no directories a DirIndex of 0 is used.
705 DirIndex = 0;
706 } else {
707 DirIndex = llvm::find(MCDwarfDirs, Directory) - MCDwarfDirs.begin();
708 if (DirIndex >= MCDwarfDirs.size())
709 MCDwarfDirs.push_back(std::string(Directory));
710 // The DirIndex is one based, as DirIndex of 0 is used for FileNames with
711 // no directories. MCDwarfDirs[] is unlike MCDwarfFiles[] in that the
712 // directory names are stored at MCDwarfDirs[DirIndex-1] where FileNames
713 // are stored at MCDwarfFiles[FileNumber].Name .
714 DirIndex++;
715 }
716
717 File.Name = std::string(FileName);
718 File.DirIndex = DirIndex;
719 File.Checksum = Checksum;
720 trackMD5Usage(Checksum.has_value());
721 File.Source = Source;
722 if (Source.has_value())
723 HasAnySource = true;
724
725 // return the allocated FileNumber.
726 return FileNumber;
727}
728
729/// Utility function to emit the encoding to a streamer.
731 int64_t LineDelta, uint64_t AddrDelta) {
732 MCContext &Context = MCOS->getContext();
734 MCDwarfLineAddr::encode(Context, Params, LineDelta, AddrDelta, Tmp);
735 MCOS->emitBytes(Tmp);
736}
737
738/// Given a special op, return the address skip amount (in units of
739/// DWARF2_LINE_MIN_INSN_LENGTH).
741 return (op - Params.DWARF2LineOpcodeBase) / Params.DWARF2LineRange;
742}
743
744/// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas.
746 int64_t LineDelta, uint64_t AddrDelta,
748 uint64_t Temp, Opcode;
749 bool NeedCopy = false;
750
751 // The maximum address skip amount that can be encoded with a special op.
752 uint64_t MaxSpecialAddrDelta = SpecialAddr(Params, 255);
753
754 // Scale the address delta by the minimum instruction length.
755 AddrDelta = ScaleAddrDelta(Context, AddrDelta);
756
757 // A LineDelta of INT64_MAX is a signal that this is actually a
758 // DW_LNE_end_sequence. We cannot use special opcodes here, since we want the
759 // end_sequence to emit the matrix entry.
760 if (LineDelta == INT64_MAX) {
761 if (AddrDelta == MaxSpecialAddrDelta)
762 Out.push_back(dwarf::DW_LNS_const_add_pc);
763 else if (AddrDelta) {
764 Out.push_back(dwarf::DW_LNS_advance_pc);
766 }
767 Out.push_back(dwarf::DW_LNS_extended_op);
768 Out.push_back(1);
769 Out.push_back(dwarf::DW_LNE_end_sequence);
770 return;
771 }
772
773 // Bias the line delta by the base.
774 Temp = LineDelta - Params.DWARF2LineBase;
775
776 // If the line increment is out of range of a special opcode, we must encode
777 // it with DW_LNS_advance_line.
778 if (Temp >= Params.DWARF2LineRange ||
779 Temp + Params.DWARF2LineOpcodeBase > 255) {
780 Out.push_back(dwarf::DW_LNS_advance_line);
781 appendLEB128<LEB128Sign::Signed>(Out, LineDelta);
782
783 LineDelta = 0;
784 Temp = 0 - Params.DWARF2LineBase;
785 NeedCopy = true;
786 }
787
788 // Use DW_LNS_copy instead of a "line +0, addr +0" special opcode.
789 if (LineDelta == 0 && AddrDelta == 0) {
790 Out.push_back(dwarf::DW_LNS_copy);
791 return;
792 }
793
794 // Bias the opcode by the special opcode base.
795 Temp += Params.DWARF2LineOpcodeBase;
796
797 // Avoid overflow when addr_delta is large.
798 if (AddrDelta < 256 + MaxSpecialAddrDelta) {
799 // Try using a special opcode.
800 Opcode = Temp + AddrDelta * Params.DWARF2LineRange;
801 if (Opcode <= 255) {
802 Out.push_back(Opcode);
803 return;
804 }
805
806 // Try using DW_LNS_const_add_pc followed by special op.
807 Opcode = Temp + (AddrDelta - MaxSpecialAddrDelta) * Params.DWARF2LineRange;
808 if (Opcode <= 255) {
809 Out.push_back(dwarf::DW_LNS_const_add_pc);
810 Out.push_back(Opcode);
811 return;
812 }
813 }
814
815 // Otherwise use DW_LNS_advance_pc.
816 Out.push_back(dwarf::DW_LNS_advance_pc);
818
819 if (NeedCopy)
820 Out.push_back(dwarf::DW_LNS_copy);
821 else {
822 assert(Temp <= 255 && "Buggy special opcode encoding.");
823 Out.push_back(Temp);
824 }
825}
826
827// Utility function to write a tuple for .debug_abbrev.
828static void EmitAbbrev(MCStreamer *MCOS, uint64_t Name, uint64_t Form) {
829 MCOS->emitULEB128IntValue(Name);
830 MCOS->emitULEB128IntValue(Form);
831}
832
833// When generating dwarf for assembly source files this emits
834// the data for .debug_abbrev section which contains three DIEs.
835static void EmitGenDwarfAbbrev(MCStreamer *MCOS) {
836 MCContext &context = MCOS->getContext();
838
839 // DW_TAG_compile_unit DIE abbrev (1).
840 MCOS->emitULEB128IntValue(1);
841 MCOS->emitULEB128IntValue(dwarf::DW_TAG_compile_unit);
843 dwarf::Form SecOffsetForm =
844 context.getDwarfVersion() >= 4
845 ? dwarf::DW_FORM_sec_offset
846 : (context.getDwarfFormat() == dwarf::DWARF64 ? dwarf::DW_FORM_data8
847 : dwarf::DW_FORM_data4);
848 EmitAbbrev(MCOS, dwarf::DW_AT_stmt_list, SecOffsetForm);
849 if (context.getGenDwarfSectionSyms().size() > 1 &&
850 context.getDwarfVersion() >= 3) {
851 EmitAbbrev(MCOS, dwarf::DW_AT_ranges, SecOffsetForm);
852 } else {
853 EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
854 EmitAbbrev(MCOS, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr);
855 }
856 EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
857 if (!context.getCompilationDir().empty())
858 EmitAbbrev(MCOS, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string);
859 StringRef DwarfDebugFlags = context.getDwarfDebugFlags();
860 if (!DwarfDebugFlags.empty())
861 EmitAbbrev(MCOS, dwarf::DW_AT_APPLE_flags, dwarf::DW_FORM_string);
862 EmitAbbrev(MCOS, dwarf::DW_AT_producer, dwarf::DW_FORM_string);
863
864 if (context.getDwarfVersion() >= 6)
865 EmitAbbrev(MCOS, dwarf::DW_AT_language_name, dwarf::DW_FORM_data2);
866 else
867 EmitAbbrev(MCOS, dwarf::DW_AT_language, dwarf::DW_FORM_data2);
868
869 EmitAbbrev(MCOS, 0, 0);
870
871 // DW_TAG_label DIE abbrev (2).
872 MCOS->emitULEB128IntValue(2);
873 MCOS->emitULEB128IntValue(dwarf::DW_TAG_label);
875 EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
876 EmitAbbrev(MCOS, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data4);
877 EmitAbbrev(MCOS, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data4);
878 EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
879 EmitAbbrev(MCOS, 0, 0);
880
881 // Terminate the abbreviations for this compilation unit.
882 MCOS->emitInt8(0);
883}
884
885// When generating dwarf for assembly source files this emits the data for
886// .debug_aranges section. This section contains a header and a table of pairs
887// of PointerSize'ed values for the address and size of section(s) with line
888// table entries.
890 const MCSymbol *InfoSectionSymbol) {
891 MCContext &context = MCOS->getContext();
892
893 auto &Sections = context.getGenDwarfSectionSyms();
894
896
897 unsigned UnitLengthBytes =
899 unsigned OffsetSize = dwarf::getDwarfOffsetByteSize(context.getDwarfFormat());
900
901 // This will be the length of the .debug_aranges section, first account for
902 // the size of each item in the header (see below where we emit these items).
903 int Length = UnitLengthBytes + 2 + OffsetSize + 1 + 1;
904
905 // Figure the padding after the header before the table of address and size
906 // pairs who's values are PointerSize'ed.
907 const MCAsmInfo &asmInfo = context.getAsmInfo();
908 int AddrSize = asmInfo.getCodePointerSize();
909 int Pad = 2 * AddrSize - (Length & (2 * AddrSize - 1));
910 if (Pad == 2 * AddrSize)
911 Pad = 0;
912 Length += Pad;
913
914 // Add the size of the pair of PointerSize'ed values for the address and size
915 // of each section we have in the table.
916 Length += 2 * AddrSize * Sections.size();
917 // And the pair of terminating zeros.
918 Length += 2 * AddrSize;
919
920 // Emit the header for this section.
921 if (context.getDwarfFormat() == dwarf::DWARF64)
922 // The DWARF64 mark.
924 // The 4 (8 for DWARF64) byte length not including the length of the unit
925 // length field itself.
926 MCOS->emitIntValue(Length - UnitLengthBytes, OffsetSize);
927 // The 2 byte version, which is 2.
928 MCOS->emitInt16(2);
929 // The 4 (8 for DWARF64) byte offset to the compile unit in the .debug_info
930 // from the start of the .debug_info.
931 if (InfoSectionSymbol)
932 MCOS->emitSymbolValue(InfoSectionSymbol, OffsetSize,
934 else
935 MCOS->emitIntValue(0, OffsetSize);
936 // The 1 byte size of an address.
937 MCOS->emitInt8(AddrSize);
938 // The 1 byte size of a segment descriptor, we use a value of zero.
939 MCOS->emitInt8(0);
940 // Align the header with the padding if needed, before we put out the table.
941 for(int i = 0; i < Pad; i++)
942 MCOS->emitInt8(0);
943
944 // Now emit the table of pairs of PointerSize'ed values for the section
945 // addresses and sizes.
946 for (MCSection *Sec : Sections) {
947 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
948 MCSymbol *EndSymbol = Sec->getEndSymbol(context);
949 assert(StartSymbol && "StartSymbol must not be NULL");
950 assert(EndSymbol && "EndSymbol must not be NULL");
951
952 const MCExpr *Addr = MCSymbolRefExpr::create(StartSymbol, context);
953 const MCExpr *Size =
954 makeEndMinusStartExpr(context, *StartSymbol, *EndSymbol, 0);
955 MCOS->emitValue(Addr, AddrSize);
956 emitAbsValue(*MCOS, Size, AddrSize);
957 }
958
959 // And finally the pair of terminating zeros.
960 MCOS->emitIntValue(0, AddrSize);
961 MCOS->emitIntValue(0, AddrSize);
962}
963
964// When generating dwarf for assembly source files this emits the data for
965// .debug_info section which contains three parts. The header, the compile_unit
966// DIE and a list of label DIEs.
967static void EmitGenDwarfInfo(MCStreamer *MCOS,
968 const MCSymbol *AbbrevSectionSymbol,
969 const MCSymbol *LineSectionSymbol,
970 const MCSymbol *RangesSymbol) {
971 MCContext &context = MCOS->getContext();
972
974
975 // Create a symbol at the start and end of this section used in here for the
976 // expression to calculate the length in the header.
977 MCSymbol *InfoStart = context.createTempSymbol();
978 MCOS->emitLabel(InfoStart);
979 MCSymbol *InfoEnd = context.createTempSymbol();
980
981 // First part: the header.
982
983 unsigned UnitLengthBytes =
985 unsigned OffsetSize = dwarf::getDwarfOffsetByteSize(context.getDwarfFormat());
986
987 if (context.getDwarfFormat() == dwarf::DWARF64)
988 // Emit DWARF64 mark.
990
991 // The 4 (8 for DWARF64) byte total length of the information for this
992 // compilation unit, not including the unit length field itself.
993 const MCExpr *Length =
994 makeEndMinusStartExpr(context, *InfoStart, *InfoEnd, UnitLengthBytes);
995 emitAbsValue(*MCOS, Length, OffsetSize);
996
997 // The 2 byte DWARF version.
998 MCOS->emitInt16(context.getDwarfVersion());
999
1000 // The DWARF v5 header has unit type, address size, abbrev offset.
1001 // Earlier versions have abbrev offset, address size.
1002 const MCAsmInfo &AsmInfo = context.getAsmInfo();
1003 int AddrSize = AsmInfo.getCodePointerSize();
1004 if (context.getDwarfVersion() >= 5) {
1005 MCOS->emitInt8(dwarf::DW_UT_compile);
1006 MCOS->emitInt8(AddrSize);
1007 }
1008 // The 4 (8 for DWARF64) byte offset to the debug abbrevs from the start of
1009 // the .debug_abbrev.
1010 if (AbbrevSectionSymbol)
1011 MCOS->emitSymbolValue(AbbrevSectionSymbol, OffsetSize,
1013 else
1014 // Since the abbrevs are at the start of the section, the offset is zero.
1015 MCOS->emitIntValue(0, OffsetSize);
1016 if (context.getDwarfVersion() <= 4)
1017 MCOS->emitInt8(AddrSize);
1018
1019 // Second part: the compile_unit DIE.
1020
1021 // The DW_TAG_compile_unit DIE abbrev (1).
1022 MCOS->emitULEB128IntValue(1);
1023
1024 // DW_AT_stmt_list, a 4 (8 for DWARF64) byte offset from the start of the
1025 // .debug_line section.
1026 if (LineSectionSymbol)
1027 MCOS->emitSymbolValue(LineSectionSymbol, OffsetSize,
1029 else
1030 // The line table is at the start of the section, so the offset is zero.
1031 MCOS->emitIntValue(0, OffsetSize);
1032
1033 if (RangesSymbol) {
1034 // There are multiple sections containing code, so we must use
1035 // .debug_ranges/.debug_rnglists. AT_ranges, the 4/8 byte offset from the
1036 // start of the .debug_ranges/.debug_rnglists.
1037 MCOS->emitSymbolValue(RangesSymbol, OffsetSize);
1038 } else {
1039 // If we only have one non-empty code section, we can use the simpler
1040 // AT_low_pc and AT_high_pc attributes.
1041
1042 // Find the first (and only) non-empty text section
1043 auto &Sections = context.getGenDwarfSectionSyms();
1044 const auto TextSection = Sections.begin();
1045 assert(TextSection != Sections.end() && "No text section found");
1046
1047 MCSymbol *StartSymbol = (*TextSection)->getBeginSymbol();
1048 MCSymbol *EndSymbol = (*TextSection)->getEndSymbol(context);
1049 assert(StartSymbol && "StartSymbol must not be NULL");
1050 assert(EndSymbol && "EndSymbol must not be NULL");
1051
1052 // AT_low_pc, the first address of the default .text section.
1053 const MCExpr *Start = MCSymbolRefExpr::create(StartSymbol, context);
1054 MCOS->emitValue(Start, AddrSize);
1055
1056 // AT_high_pc, the last address of the default .text section.
1057 const MCExpr *End = MCSymbolRefExpr::create(EndSymbol, context);
1058 MCOS->emitValue(End, AddrSize);
1059 }
1060
1061 // AT_name, the name of the source file. Reconstruct from the first directory
1062 // and file table entries.
1063 const SmallVectorImpl<std::string> &MCDwarfDirs = context.getMCDwarfDirs();
1064 if (MCDwarfDirs.size() > 0) {
1065 MCOS->emitBytes(MCDwarfDirs[0]);
1067 }
1068 const SmallVectorImpl<MCDwarfFile> &MCDwarfFiles = context.getMCDwarfFiles();
1069 // MCDwarfFiles might be empty if we have an empty source file.
1070 // If it's not empty, [0] is unused and [1] is the first actual file.
1071 assert(MCDwarfFiles.empty() || MCDwarfFiles.size() >= 2);
1072 const MCDwarfFile &RootFile =
1073 MCDwarfFiles.empty()
1074 ? context.getMCDwarfLineTable(/*CUID=*/0).getRootFile()
1075 : MCDwarfFiles[1];
1076 MCOS->emitBytes(RootFile.Name);
1077 MCOS->emitInt8(0); // NULL byte to terminate the string.
1078
1079 // AT_comp_dir, the working directory the assembly was done in.
1080 if (!context.getCompilationDir().empty()) {
1081 MCOS->emitBytes(context.getCompilationDir());
1082 MCOS->emitInt8(0); // NULL byte to terminate the string.
1083 }
1084
1085 // AT_APPLE_flags, the command line arguments of the assembler tool.
1086 StringRef DwarfDebugFlags = context.getDwarfDebugFlags();
1087 if (!DwarfDebugFlags.empty()){
1088 MCOS->emitBytes(DwarfDebugFlags);
1089 MCOS->emitInt8(0); // NULL byte to terminate the string.
1090 }
1091
1092 // AT_producer, the version of the assembler tool.
1093 StringRef DwarfDebugProducer = context.getDwarfDebugProducer();
1094 if (!DwarfDebugProducer.empty())
1095 MCOS->emitBytes(DwarfDebugProducer);
1096 else
1097 MCOS->emitBytes(StringRef("llvm-mc (based on LLVM " PACKAGE_VERSION ")"));
1098 MCOS->emitInt8(0); // NULL byte to terminate the string.
1099
1100 if (context.getDwarfVersion() >= 6) {
1101 // AT_language_name, a 4 byte value.
1102 MCOS->emitInt16(dwarf::DW_LNAME_Assembly);
1103 } else {
1104 // AT_language, a 4 byte value. We use DW_LANG_Mips_Assembler as the dwarf2
1105 // draft has no standard code for assembler.
1106 // FIXME: dwarf4 has DW_LANG_Assembly which we could use instead.
1107 MCOS->emitInt16(dwarf::DW_LANG_Mips_Assembler);
1108 }
1109
1110 // Third part: the list of label DIEs.
1111
1112 // Loop on saved info for dwarf labels and create the DIEs for them.
1113 const std::vector<MCGenDwarfLabelEntry> &Entries =
1115 for (const auto &Entry : Entries) {
1116 // The DW_TAG_label DIE abbrev (2).
1117 MCOS->emitULEB128IntValue(2);
1118
1119 // AT_name, of the label without any leading underbar.
1120 MCOS->emitBytes(Entry.getName());
1121 MCOS->emitInt8(0); // NULL byte to terminate the string.
1122
1123 // AT_decl_file, index into the file table.
1124 MCOS->emitInt32(Entry.getFileNumber());
1125
1126 // AT_decl_line, source line number.
1127 MCOS->emitInt32(Entry.getLineNumber());
1128
1129 // AT_low_pc, start address of the label.
1130 const auto *AT_low_pc = MCSymbolRefExpr::create(Entry.getLabel(), context);
1131 MCOS->emitValue(AT_low_pc, AddrSize);
1132 }
1133
1134 // Add the NULL DIE terminating the Compile Unit DIE's.
1135 MCOS->emitInt8(0);
1136
1137 // Now set the value of the symbol at the end of the info section.
1138 MCOS->emitLabel(InfoEnd);
1139}
1140
1141// When generating dwarf for assembly source files this emits the data for
1142// .debug_ranges section. We only emit one range list, which spans all of the
1143// executable sections of this file.
1145 MCContext &context = MCOS->getContext();
1146 auto &Sections = context.getGenDwarfSectionSyms();
1147
1148 const MCAsmInfo &AsmInfo = context.getAsmInfo();
1149 int AddrSize = AsmInfo.getCodePointerSize();
1150 MCSymbol *RangesSymbol;
1151
1152 if (MCOS->getContext().getDwarfVersion() >= 5) {
1154 MCSymbol *EndSymbol = mcdwarf::emitListsTableHeaderStart(*MCOS);
1155 MCOS->AddComment("Offset entry count");
1156 MCOS->emitInt32(0);
1157 RangesSymbol = context.createTempSymbol("debug_rnglist0_start");
1158 MCOS->emitLabel(RangesSymbol);
1159 for (MCSection *Sec : Sections) {
1160 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
1161 const MCSymbol *EndSymbol = Sec->getEndSymbol(context);
1162 const MCExpr *SectionStartAddr =
1163 MCSymbolRefExpr::create(StartSymbol, context);
1164 const MCExpr *SectionSize =
1165 makeEndMinusStartExpr(context, *StartSymbol, *EndSymbol, 0);
1166 MCOS->emitInt8(dwarf::DW_RLE_start_length);
1167 MCOS->emitValue(SectionStartAddr, AddrSize);
1168 MCOS->emitULEB128Value(SectionSize);
1169 }
1170 MCOS->emitInt8(dwarf::DW_RLE_end_of_list);
1171 MCOS->emitLabel(EndSymbol);
1172 } else {
1174 RangesSymbol = context.createTempSymbol("debug_ranges_start");
1175 MCOS->emitLabel(RangesSymbol);
1176 for (MCSection *Sec : Sections) {
1177 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
1178 const MCSymbol *EndSymbol = Sec->getEndSymbol(context);
1179
1180 // Emit a base address selection entry for the section start.
1181 const MCExpr *SectionStartAddr =
1182 MCSymbolRefExpr::create(StartSymbol, context);
1183 MCOS->emitFill(AddrSize, 0xFF);
1184 MCOS->emitValue(SectionStartAddr, AddrSize);
1185
1186 // Emit a range list entry spanning this section.
1187 const MCExpr *SectionSize =
1188 makeEndMinusStartExpr(context, *StartSymbol, *EndSymbol, 0);
1189 MCOS->emitIntValue(0, AddrSize);
1190 emitAbsValue(*MCOS, SectionSize, AddrSize);
1191 }
1192
1193 // Emit end of list entry
1194 MCOS->emitIntValue(0, AddrSize);
1195 MCOS->emitIntValue(0, AddrSize);
1196 }
1197
1198 return RangesSymbol;
1199}
1200
1201//
1202// When generating dwarf for assembly source files this emits the Dwarf
1203// sections.
1204//
1206 MCContext &context = MCOS->getContext();
1207
1208 // Create the dwarf sections in this order (.debug_line already created).
1209 const MCAsmInfo &AsmInfo = context.getAsmInfo();
1210 bool CreateDwarfSectionSymbols =
1212 MCSymbol *LineSectionSymbol = nullptr;
1213 if (CreateDwarfSectionSymbols)
1214 LineSectionSymbol = MCOS->getDwarfLineTableSymbol(0);
1215 MCSymbol *AbbrevSectionSymbol = nullptr;
1216 MCSymbol *InfoSectionSymbol = nullptr;
1217 MCSymbol *RangesSymbol = nullptr;
1218
1219 // Create end symbols for each section, and remove empty sections
1220 MCOS->getContext().finalizeDwarfSections(*MCOS);
1221
1222 // If there are no sections to generate debug info for, we don't need
1223 // to do anything
1224 if (MCOS->getContext().getGenDwarfSectionSyms().empty())
1225 return;
1226
1227 // We only use the .debug_ranges section if we have multiple code sections,
1228 // and we are emitting a DWARF version which supports it.
1229 const bool UseRangesSection =
1230 MCOS->getContext().getGenDwarfSectionSyms().size() > 1 &&
1231 MCOS->getContext().getDwarfVersion() >= 3;
1232 CreateDwarfSectionSymbols |= UseRangesSection;
1233
1235 if (CreateDwarfSectionSymbols) {
1236 InfoSectionSymbol = context.createTempSymbol();
1237 MCOS->emitLabel(InfoSectionSymbol);
1238 }
1240 if (CreateDwarfSectionSymbols) {
1241 AbbrevSectionSymbol = context.createTempSymbol();
1242 MCOS->emitLabel(AbbrevSectionSymbol);
1243 }
1244
1246
1247 // Output the data for .debug_aranges section.
1248 EmitGenDwarfAranges(MCOS, InfoSectionSymbol);
1249
1250 if (UseRangesSection) {
1251 RangesSymbol = emitGenDwarfRanges(MCOS);
1252 assert(RangesSymbol);
1253 }
1254
1255 // Output the data for .debug_abbrev section.
1256 EmitGenDwarfAbbrev(MCOS);
1257
1258 // Output the data for .debug_info section.
1259 EmitGenDwarfInfo(MCOS, AbbrevSectionSymbol, LineSectionSymbol, RangesSymbol);
1260}
1261
1262//
1263// When generating dwarf for assembly source files this is called when symbol
1264// for a label is created. If this symbol is not a temporary and is in the
1265// section that dwarf is being generated for, save the needed info to create
1266// a dwarf label.
1267//
1270 // We won't create dwarf labels for temporary symbols.
1271 if (Symbol->isTemporary())
1272 return;
1273 MCContext &context = MCOS->getContext();
1274 // We won't create dwarf labels for symbols in sections that we are not
1275 // generating debug info for.
1276 if (!context.getGenDwarfSectionSyms().count(MCOS->getCurrentSectionOnly()))
1277 return;
1278
1279 // The dwarf label's name does not have the symbol name's leading
1280 // underbar if any.
1281 StringRef Name = Symbol->getName();
1282 if (Name.starts_with("_"))
1283 Name = Name.substr(1, Name.size()-1);
1284
1285 // Get the dwarf file number to be used for the dwarf label.
1286 unsigned FileNumber = context.getGenDwarfFileNumber();
1287
1288 // Finding the line number is the expensive part which is why we just don't
1289 // pass it in as for some symbols we won't create a dwarf label.
1290 unsigned CurBuffer = SrcMgr.FindBufferContainingLoc(Loc);
1291 unsigned LineNumber = SrcMgr.FindLineNumber(Loc, CurBuffer);
1292
1293 // We create a temporary symbol for use for the AT_high_pc and AT_low_pc
1294 // values so that they don't have things like an ARM thumb bit from the
1295 // original symbol. So when used they won't get a low bit set after
1296 // relocation.
1297 MCSymbol *Label = context.createTempSymbol();
1298 MCOS->emitLabel(Label);
1299
1300 // Create and entry for the info and add it to the other entries.
1302 MCGenDwarfLabelEntry(Name, FileNumber, LineNumber, Label));
1303}
1304
1305void MCCFIInstruction::replaceRegister(unsigned FromReg, unsigned ToReg) {
1306 auto ReplaceReg = [=](unsigned &Reg) {
1307 if (Reg == FromReg)
1308 Reg = ToReg;
1309 };
1310 auto Visitor = makeVisitor(
1311 [=](CommonFields &F) {
1312 ReplaceReg(F.Register);
1313 ReplaceReg(F.Register2);
1314 },
1315 [](EscapeFields &) {}, [](LabelFields &) {},
1316 [=](RegisterPairFields &F) {
1317 ReplaceReg(F.Register);
1318 ReplaceReg(F.Reg1);
1319 ReplaceReg(F.Reg2);
1320 },
1321 [=](VectorRegistersFields &F) {
1322 ReplaceReg(F.Register);
1323 for (VectorRegisterWithLane &VRL : F.VectorRegisters)
1324 ReplaceReg(VRL.Register);
1325 },
1326 [=](VectorOffsetFields &F) {
1327 ReplaceReg(F.Register);
1328 ReplaceReg(F.MaskRegister);
1329 },
1331 ReplaceReg(F.Register);
1332 ReplaceReg(F.SpillRegister);
1333 ReplaceReg(F.MaskRegister);
1334 },
1335 [](LLVMSetRAStateFields &) {
1336 llvm_unreachable(".cfi_set_ra_state does not have registers");
1337 });
1338 std::visit(Visitor, ExtraFields);
1339}
1340
1341static int getDataAlignmentFactor(MCStreamer &streamer) {
1342 MCContext &context = streamer.getContext();
1343 const MCAsmInfo &asmInfo = context.getAsmInfo();
1344 int size = asmInfo.getCalleeSaveStackSlotSize();
1345 if (asmInfo.isStackGrowthDirectionUp())
1346 return size;
1347 else
1348 return -size;
1349}
1350
1351static unsigned getSizeForEncoding(MCStreamer &streamer,
1352 unsigned symbolEncoding) {
1353 MCContext &context = streamer.getContext();
1354 unsigned format = symbolEncoding & 0x0f;
1355 switch (format) {
1356 default: llvm_unreachable("Unknown Encoding");
1359 return context.getAsmInfo().getCodePointerSize();
1362 return 2;
1365 return 4;
1368 return 8;
1369 }
1370}
1371
1372static void emitFDESymbol(MCObjectStreamer &streamer, const MCSymbol &symbol,
1373 unsigned symbolEncoding, bool isEH) {
1374 MCContext &context = streamer.getContext();
1375 const MCAsmInfo &asmInfo = context.getAsmInfo();
1376 const MCExpr *v =
1377 asmInfo.getExprForFDESymbol(&symbol, symbolEncoding, streamer);
1378 unsigned size = getSizeForEncoding(streamer, symbolEncoding);
1379 if (asmInfo.doDwarfFDESymbolsUseAbsDiff() && isEH)
1380 emitAbsValue(streamer, v, size);
1381 else
1382 streamer.emitValue(v, size);
1383}
1384
1385static void EmitPersonality(MCStreamer &streamer, const MCSymbol &symbol,
1386 unsigned symbolEncoding) {
1387 MCContext &context = streamer.getContext();
1388 const MCAsmInfo &asmInfo = context.getAsmInfo();
1389 const MCExpr *v =
1390 asmInfo.getExprForPersonalitySymbol(&symbol, symbolEncoding, streamer);
1391 unsigned size = getSizeForEncoding(streamer, symbolEncoding);
1392 streamer.emitValue(v, size);
1393}
1394
1395namespace {
1396
1397class FrameEmitterImpl {
1398 int64_t CFAOffset = 0;
1399 int64_t InitialCFAOffset = 0;
1400 SmallVector<int64_t, 0> SavedCFAOffsets;
1401 bool IsEH;
1402 MCObjectStreamer &Streamer;
1403
1404public:
1405 FrameEmitterImpl(bool IsEH, MCObjectStreamer &Streamer)
1406 : IsEH(IsEH), Streamer(Streamer) {}
1407
1408 /// Emit the unwind information in a compact way.
1409 void EmitCompactUnwind(const MCDwarfFrameInfo &frame);
1410
1411 const MCSymbol &EmitCIE(const MCDwarfFrameInfo &F);
1412 void EmitFDE(const MCSymbol &cieStart, const MCDwarfFrameInfo &frame,
1413 bool LastInSection, const MCSymbol &SectionStart);
1414 void emitCFIInstructions(ArrayRef<MCCFIInstruction> Instrs,
1415 MCSymbol *BaseLabel);
1416 void emitCFIInstruction(const MCCFIInstruction &Instr);
1417};
1418
1419} // end anonymous namespace
1420
1421static void emitEncodingByte(MCObjectStreamer &Streamer, unsigned Encoding) {
1422 Streamer.emitInt8(Encoding);
1423}
1424
1425static void encodeDwarfRegisterLocation(int DwarfReg, raw_ostream &OS) {
1426 assert(DwarfReg >= 0);
1427 if (DwarfReg < 32) {
1428 OS << uint8_t(dwarf::DW_OP_reg0 + DwarfReg);
1429 } else {
1430 OS << uint8_t(dwarf::DW_OP_regx);
1431 encodeULEB128(DwarfReg, OS);
1432 }
1433}
1434
1435void FrameEmitterImpl::emitCFIInstruction(const MCCFIInstruction &Instr) {
1436 int dataAlignmentFactor = getDataAlignmentFactor(Streamer);
1437 auto *MRI = Streamer.getContext().getRegisterInfo();
1438
1439 switch (Instr.getOperation()) {
1441 unsigned Reg1 = Instr.getRegister();
1442 unsigned Reg2 = Instr.getRegister2();
1443 if (!IsEH) {
1444 Reg1 = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg1);
1445 Reg2 = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg2);
1446 }
1447 Streamer.emitInt8(dwarf::DW_CFA_register);
1448 Streamer.emitULEB128IntValue(Reg1);
1449 Streamer.emitULEB128IntValue(Reg2);
1450 return;
1451 }
1453 Streamer.emitInt8(dwarf::DW_CFA_GNU_window_save);
1454 return;
1455
1457 Streamer.emitInt8(dwarf::DW_CFA_AARCH64_negate_ra_state);
1458 return;
1459
1461 Streamer.emitInt8(dwarf::DW_CFA_AARCH64_negate_ra_state_with_pc);
1462 return;
1463
1465 Streamer.emitInt8(dwarf::DW_CFA_AARCH64_set_ra_state);
1466 Streamer.emitULEB128IntValue(Instr.getRASignState());
1467 if (MCSymbol *PACSym = Instr.getRASignSymbol()) {
1468 MCContext &Ctx = Streamer.getContext();
1469 const MCExpr *Diff = MCBinaryExpr::createSub(
1470 MCSymbolRefExpr::create(PACSym, Ctx),
1471 MCSymbolRefExpr::create(Instr.getLabel(), Ctx), Ctx);
1472 const MCExpr *Factored = MCBinaryExpr::createDiv(
1473 Diff,
1475 Ctx);
1476 Streamer.emitSLEB128Value(Factored);
1477 } else {
1478 Streamer.emitSLEB128IntValue(Instr.getRASignOffset());
1479 }
1480 return;
1481 }
1483 unsigned Reg = Instr.getRegister();
1484 Streamer.emitInt8(dwarf::DW_CFA_undefined);
1485 Streamer.emitULEB128IntValue(Reg);
1486 return;
1487 }
1490 const bool IsRelative =
1492
1493 Streamer.emitInt8(dwarf::DW_CFA_def_cfa_offset);
1494
1495 if (IsRelative)
1496 CFAOffset += Instr.getOffset();
1497 else
1498 CFAOffset = Instr.getOffset();
1499
1500 Streamer.emitULEB128IntValue(CFAOffset);
1501
1502 return;
1503 }
1505 unsigned Reg = Instr.getRegister();
1506 if (!IsEH)
1507 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1508 Streamer.emitInt8(dwarf::DW_CFA_def_cfa);
1509 Streamer.emitULEB128IntValue(Reg);
1510 CFAOffset = Instr.getOffset();
1511 Streamer.emitULEB128IntValue(CFAOffset);
1512
1513 return;
1514 }
1516 unsigned Reg = Instr.getRegister();
1517 if (!IsEH)
1518 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1519 Streamer.emitInt8(dwarf::DW_CFA_def_cfa_register);
1520 Streamer.emitULEB128IntValue(Reg);
1521
1522 return;
1523 }
1524 // TODO: Implement `_sf` variants if/when they need to be emitted.
1526 unsigned Reg = Instr.getRegister();
1527 if (!IsEH)
1528 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1529 Streamer.emitIntValue(dwarf::DW_CFA_LLVM_def_aspace_cfa, 1);
1530 Streamer.emitULEB128IntValue(Reg);
1531 CFAOffset = Instr.getOffset();
1532 Streamer.emitULEB128IntValue(CFAOffset);
1533 Streamer.emitULEB128IntValue(Instr.getAddressSpace());
1534
1535 return;
1536 }
1539 const bool IsRelative =
1540 Instr.getOperation() == MCCFIInstruction::OpRelOffset;
1541
1542 unsigned Reg = Instr.getRegister();
1543 if (!IsEH)
1544 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1545
1546 int64_t Offset = Instr.getOffset();
1547 if (IsRelative)
1548 Offset -= CFAOffset;
1549 Offset = Offset / dataAlignmentFactor;
1550
1551 if (Offset < 0) {
1552 Streamer.emitInt8(dwarf::DW_CFA_offset_extended_sf);
1553 Streamer.emitULEB128IntValue(Reg);
1554 Streamer.emitSLEB128IntValue(Offset);
1555 } else if (Reg < 64) {
1556 Streamer.emitInt8(dwarf::DW_CFA_offset + Reg);
1557 Streamer.emitULEB128IntValue(Offset);
1558 } else {
1559 Streamer.emitInt8(dwarf::DW_CFA_offset_extended);
1560 Streamer.emitULEB128IntValue(Reg);
1561 Streamer.emitULEB128IntValue(Offset);
1562 }
1563 return;
1564 }
1566 Streamer.emitInt8(dwarf::DW_CFA_remember_state);
1567 SavedCFAOffsets.push_back(CFAOffset);
1568 return;
1570 Streamer.emitInt8(dwarf::DW_CFA_restore_state);
1571 CFAOffset = SavedCFAOffsets.pop_back_val();
1572 return;
1574 unsigned Reg = Instr.getRegister();
1575 Streamer.emitInt8(dwarf::DW_CFA_same_value);
1576 Streamer.emitULEB128IntValue(Reg);
1577 return;
1578 }
1580 unsigned Reg = Instr.getRegister();
1581 if (!IsEH)
1582 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1583 if (Reg < 64) {
1584 Streamer.emitInt8(dwarf::DW_CFA_restore | Reg);
1585 } else {
1586 Streamer.emitInt8(dwarf::DW_CFA_restore_extended);
1587 Streamer.emitULEB128IntValue(Reg);
1588 }
1589 return;
1590 }
1592 Streamer.emitInt8(dwarf::DW_CFA_GNU_args_size);
1593 Streamer.emitULEB128IntValue(Instr.getOffset());
1594 return;
1595
1597 Streamer.emitBytes(Instr.getValues());
1598 return;
1599
1601 Streamer.emitLabel(Instr.getCfiLabel(), Instr.getLoc());
1602 return;
1604 unsigned Reg = Instr.getRegister();
1605 if (!IsEH)
1606 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1607
1608 int64_t Offset = Instr.getOffset();
1609 Offset = Offset / dataAlignmentFactor;
1610
1611 if (Offset < 0) {
1612 Streamer.emitInt8(dwarf::DW_CFA_val_offset_sf);
1613 Streamer.emitULEB128IntValue(Reg);
1614 Streamer.emitSLEB128IntValue(Offset);
1615 } else {
1616 Streamer.emitInt8(dwarf::DW_CFA_val_offset);
1617 Streamer.emitULEB128IntValue(Reg);
1618 Streamer.emitULEB128IntValue(Offset);
1619 }
1620 return;
1621 }
1623 // CFI for a register spilled to a pair of SGPRs is implemented as an
1624 // expression(E) rule where E is a composite location description with
1625 // multiple parts each referencing SGPR register location storage with a bit
1626 // offset of 0. In other words we generate the following DWARF:
1627 //
1628 // DW_CFA_expression: <Reg>,
1629 // (DW_OP_regx <SGPRPair[0]>) (DW_OP_piece <Size>)
1630 // (DW_OP_regx <SGPRPair[1]>) (DW_OP_piece <Size>)
1631 //
1632 // The memory location description for the current CFA is pushed on the
1633 // stack before E is evaluated, but we choose not to drop it as it would
1634 // require a longer expression E and DWARF defines the result of the
1635 // evaulation to be the location description on the top of the stack (i.e.
1636 // the implictly pushed one is just ignored.)
1637
1638 const auto &Fields =
1640
1642 raw_svector_ostream OSBlock(Block);
1643 encodeDwarfRegisterLocation(Fields.Reg1, OSBlock);
1644 if (Fields.Reg1SizeInBits % 8 == 0) {
1645 OSBlock << uint8_t(dwarf::DW_OP_piece);
1646 encodeULEB128(Fields.Reg1SizeInBits / 8, OSBlock);
1647 } else {
1648 OSBlock << uint8_t(dwarf::DW_OP_bit_piece);
1649 encodeULEB128(Fields.Reg1SizeInBits, OSBlock);
1650 encodeULEB128(0, OSBlock);
1651 }
1652 encodeDwarfRegisterLocation(Fields.Reg2, OSBlock);
1653 if (Fields.Reg2SizeInBits % 8 == 0) {
1654 OSBlock << uint8_t(dwarf::DW_OP_piece);
1655 encodeULEB128(Fields.Reg2SizeInBits / 8, OSBlock);
1656 } else {
1657 OSBlock << uint8_t(dwarf::DW_OP_bit_piece);
1658 encodeULEB128(Fields.Reg2SizeInBits, OSBlock);
1659 encodeULEB128(0, OSBlock);
1660 }
1661
1662 Streamer.emitInt8(dwarf::DW_CFA_expression);
1663 Streamer.emitULEB128IntValue(Fields.Register);
1664 Streamer.emitULEB128IntValue(Block.size());
1665 Streamer.emitBinaryData(StringRef(&Block[0], Block.size()));
1666 return;
1667 }
1669 // CFI for an SGPR spilled to a multiple lanes of VGPRs is implemented as an
1670 // expression(E) rule where E is a composite location description with
1671 // multiple parts each referencing VGPR register location storage with a bit
1672 // offset of the lane index multiplied by the size of a lane. In other words
1673 // we generate the following DWARF:
1674 //
1675 // DW_CFA_expression: <SGPR>,
1676 // (DW_OP_regx <VGPR[0]>) (DW_OP_bit_piece <Size>, <Lane[0]>*<Size>)
1677 // (DW_OP_regx <VGPR[1]>) (DW_OP_bit_piece <Size>, <Lane[1]>*<Size>)
1678 // ...
1679 // (DW_OP_regx <VGPR[N]>) (DW_OP_bit_piece <Size>, <Lane[N]>*<Size>)
1680 //
1681 // However if we're only using a single lane then we can emit a slightly
1682 // more optimal form:
1683 //
1684 // DW_CFA_expression: <SGPR>,
1685 // (DW_OP_regx <VGPR[0]>) (DW_OP_LLVM_offset_uconst <Lane[0]>*<Size>)
1686 //
1687 // The memory location description for the current CFA is pushed on the
1688 // stack before E is evaluated, but we choose not to drop it as it would
1689 // require a longer expression E and DWARF defines the result of the
1690 // evaulation to be the location description on the top of the stack (i.e.
1691 // the implictly pushed one is just ignored.)
1692
1693 const auto &Fields =
1695 auto &VRs = Fields.VectorRegisters;
1696
1698 raw_svector_ostream OSBlock(Block);
1699
1700 if (VRs.size() == 1 && VRs[0].SizeInBits % 8 == 0) {
1701 encodeDwarfRegisterLocation(VRs[0].Register, OSBlock);
1702 OSBlock << uint8_t(dwarf::DW_OP_LLVM_user)
1703 << uint8_t(dwarf::DW_OP_LLVM_offset_uconst);
1704 encodeULEB128(static_cast<uint64_t>(VRs[0].SizeInBits / 8) * VRs[0].Lane,
1705 OSBlock);
1706 } else {
1707 for (const auto &VR : VRs) {
1708 // TODO: Detect when we can merge multiple adjacent pieces, or even
1709 // reduce this to a register location description (when all pieces are
1710 // adjacent).
1711 encodeDwarfRegisterLocation(VR.Register, OSBlock);
1712 OSBlock << uint8_t(dwarf::DW_OP_bit_piece);
1713 encodeULEB128(VR.SizeInBits, OSBlock);
1714 encodeULEB128(static_cast<uint64_t>(VR.SizeInBits) * VR.Lane, OSBlock);
1715 }
1716 }
1717
1718 Streamer.emitInt8(dwarf::DW_CFA_expression);
1719 Streamer.emitULEB128IntValue(Fields.Register);
1720 Streamer.emitULEB128IntValue(Block.size());
1721 Streamer.emitBinaryData(StringRef(&Block[0], Block.size()));
1722 return;
1723 }
1725 // CFI for a vector register spilled to memory is implemented as an
1726 // expression(E) rule where E is a location description.
1727 //
1728 // DW_CFA_expression: <VGPR>,
1729 // (DW_OP_regx <VGPR>)
1730 // (DW_OP_swap)
1731 // (DW_OP_LLVM_offset_uconst <Offset>)
1732 // (DW_OP_LLVM_call_frame_entry_reg <Mask>)
1733 // (DW_OP_deref_size <MaskSize>)
1734 // (DW_OP_LLVM_select_bit_piece <VGPRSize> <MaskSize>)
1735
1736 const auto &Fields =
1738
1740 raw_svector_ostream OSBlock(Block);
1741 encodeDwarfRegisterLocation(Fields.Register, OSBlock);
1742 OSBlock << uint8_t(dwarf::DW_OP_swap);
1743 OSBlock << uint8_t(dwarf::DW_OP_LLVM_user)
1744 << uint8_t(dwarf::DW_OP_LLVM_offset_uconst);
1745 encodeULEB128(Fields.Offset, OSBlock);
1746 OSBlock << uint8_t(dwarf::DW_OP_LLVM_user)
1747 << uint8_t(dwarf::DW_OP_LLVM_call_frame_entry_reg);
1748 encodeULEB128(Fields.MaskRegister, OSBlock);
1749 OSBlock << uint8_t(dwarf::DW_OP_deref_size);
1750 OSBlock << uint8_t(Fields.MaskRegisterSizeInBits / 8);
1751 OSBlock << uint8_t(dwarf::DW_OP_LLVM_user)
1752 << uint8_t(dwarf::DW_OP_LLVM_select_bit_piece);
1753 encodeULEB128(Fields.RegisterSizeInBits, OSBlock);
1754 encodeULEB128(Fields.MaskRegisterSizeInBits, OSBlock);
1755
1756 Streamer.emitInt8(dwarf::DW_CFA_expression);
1757 Streamer.emitULEB128IntValue(Fields.Register);
1758 Streamer.emitULEB128IntValue(Block.size());
1759 Streamer.emitBinaryData(StringRef(&Block[0], Block.size()));
1760 return;
1761 }
1763 // CFI for a VGPR/AGPR partially spilled to another VGPR/AGPR dependent on
1764 // an EXEC mask is implemented as an expression(E) rule where E is a
1765 // location description.
1766 //
1767 // DW_CFA_expression: <GPR>,
1768 // (DW_OP_regx <GPR>)
1769 // (DW_OP_regx <Spill GPR>)
1770 // (DW_OP_LLVM_call_frame_entry_reg <Mask>)
1771 // (DW_OP_deref_size <MaskSize>)
1772 // (DW_OP_LLVM_select_bit_piece <GPR lane size> <MaskSize>)
1773
1774 const auto Fields =
1776
1778 raw_svector_ostream OSBlock(Block);
1779 encodeDwarfRegisterLocation(Fields.Register, OSBlock);
1780 encodeDwarfRegisterLocation(Fields.SpillRegister, OSBlock);
1781 OSBlock << uint8_t(dwarf::DW_OP_LLVM_user)
1782 << uint8_t(dwarf::DW_OP_LLVM_call_frame_entry_reg);
1783 encodeULEB128(Fields.MaskRegister, OSBlock);
1784 OSBlock << uint8_t(dwarf::DW_OP_deref_size)
1785 << uint8_t(Fields.MaskRegisterSizeInBits / 8);
1786 OSBlock << uint8_t(dwarf::DW_OP_LLVM_user)
1787 << uint8_t(dwarf::DW_OP_LLVM_select_bit_piece);
1788 encodeULEB128(Fields.SpillRegisterLaneSizeInBits, OSBlock);
1789 encodeULEB128(Fields.MaskRegisterSizeInBits, OSBlock);
1790
1791 Streamer.emitInt8(dwarf::DW_CFA_expression);
1792 Streamer.emitULEB128IntValue(Fields.Register);
1793 Streamer.emitULEB128IntValue(Block.size());
1794 Streamer.emitBinaryData(StringRef(&Block[0], Block.size()));
1795 return;
1796 }
1797 }
1798
1799 llvm_unreachable("Unhandled case in switch");
1800}
1801
1802/// Emit frame instructions to describe the layout of the frame.
1803void FrameEmitterImpl::emitCFIInstructions(ArrayRef<MCCFIInstruction> Instrs,
1804 MCSymbol *BaseLabel) {
1805 for (const MCCFIInstruction &Instr : Instrs) {
1806 MCSymbol *Label = Instr.getLabel();
1807 // Throw out move if the label is invalid.
1808 if (Label && !Label->isDefined()) continue; // Not emitted, in dead code.
1809
1810 // Advance row if new location.
1811 if (BaseLabel && Label) {
1812 MCSymbol *ThisSym = Label;
1813 if (ThisSym != BaseLabel) {
1814 Streamer.emitDwarfAdvanceFrameAddr(BaseLabel, ThisSym, Instr.getLoc());
1815 BaseLabel = ThisSym;
1816 }
1817 }
1818
1819 emitCFIInstruction(Instr);
1820 }
1821}
1822
1823/// Emit the unwind information in a compact way.
1824void FrameEmitterImpl::EmitCompactUnwind(const MCDwarfFrameInfo &Frame) {
1825 MCContext &Context = Streamer.getContext();
1826 const MCObjectFileInfo *MOFI = Context.getObjectFileInfo();
1827
1828 // range-start range-length compact-unwind-enc personality-func lsda
1829 // _foo LfooEnd-_foo 0x00000023 0 0
1830 // _bar LbarEnd-_bar 0x00000025 __gxx_personality except_tab1
1831 //
1832 // .section __LD,__compact_unwind,regular,debug
1833 //
1834 // # compact unwind for _foo
1835 // .quad _foo
1836 // .set L1,LfooEnd-_foo
1837 // .long L1
1838 // .long 0x01010001
1839 // .quad 0
1840 // .quad 0
1841 //
1842 // # compact unwind for _bar
1843 // .quad _bar
1844 // .set L2,LbarEnd-_bar
1845 // .long L2
1846 // .long 0x01020011
1847 // .quad __gxx_personality
1848 // .quad except_tab1
1849
1850 uint32_t Encoding = Frame.CompactUnwindEncoding;
1851 if (!Encoding) return;
1852 bool DwarfEHFrameOnly = (Encoding == MOFI->getCompactUnwindDwarfEHFrameOnly());
1853
1854 // The encoding needs to know we have an LSDA.
1855 if (!DwarfEHFrameOnly && Frame.Lsda)
1856 Encoding |= 0x40000000;
1857
1858 // Range Start
1859 unsigned FDEEncoding = MOFI->getFDEEncoding();
1860 unsigned Size = getSizeForEncoding(Streamer, FDEEncoding);
1861 Streamer.emitSymbolValue(Frame.Begin, Size);
1862
1863 // Range Length
1864 const MCExpr *Range =
1865 makeEndMinusStartExpr(Context, *Frame.Begin, *Frame.End, 0);
1867
1868 // Compact Encoding
1870 Streamer.emitIntValue(Encoding, Size);
1871
1872 // Personality Function
1874 if (!DwarfEHFrameOnly && Frame.Personality)
1875 Streamer.emitSymbolValue(Frame.Personality, Size);
1876 else
1877 Streamer.emitIntValue(0, Size); // No personality fn
1878
1879 // LSDA
1881 if (!DwarfEHFrameOnly && Frame.Lsda)
1882 Streamer.emitSymbolValue(Frame.Lsda, Size);
1883 else
1884 Streamer.emitIntValue(0, Size); // No LSDA
1885}
1886
1887static unsigned getCIEVersion(bool IsEH, unsigned DwarfVersion) {
1888 if (IsEH)
1889 return 1;
1890 switch (DwarfVersion) {
1891 case 2:
1892 return 1;
1893 case 3:
1894 return 3;
1895 case 4:
1896 case 5:
1897 case 6:
1898 return 4;
1899 }
1900 llvm_unreachable("Unknown version");
1901}
1902
1903const MCSymbol &FrameEmitterImpl::EmitCIE(const MCDwarfFrameInfo &Frame) {
1904 MCContext &context = Streamer.getContext();
1905 const MCRegisterInfo *MRI = context.getRegisterInfo();
1906 const MCObjectFileInfo *MOFI = context.getObjectFileInfo();
1907
1908 MCSymbol *sectionStart = context.createTempSymbol();
1909 Streamer.emitLabel(sectionStart);
1910
1911 MCSymbol *sectionEnd = context.createTempSymbol();
1912
1914 unsigned UnitLengthBytes = dwarf::getUnitLengthFieldByteSize(Format);
1915 unsigned OffsetSize = dwarf::getDwarfOffsetByteSize(Format);
1916 bool IsDwarf64 = Format == dwarf::DWARF64;
1917
1918 if (IsDwarf64)
1919 // DWARF64 mark
1921
1922 // Length
1923 const MCExpr *Length = makeEndMinusStartExpr(context, *sectionStart,
1924 *sectionEnd, UnitLengthBytes);
1925 emitAbsValue(Streamer, Length, OffsetSize);
1926
1927 // CIE ID
1928 uint64_t CIE_ID =
1929 IsEH ? 0 : (IsDwarf64 ? dwarf::DW64_CIE_ID : dwarf::DW_CIE_ID);
1930 Streamer.emitIntValue(CIE_ID, OffsetSize);
1931
1932 // Version
1933 uint8_t CIEVersion = getCIEVersion(IsEH, context.getDwarfVersion());
1934 Streamer.emitInt8(CIEVersion);
1935
1936 if (IsEH) {
1937 SmallString<8> Augmentation;
1938 Augmentation += "z";
1939 if (Frame.Personality)
1940 Augmentation += "P";
1941 if (Frame.Lsda)
1942 Augmentation += "L";
1943 Augmentation += "R";
1944 if (Frame.IsSignalFrame)
1945 Augmentation += "S";
1946 if (Frame.IsBKeyFrame)
1947 Augmentation += "B";
1948 if (Frame.IsMTETaggedFrame)
1949 Augmentation += "G";
1950 if (Frame.IsNonHintPAuthFrame)
1951 Augmentation += "N";
1952 Streamer.emitBytes(Augmentation);
1953 }
1954 Streamer.emitInt8(0);
1955
1956 if (CIEVersion >= 4) {
1957 // Address Size
1958 Streamer.emitInt8(context.getAsmInfo().getCodePointerSize());
1959
1960 // Segment Descriptor Size
1961 Streamer.emitInt8(0);
1962 }
1963
1964 // Code Alignment Factor
1965 Streamer.emitULEB128IntValue(context.getAsmInfo().getMinInstAlignment());
1966
1967 // Data Alignment Factor
1968 Streamer.emitSLEB128IntValue(getDataAlignmentFactor(Streamer));
1969
1970 // Return Address Register
1971 unsigned RAReg = Frame.RAReg;
1972 if (RAReg == static_cast<unsigned>(INT_MAX))
1973 RAReg = MRI->getDwarfRegNum(MRI->getRARegister(), IsEH);
1974
1975 if (CIEVersion == 1) {
1976 assert(RAReg <= 255 &&
1977 "DWARF 2 encodes return_address_register in one byte");
1978 Streamer.emitInt8(RAReg);
1979 } else {
1980 Streamer.emitULEB128IntValue(RAReg);
1981 }
1982
1983 // Augmentation Data Length (optional)
1984 unsigned augmentationLength = 0;
1985 if (IsEH) {
1986 if (Frame.Personality) {
1987 // Personality Encoding
1988 augmentationLength += 1;
1989 // Personality
1990 augmentationLength +=
1992 }
1993 if (Frame.Lsda)
1994 augmentationLength += 1;
1995 // Encoding of the FDE pointers
1996 augmentationLength += 1;
1997
1998 Streamer.emitULEB128IntValue(augmentationLength);
1999
2000 // Augmentation Data (optional)
2001 if (Frame.Personality) {
2002 // Personality Encoding
2004 // Personality
2006 }
2007
2008 if (Frame.Lsda)
2010
2011 // Encoding of the FDE pointers
2013 }
2014
2015 // Initial Instructions
2016
2017 const MCAsmInfo &MAI = context.getAsmInfo();
2018 if (!Frame.IsSimple) {
2019 const std::vector<MCCFIInstruction> &Instructions =
2021 emitCFIInstructions(Instructions, nullptr);
2022 }
2023
2024 InitialCFAOffset = CFAOffset;
2025
2026 // Padding
2027 Streamer.emitValueToAlignment(Align(IsEH ? 4 : MAI.getCodePointerSize()));
2028
2029 Streamer.emitLabel(sectionEnd);
2030 return *sectionStart;
2031}
2032
2033void FrameEmitterImpl::EmitFDE(const MCSymbol &cieStart,
2034 const MCDwarfFrameInfo &frame,
2035 bool LastInSection,
2036 const MCSymbol &SectionStart) {
2037 MCContext &context = Streamer.getContext();
2038 MCSymbol *fdeStart = context.createTempSymbol();
2039 MCSymbol *fdeEnd = context.createTempSymbol();
2040 const MCObjectFileInfo *MOFI = context.getObjectFileInfo();
2041
2042 CFAOffset = InitialCFAOffset;
2043 SavedCFAOffsets.clear();
2044
2046 unsigned OffsetSize = dwarf::getDwarfOffsetByteSize(Format);
2047
2048 if (Format == dwarf::DWARF64)
2049 // DWARF64 mark
2051
2052 // Length
2053 const MCExpr *Length = makeEndMinusStartExpr(context, *fdeStart, *fdeEnd, 0);
2054 emitAbsValue(Streamer, Length, OffsetSize);
2055
2056 Streamer.emitLabel(fdeStart);
2057
2058 // CIE Pointer
2059 const MCAsmInfo &asmInfo = context.getAsmInfo();
2060 if (IsEH) {
2061 const MCExpr *offset =
2062 makeEndMinusStartExpr(context, cieStart, *fdeStart, 0);
2063 emitAbsValue(Streamer, offset, OffsetSize);
2064 } else if (!asmInfo.doesDwarfUseRelocationsAcrossSections()) {
2065 const MCExpr *offset =
2066 makeEndMinusStartExpr(context, SectionStart, cieStart, 0);
2067 emitAbsValue(Streamer, offset, OffsetSize);
2068 } else {
2069 Streamer.emitSymbolValue(&cieStart, OffsetSize,
2071 }
2072
2073 // PC Begin
2074 unsigned PCEncoding =
2075 IsEH ? MOFI->getFDEEncoding() : (unsigned)dwarf::DW_EH_PE_absptr;
2076 unsigned PCSize = getSizeForEncoding(Streamer, PCEncoding);
2077 emitFDESymbol(Streamer, *frame.Begin, PCEncoding, IsEH);
2078
2079 // PC Range
2080 const MCExpr *Range =
2081 makeEndMinusStartExpr(context, *frame.Begin, *frame.End, 0);
2082 emitAbsValue(Streamer, Range, PCSize);
2083
2084 if (IsEH) {
2085 // Augmentation Data Length
2086 unsigned augmentationLength = 0;
2087
2088 if (frame.Lsda)
2089 augmentationLength += getSizeForEncoding(Streamer, frame.LsdaEncoding);
2090
2091 Streamer.emitULEB128IntValue(augmentationLength);
2092
2093 // Augmentation Data
2094 if (frame.Lsda)
2095 emitFDESymbol(Streamer, *frame.Lsda, frame.LsdaEncoding, true);
2096 }
2097
2098 // Call Frame Instructions
2099 emitCFIInstructions(frame.Instructions, frame.Begin);
2100
2101 // Padding
2102 // The size of a .eh_frame section has to be a multiple of the alignment
2103 // since a null CIE is interpreted as the end. Old systems overaligned
2104 // .eh_frame, so we do too and account for it in the last FDE.
2105 unsigned Alignment = LastInSection ? asmInfo.getCodePointerSize() : PCSize;
2106 Streamer.emitValueToAlignment(Align(Alignment));
2107
2108 Streamer.emitLabel(fdeEnd);
2109}
2110
2111namespace {
2112
2113struct CIEKey {
2114 CIEKey() = default;
2115
2116 explicit CIEKey(const MCDwarfFrameInfo &Frame, bool IsEH)
2117 : Personality(Frame.Personality),
2118 PersonalityEncoding(Frame.PersonalityEncoding),
2119 LsdaEncoding(Frame.LsdaEncoding), IsSignalFrame(Frame.IsSignalFrame),
2120 IsSimple(Frame.IsSimple), RAReg(Frame.RAReg),
2121 IsBKeyFrame(Frame.IsBKeyFrame),
2122 IsMTETaggedFrame(Frame.IsMTETaggedFrame),
2123 IsNonHintPAuthFrame(Frame.IsNonHintPAuthFrame), IsEH(IsEH) {}
2124
2125 StringRef PersonalityName() const {
2126 if (!Personality)
2127 return StringRef();
2128 return Personality->getName();
2129 }
2130
2131 bool operator<(const CIEKey &Other) const {
2132 assert(IsEH == Other.IsEH);
2133 if (!IsEH)
2134 return std::make_tuple(RAReg, IsSimple) <
2135 std::make_tuple(Other.RAReg, Other.IsSimple);
2136
2137 return std::make_tuple(PersonalityName(), PersonalityEncoding, LsdaEncoding,
2138 IsSignalFrame, IsSimple, RAReg, IsBKeyFrame,
2139 IsMTETaggedFrame, IsNonHintPAuthFrame) <
2140 std::make_tuple(Other.PersonalityName(), Other.PersonalityEncoding,
2141 Other.LsdaEncoding, Other.IsSignalFrame,
2142 Other.IsSimple, Other.RAReg, Other.IsBKeyFrame,
2143 Other.IsMTETaggedFrame, Other.IsNonHintPAuthFrame);
2144 }
2145
2146 bool operator==(const CIEKey &Other) const {
2147 assert(IsEH == Other.IsEH);
2148 if (!IsEH)
2149 return RAReg == Other.RAReg && IsSimple == Other.IsSimple;
2150
2151 return Personality == Other.Personality &&
2152 PersonalityEncoding == Other.PersonalityEncoding &&
2153 LsdaEncoding == Other.LsdaEncoding &&
2154 IsSignalFrame == Other.IsSignalFrame && IsSimple == Other.IsSimple &&
2155 RAReg == Other.RAReg && IsBKeyFrame == Other.IsBKeyFrame &&
2156 IsMTETaggedFrame == Other.IsMTETaggedFrame &&
2157 IsNonHintPAuthFrame == Other.IsNonHintPAuthFrame;
2158 }
2159 bool operator!=(const CIEKey &Other) const { return !(*this == Other); }
2160
2161 const MCSymbol *Personality = nullptr;
2162 unsigned PersonalityEncoding = 0;
2163 unsigned LsdaEncoding = -1;
2164 bool IsSignalFrame = false;
2165 bool IsSimple = false;
2166 unsigned RAReg = UINT_MAX;
2167 bool IsBKeyFrame = false;
2168 bool IsMTETaggedFrame = false;
2169 bool IsNonHintPAuthFrame = false;
2170 bool IsEH = false;
2171};
2172
2173} // end anonymous namespace
2174
2176 MCContext &Context = Streamer.getContext();
2177 const MCObjectFileInfo *MOFI = Context.getObjectFileInfo();
2178 const MCAsmInfo &AsmInfo = Context.getAsmInfo();
2179 FrameEmitterImpl Emitter(IsEH, Streamer);
2180 ArrayRef<MCDwarfFrameInfo> FrameArray = Streamer.getDwarfFrameInfos();
2181
2182 // Emit the compact unwind info if available.
2183 bool NeedsEHFrameSection = !MOFI->getSupportsCompactUnwindWithoutEHFrame();
2184 if (IsEH && MOFI->getCompactUnwindSection()) {
2185 Streamer.generateCompactUnwindEncodings();
2186 bool SectionEmitted = false;
2187 for (const MCDwarfFrameInfo &Frame : FrameArray) {
2188 if (Frame.CompactUnwindEncoding == 0) continue;
2189 if (!SectionEmitted) {
2190 Streamer.switchSection(MOFI->getCompactUnwindSection());
2191 Streamer.emitValueToAlignment(Align(AsmInfo.getCodePointerSize()));
2192 SectionEmitted = true;
2193 }
2194 NeedsEHFrameSection |=
2195 Frame.CompactUnwindEncoding ==
2197 Emitter.EmitCompactUnwind(Frame);
2198 }
2199 }
2200
2201 // Compact unwind information can be emitted in the eh_frame section or the
2202 // debug_frame section. Skip emitting FDEs and CIEs when the compact unwind
2203 // doesn't need an eh_frame section and the emission location is the eh_frame
2204 // section.
2205 if (!NeedsEHFrameSection && IsEH) return;
2206
2207 MCSection &Section =
2208 IsEH ? *const_cast<MCObjectFileInfo *>(MOFI)->getEHFrameSection()
2209 : *MOFI->getDwarfFrameSection();
2210
2211 Streamer.switchSection(&Section);
2212 MCSymbol *SectionStart = Context.createTempSymbol();
2213 Streamer.emitLabel(SectionStart);
2214
2215 bool CanOmitDwarf = MOFI->getOmitDwarfIfHaveCompactUnwind();
2216 // Sort the FDEs by their corresponding CIE before we emit them.
2217 // This isn't technically necessary according to the DWARF standard,
2218 // but the Android libunwindstack rejects eh_frame sections where
2219 // an FDE refers to a CIE other than the closest previous CIE.
2220 std::vector<MCDwarfFrameInfo> FrameArrayX(FrameArray.begin(), FrameArray.end());
2221 llvm::stable_sort(FrameArrayX, [IsEH](const MCDwarfFrameInfo &X,
2222 const MCDwarfFrameInfo &Y) {
2223 return CIEKey(X, IsEH) < CIEKey(Y, IsEH);
2224 });
2225 CIEKey LastKey;
2226 const MCSymbol *LastCIEStart = nullptr;
2227 for (auto I = FrameArrayX.begin(), E = FrameArrayX.end(); I != E;) {
2228 const MCDwarfFrameInfo &Frame = *I;
2229 ++I;
2230 if (CanOmitDwarf && Frame.CompactUnwindEncoding !=
2231 MOFI->getCompactUnwindDwarfEHFrameOnly() && IsEH)
2232 // CIEs and FDEs can be emitted in either the eh_frame section or the
2233 // debug_frame section, on some platforms (e.g. AArch64) the target object
2234 // file supports emitting a compact_unwind section without an associated
2235 // eh_frame section. If the eh_frame section is not needed, and the
2236 // location where the CIEs and FDEs are to be emitted is the eh_frame
2237 // section, do not emit anything.
2238 continue;
2239
2240 CIEKey Key(Frame, IsEH);
2241 if (!LastCIEStart || Key != LastKey) {
2242 LastKey = Key;
2243 LastCIEStart = &Emitter.EmitCIE(Frame);
2244 }
2245
2246 Emitter.EmitFDE(*LastCIEStart, Frame, I == E, *SectionStart);
2247 }
2248}
2249
2251 uint64_t AddrDelta,
2252 SmallVectorImpl<char> &Out) {
2253 // Scale the address delta by the minimum instruction length.
2254 AddrDelta = ScaleAddrDelta(Context, AddrDelta);
2255 if (AddrDelta == 0)
2256 return;
2257
2258 llvm::endianness E = Context.getAsmInfo().isLittleEndian()
2261
2262 if (isUIntN(6, AddrDelta)) {
2263 uint8_t Opcode = dwarf::DW_CFA_advance_loc | AddrDelta;
2264 Out.push_back(Opcode);
2265 } else if (isUInt<8>(AddrDelta)) {
2266 Out.push_back(dwarf::DW_CFA_advance_loc1);
2267 Out.push_back(AddrDelta);
2268 } else if (isUInt<16>(AddrDelta)) {
2269 Out.push_back(dwarf::DW_CFA_advance_loc2);
2270 support::endian::write<uint16_t>(Out, AddrDelta, E);
2271 } else {
2272 assert(isUInt<32>(AddrDelta));
2273 Out.push_back(dwarf::DW_CFA_advance_loc4);
2274 support::endian::write<uint32_t>(Out, AddrDelta, E);
2275 }
2276}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
#define X(NUM, ENUM, NAME)
Definition ELF.h:665
dxil container 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:1372
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:740
static void EmitGenDwarfAranges(MCStreamer *MCOS, const MCSymbol *InfoSectionSymbol)
Definition MCDwarf.cpp:889
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:1425
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:1887
static void EmitGenDwarfInfo(MCStreamer *MCOS, const MCSymbol *AbbrevSectionSymbol, const MCSymbol *LineSectionSymbol, const MCSymbol *RangesSymbol)
Definition MCDwarf.cpp:967
static void EmitAbbrev(MCStreamer *MCOS, uint64_t Name, uint64_t Form)
Definition MCDwarf.cpp:828
static void EmitPersonality(MCStreamer &streamer, const MCSymbol &symbol, unsigned symbolEncoding)
Definition MCDwarf.cpp:1385
static void emitEncodingByte(MCObjectStreamer &Streamer, unsigned Encoding)
Definition MCDwarf.cpp:1421
static int getDataAlignmentFactor(MCStreamer &streamer)
Definition MCDwarf.cpp:1341
static MCSymbol * emitGenDwarfRanges(MCStreamer *MCOS)
Definition MCDwarf.cpp:1144
static const MCExpr * makeStartPlusIntExpr(MCContext &Ctx, const MCSymbol &Start, int IntVal)
Definition MCDwarf.cpp:135
static void EmitGenDwarfAbbrev(MCStreamer *MCOS)
Definition MCDwarf.cpp:835
static unsigned getSizeForEncoding(MCStreamer &streamer, unsigned symbolEncoding)
Definition MCDwarf.cpp:1351
#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
MachineRegisterInfo & MRI
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.
std::unique_ptr< MCStreamer > && Streamer
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:552
const std::vector< MCCFIInstruction > & getInitialFrameState() const
Definition MCAsmInfo.h:717
bool needsDwarfSectionOffsetDirective() const
Definition MCAsmInfo.h:534
bool doesDwarfUseRelocationsAcrossSections() const
Definition MCAsmInfo.h:699
const MCExpr * getExprForFDESymbol(const MCSymbol *Sym, unsigned Encoding, MCStreamer &Streamer) const
Definition MCAsmInfo.cpp:54
bool isStackGrowthDirectionUp() const
True if target stack grow up.
Definition MCAsmInfo.h:469
unsigned getCalleeSaveStackSlotSize() const
Get the callee-saved register stack slot size in bytes.
Definition MCAsmInfo.h:461
bool doDwarfFDESymbolsUseAbsDiff() const
Definition MCAsmInfo.h:703
virtual const MCExpr * getExprForPersonalitySymbol(const MCSymbol *Sym, unsigned Encoding, MCStreamer &Streamer) const
Definition MCAsmInfo.cpp:48
unsigned getCodePointerSize() const
Get the code pointer size in bytes.
Definition MCAsmInfo.h:457
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:1305
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:415
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:788
const SmallVectorImpl< std::string > & getMCDwarfDirs(unsigned CUID=0)
Definition MCContext.h:730
StringRef getDwarfDebugProducer()
Definition MCContext.h:810
StringRef getDwarfDebugFlags()
Definition MCContext.h:807
bool getDwarfLocSeen()
Definition MCContext.h:771
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:681
void clearDwarfLocSeen()
Definition MCContext.h:769
MCDwarfLineTable & getMCDwarfLineTable(unsigned CUID)
Definition MCContext.h:716
unsigned getDwarfCompileUnitID()
Definition MCContext.h:734
const MCRegisterInfo * getRegisterInfo() const
Definition MCContext.h:413
const SmallVectorImpl< MCDwarfFile > & getMCDwarfFiles(unsigned CUID=0)
Definition MCContext.h:726
const std::map< unsigned, MCDwarfLineTable > & getMCDwarfLineTables() const
Definition MCContext.h:712
unsigned getGenDwarfFileNumber()
Definition MCContext.h:776
uint16_t getDwarfVersion() const
Definition MCContext.h:816
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:802
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
const MCDwarfLoc & getCurrentDwarfLoc()
Definition MCContext.h:772
dwarf::DwarfFormat getDwarfFormat() const
Definition MCContext.h:813
const MCAsmInfo & getAsmInfo() const
Definition MCContext.h:411
const std::vector< MCGenDwarfLabelEntry > & getMCGenDwarfLabelEntries() const
Definition MCContext.h:798
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:2175
static LLVM_ABI void encodeAdvanceLoc(MCContext &Context, uint64_t AddrDelta, SmallVectorImpl< char > &OS)
Definition MCDwarf.cpp:2250
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:730
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:745
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:1205
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:1268
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.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition MCSection.h:580
MCSymbol * getBeginSymbol()
Definition MCSection.h:653
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:768
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)
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:769
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:767
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:28
StringRef str() const
Explicit conversion to StringRef.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This owns the files read by a parser, handles include stacks, and handles diagnostic wrangling.
Definition SourceMgr.h:34
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:1250
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:1208
@ DW_CHILDREN_no
Definition Dwarf.h:968
@ DW_EH_PE_signed
Definition Dwarf.h:981
@ DW_CHILDREN_yes
Definition Dwarf.h:969
@ DW_EH_PE_sdata4
Definition Dwarf.h:979
@ DW_EH_PE_udata2
Definition Dwarf.h:974
@ DW_EH_PE_sdata8
Definition Dwarf.h:980
@ DW_EH_PE_absptr
Definition Dwarf.h:971
@ DW_EH_PE_sdata2
Definition Dwarf.h:978
@ DW_EH_PE_udata4
Definition Dwarf.h:975
@ DW_EH_PE_udata8
Definition Dwarf.h:976
@ 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:82
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:577
@ Length
Definition DWP.cpp:577
bool operator<(int64_t V1, const APSInt &V2)
Definition APSInt.h:360
void stable_sort(R &&Range)
Definition STLExtras.h:2132
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:1781
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:1685
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:2139
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
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
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:102
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:280
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:1535
endianness
Definition bit.h:71
@ End
Run the machine verifier once, at the end of the pipeline.
Definition CodeGen.h:320
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:909
uint64_t CompactUnwindEncoding
Definition MCDwarf.h:911
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