LLVM 23.0.0git
MCDwarf.cpp
Go to the documentation of this file.
1//===- lib/MC/MCDwarf.cpp - MCDwarf implementation ------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "llvm/MC/MCDwarf.h"
10#include "llvm/ADT/ArrayRef.h"
11#include "llvm/ADT/STLExtras.h"
14#include "llvm/ADT/StringRef.h"
15#include "llvm/ADT/Twine.h"
17#include "llvm/Config/config.h"
18#include "llvm/MC/MCAsmInfo.h"
19#include "llvm/MC/MCContext.h"
20#include "llvm/MC/MCExpr.h"
24#include "llvm/MC/MCSection.h"
25#include "llvm/MC/MCStreamer.h"
26#include "llvm/MC/MCSymbol.h"
30#include "llvm/Support/LEB128.h"
32#include "llvm/Support/Path.h"
35#include <cassert>
36#include <cstdint>
37#include <optional>
38#include <string>
39#include <utility>
40#include <vector>
41
42using namespace llvm;
43
45 MCSymbol *Start = S.getContext().createTempSymbol("debug_list_header_start");
46 MCSymbol *End = S.getContext().createTempSymbol("debug_list_header_end");
47 auto DwarfFormat = S.getContext().getDwarfFormat();
48 if (DwarfFormat == dwarf::DWARF64) {
49 S.AddComment("DWARF64 mark");
51 }
52 S.AddComment("Length");
53 S.emitAbsoluteSymbolDiff(End, Start,
55 S.emitLabel(Start);
56 S.AddComment("Version");
58 S.AddComment("Address size");
60 S.AddComment("Segment selector size");
61 S.emitInt8(0);
62 return End;
63}
64
65static inline uint64_t ScaleAddrDelta(MCContext &Context, uint64_t AddrDelta) {
66 unsigned MinInsnLength = Context.getAsmInfo()->getMinInstAlignment();
67 if (MinInsnLength == 1)
68 return AddrDelta;
69 if (AddrDelta % MinInsnLength != 0) {
70 // TODO: report this error, but really only once.
71 ;
72 }
73 return AddrDelta / MinInsnLength;
74}
75
77 UseRelocs = Ctx.getAsmInfo()->doesDwarfUseRelocationsAcrossSections();
78 if (UseRelocs) {
79 MCSection *DwarfLineStrSection =
80 Ctx.getObjectFileInfo()->getDwarfLineStrSection();
81 assert(DwarfLineStrSection && "DwarfLineStrSection must not be NULL");
82 LineStrLabel = DwarfLineStrSection->getBeginSymbol();
83 }
84}
85
86//
87// This is called when an instruction is assembled into the specified section
88// and if there is information from the last .loc directive that has yet to have
89// a line entry made for it is made.
90//
92 if (!MCOS->getContext().getDwarfLocSeen())
93 return;
94
95 // Create a symbol at in the current section for use in the line entry.
96 MCSymbol *LineSym = MCOS->getContext().createTempSymbol();
97 // Set the value of the symbol to use for the MCDwarfLineEntry.
98 MCOS->emitLabel(LineSym);
99
100 // Get the current .loc info saved in the context.
101 const MCDwarfLoc &DwarfLoc = MCOS->getContext().getCurrentDwarfLoc();
102
103 // Create a (local) line entry with the symbol and the current .loc info.
104 MCDwarfLineEntry LineEntry(LineSym, DwarfLoc);
105
106 // clear DwarfLocSeen saying the current .loc info is now used.
108
109 // Add the line entry to this section's entries.
110 MCOS->getContext()
113 .addLineEntry(LineEntry, Section);
114}
115
116//
117// This helper routine returns an expression of End - Start - IntVal .
118//
119static inline const MCExpr *makeEndMinusStartExpr(MCContext &Ctx,
120 const MCSymbol &Start,
121 const MCSymbol &End,
122 int IntVal) {
123 const MCExpr *Res = MCSymbolRefExpr::create(&End, Ctx);
124 const MCExpr *RHS = MCSymbolRefExpr::create(&Start, Ctx);
125 const MCExpr *Res1 = MCBinaryExpr::create(MCBinaryExpr::Sub, Res, RHS, Ctx);
126 const MCExpr *Res2 = MCConstantExpr::create(IntVal, Ctx);
127 const MCExpr *Res3 = MCBinaryExpr::create(MCBinaryExpr::Sub, Res1, Res2, Ctx);
128 return Res3;
129}
130
131//
132// This helper routine returns an expression of Start + IntVal .
133//
134static inline const MCExpr *
135makeStartPlusIntExpr(MCContext &Ctx, const MCSymbol &Start, int IntVal) {
136 const MCExpr *LHS = MCSymbolRefExpr::create(&Start, Ctx);
137 const MCExpr *RHS = MCConstantExpr::create(IntVal, Ctx);
139 return Res;
140}
141
143 auto *Sec = &EndLabel->getSection();
144 // The line table may be empty, which we should skip adding an end entry.
145 // There are three cases:
146 // (1) MCAsmStreamer - emitDwarfLocDirective emits a location directive in
147 // place instead of adding a line entry if the target has
148 // usesDwarfFileAndLocDirectives.
149 // (2) MCObjectStreamer - if a function has incomplete debug info where
150 // instructions don't have DILocations, the line entries are missing.
151 // (3) It's also possible that there are no prior line entries if the section
152 // itself is empty before this end label.
153 auto I = MCLineDivisions.find(Sec);
154 if (I == MCLineDivisions.end()) // If section not found, do nothing.
155 return;
156
157 auto &Entries = I->second;
158 // If no entries in this section's list, nothing to base the end entry on.
159 if (Entries.empty())
160 return;
161
162 // Create the end entry based on the last existing entry.
163 MCDwarfLineEntry EndEntry = Entries.back();
164
165 // An end entry is just for marking the end of a sequence of code locations.
166 // It should not carry forward a LineStreamLabel from a previous special entry
167 // if Entries.back() happened to be such an entry. So here we clear
168 // LineStreamLabel.
169 EndEntry.LineStreamLabel = nullptr;
170 EndEntry.setEndLabel(EndLabel);
171 Entries.push_back(EndEntry);
172}
173
174//
175// This emits the Dwarf line table for the specified section from the entries
176// in the LineSection.
177//
179 MCStreamer *MCOS, MCSection *Section,
181
182 unsigned FileNum, LastLine, Column, Flags, Isa, Discriminator;
183 bool IsAtStartSeq;
184 MCSymbol *PrevLabel;
185 auto init = [&]() {
186 FileNum = 1;
187 LastLine = 1;
188 Column = 0;
190 Isa = 0;
191 Discriminator = 0;
192 PrevLabel = nullptr;
193 IsAtStartSeq = true;
194 };
195 init();
196
197 // Loop through each MCDwarfLineEntry and encode the dwarf line number table.
198 bool EndEntryEmitted = false;
199 for (auto It = LineEntries.begin(); It != LineEntries.end(); ++It) {
200 auto LineEntry = *It;
201 MCSymbol *CurrLabel = LineEntry.getLabel();
202 const MCAsmInfo *asmInfo = MCOS->getContext().getAsmInfo();
203
204 if (LineEntry.LineStreamLabel) {
205 if (!IsAtStartSeq) {
206 auto *Label = CurrLabel;
207 auto NextIt = It + 1;
208 // LineEntry with a null Label is probably a fake LineEntry we added
209 // when `-emit-func-debug-line-table-offsets` in order to terminate the
210 // sequence. Look for the next Label if possible, otherwise we will set
211 // the PC to the end of the section.
212 if (!Label && NextIt != LineEntries.end()) {
213 Label = NextIt->getLabel();
214 }
215 MCOS->emitDwarfLineEndEntry(Section, PrevLabel,
216 /*EndLabel =*/Label);
217 init();
218 }
219 MCOS->emitLabel(LineEntry.LineStreamLabel, LineEntry.StreamLabelDefLoc);
220 continue;
221 }
222
223 if (LineEntry.IsEndEntry) {
224 MCOS->emitDwarfAdvanceLineAddr(INT64_MAX, PrevLabel, CurrLabel,
225 asmInfo->getCodePointerSize());
226 init();
227 EndEntryEmitted = true;
228 continue;
229 }
230
231 int64_t LineDelta = static_cast<int64_t>(LineEntry.getLine()) - LastLine;
232
233 if (FileNum != LineEntry.getFileNum()) {
234 FileNum = LineEntry.getFileNum();
235 MCOS->emitInt8(dwarf::DW_LNS_set_file);
236 MCOS->emitULEB128IntValue(FileNum);
237 }
238 if (Column != LineEntry.getColumn()) {
239 Column = LineEntry.getColumn();
240 MCOS->emitInt8(dwarf::DW_LNS_set_column);
241 MCOS->emitULEB128IntValue(Column);
242 }
243 if (Discriminator != LineEntry.getDiscriminator() &&
244 MCOS->getContext().getDwarfVersion() >= 4) {
245 Discriminator = LineEntry.getDiscriminator();
246 unsigned Size = getULEB128Size(Discriminator);
247 MCOS->emitInt8(dwarf::DW_LNS_extended_op);
248 MCOS->emitULEB128IntValue(Size + 1);
249 MCOS->emitInt8(dwarf::DW_LNE_set_discriminator);
250 MCOS->emitULEB128IntValue(Discriminator);
251 }
252 if (Isa != LineEntry.getIsa()) {
253 Isa = LineEntry.getIsa();
254 MCOS->emitInt8(dwarf::DW_LNS_set_isa);
255 MCOS->emitULEB128IntValue(Isa);
256 }
257 if ((LineEntry.getFlags() ^ Flags) & DWARF2_FLAG_IS_STMT) {
258 Flags = LineEntry.getFlags();
259 MCOS->emitInt8(dwarf::DW_LNS_negate_stmt);
260 }
261 if (LineEntry.getFlags() & DWARF2_FLAG_BASIC_BLOCK)
262 MCOS->emitInt8(dwarf::DW_LNS_set_basic_block);
263 if (LineEntry.getFlags() & DWARF2_FLAG_PROLOGUE_END)
264 MCOS->emitInt8(dwarf::DW_LNS_set_prologue_end);
265 if (LineEntry.getFlags() & DWARF2_FLAG_EPILOGUE_BEGIN)
266 MCOS->emitInt8(dwarf::DW_LNS_set_epilogue_begin);
267
268 // At this point we want to emit/create the sequence to encode the delta in
269 // line numbers and the increment of the address from the previous Label
270 // and the current Label.
271 MCOS->emitDwarfAdvanceLineAddr(LineDelta, PrevLabel, CurrLabel,
272 asmInfo->getCodePointerSize());
273
274 Discriminator = 0;
275 LastLine = LineEntry.getLine();
276 PrevLabel = CurrLabel;
277 IsAtStartSeq = false;
278 }
279
280 // Generate DWARF line end entry.
281 // We do not need this for DwarfDebug that explicitly terminates the line
282 // table using ranges whenever CU or section changes. However, the MC path
283 // does not track ranges nor terminate the line table. In that case,
284 // conservatively use the section end symbol to end the line table.
285 if (!EndEntryEmitted && !IsAtStartSeq)
286 MCOS->emitDwarfLineEndEntry(Section, PrevLabel);
287}
288
290 SMLoc DefLoc,
291 StringRef Name) {
292 auto &ctx = MCOS->getContext();
293 auto *LineStreamLabel = ctx.getOrCreateSymbol(Name);
294 auto *LineSym = ctx.createTempSymbol();
295 MCOS->emitLabel(LineSym);
296 const MCDwarfLoc &DwarfLoc = ctx.getCurrentDwarfLoc();
297
298 // Create a 'fake' line entry by having LineStreamLabel be non-null. This
299 // won't actually emit any line information, it will reset the line table
300 // sequence and emit a label at the start of the new line table sequence.
301 MCDwarfLineEntry LineEntry(LineSym, DwarfLoc, LineStreamLabel, DefLoc);
303}
304
305//
306// This emits the Dwarf file and the line tables.
307//
309 MCContext &context = MCOS->getContext();
310
311 auto &LineTables = context.getMCDwarfLineTables();
312
313 // Bail out early so we don't switch to the debug_line section needlessly and
314 // in doing so create an unnecessary (if empty) section.
315 if (LineTables.empty())
316 return;
317
318 // In a v5 non-split line table, put the strings in a separate section.
319 std::optional<MCDwarfLineStr> LineStr;
320 if (context.getDwarfVersion() >= 5)
321 LineStr.emplace(context);
322
323 // Switch to the section where the table will be emitted into.
325
326 // Handle the rest of the Compile Units.
327 for (const auto &CUIDTablePair : LineTables) {
328 CUIDTablePair.second.emitCU(MCOS, Params, LineStr);
329 }
330
331 if (LineStr)
332 LineStr->emitSection(MCOS);
333}
334
336 MCSection *Section) const {
337 if (!HasSplitLineTable)
338 return;
339 std::optional<MCDwarfLineStr> NoLineStr(std::nullopt);
340 MCOS.switchSection(Section);
341 MCOS.emitLabel(Header.Emit(&MCOS, Params, {}, NoLineStr).second);
342}
343
344std::pair<MCSymbol *, MCSymbol *>
346 std::optional<MCDwarfLineStr> &LineStr) const {
347 static const char StandardOpcodeLengths[] = {
348 0, // length of DW_LNS_copy
349 1, // length of DW_LNS_advance_pc
350 1, // length of DW_LNS_advance_line
351 1, // length of DW_LNS_set_file
352 1, // length of DW_LNS_set_column
353 0, // length of DW_LNS_negate_stmt
354 0, // length of DW_LNS_set_basic_block
355 0, // length of DW_LNS_const_add_pc
356 1, // length of DW_LNS_fixed_advance_pc
357 0, // length of DW_LNS_set_prologue_end
358 0, // length of DW_LNS_set_epilogue_begin
359 1 // DW_LNS_set_isa
360 };
361 assert(std::size(StandardOpcodeLengths) >=
362 (Params.DWARF2LineOpcodeBase - 1U));
363 return Emit(MCOS, Params,
364 ArrayRef(StandardOpcodeLengths, Params.DWARF2LineOpcodeBase - 1),
365 LineStr);
366}
367
368static const MCExpr *forceExpAbs(MCStreamer &OS, const MCExpr* Expr) {
369 MCContext &Context = OS.getContext();
371 if (!Context.getAsmInfo()->doesSetDirectiveSuppressReloc())
372 return Expr;
373
374 // On Mach-O, try to avoid a relocation by using a set directive.
375 MCSymbol *ABS = Context.createTempSymbol();
376 OS.emitAssignment(ABS, Expr);
377 return MCSymbolRefExpr::create(ABS, Context);
378}
379
380static void emitAbsValue(MCStreamer &OS, const MCExpr *Value, unsigned Size) {
381 const MCExpr *ABS = forceExpAbs(OS, Value);
382 OS.emitValue(ABS, Size);
383}
384
386 // Switch to the .debug_line_str section.
387 MCOS->switchSection(
390 MCOS->emitBinaryData(Data.str());
391}
392
394 // Emit the strings without perturbing the offsets we used.
395 if (!LineStrings.isFinalized())
396 LineStrings.finalizeInOrder();
398 Data.resize(LineStrings.getSize());
399 LineStrings.write((uint8_t *)Data.data());
400 return Data;
401}
402
404 return LineStrings.add(Path);
405}
406
408 int RefSize =
410 size_t Offset = addString(Path);
411 if (UseRelocs) {
412 MCContext &Ctx = MCOS->getContext();
413 if (Ctx.getAsmInfo()->needsDwarfSectionOffsetDirective()) {
414 MCOS->emitCOFFSecRel32(LineStrLabel, Offset);
415 } else {
416 MCOS->emitValue(makeStartPlusIntExpr(Ctx, *LineStrLabel, Offset),
417 RefSize);
418 }
419 } else
420 MCOS->emitIntValue(Offset, RefSize);
421}
422
423void MCDwarfLineTableHeader::emitV2FileDirTables(MCStreamer *MCOS) const {
424 // First the directory table.
425 for (auto &Dir : MCDwarfDirs) {
426 MCOS->emitBytes(Dir); // The DirectoryName, and...
427 MCOS->emitBytes(StringRef("\0", 1)); // its null terminator.
428 }
429 MCOS->emitInt8(0); // Terminate the directory list.
430
431 // Second the file table.
432 for (unsigned i = 1; i < MCDwarfFiles.size(); i++) {
433 assert(!MCDwarfFiles[i].Name.empty());
434 MCOS->emitBytes(MCDwarfFiles[i].Name); // FileName and...
435 MCOS->emitBytes(StringRef("\0", 1)); // its null terminator.
436 MCOS->emitULEB128IntValue(MCDwarfFiles[i].DirIndex); // Directory number.
437 MCOS->emitInt8(0); // Last modification timestamp (always 0).
438 MCOS->emitInt8(0); // File size (always 0).
439 }
440 MCOS->emitInt8(0); // Terminate the file list.
441}
442
444 bool EmitMD5, bool HasAnySource,
445 std::optional<MCDwarfLineStr> &LineStr) {
446 assert(!DwarfFile.Name.empty());
447 if (LineStr)
448 LineStr->emitRef(MCOS, DwarfFile.Name);
449 else {
450 MCOS->emitBytes(DwarfFile.Name); // FileName and...
451 MCOS->emitBytes(StringRef("\0", 1)); // its null terminator.
452 }
453 MCOS->emitULEB128IntValue(DwarfFile.DirIndex); // Directory number.
454 if (EmitMD5) {
455 const MD5::MD5Result &Cksum = *DwarfFile.Checksum;
456 MCOS->emitBinaryData(
457 StringRef(reinterpret_cast<const char *>(Cksum.data()), Cksum.size()));
458 }
459 if (HasAnySource) {
460 // From https://dwarfstd.org/issues/180201.1.html
461 // * The value is an empty null-terminated string if no source is available
462 StringRef Source = DwarfFile.Source.value_or(StringRef());
463 // * If the source is available but is an empty file then the value is a
464 // null-terminated single "\n".
465 if (DwarfFile.Source && DwarfFile.Source->empty())
466 Source = "\n";
467 if (LineStr)
468 LineStr->emitRef(MCOS, Source);
469 else {
470 MCOS->emitBytes(Source); // Source and...
471 MCOS->emitBytes(StringRef("\0", 1)); // its null terminator.
472 }
473 }
474}
475
476void MCDwarfLineTableHeader::emitV5FileDirTables(
477 MCStreamer *MCOS, std::optional<MCDwarfLineStr> &LineStr) const {
478 // The directory format, which is just a list of the directory paths. In a
479 // non-split object, these are references to .debug_line_str; in a split
480 // object, they are inline strings.
481 MCOS->emitInt8(1);
482 MCOS->emitULEB128IntValue(dwarf::DW_LNCT_path);
483 MCOS->emitULEB128IntValue(LineStr ? dwarf::DW_FORM_line_strp
484 : dwarf::DW_FORM_string);
485 MCOS->emitULEB128IntValue(MCDwarfDirs.size() + 1);
486 // Try not to emit an empty compilation directory.
487 SmallString<256> Dir;
488 StringRef CompDir = MCOS->getContext().getCompilationDir();
489 if (!CompilationDir.empty()) {
490 Dir = CompilationDir;
491 MCOS->getContext().remapDebugPath(Dir);
492 CompDir = Dir.str();
493 if (LineStr)
494 CompDir = LineStr->getSaver().save(CompDir);
495 }
496 if (LineStr) {
497 // Record path strings, emit references here.
498 LineStr->emitRef(MCOS, CompDir);
499 for (const auto &Dir : MCDwarfDirs)
500 LineStr->emitRef(MCOS, Dir);
501 } else {
502 // The list of directory paths. Compilation directory comes first.
503 MCOS->emitBytes(CompDir);
504 MCOS->emitBytes(StringRef("\0", 1));
505 for (const auto &Dir : MCDwarfDirs) {
506 MCOS->emitBytes(Dir); // The DirectoryName, and...
507 MCOS->emitBytes(StringRef("\0", 1)); // its null terminator.
508 }
509 }
510
511 // The file format, which is the inline null-terminated filename and a
512 // directory index. We don't track file size/timestamp so don't emit them
513 // in the v5 table. Emit MD5 checksums and source if we have them.
514 uint64_t Entries = 2;
515 if (HasAllMD5)
516 Entries += 1;
517 if (HasAnySource)
518 Entries += 1;
519 MCOS->emitInt8(Entries);
520 MCOS->emitULEB128IntValue(dwarf::DW_LNCT_path);
521 MCOS->emitULEB128IntValue(LineStr ? dwarf::DW_FORM_line_strp
522 : dwarf::DW_FORM_string);
523 MCOS->emitULEB128IntValue(dwarf::DW_LNCT_directory_index);
524 MCOS->emitULEB128IntValue(dwarf::DW_FORM_udata);
525 if (HasAllMD5) {
526 MCOS->emitULEB128IntValue(dwarf::DW_LNCT_MD5);
527 MCOS->emitULEB128IntValue(dwarf::DW_FORM_data16);
528 }
529 if (HasAnySource) {
530 MCOS->emitULEB128IntValue(dwarf::DW_LNCT_LLVM_source);
531 MCOS->emitULEB128IntValue(LineStr ? dwarf::DW_FORM_line_strp
532 : dwarf::DW_FORM_string);
533 }
534 // Then the counted list of files. The root file is file #0, then emit the
535 // files as provide by .file directives.
536 // MCDwarfFiles has an unused element [0] so use size() not size()+1.
537 // But sometimes MCDwarfFiles is empty, in which case we still emit one file.
538 MCOS->emitULEB128IntValue(MCDwarfFiles.empty() ? 1 : MCDwarfFiles.size());
539 // To accommodate assembler source written for DWARF v4 but trying to emit
540 // v5: If we didn't see a root file explicitly, replicate file #1.
541 assert((!RootFile.Name.empty() || MCDwarfFiles.size() >= 1) &&
542 "No root file and no .file directives");
543 emitOneV5FileEntry(MCOS, RootFile.Name.empty() ? MCDwarfFiles[1] : RootFile,
544 HasAllMD5, HasAnySource, LineStr);
545 for (unsigned i = 1; i < MCDwarfFiles.size(); ++i)
546 emitOneV5FileEntry(MCOS, MCDwarfFiles[i], HasAllMD5, HasAnySource, LineStr);
547}
548
549std::pair<MCSymbol *, MCSymbol *>
551 ArrayRef<char> StandardOpcodeLengths,
552 std::optional<MCDwarfLineStr> &LineStr) const {
553 MCContext &context = MCOS->getContext();
554
555 // Create a symbol at the beginning of the line table.
556 MCSymbol *LineStartSym = Label;
557 if (!LineStartSym)
558 LineStartSym = context.createTempSymbol();
559
560 // Set the value of the symbol, as we are at the start of the line table.
561 MCOS->emitDwarfLineStartLabel(LineStartSym);
562
563 unsigned OffsetSize = dwarf::getDwarfOffsetByteSize(context.getDwarfFormat());
564
565 MCSymbol *LineEndSym = MCOS->emitDwarfUnitLength("debug_line", "unit length");
566
567 // Next 2 bytes is the Version.
568 unsigned LineTableVersion = context.getDwarfVersion();
569 MCOS->emitInt16(LineTableVersion);
570
571 // In v5, we get address info next.
572 if (LineTableVersion >= 5) {
573 MCOS->emitInt8(context.getAsmInfo()->getCodePointerSize());
574 MCOS->emitInt8(0); // Segment selector; same as EmitGenDwarfAranges.
575 }
576
577 // Create symbols for the start/end of the prologue.
578 MCSymbol *ProStartSym = context.createTempSymbol("prologue_start");
579 MCSymbol *ProEndSym = context.createTempSymbol("prologue_end");
580
581 // Length of the prologue, is the next 4 bytes (8 bytes for DWARF64). This is
582 // actually the length from after the length word, to the end of the prologue.
583 MCOS->emitAbsoluteSymbolDiff(ProEndSym, ProStartSym, OffsetSize);
584
585 MCOS->emitLabel(ProStartSym);
586
587 // Parameters of the state machine, are next.
588 MCOS->emitInt8(context.getAsmInfo()->getMinInstAlignment());
589 // maximum_operations_per_instruction
590 // For non-VLIW architectures this field is always 1.
591 // FIXME: VLIW architectures need to update this field accordingly.
592 if (LineTableVersion >= 4)
593 MCOS->emitInt8(1);
595 MCOS->emitInt8(Params.DWARF2LineBase);
596 MCOS->emitInt8(Params.DWARF2LineRange);
597 MCOS->emitInt8(StandardOpcodeLengths.size() + 1);
598
599 // Standard opcode lengths
600 for (char Length : StandardOpcodeLengths)
601 MCOS->emitInt8(Length);
602
603 // Put out the directory and file tables. The formats vary depending on
604 // the version.
605 if (LineTableVersion >= 5)
606 emitV5FileDirTables(MCOS, LineStr);
607 else
608 emitV2FileDirTables(MCOS);
609
610 // This is the end of the prologue, so set the value of the symbol at the
611 // end of the prologue (that was used in a previous expression).
612 MCOS->emitLabel(ProEndSym);
613
614 return std::make_pair(LineStartSym, LineEndSym);
615}
616
618 std::optional<MCDwarfLineStr> &LineStr) const {
619 MCSymbol *LineEndSym = Header.Emit(MCOS, Params, LineStr).second;
620
621 // Put out the line tables.
622 for (const auto &LineSec : MCLineSections.getMCLineEntries())
623 emitOne(MCOS, LineSec.first, LineSec.second);
624
625 // This is the end of the section, so set the value of the symbol at the end
626 // of this section (that was used in a previous expression).
627 MCOS->emitLabel(LineEndSym);
628}
629
632 std::optional<MD5::MD5Result> Checksum,
633 std::optional<StringRef> Source,
634 uint16_t DwarfVersion, unsigned FileNumber) {
635 return Header.tryGetFile(Directory, FileName, Checksum, Source, DwarfVersion,
636 FileNumber);
637}
638
639static bool isRootFile(const MCDwarfFile &RootFile, StringRef &Directory,
640 StringRef &FileName,
641 std::optional<MD5::MD5Result> Checksum) {
642 if (RootFile.Name.empty() || StringRef(RootFile.Name) != FileName)
643 return false;
644 return RootFile.Checksum == Checksum;
645}
646
649 std::optional<MD5::MD5Result> Checksum,
650 std::optional<StringRef> Source,
651 uint16_t DwarfVersion, unsigned FileNumber) {
652 if (Directory == CompilationDir)
653 Directory = "";
654 if (FileName.empty()) {
655 FileName = "<stdin>";
656 Directory = "";
657 }
658 assert(!FileName.empty());
659 // Keep track of whether any or all files have an MD5 checksum.
660 // If any files have embedded source, they all must.
661 if (MCDwarfFiles.empty()) {
662 trackMD5Usage(Checksum.has_value());
663 HasAnySource |= Source.has_value();
664 }
665 if (DwarfVersion >= 5 && isRootFile(RootFile, Directory, FileName, Checksum))
666 return 0;
667 if (FileNumber == 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
1305static int getDataAlignmentFactor(MCStreamer &streamer) {
1306 MCContext &context = streamer.getContext();
1307 const MCAsmInfo *asmInfo = context.getAsmInfo();
1308 int size = asmInfo->getCalleeSaveStackSlotSize();
1309 if (asmInfo->isStackGrowthDirectionUp())
1310 return size;
1311 else
1312 return -size;
1313}
1314
1315static unsigned getSizeForEncoding(MCStreamer &streamer,
1316 unsigned symbolEncoding) {
1317 MCContext &context = streamer.getContext();
1318 unsigned format = symbolEncoding & 0x0f;
1319 switch (format) {
1320 default: llvm_unreachable("Unknown Encoding");
1323 return context.getAsmInfo()->getCodePointerSize();
1326 return 2;
1329 return 4;
1332 return 8;
1333 }
1334}
1335
1336static void emitFDESymbol(MCObjectStreamer &streamer, const MCSymbol &symbol,
1337 unsigned symbolEncoding, bool isEH) {
1338 MCContext &context = streamer.getContext();
1339 const MCAsmInfo *asmInfo = context.getAsmInfo();
1340 const MCExpr *v = asmInfo->getExprForFDESymbol(&symbol,
1341 symbolEncoding,
1342 streamer);
1343 unsigned size = getSizeForEncoding(streamer, symbolEncoding);
1344 if (asmInfo->doDwarfFDESymbolsUseAbsDiff() && isEH)
1345 emitAbsValue(streamer, v, size);
1346 else
1347 streamer.emitValue(v, size);
1348}
1349
1350static void EmitPersonality(MCStreamer &streamer, const MCSymbol &symbol,
1351 unsigned symbolEncoding) {
1352 MCContext &context = streamer.getContext();
1353 const MCAsmInfo *asmInfo = context.getAsmInfo();
1354 const MCExpr *v = asmInfo->getExprForPersonalitySymbol(&symbol,
1355 symbolEncoding,
1356 streamer);
1357 unsigned size = getSizeForEncoding(streamer, symbolEncoding);
1358 streamer.emitValue(v, size);
1359}
1360
1361namespace {
1362
1363class FrameEmitterImpl {
1364 int64_t CFAOffset = 0;
1365 int64_t InitialCFAOffset = 0;
1366 bool IsEH;
1367 MCObjectStreamer &Streamer;
1368
1369public:
1370 FrameEmitterImpl(bool IsEH, MCObjectStreamer &Streamer)
1371 : IsEH(IsEH), Streamer(Streamer) {}
1372
1373 /// Emit the unwind information in a compact way.
1374 void EmitCompactUnwind(const MCDwarfFrameInfo &frame);
1375
1376 const MCSymbol &EmitCIE(const MCDwarfFrameInfo &F);
1377 void EmitFDE(const MCSymbol &cieStart, const MCDwarfFrameInfo &frame,
1378 bool LastInSection, const MCSymbol &SectionStart);
1379 void emitCFIInstructions(ArrayRef<MCCFIInstruction> Instrs,
1380 MCSymbol *BaseLabel);
1381 void emitCFIInstruction(const MCCFIInstruction &Instr);
1382};
1383
1384} // end anonymous namespace
1385
1386static void emitEncodingByte(MCObjectStreamer &Streamer, unsigned Encoding) {
1387 Streamer.emitInt8(Encoding);
1388}
1389
1390void FrameEmitterImpl::emitCFIInstruction(const MCCFIInstruction &Instr) {
1391 int dataAlignmentFactor = getDataAlignmentFactor(Streamer);
1392 auto *MRI = Streamer.getContext().getRegisterInfo();
1393
1394 switch (Instr.getOperation()) {
1396 unsigned Reg1 = Instr.getRegister();
1397 unsigned Reg2 = Instr.getRegister2();
1398 if (!IsEH) {
1399 Reg1 = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg1);
1400 Reg2 = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg2);
1401 }
1402 Streamer.emitInt8(dwarf::DW_CFA_register);
1403 Streamer.emitULEB128IntValue(Reg1);
1404 Streamer.emitULEB128IntValue(Reg2);
1405 return;
1406 }
1408 Streamer.emitInt8(dwarf::DW_CFA_GNU_window_save);
1409 return;
1410
1412 Streamer.emitInt8(dwarf::DW_CFA_AARCH64_negate_ra_state);
1413 return;
1414
1416 Streamer.emitInt8(dwarf::DW_CFA_AARCH64_negate_ra_state_with_pc);
1417 return;
1418
1420 unsigned Reg = Instr.getRegister();
1421 Streamer.emitInt8(dwarf::DW_CFA_undefined);
1422 Streamer.emitULEB128IntValue(Reg);
1423 return;
1424 }
1427 const bool IsRelative =
1429
1430 Streamer.emitInt8(dwarf::DW_CFA_def_cfa_offset);
1431
1432 if (IsRelative)
1433 CFAOffset += Instr.getOffset();
1434 else
1435 CFAOffset = Instr.getOffset();
1436
1437 Streamer.emitULEB128IntValue(CFAOffset);
1438
1439 return;
1440 }
1442 unsigned Reg = Instr.getRegister();
1443 if (!IsEH)
1444 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1445 Streamer.emitInt8(dwarf::DW_CFA_def_cfa);
1446 Streamer.emitULEB128IntValue(Reg);
1447 CFAOffset = Instr.getOffset();
1448 Streamer.emitULEB128IntValue(CFAOffset);
1449
1450 return;
1451 }
1453 unsigned Reg = Instr.getRegister();
1454 if (!IsEH)
1455 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1456 Streamer.emitInt8(dwarf::DW_CFA_def_cfa_register);
1457 Streamer.emitULEB128IntValue(Reg);
1458
1459 return;
1460 }
1461 // TODO: Implement `_sf` variants if/when they need to be emitted.
1463 unsigned Reg = Instr.getRegister();
1464 if (!IsEH)
1465 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1466 Streamer.emitIntValue(dwarf::DW_CFA_LLVM_def_aspace_cfa, 1);
1467 Streamer.emitULEB128IntValue(Reg);
1468 CFAOffset = Instr.getOffset();
1469 Streamer.emitULEB128IntValue(CFAOffset);
1470 Streamer.emitULEB128IntValue(Instr.getAddressSpace());
1471
1472 return;
1473 }
1476 const bool IsRelative =
1477 Instr.getOperation() == MCCFIInstruction::OpRelOffset;
1478
1479 unsigned Reg = Instr.getRegister();
1480 if (!IsEH)
1481 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1482
1483 int64_t Offset = Instr.getOffset();
1484 if (IsRelative)
1485 Offset -= CFAOffset;
1486 Offset = Offset / dataAlignmentFactor;
1487
1488 if (Offset < 0) {
1489 Streamer.emitInt8(dwarf::DW_CFA_offset_extended_sf);
1490 Streamer.emitULEB128IntValue(Reg);
1491 Streamer.emitSLEB128IntValue(Offset);
1492 } else if (Reg < 64) {
1493 Streamer.emitInt8(dwarf::DW_CFA_offset + Reg);
1494 Streamer.emitULEB128IntValue(Offset);
1495 } else {
1496 Streamer.emitInt8(dwarf::DW_CFA_offset_extended);
1497 Streamer.emitULEB128IntValue(Reg);
1498 Streamer.emitULEB128IntValue(Offset);
1499 }
1500 return;
1501 }
1503 Streamer.emitInt8(dwarf::DW_CFA_remember_state);
1504 return;
1506 Streamer.emitInt8(dwarf::DW_CFA_restore_state);
1507 return;
1509 unsigned Reg = Instr.getRegister();
1510 Streamer.emitInt8(dwarf::DW_CFA_same_value);
1511 Streamer.emitULEB128IntValue(Reg);
1512 return;
1513 }
1515 unsigned Reg = Instr.getRegister();
1516 if (!IsEH)
1517 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1518 if (Reg < 64) {
1519 Streamer.emitInt8(dwarf::DW_CFA_restore | Reg);
1520 } else {
1521 Streamer.emitInt8(dwarf::DW_CFA_restore_extended);
1522 Streamer.emitULEB128IntValue(Reg);
1523 }
1524 return;
1525 }
1527 Streamer.emitInt8(dwarf::DW_CFA_GNU_args_size);
1528 Streamer.emitULEB128IntValue(Instr.getOffset());
1529 return;
1530
1532 Streamer.emitBytes(Instr.getValues());
1533 return;
1535 Streamer.emitLabel(Instr.getCfiLabel(), Instr.getLoc());
1536 return;
1538 unsigned Reg = Instr.getRegister();
1539 if (!IsEH)
1540 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1541
1542 int Offset = Instr.getOffset();
1543 Offset = Offset / dataAlignmentFactor;
1544
1545 if (Offset < 0) {
1546 Streamer.emitInt8(dwarf::DW_CFA_val_offset_sf);
1547 Streamer.emitULEB128IntValue(Reg);
1548 Streamer.emitSLEB128IntValue(Offset);
1549 } else {
1550 Streamer.emitInt8(dwarf::DW_CFA_val_offset);
1551 Streamer.emitULEB128IntValue(Reg);
1552 Streamer.emitULEB128IntValue(Offset);
1553 }
1554 return;
1555 }
1556 }
1557 llvm_unreachable("Unhandled case in switch");
1558}
1559
1560/// Emit frame instructions to describe the layout of the frame.
1561void FrameEmitterImpl::emitCFIInstructions(ArrayRef<MCCFIInstruction> Instrs,
1562 MCSymbol *BaseLabel) {
1563 for (const MCCFIInstruction &Instr : Instrs) {
1564 MCSymbol *Label = Instr.getLabel();
1565 // Throw out move if the label is invalid.
1566 if (Label && !Label->isDefined()) continue; // Not emitted, in dead code.
1567
1568 // Advance row if new location.
1569 if (BaseLabel && Label) {
1570 MCSymbol *ThisSym = Label;
1571 if (ThisSym != BaseLabel) {
1572 Streamer.emitDwarfAdvanceFrameAddr(BaseLabel, ThisSym, Instr.getLoc());
1573 BaseLabel = ThisSym;
1574 }
1575 }
1576
1577 emitCFIInstruction(Instr);
1578 }
1579}
1580
1581/// Emit the unwind information in a compact way.
1582void FrameEmitterImpl::EmitCompactUnwind(const MCDwarfFrameInfo &Frame) {
1583 MCContext &Context = Streamer.getContext();
1584 const MCObjectFileInfo *MOFI = Context.getObjectFileInfo();
1585
1586 // range-start range-length compact-unwind-enc personality-func lsda
1587 // _foo LfooEnd-_foo 0x00000023 0 0
1588 // _bar LbarEnd-_bar 0x00000025 __gxx_personality except_tab1
1589 //
1590 // .section __LD,__compact_unwind,regular,debug
1591 //
1592 // # compact unwind for _foo
1593 // .quad _foo
1594 // .set L1,LfooEnd-_foo
1595 // .long L1
1596 // .long 0x01010001
1597 // .quad 0
1598 // .quad 0
1599 //
1600 // # compact unwind for _bar
1601 // .quad _bar
1602 // .set L2,LbarEnd-_bar
1603 // .long L2
1604 // .long 0x01020011
1605 // .quad __gxx_personality
1606 // .quad except_tab1
1607
1608 uint32_t Encoding = Frame.CompactUnwindEncoding;
1609 if (!Encoding) return;
1610 bool DwarfEHFrameOnly = (Encoding == MOFI->getCompactUnwindDwarfEHFrameOnly());
1611
1612 // The encoding needs to know we have an LSDA.
1613 if (!DwarfEHFrameOnly && Frame.Lsda)
1614 Encoding |= 0x40000000;
1615
1616 // Range Start
1617 unsigned FDEEncoding = MOFI->getFDEEncoding();
1618 unsigned Size = getSizeForEncoding(Streamer, FDEEncoding);
1619 Streamer.emitSymbolValue(Frame.Begin, Size);
1620
1621 // Range Length
1622 const MCExpr *Range =
1623 makeEndMinusStartExpr(Context, *Frame.Begin, *Frame.End, 0);
1624 emitAbsValue(Streamer, Range, 4);
1625
1626 // Compact Encoding
1628 Streamer.emitIntValue(Encoding, Size);
1629
1630 // Personality Function
1632 if (!DwarfEHFrameOnly && Frame.Personality)
1633 Streamer.emitSymbolValue(Frame.Personality, Size);
1634 else
1635 Streamer.emitIntValue(0, Size); // No personality fn
1636
1637 // LSDA
1638 Size = getSizeForEncoding(Streamer, Frame.LsdaEncoding);
1639 if (!DwarfEHFrameOnly && Frame.Lsda)
1640 Streamer.emitSymbolValue(Frame.Lsda, Size);
1641 else
1642 Streamer.emitIntValue(0, Size); // No LSDA
1643}
1644
1645static unsigned getCIEVersion(bool IsEH, unsigned DwarfVersion) {
1646 if (IsEH)
1647 return 1;
1648 switch (DwarfVersion) {
1649 case 2:
1650 return 1;
1651 case 3:
1652 return 3;
1653 case 4:
1654 case 5:
1655 return 4;
1656 }
1657 llvm_unreachable("Unknown version");
1658}
1659
1660const MCSymbol &FrameEmitterImpl::EmitCIE(const MCDwarfFrameInfo &Frame) {
1661 MCContext &context = Streamer.getContext();
1662 const MCRegisterInfo *MRI = context.getRegisterInfo();
1663 const MCObjectFileInfo *MOFI = context.getObjectFileInfo();
1664
1665 MCSymbol *sectionStart = context.createTempSymbol();
1666 Streamer.emitLabel(sectionStart);
1667
1668 MCSymbol *sectionEnd = context.createTempSymbol();
1669
1671 unsigned UnitLengthBytes = dwarf::getUnitLengthFieldByteSize(Format);
1672 unsigned OffsetSize = dwarf::getDwarfOffsetByteSize(Format);
1673 bool IsDwarf64 = Format == dwarf::DWARF64;
1674
1675 if (IsDwarf64)
1676 // DWARF64 mark
1677 Streamer.emitInt32(dwarf::DW_LENGTH_DWARF64);
1678
1679 // Length
1680 const MCExpr *Length = makeEndMinusStartExpr(context, *sectionStart,
1681 *sectionEnd, UnitLengthBytes);
1682 emitAbsValue(Streamer, Length, OffsetSize);
1683
1684 // CIE ID
1685 uint64_t CIE_ID =
1686 IsEH ? 0 : (IsDwarf64 ? dwarf::DW64_CIE_ID : dwarf::DW_CIE_ID);
1687 Streamer.emitIntValue(CIE_ID, OffsetSize);
1688
1689 // Version
1690 uint8_t CIEVersion = getCIEVersion(IsEH, context.getDwarfVersion());
1691 Streamer.emitInt8(CIEVersion);
1692
1693 if (IsEH) {
1694 SmallString<8> Augmentation;
1695 Augmentation += "z";
1696 if (Frame.Personality)
1697 Augmentation += "P";
1698 if (Frame.Lsda)
1699 Augmentation += "L";
1700 Augmentation += "R";
1701 if (Frame.IsSignalFrame)
1702 Augmentation += "S";
1703 if (Frame.IsBKeyFrame)
1704 Augmentation += "B";
1705 if (Frame.IsMTETaggedFrame)
1706 Augmentation += "G";
1707 Streamer.emitBytes(Augmentation);
1708 }
1709 Streamer.emitInt8(0);
1710
1711 if (CIEVersion >= 4) {
1712 // Address Size
1713 Streamer.emitInt8(context.getAsmInfo()->getCodePointerSize());
1714
1715 // Segment Descriptor Size
1716 Streamer.emitInt8(0);
1717 }
1718
1719 // Code Alignment Factor
1720 Streamer.emitULEB128IntValue(context.getAsmInfo()->getMinInstAlignment());
1721
1722 // Data Alignment Factor
1723 Streamer.emitSLEB128IntValue(getDataAlignmentFactor(Streamer));
1724
1725 // Return Address Register
1726 unsigned RAReg = Frame.RAReg;
1727 if (RAReg == static_cast<unsigned>(INT_MAX))
1728 RAReg = MRI->getDwarfRegNum(MRI->getRARegister(), IsEH);
1729
1730 if (CIEVersion == 1) {
1731 assert(RAReg <= 255 &&
1732 "DWARF 2 encodes return_address_register in one byte");
1733 Streamer.emitInt8(RAReg);
1734 } else {
1735 Streamer.emitULEB128IntValue(RAReg);
1736 }
1737
1738 // Augmentation Data Length (optional)
1739 unsigned augmentationLength = 0;
1740 if (IsEH) {
1741 if (Frame.Personality) {
1742 // Personality Encoding
1743 augmentationLength += 1;
1744 // Personality
1745 augmentationLength +=
1746 getSizeForEncoding(Streamer, Frame.PersonalityEncoding);
1747 }
1748 if (Frame.Lsda)
1749 augmentationLength += 1;
1750 // Encoding of the FDE pointers
1751 augmentationLength += 1;
1752
1753 Streamer.emitULEB128IntValue(augmentationLength);
1754
1755 // Augmentation Data (optional)
1756 if (Frame.Personality) {
1757 // Personality Encoding
1758 emitEncodingByte(Streamer, Frame.PersonalityEncoding);
1759 // Personality
1760 EmitPersonality(Streamer, *Frame.Personality, Frame.PersonalityEncoding);
1761 }
1762
1763 if (Frame.Lsda)
1764 emitEncodingByte(Streamer, Frame.LsdaEncoding);
1765
1766 // Encoding of the FDE pointers
1767 emitEncodingByte(Streamer, MOFI->getFDEEncoding());
1768 }
1769
1770 // Initial Instructions
1771
1772 const MCAsmInfo *MAI = context.getAsmInfo();
1773 if (!Frame.IsSimple) {
1774 const std::vector<MCCFIInstruction> &Instructions =
1775 MAI->getInitialFrameState();
1776 emitCFIInstructions(Instructions, nullptr);
1777 }
1778
1779 InitialCFAOffset = CFAOffset;
1780
1781 // Padding
1782 Streamer.emitValueToAlignment(Align(IsEH ? 4 : MAI->getCodePointerSize()));
1783
1784 Streamer.emitLabel(sectionEnd);
1785 return *sectionStart;
1786}
1787
1788void FrameEmitterImpl::EmitFDE(const MCSymbol &cieStart,
1789 const MCDwarfFrameInfo &frame,
1790 bool LastInSection,
1791 const MCSymbol &SectionStart) {
1792 MCContext &context = Streamer.getContext();
1793 MCSymbol *fdeStart = context.createTempSymbol();
1794 MCSymbol *fdeEnd = context.createTempSymbol();
1795 const MCObjectFileInfo *MOFI = context.getObjectFileInfo();
1796
1797 CFAOffset = InitialCFAOffset;
1798
1800 unsigned OffsetSize = dwarf::getDwarfOffsetByteSize(Format);
1801
1802 if (Format == dwarf::DWARF64)
1803 // DWARF64 mark
1804 Streamer.emitInt32(dwarf::DW_LENGTH_DWARF64);
1805
1806 // Length
1807 const MCExpr *Length = makeEndMinusStartExpr(context, *fdeStart, *fdeEnd, 0);
1808 emitAbsValue(Streamer, Length, OffsetSize);
1809
1810 Streamer.emitLabel(fdeStart);
1811
1812 // CIE Pointer
1813 const MCAsmInfo *asmInfo = context.getAsmInfo();
1814 if (IsEH) {
1815 const MCExpr *offset =
1816 makeEndMinusStartExpr(context, cieStart, *fdeStart, 0);
1817 emitAbsValue(Streamer, offset, OffsetSize);
1818 } else if (!asmInfo->doesDwarfUseRelocationsAcrossSections()) {
1819 const MCExpr *offset =
1820 makeEndMinusStartExpr(context, SectionStart, cieStart, 0);
1821 emitAbsValue(Streamer, offset, OffsetSize);
1822 } else {
1823 Streamer.emitSymbolValue(&cieStart, OffsetSize,
1825 }
1826
1827 // PC Begin
1828 unsigned PCEncoding =
1829 IsEH ? MOFI->getFDEEncoding() : (unsigned)dwarf::DW_EH_PE_absptr;
1830 unsigned PCSize = getSizeForEncoding(Streamer, PCEncoding);
1831 emitFDESymbol(Streamer, *frame.Begin, PCEncoding, IsEH);
1832
1833 // PC Range
1834 const MCExpr *Range =
1835 makeEndMinusStartExpr(context, *frame.Begin, *frame.End, 0);
1836 emitAbsValue(Streamer, Range, PCSize);
1837
1838 if (IsEH) {
1839 // Augmentation Data Length
1840 unsigned augmentationLength = 0;
1841
1842 if (frame.Lsda)
1843 augmentationLength += getSizeForEncoding(Streamer, frame.LsdaEncoding);
1844
1845 Streamer.emitULEB128IntValue(augmentationLength);
1846
1847 // Augmentation Data
1848 if (frame.Lsda)
1849 emitFDESymbol(Streamer, *frame.Lsda, frame.LsdaEncoding, true);
1850 }
1851
1852 // Call Frame Instructions
1853 emitCFIInstructions(frame.Instructions, frame.Begin);
1854
1855 // Padding
1856 // The size of a .eh_frame section has to be a multiple of the alignment
1857 // since a null CIE is interpreted as the end. Old systems overaligned
1858 // .eh_frame, so we do too and account for it in the last FDE.
1859 unsigned Alignment = LastInSection ? asmInfo->getCodePointerSize() : PCSize;
1860 Streamer.emitValueToAlignment(Align(Alignment));
1861
1862 Streamer.emitLabel(fdeEnd);
1863}
1864
1865namespace {
1866
1867struct CIEKey {
1868 CIEKey() = default;
1869
1870 explicit CIEKey(const MCDwarfFrameInfo &Frame)
1871 : Personality(Frame.Personality),
1872 PersonalityEncoding(Frame.PersonalityEncoding),
1873 LsdaEncoding(Frame.LsdaEncoding), IsSignalFrame(Frame.IsSignalFrame),
1874 IsSimple(Frame.IsSimple), RAReg(Frame.RAReg),
1875 IsBKeyFrame(Frame.IsBKeyFrame),
1876 IsMTETaggedFrame(Frame.IsMTETaggedFrame) {}
1877
1878 StringRef PersonalityName() const {
1879 if (!Personality)
1880 return StringRef();
1881 return Personality->getName();
1882 }
1883
1884 bool operator<(const CIEKey &Other) const {
1885 return std::make_tuple(PersonalityName(), PersonalityEncoding, LsdaEncoding,
1886 IsSignalFrame, IsSimple, RAReg, IsBKeyFrame,
1887 IsMTETaggedFrame) <
1888 std::make_tuple(Other.PersonalityName(), Other.PersonalityEncoding,
1889 Other.LsdaEncoding, Other.IsSignalFrame,
1890 Other.IsSimple, Other.RAReg, Other.IsBKeyFrame,
1891 Other.IsMTETaggedFrame);
1892 }
1893
1894 bool operator==(const CIEKey &Other) const {
1895 return Personality == Other.Personality &&
1896 PersonalityEncoding == Other.PersonalityEncoding &&
1897 LsdaEncoding == Other.LsdaEncoding &&
1898 IsSignalFrame == Other.IsSignalFrame && IsSimple == Other.IsSimple &&
1899 RAReg == Other.RAReg && IsBKeyFrame == Other.IsBKeyFrame &&
1900 IsMTETaggedFrame == Other.IsMTETaggedFrame;
1901 }
1902 bool operator!=(const CIEKey &Other) const { return !(*this == Other); }
1903
1904 const MCSymbol *Personality = nullptr;
1905 unsigned PersonalityEncoding = 0;
1906 unsigned LsdaEncoding = -1;
1907 bool IsSignalFrame = false;
1908 bool IsSimple = false;
1909 unsigned RAReg = UINT_MAX;
1910 bool IsBKeyFrame = false;
1911 bool IsMTETaggedFrame = false;
1912};
1913
1914} // end anonymous namespace
1915
1917 MCContext &Context = Streamer.getContext();
1918 const MCObjectFileInfo *MOFI = Context.getObjectFileInfo();
1919 const MCAsmInfo *AsmInfo = Context.getAsmInfo();
1920 FrameEmitterImpl Emitter(IsEH, Streamer);
1921 ArrayRef<MCDwarfFrameInfo> FrameArray = Streamer.getDwarfFrameInfos();
1922
1923 // Emit the compact unwind info if available.
1924 bool NeedsEHFrameSection = !MOFI->getSupportsCompactUnwindWithoutEHFrame();
1925 if (IsEH && MOFI->getCompactUnwindSection()) {
1927 bool SectionEmitted = false;
1928 for (const MCDwarfFrameInfo &Frame : FrameArray) {
1929 if (Frame.CompactUnwindEncoding == 0) continue;
1930 if (!SectionEmitted) {
1931 Streamer.switchSection(MOFI->getCompactUnwindSection());
1932 Streamer.emitValueToAlignment(Align(AsmInfo->getCodePointerSize()));
1933 SectionEmitted = true;
1934 }
1935 NeedsEHFrameSection |=
1936 Frame.CompactUnwindEncoding ==
1938 Emitter.EmitCompactUnwind(Frame);
1939 }
1940 }
1941
1942 // Compact unwind information can be emitted in the eh_frame section or the
1943 // debug_frame section. Skip emitting FDEs and CIEs when the compact unwind
1944 // doesn't need an eh_frame section and the emission location is the eh_frame
1945 // section.
1946 if (!NeedsEHFrameSection && IsEH) return;
1947
1948 MCSection &Section =
1949 IsEH ? *const_cast<MCObjectFileInfo *>(MOFI)->getEHFrameSection()
1950 : *MOFI->getDwarfFrameSection();
1951
1952 Streamer.switchSection(&Section);
1953 MCSymbol *SectionStart = Context.createTempSymbol();
1954 Streamer.emitLabel(SectionStart);
1955
1956 bool CanOmitDwarf = MOFI->getOmitDwarfIfHaveCompactUnwind();
1957 // Sort the FDEs by their corresponding CIE before we emit them.
1958 // This isn't technically necessary according to the DWARF standard,
1959 // but the Android libunwindstack rejects eh_frame sections where
1960 // an FDE refers to a CIE other than the closest previous CIE.
1961 std::vector<MCDwarfFrameInfo> FrameArrayX(FrameArray.begin(), FrameArray.end());
1962 llvm::stable_sort(FrameArrayX,
1963 [](const MCDwarfFrameInfo &X, const MCDwarfFrameInfo &Y) {
1964 return CIEKey(X) < CIEKey(Y);
1965 });
1966 CIEKey LastKey;
1967 const MCSymbol *LastCIEStart = nullptr;
1968 for (auto I = FrameArrayX.begin(), E = FrameArrayX.end(); I != E;) {
1969 const MCDwarfFrameInfo &Frame = *I;
1970 ++I;
1971 if (CanOmitDwarf && Frame.CompactUnwindEncoding !=
1972 MOFI->getCompactUnwindDwarfEHFrameOnly() && IsEH)
1973 // CIEs and FDEs can be emitted in either the eh_frame section or the
1974 // debug_frame section, on some platforms (e.g. AArch64) the target object
1975 // file supports emitting a compact_unwind section without an associated
1976 // eh_frame section. If the eh_frame section is not needed, and the
1977 // location where the CIEs and FDEs are to be emitted is the eh_frame
1978 // section, do not emit anything.
1979 continue;
1980
1981 CIEKey Key(Frame);
1982 if (!LastCIEStart || (IsEH && Key != LastKey)) {
1983 LastKey = Key;
1984 LastCIEStart = &Emitter.EmitCIE(Frame);
1985 }
1986
1987 Emitter.EmitFDE(*LastCIEStart, Frame, I == E, *SectionStart);
1988 }
1989}
1990
1992 uint64_t AddrDelta,
1993 SmallVectorImpl<char> &Out) {
1994 // Scale the address delta by the minimum instruction length.
1995 AddrDelta = ScaleAddrDelta(Context, AddrDelta);
1996 if (AddrDelta == 0)
1997 return;
1998
1999 llvm::endianness E = Context.getAsmInfo()->isLittleEndian()
2002
2003 if (isUIntN(6, AddrDelta)) {
2004 uint8_t Opcode = dwarf::DW_CFA_advance_loc | AddrDelta;
2005 Out.push_back(Opcode);
2006 } else if (isUInt<8>(AddrDelta)) {
2007 Out.push_back(dwarf::DW_CFA_advance_loc1);
2008 Out.push_back(AddrDelta);
2009 } else if (isUInt<16>(AddrDelta)) {
2010 Out.push_back(dwarf::DW_CFA_advance_loc2);
2011 support::endian::write<uint16_t>(Out, AddrDelta, E);
2012 } else {
2013 assert(isUInt<32>(AddrDelta));
2014 Out.push_back(dwarf::DW_CFA_advance_loc4);
2015 support::endian::write<uint32_t>(Out, AddrDelta, E);
2016 }
2017}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
dxil DXContainer Global Emitter
This file contains constants used for implementing Dwarf debug support.
#define op(i)
static void emitFDESymbol(MCObjectStreamer &streamer, const MCSymbol &symbol, unsigned symbolEncoding, bool isEH)
Definition MCDwarf.cpp:1336
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:639
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:368
static void emitAbsValue(MCStreamer &OS, const MCExpr *Value, unsigned Size)
Definition MCDwarf.cpp:380
static void emitOneV5FileEntry(MCStreamer *MCOS, const MCDwarfFile &DwarfFile, bool EmitMD5, bool HasAnySource, std::optional< MCDwarfLineStr > &LineStr)
Definition MCDwarf.cpp:443
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:1645
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:1350
static void emitEncodingByte(MCObjectStreamer &Streamer, unsigned Encoding)
Definition MCDwarf.cpp:1386
static int getDataAlignmentFactor(MCStreamer &streamer)
Definition MCDwarf.cpp:1305
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:1315
#define DWARF2_FLAG_IS_STMT
Definition MCDwarf.h:119
#define DWARF2_FLAG_BASIC_BLOCK
Definition MCDwarf.h:120
#define DWARF2_LINE_DEFAULT_IS_STMT
Definition MCDwarf.h:117
#define DWARF2_FLAG_PROLOGUE_END
Definition MCDwarf.h:121
#define DWARF2_FLAG_EPILOGUE_BEGIN
Definition MCDwarf.h:122
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
static constexpr MCPhysReg RAReg
This file contains some templates that are useful if you are working with the STL at all.
This file defines the SmallString class.
This file defines the SmallVector class.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
Value * RHS
Value * LHS
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
iterator end() const
Definition ArrayRef.h:131
size_t size() const
size - Get the array size.
Definition ArrayRef.h:142
iterator begin() const
Definition ArrayRef.h:130
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:64
unsigned getMinInstAlignment() const
Definition MCAsmInfo.h:533
const std::vector< MCCFIInstruction > & getInitialFrameState() const
Definition MCAsmInfo.h:681
bool needsDwarfSectionOffsetDirective() const
Definition MCAsmInfo.h:515
bool doesDwarfUseRelocationsAcrossSections() const
Definition MCAsmInfo.h:661
virtual const MCExpr * getExprForFDESymbol(const MCSymbol *Sym, unsigned Encoding, MCStreamer &Streamer) const
Definition MCAsmInfo.cpp:65
bool isStackGrowthDirectionUp() const
True if target stack grow up.
Definition MCAsmInfo.h:457
unsigned getCalleeSaveStackSlotSize() const
Get the callee-saved register stack slot size in bytes.
Definition MCAsmInfo.h:449
bool doDwarfFDESymbolsUseAbsDiff() const
Definition MCAsmInfo.h:665
virtual const MCExpr * getExprForPersonalitySymbol(const MCSymbol *Sym, unsigned Encoding, MCStreamer &Streamer) const
Definition MCAsmInfo.cpp:58
unsigned getCodePointerSize() const
Get the code pointer size in bytes.
Definition MCAsmInfo.h:445
static LLVM_ABI const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.cpp:201
@ Sub
Subtraction.
Definition MCExpr.h:324
@ Add
Addition.
Definition MCExpr.h:302
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:416
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:789
const SmallVectorImpl< std::string > & getMCDwarfDirs(unsigned CUID=0)
Definition MCContext.h:731
StringRef getDwarfDebugProducer()
Definition MCContext.h:811
StringRef getDwarfDebugFlags()
Definition MCContext.h:808
bool getDwarfLocSeen()
Definition MCContext.h:772
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:682
void clearDwarfLocSeen()
Definition MCContext.h:770
MCDwarfLineTable & getMCDwarfLineTable(unsigned CUID)
Definition MCContext.h:717
unsigned getDwarfCompileUnitID()
Definition MCContext.h:735
const MCRegisterInfo * getRegisterInfo() const
Definition MCContext.h:414
const SmallVectorImpl< MCDwarfFile > & getMCDwarfFiles(unsigned CUID=0)
Definition MCContext.h:727
const std::map< unsigned, MCDwarfLineTable > & getMCDwarfLineTables() const
Definition MCContext.h:713
unsigned getGenDwarfFileNumber()
Definition MCContext.h:777
uint16_t getDwarfVersion() const
Definition MCContext.h:817
const MCAsmInfo * getAsmInfo() const
Definition MCContext.h:412
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:803
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
const MCDwarfLoc & getCurrentDwarfLoc()
Definition MCContext.h:773
dwarf::DwarfFormat getDwarfFormat() const
Definition MCContext.h:814
const std::vector< MCGenDwarfLabelEntry > & getMCGenDwarfLabelEntries() const
Definition MCContext.h:799
LLVM_ABI void Emit(MCStreamer &MCOS, MCDwarfLineTableParams Params, MCSection *Section) const
Definition MCDwarf.cpp:335
static LLVM_ABI void emit(MCObjectStreamer &streamer, bool isEH)
Definition MCDwarf.cpp:1916
static LLVM_ABI void encodeAdvanceLoc(MCContext &Context, uint64_t AddrDelta, SmallVectorImpl< char > &OS)
Definition MCDwarf.cpp:1991
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:385
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:393
LLVM_ABI void emitRef(MCStreamer *MCOS, StringRef Path)
Emit a reference to the string.
Definition MCDwarf.cpp:407
LLVM_ABI size_t addString(StringRef Path)
Adds path Path to the line string.
Definition MCDwarf.cpp:403
LLVM_ABI void endCurrentSeqAndEmitLineStreamLabel(MCStreamer *MCOS, SMLoc DefLoc, StringRef Name)
Definition MCDwarf.cpp:289
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:308
static LLVM_ABI void emitOne(MCStreamer *MCOS, MCSection *Section, const MCLineSection::MCDwarfLineEntryCollection &LineEntries)
Definition MCDwarf.cpp:178
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:631
LLVM_ABI void emitCU(MCStreamer *MCOS, MCDwarfLineTableParams Params, std::optional< MCDwarfLineStr > &LineStr) const
Definition MCDwarf.cpp:617
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.
void emitValueToAlignment(Align Alignment, int64_t Fill=0, uint8_t FillLen=1, unsigned MaxBytesToEmit=0) override
Emit some number of copies of Value until the byte alignment ByteAlignment is reached.
void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc()) override
Emit a label for Symbol into the current section.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
MCRegister getRARegister() const
This method should return the register where the return address can be found.
virtual int64_t getDwarfRegNum(MCRegister Reg, bool isEH) const
Map a target register to an equivalent dwarf register number.
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition MCSection.h:516
MCSymbol * getBeginSymbol()
Definition MCSection.h:589
Streaming machine code generation interface.
Definition MCStreamer.h:221
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:322
virtual void AddComment(const Twine &T, bool EOL=true)
Add a textual comment.
Definition MCStreamer.h:393
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:755
virtual MCSymbol * getDwarfLineTableSymbol(unsigned CUID)
unsigned emitULEB128IntValue(uint64_t Value, unsigned PadTo=0)
Special case of EmitULEB128Value that avoids the client having to pass in a MCExpr for constant integ...
virtual void emitULEB128Value(const MCExpr *Value)
ArrayRef< MCDwarfFrameInfo > getDwarfFrameInfos() const
virtual void switchSection(MCSection *Section, uint32_t Subsec=0)
Set the current section where code is being emitted to Section.
void emitInt32(uint64_t Value)
Definition MCStreamer.h:756
MCSection * getCurrentSectionOnly() const
Definition MCStreamer.h:427
virtual void emitDwarfLineEndEntry(MCSection *Section, MCSymbol *LastLabel, MCSymbol *EndLabel=nullptr)
Emit the debug line end entry.
void emitInt8(uint64_t Value)
Definition MCStreamer.h:754
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:214
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
Represents a location in source code.
Definition SMLoc.h:22
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
StringRef str() const
Explicit conversion to StringRef.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This owns the files read by a parser, handles include stacks, and handles diagnostic wrangling.
Definition SourceMgr.h:37
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition StringRef.h:591
constexpr bool empty() const
empty - Check if the string is empty.
Definition StringRef.h:140
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
LLVM Value Representation.
Definition Value.h:75
#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:1139
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:1097
@ DW_CHILDREN_no
Definition Dwarf.h:865
@ DW_EH_PE_signed
Definition Dwarf.h:878
@ DW_CHILDREN_yes
Definition Dwarf.h:866
@ DW_EH_PE_sdata4
Definition Dwarf.h:876
@ DW_EH_PE_udata2
Definition Dwarf.h:871
@ DW_EH_PE_sdata8
Definition Dwarf.h:877
@ DW_EH_PE_absptr
Definition Dwarf.h:868
@ DW_EH_PE_sdata2
Definition Dwarf.h:875
@ DW_EH_PE_udata4
Definition Dwarf.h:872
@ DW_EH_PE_udata8
Definition Dwarf.h:873
@ DW_LENGTH_DWARF64
Indicator of 64-bit DWARF format.
Definition Dwarf.h:57
LLVM_ABI MCSymbol * emitListsTableHeaderStart(MCStreamer &S)
Definition MCDwarf.cpp:44
NodeAddr< InstrNode * > Instr
Definition RDFGraph.h:389
void write(void *memory, value_type value, endianness endian)
Write a value to memory with a particular endianness.
Definition Endian.h:96
LLVM_ABI StringRef get_separator(Style style=Style::native)
Return the preferred separator for this platform.
Definition Path.cpp:610
LLVM_ABI StringRef parent_path(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get parent path.
Definition Path.cpp:468
LLVM_ABI StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get filename.
Definition Path.cpp:578
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
@ Offset
Definition DWP.cpp:532
@ Length
Definition DWP.cpp:532
bool operator<(int64_t V1, const APSInt &V2)
Definition APSInt.h:360
void stable_sort(R &&Range)
Definition STLExtras.h:2116
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1765
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition STLExtras.h:1669
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition Error.cpp:94
bool operator!=(uint64_t V1, const APInt &V2)
Definition APInt.h:2128
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
Definition MathExtras.h:243
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
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:189
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:129
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
FunctionAddr VTableAddr uintptr_t uintptr_t Data
Definition InstrProf.h:189
ArrayRef(const T &OneElt) -> ArrayRef< T >
void appendLEB128(SmallVectorImpl< U > &Buffer, T Value)
Definition LEB128.h:236
endianness
Definition bit.h:71
StringRef toStringRef(bool B)
Construct a string ref from a boolean.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
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:767
unsigned PersonalityEncoding
Definition MCDwarf.h:771
uint64_t CompactUnwindEncoding
Definition MCDwarf.h:773
std::vector< MCCFIInstruction > Instructions
Definition MCDwarf.h:769
const MCSymbol * Lsda
Definition MCDwarf.h:768
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:345
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:648
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