LLVM 22.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 uint8_t Buf[16];
749 uint64_t Temp, Opcode;
750 bool NeedCopy = false;
751
752 // The maximum address skip amount that can be encoded with a special op.
753 uint64_t MaxSpecialAddrDelta = SpecialAddr(Params, 255);
754
755 // Scale the address delta by the minimum instruction length.
756 AddrDelta = ScaleAddrDelta(Context, AddrDelta);
757
758 // A LineDelta of INT64_MAX is a signal that this is actually a
759 // DW_LNE_end_sequence. We cannot use special opcodes here, since we want the
760 // end_sequence to emit the matrix entry.
761 if (LineDelta == INT64_MAX) {
762 if (AddrDelta == MaxSpecialAddrDelta)
763 Out.push_back(dwarf::DW_LNS_const_add_pc);
764 else if (AddrDelta) {
765 Out.push_back(dwarf::DW_LNS_advance_pc);
766 Out.append(Buf, Buf + encodeULEB128(AddrDelta, Buf));
767 }
768 Out.push_back(dwarf::DW_LNS_extended_op);
769 Out.push_back(1);
770 Out.push_back(dwarf::DW_LNE_end_sequence);
771 return;
772 }
773
774 // Bias the line delta by the base.
775 Temp = LineDelta - Params.DWARF2LineBase;
776
777 // If the line increment is out of range of a special opcode, we must encode
778 // it with DW_LNS_advance_line.
779 if (Temp >= Params.DWARF2LineRange ||
780 Temp + Params.DWARF2LineOpcodeBase > 255) {
781 Out.push_back(dwarf::DW_LNS_advance_line);
782 Out.append(Buf, Buf + encodeSLEB128(LineDelta, Buf));
783
784 LineDelta = 0;
785 Temp = 0 - Params.DWARF2LineBase;
786 NeedCopy = true;
787 }
788
789 // Use DW_LNS_copy instead of a "line +0, addr +0" special opcode.
790 if (LineDelta == 0 && AddrDelta == 0) {
791 Out.push_back(dwarf::DW_LNS_copy);
792 return;
793 }
794
795 // Bias the opcode by the special opcode base.
796 Temp += Params.DWARF2LineOpcodeBase;
797
798 // Avoid overflow when addr_delta is large.
799 if (AddrDelta < 256 + MaxSpecialAddrDelta) {
800 // Try using a special opcode.
801 Opcode = Temp + AddrDelta * Params.DWARF2LineRange;
802 if (Opcode <= 255) {
803 Out.push_back(Opcode);
804 return;
805 }
806
807 // Try using DW_LNS_const_add_pc followed by special op.
808 Opcode = Temp + (AddrDelta - MaxSpecialAddrDelta) * Params.DWARF2LineRange;
809 if (Opcode <= 255) {
810 Out.push_back(dwarf::DW_LNS_const_add_pc);
811 Out.push_back(Opcode);
812 return;
813 }
814 }
815
816 // Otherwise use DW_LNS_advance_pc.
817 Out.push_back(dwarf::DW_LNS_advance_pc);
818 Out.append(Buf, Buf + encodeULEB128(AddrDelta, Buf));
819
820 if (NeedCopy)
821 Out.push_back(dwarf::DW_LNS_copy);
822 else {
823 assert(Temp <= 255 && "Buggy special opcode encoding.");
824 Out.push_back(Temp);
825 }
826}
827
828// Utility function to write a tuple for .debug_abbrev.
829static void EmitAbbrev(MCStreamer *MCOS, uint64_t Name, uint64_t Form) {
830 MCOS->emitULEB128IntValue(Name);
831 MCOS->emitULEB128IntValue(Form);
832}
833
834// When generating dwarf for assembly source files this emits
835// the data for .debug_abbrev section which contains three DIEs.
836static void EmitGenDwarfAbbrev(MCStreamer *MCOS) {
837 MCContext &context = MCOS->getContext();
839
840 // DW_TAG_compile_unit DIE abbrev (1).
841 MCOS->emitULEB128IntValue(1);
842 MCOS->emitULEB128IntValue(dwarf::DW_TAG_compile_unit);
844 dwarf::Form SecOffsetForm =
845 context.getDwarfVersion() >= 4
846 ? dwarf::DW_FORM_sec_offset
847 : (context.getDwarfFormat() == dwarf::DWARF64 ? dwarf::DW_FORM_data8
848 : dwarf::DW_FORM_data4);
849 EmitAbbrev(MCOS, dwarf::DW_AT_stmt_list, SecOffsetForm);
850 if (context.getGenDwarfSectionSyms().size() > 1 &&
851 context.getDwarfVersion() >= 3) {
852 EmitAbbrev(MCOS, dwarf::DW_AT_ranges, SecOffsetForm);
853 } else {
854 EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
855 EmitAbbrev(MCOS, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr);
856 }
857 EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
858 if (!context.getCompilationDir().empty())
859 EmitAbbrev(MCOS, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string);
860 StringRef DwarfDebugFlags = context.getDwarfDebugFlags();
861 if (!DwarfDebugFlags.empty())
862 EmitAbbrev(MCOS, dwarf::DW_AT_APPLE_flags, dwarf::DW_FORM_string);
863 EmitAbbrev(MCOS, dwarf::DW_AT_producer, dwarf::DW_FORM_string);
864 EmitAbbrev(MCOS, dwarf::DW_AT_language, dwarf::DW_FORM_data2);
865 EmitAbbrev(MCOS, 0, 0);
866
867 // DW_TAG_label DIE abbrev (2).
868 MCOS->emitULEB128IntValue(2);
869 MCOS->emitULEB128IntValue(dwarf::DW_TAG_label);
871 EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
872 EmitAbbrev(MCOS, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data4);
873 EmitAbbrev(MCOS, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data4);
874 EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
875 EmitAbbrev(MCOS, 0, 0);
876
877 // Terminate the abbreviations for this compilation unit.
878 MCOS->emitInt8(0);
879}
880
881// When generating dwarf for assembly source files this emits the data for
882// .debug_aranges section. This section contains a header and a table of pairs
883// of PointerSize'ed values for the address and size of section(s) with line
884// table entries.
886 const MCSymbol *InfoSectionSymbol) {
887 MCContext &context = MCOS->getContext();
888
889 auto &Sections = context.getGenDwarfSectionSyms();
890
892
893 unsigned UnitLengthBytes =
895 unsigned OffsetSize = dwarf::getDwarfOffsetByteSize(context.getDwarfFormat());
896
897 // This will be the length of the .debug_aranges section, first account for
898 // the size of each item in the header (see below where we emit these items).
899 int Length = UnitLengthBytes + 2 + OffsetSize + 1 + 1;
900
901 // Figure the padding after the header before the table of address and size
902 // pairs who's values are PointerSize'ed.
903 const MCAsmInfo *asmInfo = context.getAsmInfo();
904 int AddrSize = asmInfo->getCodePointerSize();
905 int Pad = 2 * AddrSize - (Length & (2 * AddrSize - 1));
906 if (Pad == 2 * AddrSize)
907 Pad = 0;
908 Length += Pad;
909
910 // Add the size of the pair of PointerSize'ed values for the address and size
911 // of each section we have in the table.
912 Length += 2 * AddrSize * Sections.size();
913 // And the pair of terminating zeros.
914 Length += 2 * AddrSize;
915
916 // Emit the header for this section.
917 if (context.getDwarfFormat() == dwarf::DWARF64)
918 // The DWARF64 mark.
920 // The 4 (8 for DWARF64) byte length not including the length of the unit
921 // length field itself.
922 MCOS->emitIntValue(Length - UnitLengthBytes, OffsetSize);
923 // The 2 byte version, which is 2.
924 MCOS->emitInt16(2);
925 // The 4 (8 for DWARF64) byte offset to the compile unit in the .debug_info
926 // from the start of the .debug_info.
927 if (InfoSectionSymbol)
928 MCOS->emitSymbolValue(InfoSectionSymbol, OffsetSize,
930 else
931 MCOS->emitIntValue(0, OffsetSize);
932 // The 1 byte size of an address.
933 MCOS->emitInt8(AddrSize);
934 // The 1 byte size of a segment descriptor, we use a value of zero.
935 MCOS->emitInt8(0);
936 // Align the header with the padding if needed, before we put out the table.
937 for(int i = 0; i < Pad; i++)
938 MCOS->emitInt8(0);
939
940 // Now emit the table of pairs of PointerSize'ed values for the section
941 // addresses and sizes.
942 for (MCSection *Sec : Sections) {
943 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
944 MCSymbol *EndSymbol = Sec->getEndSymbol(context);
945 assert(StartSymbol && "StartSymbol must not be NULL");
946 assert(EndSymbol && "EndSymbol must not be NULL");
947
948 const MCExpr *Addr = MCSymbolRefExpr::create(StartSymbol, context);
949 const MCExpr *Size =
950 makeEndMinusStartExpr(context, *StartSymbol, *EndSymbol, 0);
951 MCOS->emitValue(Addr, AddrSize);
952 emitAbsValue(*MCOS, Size, AddrSize);
953 }
954
955 // And finally the pair of terminating zeros.
956 MCOS->emitIntValue(0, AddrSize);
957 MCOS->emitIntValue(0, AddrSize);
958}
959
960// When generating dwarf for assembly source files this emits the data for
961// .debug_info section which contains three parts. The header, the compile_unit
962// DIE and a list of label DIEs.
963static void EmitGenDwarfInfo(MCStreamer *MCOS,
964 const MCSymbol *AbbrevSectionSymbol,
965 const MCSymbol *LineSectionSymbol,
966 const MCSymbol *RangesSymbol) {
967 MCContext &context = MCOS->getContext();
968
970
971 // Create a symbol at the start and end of this section used in here for the
972 // expression to calculate the length in the header.
973 MCSymbol *InfoStart = context.createTempSymbol();
974 MCOS->emitLabel(InfoStart);
975 MCSymbol *InfoEnd = context.createTempSymbol();
976
977 // First part: the header.
978
979 unsigned UnitLengthBytes =
981 unsigned OffsetSize = dwarf::getDwarfOffsetByteSize(context.getDwarfFormat());
982
983 if (context.getDwarfFormat() == dwarf::DWARF64)
984 // Emit DWARF64 mark.
986
987 // The 4 (8 for DWARF64) byte total length of the information for this
988 // compilation unit, not including the unit length field itself.
989 const MCExpr *Length =
990 makeEndMinusStartExpr(context, *InfoStart, *InfoEnd, UnitLengthBytes);
991 emitAbsValue(*MCOS, Length, OffsetSize);
992
993 // The 2 byte DWARF version.
994 MCOS->emitInt16(context.getDwarfVersion());
995
996 // The DWARF v5 header has unit type, address size, abbrev offset.
997 // Earlier versions have abbrev offset, address size.
998 const MCAsmInfo &AsmInfo = *context.getAsmInfo();
999 int AddrSize = AsmInfo.getCodePointerSize();
1000 if (context.getDwarfVersion() >= 5) {
1001 MCOS->emitInt8(dwarf::DW_UT_compile);
1002 MCOS->emitInt8(AddrSize);
1003 }
1004 // The 4 (8 for DWARF64) byte offset to the debug abbrevs from the start of
1005 // the .debug_abbrev.
1006 if (AbbrevSectionSymbol)
1007 MCOS->emitSymbolValue(AbbrevSectionSymbol, OffsetSize,
1009 else
1010 // Since the abbrevs are at the start of the section, the offset is zero.
1011 MCOS->emitIntValue(0, OffsetSize);
1012 if (context.getDwarfVersion() <= 4)
1013 MCOS->emitInt8(AddrSize);
1014
1015 // Second part: the compile_unit DIE.
1016
1017 // The DW_TAG_compile_unit DIE abbrev (1).
1018 MCOS->emitULEB128IntValue(1);
1019
1020 // DW_AT_stmt_list, a 4 (8 for DWARF64) byte offset from the start of the
1021 // .debug_line section.
1022 if (LineSectionSymbol)
1023 MCOS->emitSymbolValue(LineSectionSymbol, OffsetSize,
1025 else
1026 // The line table is at the start of the section, so the offset is zero.
1027 MCOS->emitIntValue(0, OffsetSize);
1028
1029 if (RangesSymbol) {
1030 // There are multiple sections containing code, so we must use
1031 // .debug_ranges/.debug_rnglists. AT_ranges, the 4/8 byte offset from the
1032 // start of the .debug_ranges/.debug_rnglists.
1033 MCOS->emitSymbolValue(RangesSymbol, OffsetSize);
1034 } else {
1035 // If we only have one non-empty code section, we can use the simpler
1036 // AT_low_pc and AT_high_pc attributes.
1037
1038 // Find the first (and only) non-empty text section
1039 auto &Sections = context.getGenDwarfSectionSyms();
1040 const auto TextSection = Sections.begin();
1041 assert(TextSection != Sections.end() && "No text section found");
1042
1043 MCSymbol *StartSymbol = (*TextSection)->getBeginSymbol();
1044 MCSymbol *EndSymbol = (*TextSection)->getEndSymbol(context);
1045 assert(StartSymbol && "StartSymbol must not be NULL");
1046 assert(EndSymbol && "EndSymbol must not be NULL");
1047
1048 // AT_low_pc, the first address of the default .text section.
1049 const MCExpr *Start = MCSymbolRefExpr::create(StartSymbol, context);
1050 MCOS->emitValue(Start, AddrSize);
1051
1052 // AT_high_pc, the last address of the default .text section.
1053 const MCExpr *End = MCSymbolRefExpr::create(EndSymbol, context);
1054 MCOS->emitValue(End, AddrSize);
1055 }
1056
1057 // AT_name, the name of the source file. Reconstruct from the first directory
1058 // and file table entries.
1059 const SmallVectorImpl<std::string> &MCDwarfDirs = context.getMCDwarfDirs();
1060 if (MCDwarfDirs.size() > 0) {
1061 MCOS->emitBytes(MCDwarfDirs[0]);
1063 }
1064 const SmallVectorImpl<MCDwarfFile> &MCDwarfFiles = context.getMCDwarfFiles();
1065 // MCDwarfFiles might be empty if we have an empty source file.
1066 // If it's not empty, [0] is unused and [1] is the first actual file.
1067 assert(MCDwarfFiles.empty() || MCDwarfFiles.size() >= 2);
1068 const MCDwarfFile &RootFile =
1069 MCDwarfFiles.empty()
1070 ? context.getMCDwarfLineTable(/*CUID=*/0).getRootFile()
1071 : MCDwarfFiles[1];
1072 MCOS->emitBytes(RootFile.Name);
1073 MCOS->emitInt8(0); // NULL byte to terminate the string.
1074
1075 // AT_comp_dir, the working directory the assembly was done in.
1076 if (!context.getCompilationDir().empty()) {
1077 MCOS->emitBytes(context.getCompilationDir());
1078 MCOS->emitInt8(0); // NULL byte to terminate the string.
1079 }
1080
1081 // AT_APPLE_flags, the command line arguments of the assembler tool.
1082 StringRef DwarfDebugFlags = context.getDwarfDebugFlags();
1083 if (!DwarfDebugFlags.empty()){
1084 MCOS->emitBytes(DwarfDebugFlags);
1085 MCOS->emitInt8(0); // NULL byte to terminate the string.
1086 }
1087
1088 // AT_producer, the version of the assembler tool.
1089 StringRef DwarfDebugProducer = context.getDwarfDebugProducer();
1090 if (!DwarfDebugProducer.empty())
1091 MCOS->emitBytes(DwarfDebugProducer);
1092 else
1093 MCOS->emitBytes(StringRef("llvm-mc (based on LLVM " PACKAGE_VERSION ")"));
1094 MCOS->emitInt8(0); // NULL byte to terminate the string.
1095
1096 // AT_language, a 4 byte value. We use DW_LANG_Mips_Assembler as the dwarf2
1097 // draft has no standard code for assembler.
1098 MCOS->emitInt16(dwarf::DW_LANG_Mips_Assembler);
1099
1100 // Third part: the list of label DIEs.
1101
1102 // Loop on saved info for dwarf labels and create the DIEs for them.
1103 const std::vector<MCGenDwarfLabelEntry> &Entries =
1105 for (const auto &Entry : Entries) {
1106 // The DW_TAG_label DIE abbrev (2).
1107 MCOS->emitULEB128IntValue(2);
1108
1109 // AT_name, of the label without any leading underbar.
1110 MCOS->emitBytes(Entry.getName());
1111 MCOS->emitInt8(0); // NULL byte to terminate the string.
1112
1113 // AT_decl_file, index into the file table.
1114 MCOS->emitInt32(Entry.getFileNumber());
1115
1116 // AT_decl_line, source line number.
1117 MCOS->emitInt32(Entry.getLineNumber());
1118
1119 // AT_low_pc, start address of the label.
1120 const auto *AT_low_pc = MCSymbolRefExpr::create(Entry.getLabel(), context);
1121 MCOS->emitValue(AT_low_pc, AddrSize);
1122 }
1123
1124 // Add the NULL DIE terminating the Compile Unit DIE's.
1125 MCOS->emitInt8(0);
1126
1127 // Now set the value of the symbol at the end of the info section.
1128 MCOS->emitLabel(InfoEnd);
1129}
1130
1131// When generating dwarf for assembly source files this emits the data for
1132// .debug_ranges section. We only emit one range list, which spans all of the
1133// executable sections of this file.
1135 MCContext &context = MCOS->getContext();
1136 auto &Sections = context.getGenDwarfSectionSyms();
1137
1138 const MCAsmInfo *AsmInfo = context.getAsmInfo();
1139 int AddrSize = AsmInfo->getCodePointerSize();
1140 MCSymbol *RangesSymbol;
1141
1142 if (MCOS->getContext().getDwarfVersion() >= 5) {
1144 MCSymbol *EndSymbol = mcdwarf::emitListsTableHeaderStart(*MCOS);
1145 MCOS->AddComment("Offset entry count");
1146 MCOS->emitInt32(0);
1147 RangesSymbol = context.createTempSymbol("debug_rnglist0_start");
1148 MCOS->emitLabel(RangesSymbol);
1149 for (MCSection *Sec : Sections) {
1150 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
1151 const MCSymbol *EndSymbol = Sec->getEndSymbol(context);
1152 const MCExpr *SectionStartAddr =
1153 MCSymbolRefExpr::create(StartSymbol, context);
1154 const MCExpr *SectionSize =
1155 makeEndMinusStartExpr(context, *StartSymbol, *EndSymbol, 0);
1156 MCOS->emitInt8(dwarf::DW_RLE_start_length);
1157 MCOS->emitValue(SectionStartAddr, AddrSize);
1158 MCOS->emitULEB128Value(SectionSize);
1159 }
1160 MCOS->emitInt8(dwarf::DW_RLE_end_of_list);
1161 MCOS->emitLabel(EndSymbol);
1162 } else {
1164 RangesSymbol = context.createTempSymbol("debug_ranges_start");
1165 MCOS->emitLabel(RangesSymbol);
1166 for (MCSection *Sec : Sections) {
1167 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
1168 const MCSymbol *EndSymbol = Sec->getEndSymbol(context);
1169
1170 // Emit a base address selection entry for the section start.
1171 const MCExpr *SectionStartAddr =
1172 MCSymbolRefExpr::create(StartSymbol, context);
1173 MCOS->emitFill(AddrSize, 0xFF);
1174 MCOS->emitValue(SectionStartAddr, AddrSize);
1175
1176 // Emit a range list entry spanning this section.
1177 const MCExpr *SectionSize =
1178 makeEndMinusStartExpr(context, *StartSymbol, *EndSymbol, 0);
1179 MCOS->emitIntValue(0, AddrSize);
1180 emitAbsValue(*MCOS, SectionSize, AddrSize);
1181 }
1182
1183 // Emit end of list entry
1184 MCOS->emitIntValue(0, AddrSize);
1185 MCOS->emitIntValue(0, AddrSize);
1186 }
1187
1188 return RangesSymbol;
1189}
1190
1191//
1192// When generating dwarf for assembly source files this emits the Dwarf
1193// sections.
1194//
1196 MCContext &context = MCOS->getContext();
1197
1198 // Create the dwarf sections in this order (.debug_line already created).
1199 const MCAsmInfo *AsmInfo = context.getAsmInfo();
1200 bool CreateDwarfSectionSymbols =
1202 MCSymbol *LineSectionSymbol = nullptr;
1203 if (CreateDwarfSectionSymbols)
1204 LineSectionSymbol = MCOS->getDwarfLineTableSymbol(0);
1205 MCSymbol *AbbrevSectionSymbol = nullptr;
1206 MCSymbol *InfoSectionSymbol = nullptr;
1207 MCSymbol *RangesSymbol = nullptr;
1208
1209 // Create end symbols for each section, and remove empty sections
1210 MCOS->getContext().finalizeDwarfSections(*MCOS);
1211
1212 // If there are no sections to generate debug info for, we don't need
1213 // to do anything
1214 if (MCOS->getContext().getGenDwarfSectionSyms().empty())
1215 return;
1216
1217 // We only use the .debug_ranges section if we have multiple code sections,
1218 // and we are emitting a DWARF version which supports it.
1219 const bool UseRangesSection =
1220 MCOS->getContext().getGenDwarfSectionSyms().size() > 1 &&
1221 MCOS->getContext().getDwarfVersion() >= 3;
1222 CreateDwarfSectionSymbols |= UseRangesSection;
1223
1225 if (CreateDwarfSectionSymbols) {
1226 InfoSectionSymbol = context.createTempSymbol();
1227 MCOS->emitLabel(InfoSectionSymbol);
1228 }
1230 if (CreateDwarfSectionSymbols) {
1231 AbbrevSectionSymbol = context.createTempSymbol();
1232 MCOS->emitLabel(AbbrevSectionSymbol);
1233 }
1234
1236
1237 // Output the data for .debug_aranges section.
1238 EmitGenDwarfAranges(MCOS, InfoSectionSymbol);
1239
1240 if (UseRangesSection) {
1241 RangesSymbol = emitGenDwarfRanges(MCOS);
1242 assert(RangesSymbol);
1243 }
1244
1245 // Output the data for .debug_abbrev section.
1246 EmitGenDwarfAbbrev(MCOS);
1247
1248 // Output the data for .debug_info section.
1249 EmitGenDwarfInfo(MCOS, AbbrevSectionSymbol, LineSectionSymbol, RangesSymbol);
1250}
1251
1252//
1253// When generating dwarf for assembly source files this is called when symbol
1254// for a label is created. If this symbol is not a temporary and is in the
1255// section that dwarf is being generated for, save the needed info to create
1256// a dwarf label.
1257//
1260 // We won't create dwarf labels for temporary symbols.
1261 if (Symbol->isTemporary())
1262 return;
1263 MCContext &context = MCOS->getContext();
1264 // We won't create dwarf labels for symbols in sections that we are not
1265 // generating debug info for.
1266 if (!context.getGenDwarfSectionSyms().count(MCOS->getCurrentSectionOnly()))
1267 return;
1268
1269 // The dwarf label's name does not have the symbol name's leading
1270 // underbar if any.
1271 StringRef Name = Symbol->getName();
1272 if (Name.starts_with("_"))
1273 Name = Name.substr(1, Name.size()-1);
1274
1275 // Get the dwarf file number to be used for the dwarf label.
1276 unsigned FileNumber = context.getGenDwarfFileNumber();
1277
1278 // Finding the line number is the expensive part which is why we just don't
1279 // pass it in as for some symbols we won't create a dwarf label.
1280 unsigned CurBuffer = SrcMgr.FindBufferContainingLoc(Loc);
1281 unsigned LineNumber = SrcMgr.FindLineNumber(Loc, CurBuffer);
1282
1283 // We create a temporary symbol for use for the AT_high_pc and AT_low_pc
1284 // values so that they don't have things like an ARM thumb bit from the
1285 // original symbol. So when used they won't get a low bit set after
1286 // relocation.
1287 MCSymbol *Label = context.createTempSymbol();
1288 MCOS->emitLabel(Label);
1289
1290 // Create and entry for the info and add it to the other entries.
1292 MCGenDwarfLabelEntry(Name, FileNumber, LineNumber, Label));
1293}
1294
1295static int getDataAlignmentFactor(MCStreamer &streamer) {
1296 MCContext &context = streamer.getContext();
1297 const MCAsmInfo *asmInfo = context.getAsmInfo();
1298 int size = asmInfo->getCalleeSaveStackSlotSize();
1299 if (asmInfo->isStackGrowthDirectionUp())
1300 return size;
1301 else
1302 return -size;
1303}
1304
1305static unsigned getSizeForEncoding(MCStreamer &streamer,
1306 unsigned symbolEncoding) {
1307 MCContext &context = streamer.getContext();
1308 unsigned format = symbolEncoding & 0x0f;
1309 switch (format) {
1310 default: llvm_unreachable("Unknown Encoding");
1313 return context.getAsmInfo()->getCodePointerSize();
1316 return 2;
1319 return 4;
1322 return 8;
1323 }
1324}
1325
1326static void emitFDESymbol(MCObjectStreamer &streamer, const MCSymbol &symbol,
1327 unsigned symbolEncoding, bool isEH) {
1328 MCContext &context = streamer.getContext();
1329 const MCAsmInfo *asmInfo = context.getAsmInfo();
1330 const MCExpr *v = asmInfo->getExprForFDESymbol(&symbol,
1331 symbolEncoding,
1332 streamer);
1333 unsigned size = getSizeForEncoding(streamer, symbolEncoding);
1334 if (asmInfo->doDwarfFDESymbolsUseAbsDiff() && isEH)
1335 emitAbsValue(streamer, v, size);
1336 else
1337 streamer.emitValue(v, size);
1338}
1339
1340static void EmitPersonality(MCStreamer &streamer, const MCSymbol &symbol,
1341 unsigned symbolEncoding) {
1342 MCContext &context = streamer.getContext();
1343 const MCAsmInfo *asmInfo = context.getAsmInfo();
1344 const MCExpr *v = asmInfo->getExprForPersonalitySymbol(&symbol,
1345 symbolEncoding,
1346 streamer);
1347 unsigned size = getSizeForEncoding(streamer, symbolEncoding);
1348 streamer.emitValue(v, size);
1349}
1350
1351namespace {
1352
1353class FrameEmitterImpl {
1354 int64_t CFAOffset = 0;
1355 int64_t InitialCFAOffset = 0;
1356 bool IsEH;
1357 MCObjectStreamer &Streamer;
1358
1359public:
1360 FrameEmitterImpl(bool IsEH, MCObjectStreamer &Streamer)
1361 : IsEH(IsEH), Streamer(Streamer) {}
1362
1363 /// Emit the unwind information in a compact way.
1364 void EmitCompactUnwind(const MCDwarfFrameInfo &frame);
1365
1366 const MCSymbol &EmitCIE(const MCDwarfFrameInfo &F);
1367 void EmitFDE(const MCSymbol &cieStart, const MCDwarfFrameInfo &frame,
1368 bool LastInSection, const MCSymbol &SectionStart);
1369 void emitCFIInstructions(ArrayRef<MCCFIInstruction> Instrs,
1370 MCSymbol *BaseLabel);
1371 void emitCFIInstruction(const MCCFIInstruction &Instr);
1372};
1373
1374} // end anonymous namespace
1375
1376static void emitEncodingByte(MCObjectStreamer &Streamer, unsigned Encoding) {
1377 Streamer.emitInt8(Encoding);
1378}
1379
1380void FrameEmitterImpl::emitCFIInstruction(const MCCFIInstruction &Instr) {
1381 int dataAlignmentFactor = getDataAlignmentFactor(Streamer);
1382 auto *MRI = Streamer.getContext().getRegisterInfo();
1383
1384 switch (Instr.getOperation()) {
1386 unsigned Reg1 = Instr.getRegister();
1387 unsigned Reg2 = Instr.getRegister2();
1388 if (!IsEH) {
1389 Reg1 = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg1);
1390 Reg2 = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg2);
1391 }
1392 Streamer.emitInt8(dwarf::DW_CFA_register);
1393 Streamer.emitULEB128IntValue(Reg1);
1394 Streamer.emitULEB128IntValue(Reg2);
1395 return;
1396 }
1398 Streamer.emitInt8(dwarf::DW_CFA_GNU_window_save);
1399 return;
1400
1402 Streamer.emitInt8(dwarf::DW_CFA_AARCH64_negate_ra_state);
1403 return;
1404
1406 Streamer.emitInt8(dwarf::DW_CFA_AARCH64_negate_ra_state_with_pc);
1407 return;
1408
1410 unsigned Reg = Instr.getRegister();
1411 Streamer.emitInt8(dwarf::DW_CFA_undefined);
1412 Streamer.emitULEB128IntValue(Reg);
1413 return;
1414 }
1417 const bool IsRelative =
1419
1420 Streamer.emitInt8(dwarf::DW_CFA_def_cfa_offset);
1421
1422 if (IsRelative)
1423 CFAOffset += Instr.getOffset();
1424 else
1425 CFAOffset = Instr.getOffset();
1426
1427 Streamer.emitULEB128IntValue(CFAOffset);
1428
1429 return;
1430 }
1432 unsigned Reg = Instr.getRegister();
1433 if (!IsEH)
1434 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1435 Streamer.emitInt8(dwarf::DW_CFA_def_cfa);
1436 Streamer.emitULEB128IntValue(Reg);
1437 CFAOffset = Instr.getOffset();
1438 Streamer.emitULEB128IntValue(CFAOffset);
1439
1440 return;
1441 }
1443 unsigned Reg = Instr.getRegister();
1444 if (!IsEH)
1445 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1446 Streamer.emitInt8(dwarf::DW_CFA_def_cfa_register);
1447 Streamer.emitULEB128IntValue(Reg);
1448
1449 return;
1450 }
1451 // TODO: Implement `_sf` variants if/when they need to be emitted.
1453 unsigned Reg = Instr.getRegister();
1454 if (!IsEH)
1455 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1456 Streamer.emitIntValue(dwarf::DW_CFA_LLVM_def_aspace_cfa, 1);
1457 Streamer.emitULEB128IntValue(Reg);
1458 CFAOffset = Instr.getOffset();
1459 Streamer.emitULEB128IntValue(CFAOffset);
1460 Streamer.emitULEB128IntValue(Instr.getAddressSpace());
1461
1462 return;
1463 }
1466 const bool IsRelative =
1467 Instr.getOperation() == MCCFIInstruction::OpRelOffset;
1468
1469 unsigned Reg = Instr.getRegister();
1470 if (!IsEH)
1471 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1472
1473 int64_t Offset = Instr.getOffset();
1474 if (IsRelative)
1475 Offset -= CFAOffset;
1476 Offset = Offset / dataAlignmentFactor;
1477
1478 if (Offset < 0) {
1479 Streamer.emitInt8(dwarf::DW_CFA_offset_extended_sf);
1480 Streamer.emitULEB128IntValue(Reg);
1481 Streamer.emitSLEB128IntValue(Offset);
1482 } else if (Reg < 64) {
1483 Streamer.emitInt8(dwarf::DW_CFA_offset + Reg);
1484 Streamer.emitULEB128IntValue(Offset);
1485 } else {
1486 Streamer.emitInt8(dwarf::DW_CFA_offset_extended);
1487 Streamer.emitULEB128IntValue(Reg);
1488 Streamer.emitULEB128IntValue(Offset);
1489 }
1490 return;
1491 }
1493 Streamer.emitInt8(dwarf::DW_CFA_remember_state);
1494 return;
1496 Streamer.emitInt8(dwarf::DW_CFA_restore_state);
1497 return;
1499 unsigned Reg = Instr.getRegister();
1500 Streamer.emitInt8(dwarf::DW_CFA_same_value);
1501 Streamer.emitULEB128IntValue(Reg);
1502 return;
1503 }
1505 unsigned Reg = Instr.getRegister();
1506 if (!IsEH)
1507 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1508 if (Reg < 64) {
1509 Streamer.emitInt8(dwarf::DW_CFA_restore | Reg);
1510 } else {
1511 Streamer.emitInt8(dwarf::DW_CFA_restore_extended);
1512 Streamer.emitULEB128IntValue(Reg);
1513 }
1514 return;
1515 }
1517 Streamer.emitInt8(dwarf::DW_CFA_GNU_args_size);
1518 Streamer.emitULEB128IntValue(Instr.getOffset());
1519 return;
1520
1522 Streamer.emitBytes(Instr.getValues());
1523 return;
1525 Streamer.emitLabel(Instr.getCfiLabel(), Instr.getLoc());
1526 return;
1528 unsigned Reg = Instr.getRegister();
1529 if (!IsEH)
1530 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1531
1532 int Offset = Instr.getOffset();
1533 Offset = Offset / dataAlignmentFactor;
1534
1535 if (Offset < 0) {
1536 Streamer.emitInt8(dwarf::DW_CFA_val_offset_sf);
1537 Streamer.emitULEB128IntValue(Reg);
1538 Streamer.emitSLEB128IntValue(Offset);
1539 } else {
1540 Streamer.emitInt8(dwarf::DW_CFA_val_offset);
1541 Streamer.emitULEB128IntValue(Reg);
1542 Streamer.emitULEB128IntValue(Offset);
1543 }
1544 return;
1545 }
1546 }
1547 llvm_unreachable("Unhandled case in switch");
1548}
1549
1550/// Emit frame instructions to describe the layout of the frame.
1551void FrameEmitterImpl::emitCFIInstructions(ArrayRef<MCCFIInstruction> Instrs,
1552 MCSymbol *BaseLabel) {
1553 for (const MCCFIInstruction &Instr : Instrs) {
1554 MCSymbol *Label = Instr.getLabel();
1555 // Throw out move if the label is invalid.
1556 if (Label && !Label->isDefined()) continue; // Not emitted, in dead code.
1557
1558 // Advance row if new location.
1559 if (BaseLabel && Label) {
1560 MCSymbol *ThisSym = Label;
1561 if (ThisSym != BaseLabel) {
1562 Streamer.emitDwarfAdvanceFrameAddr(BaseLabel, ThisSym, Instr.getLoc());
1563 BaseLabel = ThisSym;
1564 }
1565 }
1566
1567 emitCFIInstruction(Instr);
1568 }
1569}
1570
1571/// Emit the unwind information in a compact way.
1572void FrameEmitterImpl::EmitCompactUnwind(const MCDwarfFrameInfo &Frame) {
1573 MCContext &Context = Streamer.getContext();
1574 const MCObjectFileInfo *MOFI = Context.getObjectFileInfo();
1575
1576 // range-start range-length compact-unwind-enc personality-func lsda
1577 // _foo LfooEnd-_foo 0x00000023 0 0
1578 // _bar LbarEnd-_bar 0x00000025 __gxx_personality except_tab1
1579 //
1580 // .section __LD,__compact_unwind,regular,debug
1581 //
1582 // # compact unwind for _foo
1583 // .quad _foo
1584 // .set L1,LfooEnd-_foo
1585 // .long L1
1586 // .long 0x01010001
1587 // .quad 0
1588 // .quad 0
1589 //
1590 // # compact unwind for _bar
1591 // .quad _bar
1592 // .set L2,LbarEnd-_bar
1593 // .long L2
1594 // .long 0x01020011
1595 // .quad __gxx_personality
1596 // .quad except_tab1
1597
1598 uint32_t Encoding = Frame.CompactUnwindEncoding;
1599 if (!Encoding) return;
1600 bool DwarfEHFrameOnly = (Encoding == MOFI->getCompactUnwindDwarfEHFrameOnly());
1601
1602 // The encoding needs to know we have an LSDA.
1603 if (!DwarfEHFrameOnly && Frame.Lsda)
1604 Encoding |= 0x40000000;
1605
1606 // Range Start
1607 unsigned FDEEncoding = MOFI->getFDEEncoding();
1608 unsigned Size = getSizeForEncoding(Streamer, FDEEncoding);
1609 Streamer.emitSymbolValue(Frame.Begin, Size);
1610
1611 // Range Length
1612 const MCExpr *Range =
1613 makeEndMinusStartExpr(Context, *Frame.Begin, *Frame.End, 0);
1614 emitAbsValue(Streamer, Range, 4);
1615
1616 // Compact Encoding
1618 Streamer.emitIntValue(Encoding, Size);
1619
1620 // Personality Function
1622 if (!DwarfEHFrameOnly && Frame.Personality)
1623 Streamer.emitSymbolValue(Frame.Personality, Size);
1624 else
1625 Streamer.emitIntValue(0, Size); // No personality fn
1626
1627 // LSDA
1628 Size = getSizeForEncoding(Streamer, Frame.LsdaEncoding);
1629 if (!DwarfEHFrameOnly && Frame.Lsda)
1630 Streamer.emitSymbolValue(Frame.Lsda, Size);
1631 else
1632 Streamer.emitIntValue(0, Size); // No LSDA
1633}
1634
1635static unsigned getCIEVersion(bool IsEH, unsigned DwarfVersion) {
1636 if (IsEH)
1637 return 1;
1638 switch (DwarfVersion) {
1639 case 2:
1640 return 1;
1641 case 3:
1642 return 3;
1643 case 4:
1644 case 5:
1645 return 4;
1646 }
1647 llvm_unreachable("Unknown version");
1648}
1649
1650const MCSymbol &FrameEmitterImpl::EmitCIE(const MCDwarfFrameInfo &Frame) {
1651 MCContext &context = Streamer.getContext();
1652 const MCRegisterInfo *MRI = context.getRegisterInfo();
1653 const MCObjectFileInfo *MOFI = context.getObjectFileInfo();
1654
1655 MCSymbol *sectionStart = context.createTempSymbol();
1656 Streamer.emitLabel(sectionStart);
1657
1658 MCSymbol *sectionEnd = context.createTempSymbol();
1659
1661 unsigned UnitLengthBytes = dwarf::getUnitLengthFieldByteSize(Format);
1662 unsigned OffsetSize = dwarf::getDwarfOffsetByteSize(Format);
1663 bool IsDwarf64 = Format == dwarf::DWARF64;
1664
1665 if (IsDwarf64)
1666 // DWARF64 mark
1667 Streamer.emitInt32(dwarf::DW_LENGTH_DWARF64);
1668
1669 // Length
1670 const MCExpr *Length = makeEndMinusStartExpr(context, *sectionStart,
1671 *sectionEnd, UnitLengthBytes);
1672 emitAbsValue(Streamer, Length, OffsetSize);
1673
1674 // CIE ID
1675 uint64_t CIE_ID =
1676 IsEH ? 0 : (IsDwarf64 ? dwarf::DW64_CIE_ID : dwarf::DW_CIE_ID);
1677 Streamer.emitIntValue(CIE_ID, OffsetSize);
1678
1679 // Version
1680 uint8_t CIEVersion = getCIEVersion(IsEH, context.getDwarfVersion());
1681 Streamer.emitInt8(CIEVersion);
1682
1683 if (IsEH) {
1684 SmallString<8> Augmentation;
1685 Augmentation += "z";
1686 if (Frame.Personality)
1687 Augmentation += "P";
1688 if (Frame.Lsda)
1689 Augmentation += "L";
1690 Augmentation += "R";
1691 if (Frame.IsSignalFrame)
1692 Augmentation += "S";
1693 if (Frame.IsBKeyFrame)
1694 Augmentation += "B";
1695 if (Frame.IsMTETaggedFrame)
1696 Augmentation += "G";
1697 Streamer.emitBytes(Augmentation);
1698 }
1699 Streamer.emitInt8(0);
1700
1701 if (CIEVersion >= 4) {
1702 // Address Size
1703 Streamer.emitInt8(context.getAsmInfo()->getCodePointerSize());
1704
1705 // Segment Descriptor Size
1706 Streamer.emitInt8(0);
1707 }
1708
1709 // Code Alignment Factor
1710 Streamer.emitULEB128IntValue(context.getAsmInfo()->getMinInstAlignment());
1711
1712 // Data Alignment Factor
1713 Streamer.emitSLEB128IntValue(getDataAlignmentFactor(Streamer));
1714
1715 // Return Address Register
1716 unsigned RAReg = Frame.RAReg;
1717 if (RAReg == static_cast<unsigned>(INT_MAX))
1718 RAReg = MRI->getDwarfRegNum(MRI->getRARegister(), IsEH);
1719
1720 if (CIEVersion == 1) {
1721 assert(RAReg <= 255 &&
1722 "DWARF 2 encodes return_address_register in one byte");
1723 Streamer.emitInt8(RAReg);
1724 } else {
1725 Streamer.emitULEB128IntValue(RAReg);
1726 }
1727
1728 // Augmentation Data Length (optional)
1729 unsigned augmentationLength = 0;
1730 if (IsEH) {
1731 if (Frame.Personality) {
1732 // Personality Encoding
1733 augmentationLength += 1;
1734 // Personality
1735 augmentationLength +=
1736 getSizeForEncoding(Streamer, Frame.PersonalityEncoding);
1737 }
1738 if (Frame.Lsda)
1739 augmentationLength += 1;
1740 // Encoding of the FDE pointers
1741 augmentationLength += 1;
1742
1743 Streamer.emitULEB128IntValue(augmentationLength);
1744
1745 // Augmentation Data (optional)
1746 if (Frame.Personality) {
1747 // Personality Encoding
1748 emitEncodingByte(Streamer, Frame.PersonalityEncoding);
1749 // Personality
1750 EmitPersonality(Streamer, *Frame.Personality, Frame.PersonalityEncoding);
1751 }
1752
1753 if (Frame.Lsda)
1754 emitEncodingByte(Streamer, Frame.LsdaEncoding);
1755
1756 // Encoding of the FDE pointers
1757 emitEncodingByte(Streamer, MOFI->getFDEEncoding());
1758 }
1759
1760 // Initial Instructions
1761
1762 const MCAsmInfo *MAI = context.getAsmInfo();
1763 if (!Frame.IsSimple) {
1764 const std::vector<MCCFIInstruction> &Instructions =
1765 MAI->getInitialFrameState();
1766 emitCFIInstructions(Instructions, nullptr);
1767 }
1768
1769 InitialCFAOffset = CFAOffset;
1770
1771 // Padding
1772 Streamer.emitValueToAlignment(Align(IsEH ? 4 : MAI->getCodePointerSize()));
1773
1774 Streamer.emitLabel(sectionEnd);
1775 return *sectionStart;
1776}
1777
1778void FrameEmitterImpl::EmitFDE(const MCSymbol &cieStart,
1779 const MCDwarfFrameInfo &frame,
1780 bool LastInSection,
1781 const MCSymbol &SectionStart) {
1782 MCContext &context = Streamer.getContext();
1783 MCSymbol *fdeStart = context.createTempSymbol();
1784 MCSymbol *fdeEnd = context.createTempSymbol();
1785 const MCObjectFileInfo *MOFI = context.getObjectFileInfo();
1786
1787 CFAOffset = InitialCFAOffset;
1788
1790 unsigned OffsetSize = dwarf::getDwarfOffsetByteSize(Format);
1791
1792 if (Format == dwarf::DWARF64)
1793 // DWARF64 mark
1794 Streamer.emitInt32(dwarf::DW_LENGTH_DWARF64);
1795
1796 // Length
1797 const MCExpr *Length = makeEndMinusStartExpr(context, *fdeStart, *fdeEnd, 0);
1798 emitAbsValue(Streamer, Length, OffsetSize);
1799
1800 Streamer.emitLabel(fdeStart);
1801
1802 // CIE Pointer
1803 const MCAsmInfo *asmInfo = context.getAsmInfo();
1804 if (IsEH) {
1805 const MCExpr *offset =
1806 makeEndMinusStartExpr(context, cieStart, *fdeStart, 0);
1807 emitAbsValue(Streamer, offset, OffsetSize);
1808 } else if (!asmInfo->doesDwarfUseRelocationsAcrossSections()) {
1809 const MCExpr *offset =
1810 makeEndMinusStartExpr(context, SectionStart, cieStart, 0);
1811 emitAbsValue(Streamer, offset, OffsetSize);
1812 } else {
1813 Streamer.emitSymbolValue(&cieStart, OffsetSize,
1815 }
1816
1817 // PC Begin
1818 unsigned PCEncoding =
1819 IsEH ? MOFI->getFDEEncoding() : (unsigned)dwarf::DW_EH_PE_absptr;
1820 unsigned PCSize = getSizeForEncoding(Streamer, PCEncoding);
1821 emitFDESymbol(Streamer, *frame.Begin, PCEncoding, IsEH);
1822
1823 // PC Range
1824 const MCExpr *Range =
1825 makeEndMinusStartExpr(context, *frame.Begin, *frame.End, 0);
1826 emitAbsValue(Streamer, Range, PCSize);
1827
1828 if (IsEH) {
1829 // Augmentation Data Length
1830 unsigned augmentationLength = 0;
1831
1832 if (frame.Lsda)
1833 augmentationLength += getSizeForEncoding(Streamer, frame.LsdaEncoding);
1834
1835 Streamer.emitULEB128IntValue(augmentationLength);
1836
1837 // Augmentation Data
1838 if (frame.Lsda)
1839 emitFDESymbol(Streamer, *frame.Lsda, frame.LsdaEncoding, true);
1840 }
1841
1842 // Call Frame Instructions
1843 emitCFIInstructions(frame.Instructions, frame.Begin);
1844
1845 // Padding
1846 // The size of a .eh_frame section has to be a multiple of the alignment
1847 // since a null CIE is interpreted as the end. Old systems overaligned
1848 // .eh_frame, so we do too and account for it in the last FDE.
1849 unsigned Alignment = LastInSection ? asmInfo->getCodePointerSize() : PCSize;
1850 Streamer.emitValueToAlignment(Align(Alignment));
1851
1852 Streamer.emitLabel(fdeEnd);
1853}
1854
1855namespace {
1856
1857struct CIEKey {
1858 CIEKey() = default;
1859
1860 explicit CIEKey(const MCDwarfFrameInfo &Frame)
1861 : Personality(Frame.Personality),
1862 PersonalityEncoding(Frame.PersonalityEncoding),
1863 LsdaEncoding(Frame.LsdaEncoding), IsSignalFrame(Frame.IsSignalFrame),
1864 IsSimple(Frame.IsSimple), RAReg(Frame.RAReg),
1865 IsBKeyFrame(Frame.IsBKeyFrame),
1866 IsMTETaggedFrame(Frame.IsMTETaggedFrame) {}
1867
1868 StringRef PersonalityName() const {
1869 if (!Personality)
1870 return StringRef();
1871 return Personality->getName();
1872 }
1873
1874 bool operator<(const CIEKey &Other) const {
1875 return std::make_tuple(PersonalityName(), PersonalityEncoding, LsdaEncoding,
1876 IsSignalFrame, IsSimple, RAReg, IsBKeyFrame,
1877 IsMTETaggedFrame) <
1878 std::make_tuple(Other.PersonalityName(), Other.PersonalityEncoding,
1879 Other.LsdaEncoding, Other.IsSignalFrame,
1880 Other.IsSimple, Other.RAReg, Other.IsBKeyFrame,
1881 Other.IsMTETaggedFrame);
1882 }
1883
1884 bool operator==(const CIEKey &Other) const {
1885 return Personality == Other.Personality &&
1886 PersonalityEncoding == Other.PersonalityEncoding &&
1887 LsdaEncoding == Other.LsdaEncoding &&
1888 IsSignalFrame == Other.IsSignalFrame && IsSimple == Other.IsSimple &&
1889 RAReg == Other.RAReg && IsBKeyFrame == Other.IsBKeyFrame &&
1890 IsMTETaggedFrame == Other.IsMTETaggedFrame;
1891 }
1892 bool operator!=(const CIEKey &Other) const { return !(*this == Other); }
1893
1894 const MCSymbol *Personality = nullptr;
1895 unsigned PersonalityEncoding = 0;
1896 unsigned LsdaEncoding = -1;
1897 bool IsSignalFrame = false;
1898 bool IsSimple = false;
1899 unsigned RAReg = UINT_MAX;
1900 bool IsBKeyFrame = false;
1901 bool IsMTETaggedFrame = false;
1902};
1903
1904} // end anonymous namespace
1905
1907 bool IsEH) {
1908 MCContext &Context = Streamer.getContext();
1909 const MCObjectFileInfo *MOFI = Context.getObjectFileInfo();
1910 const MCAsmInfo *AsmInfo = Context.getAsmInfo();
1911 FrameEmitterImpl Emitter(IsEH, Streamer);
1912 ArrayRef<MCDwarfFrameInfo> FrameArray = Streamer.getDwarfFrameInfos();
1913
1914 // Emit the compact unwind info if available.
1915 bool NeedsEHFrameSection = !MOFI->getSupportsCompactUnwindWithoutEHFrame();
1916 if (IsEH && MOFI->getCompactUnwindSection()) {
1917 Streamer.generateCompactUnwindEncodings(MAB);
1918 bool SectionEmitted = false;
1919 for (const MCDwarfFrameInfo &Frame : FrameArray) {
1920 if (Frame.CompactUnwindEncoding == 0) continue;
1921 if (!SectionEmitted) {
1922 Streamer.switchSection(MOFI->getCompactUnwindSection());
1923 Streamer.emitValueToAlignment(Align(AsmInfo->getCodePointerSize()));
1924 SectionEmitted = true;
1925 }
1926 NeedsEHFrameSection |=
1927 Frame.CompactUnwindEncoding ==
1929 Emitter.EmitCompactUnwind(Frame);
1930 }
1931 }
1932
1933 // Compact unwind information can be emitted in the eh_frame section or the
1934 // debug_frame section. Skip emitting FDEs and CIEs when the compact unwind
1935 // doesn't need an eh_frame section and the emission location is the eh_frame
1936 // section.
1937 if (!NeedsEHFrameSection && IsEH) return;
1938
1939 MCSection &Section =
1940 IsEH ? *const_cast<MCObjectFileInfo *>(MOFI)->getEHFrameSection()
1941 : *MOFI->getDwarfFrameSection();
1942
1943 Streamer.switchSection(&Section);
1944 MCSymbol *SectionStart = Context.createTempSymbol();
1945 Streamer.emitLabel(SectionStart);
1946
1947 bool CanOmitDwarf = MOFI->getOmitDwarfIfHaveCompactUnwind();
1948 // Sort the FDEs by their corresponding CIE before we emit them.
1949 // This isn't technically necessary according to the DWARF standard,
1950 // but the Android libunwindstack rejects eh_frame sections where
1951 // an FDE refers to a CIE other than the closest previous CIE.
1952 std::vector<MCDwarfFrameInfo> FrameArrayX(FrameArray.begin(), FrameArray.end());
1953 llvm::stable_sort(FrameArrayX,
1954 [](const MCDwarfFrameInfo &X, const MCDwarfFrameInfo &Y) {
1955 return CIEKey(X) < CIEKey(Y);
1956 });
1957 CIEKey LastKey;
1958 const MCSymbol *LastCIEStart = nullptr;
1959 for (auto I = FrameArrayX.begin(), E = FrameArrayX.end(); I != E;) {
1960 const MCDwarfFrameInfo &Frame = *I;
1961 ++I;
1962 if (CanOmitDwarf && Frame.CompactUnwindEncoding !=
1963 MOFI->getCompactUnwindDwarfEHFrameOnly() && IsEH)
1964 // CIEs and FDEs can be emitted in either the eh_frame section or the
1965 // debug_frame section, on some platforms (e.g. AArch64) the target object
1966 // file supports emitting a compact_unwind section without an associated
1967 // eh_frame section. If the eh_frame section is not needed, and the
1968 // location where the CIEs and FDEs are to be emitted is the eh_frame
1969 // section, do not emit anything.
1970 continue;
1971
1972 CIEKey Key(Frame);
1973 if (!LastCIEStart || (IsEH && Key != LastKey)) {
1974 LastKey = Key;
1975 LastCIEStart = &Emitter.EmitCIE(Frame);
1976 }
1977
1978 Emitter.EmitFDE(*LastCIEStart, Frame, I == E, *SectionStart);
1979 }
1980}
1981
1983 uint64_t AddrDelta,
1984 SmallVectorImpl<char> &Out) {
1985 // Scale the address delta by the minimum instruction length.
1986 AddrDelta = ScaleAddrDelta(Context, AddrDelta);
1987 if (AddrDelta == 0)
1988 return;
1989
1990 llvm::endianness E = Context.getAsmInfo()->isLittleEndian()
1993
1994 if (isUIntN(6, AddrDelta)) {
1995 uint8_t Opcode = dwarf::DW_CFA_advance_loc | AddrDelta;
1996 Out.push_back(Opcode);
1997 } else if (isUInt<8>(AddrDelta)) {
1998 Out.push_back(dwarf::DW_CFA_advance_loc1);
1999 Out.push_back(AddrDelta);
2000 } else if (isUInt<16>(AddrDelta)) {
2001 Out.push_back(dwarf::DW_CFA_advance_loc2);
2002 support::endian::write<uint16_t>(Out, AddrDelta, E);
2003 } else {
2004 assert(isUInt<32>(AddrDelta));
2005 Out.push_back(dwarf::DW_CFA_advance_loc4);
2006 support::endian::write<uint32_t>(Out, AddrDelta, E);
2007 }
2008}
unsigned const MachineRegisterInfo * MRI
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:1326
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:885
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:1635
static void EmitGenDwarfInfo(MCStreamer *MCOS, const MCSymbol *AbbrevSectionSymbol, const MCSymbol *LineSectionSymbol, const MCSymbol *RangesSymbol)
Definition MCDwarf.cpp:963
static void EmitAbbrev(MCStreamer *MCOS, uint64_t Name, uint64_t Form)
Definition MCDwarf.cpp:829
static void EmitPersonality(MCStreamer &streamer, const MCSymbol &symbol, unsigned symbolEncoding)
Definition MCDwarf.cpp:1340
static void emitEncodingByte(MCObjectStreamer &Streamer, unsigned Encoding)
Definition MCDwarf.cpp:1376
static int getDataAlignmentFactor(MCStreamer &streamer)
Definition MCDwarf.cpp:1295
static MCSymbol * emitGenDwarfRanges(MCStreamer *MCOS)
Definition MCDwarf.cpp:1134
static const MCExpr * makeStartPlusIntExpr(MCContext &Ctx, const MCSymbol &Start, int IntVal)
Definition MCDwarf.cpp:135
static void EmitGenDwarfAbbrev(MCStreamer *MCOS)
Definition MCDwarf.cpp:836
static unsigned getSizeForEncoding(MCStreamer &streamer, unsigned symbolEncoding)
Definition MCDwarf.cpp:1305
#define DWARF2_FLAG_IS_STMT
Definition MCDwarf.h:118
#define DWARF2_FLAG_BASIC_BLOCK
Definition MCDwarf.h:119
#define DWARF2_LINE_DEFAULT_IS_STMT
Definition MCDwarf.h:116
#define DWARF2_FLAG_PROLOGUE_END
Definition MCDwarf.h:120
#define DWARF2_FLAG_EPILOGUE_BEGIN
Definition MCDwarf.h:121
#define F(x, y, z)
Definition MD5.cpp:55
#define I(x, y, z)
Definition MD5.cpp:58
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:41
iterator end() const
Definition ArrayRef.h:136
size_t size() const
size - Get the array size.
Definition ArrayRef.h:147
iterator begin() const
Definition ArrayRef.h:135
Tagged union holding either a T or a Error.
Definition Error.h:485
Generic interface to target specific assembler backends.
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:531
const std::vector< MCCFIInstruction > & getInitialFrameState() const
Definition MCAsmInfo.h:678
bool needsDwarfSectionOffsetDirective() const
Definition MCAsmInfo.h:513
bool doesDwarfUseRelocationsAcrossSections() const
Definition MCAsmInfo.h:658
virtual const MCExpr * getExprForFDESymbol(const MCSymbol *Sym, unsigned Encoding, MCStreamer &Streamer) const
Definition MCAsmInfo.cpp:86
bool isStackGrowthDirectionUp() const
True if target stack grow up.
Definition MCAsmInfo.h:455
unsigned getCalleeSaveStackSlotSize() const
Get the callee-saved register stack slot size in bytes.
Definition MCAsmInfo.h:447
bool doDwarfFDESymbolsUseAbsDiff() const
Definition MCAsmInfo.h:662
virtual const MCExpr * getExprForPersonalitySymbol(const MCSymbol *Sym, unsigned Encoding, MCStreamer &Streamer) const
Definition MCAsmInfo.cpp:79
unsigned getCodePointerSize() const
Get the code pointer size in bytes.
Definition MCAsmInfo.h:443
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, MCAsmBackend *MAB, bool isEH)
Definition MCDwarf.cpp:1906
static LLVM_ABI void encodeAdvanceLoc(MCContext &Context, uint64_t AddrDelta, SmallVectorImpl< char > &OS)
Definition MCDwarf.cpp:1982
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:189
void setEndLabel(MCSymbol *EndLabel)
Definition MCDwarf.h:219
MCDwarfLineEntry(MCSymbol *label, const MCDwarfLoc loc, MCSymbol *lineStreamLabel=nullptr, SMLoc streamLabelDefLoc={})
Definition MCDwarf.h:198
MCSymbol * LineStreamLabel
Definition MCDwarf.h:209
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:420
const MCLineSection & getMCLineSections() const
Definition MCDwarf.h:450
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:106
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:1195
MCGenDwarfLabelEntry(StringRef name, unsigned fileNumber, unsigned lineNumber, MCSymbol *label)
Definition MCDwarf.h:493
static LLVM_ABI void Make(MCSymbol *Symbol, MCStreamer *MCOS, SourceMgr &SrcMgr, SMLoc &Loc)
Definition MCDwarf.cpp:1258
LLVM_ABI void addEndEntry(MCSymbol *EndLabel)
Definition MCDwarf.cpp:142
void addLineEntry(const MCDwarfLineEntry &LineEntry, MCSection *Sec)
Definition MCDwarf.h:240
std::vector< MCDwarfLineEntry > MCDwarfLineEntryCollection
Definition MCDwarf.h:248
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...
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition MCSection.h:521
MCSymbol * getBeginSymbol()
Definition MCSection.h:593
Streaming machine code generation interface.
Definition MCStreamer.h:220
virtual void emitAssignment(MCSymbol *Symbol, const MCExpr *Value)
Emit an assignment of Value to Symbol.
void generateCompactUnwindEncodings(MCAsmBackend *MAB)
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:314
virtual void AddComment(const Twine &T, bool EOL=true)
Add a textual comment.
Definition MCStreamer.h:387
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:749
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:750
MCSection * getCurrentSectionOnly() const
Definition MCStreamer.h:421
virtual void emitDwarfLineEndEntry(MCSection *Section, MCSymbol *LastLabel, MCSymbol *EndLabel=nullptr)
Emit the debug line end entry.
void emitInt8(uint64_t Value)
Definition MCStreamer.h:748
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:23
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 append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This owns the files read by a parser, handles include stacks, and handles diagnostic wrangling.
Definition SourceMgr.h:32
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:581
constexpr bool empty() const
empty - Check if the string is empty.
Definition StringRef.h:151
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:1127
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:1088
@ DW_CHILDREN_no
Definition Dwarf.h:858
@ DW_EH_PE_signed
Definition Dwarf.h:871
@ DW_CHILDREN_yes
Definition Dwarf.h:859
@ DW_EH_PE_sdata4
Definition Dwarf.h:869
@ DW_EH_PE_udata2
Definition Dwarf.h:864
@ DW_EH_PE_sdata8
Definition Dwarf.h:870
@ DW_EH_PE_absptr
Definition Dwarf.h:861
@ DW_EH_PE_sdata2
Definition Dwarf.h:868
@ DW_EH_PE_udata4
Definition Dwarf.h:865
@ DW_EH_PE_udata8
Definition Dwarf.h:866
@ 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:92
LLVM_ABI StringRef get_separator(Style style=Style::native)
Return the preferred separator for this platform.
Definition Path.cpp:609
LLVM_ABI StringRef parent_path(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get parent path.
Definition Path.cpp:467
LLVM_ABI StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get filename.
Definition Path.cpp:577
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:477
@ Length
Definition DWP.cpp:477
bool operator<(int64_t V1, const APSInt &V2)
Definition APSInt.h:362
void stable_sort(R &&Range)
Definition STLExtras.h:2038
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:1731
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:1657
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:98
bool operator!=(uint64_t V1, const APInt &V2)
Definition APInt.h:2113
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
Definition MathExtras.h:252
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:198
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:548
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition Format.h:126
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 >
unsigned encodeSLEB128(int64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a SLEB128 value to an output stream.
Definition LEB128.h:24
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:81
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:88
std::optional< MD5::MD5Result > Checksum
The MD5 checksum, if there is one.
Definition MCDwarf.h:97
std::string Name
Definition MCDwarf.h:90
const MCSymbol * Personality
Definition MCDwarf.h:774
unsigned PersonalityEncoding
Definition MCDwarf.h:778
uint64_t CompactUnwindEncoding
Definition MCDwarf.h:780
std::vector< MCCFIInstruction > Instructions
Definition MCDwarf.h:776
const MCSymbol * Lsda
Definition MCDwarf.h:775
void trackMD5Usage(bool MD5Used)
Definition MCDwarf.h:310
SmallVector< MCDwarfFile, 3 > MCDwarfFiles
Definition MCDwarf.h:280
SmallVector< std::string, 3 > MCDwarfDirs
Definition MCDwarf.h:279
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:281
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:269
uint8_t DWARF2LineRange
Range of line offsets in a special line info. opcode.
Definition MCDwarf.h:274
int8_t DWARF2LineBase
Minimum line offset in a special line info.
Definition MCDwarf.h:272