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 *LastLabel;
185 auto init = [&]() {
186 FileNum = 1;
187 LastLine = 1;
188 Column = 0;
190 Isa = 0;
191 Discriminator = 0;
192 LastLabel = 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 (const MCDwarfLineEntry &LineEntry : LineEntries) {
200 MCSymbol *Label = LineEntry.getLabel();
201 const MCAsmInfo *asmInfo = MCOS->getContext().getAsmInfo();
202
203 if (LineEntry.LineStreamLabel) {
204 if (!IsAtStartSeq) {
205 MCOS->emitDwarfLineEndEntry(Section, LastLabel,
206 /*EndLabel =*/LastLabel);
207 init();
208 }
209 MCOS->emitLabel(LineEntry.LineStreamLabel, LineEntry.StreamLabelDefLoc);
210 continue;
211 }
212
213 if (LineEntry.IsEndEntry) {
214 MCOS->emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, Label,
215 asmInfo->getCodePointerSize());
216 init();
217 EndEntryEmitted = true;
218 continue;
219 }
220
221 int64_t LineDelta = static_cast<int64_t>(LineEntry.getLine()) - LastLine;
222
223 if (FileNum != LineEntry.getFileNum()) {
224 FileNum = LineEntry.getFileNum();
225 MCOS->emitInt8(dwarf::DW_LNS_set_file);
226 MCOS->emitULEB128IntValue(FileNum);
227 }
228 if (Column != LineEntry.getColumn()) {
229 Column = LineEntry.getColumn();
230 MCOS->emitInt8(dwarf::DW_LNS_set_column);
231 MCOS->emitULEB128IntValue(Column);
232 }
233 if (Discriminator != LineEntry.getDiscriminator() &&
234 MCOS->getContext().getDwarfVersion() >= 4) {
235 Discriminator = LineEntry.getDiscriminator();
236 unsigned Size = getULEB128Size(Discriminator);
237 MCOS->emitInt8(dwarf::DW_LNS_extended_op);
238 MCOS->emitULEB128IntValue(Size + 1);
239 MCOS->emitInt8(dwarf::DW_LNE_set_discriminator);
240 MCOS->emitULEB128IntValue(Discriminator);
241 }
242 if (Isa != LineEntry.getIsa()) {
243 Isa = LineEntry.getIsa();
244 MCOS->emitInt8(dwarf::DW_LNS_set_isa);
245 MCOS->emitULEB128IntValue(Isa);
246 }
247 if ((LineEntry.getFlags() ^ Flags) & DWARF2_FLAG_IS_STMT) {
248 Flags = LineEntry.getFlags();
249 MCOS->emitInt8(dwarf::DW_LNS_negate_stmt);
250 }
251 if (LineEntry.getFlags() & DWARF2_FLAG_BASIC_BLOCK)
252 MCOS->emitInt8(dwarf::DW_LNS_set_basic_block);
253 if (LineEntry.getFlags() & DWARF2_FLAG_PROLOGUE_END)
254 MCOS->emitInt8(dwarf::DW_LNS_set_prologue_end);
255 if (LineEntry.getFlags() & DWARF2_FLAG_EPILOGUE_BEGIN)
256 MCOS->emitInt8(dwarf::DW_LNS_set_epilogue_begin);
257
258 // At this point we want to emit/create the sequence to encode the delta in
259 // line numbers and the increment of the address from the previous Label
260 // and the current Label.
261 MCOS->emitDwarfAdvanceLineAddr(LineDelta, LastLabel, Label,
262 asmInfo->getCodePointerSize());
263
264 Discriminator = 0;
265 LastLine = LineEntry.getLine();
266 LastLabel = Label;
267 IsAtStartSeq = false;
268 }
269
270 // Generate DWARF line end entry.
271 // We do not need this for DwarfDebug that explicitly terminates the line
272 // table using ranges whenever CU or section changes. However, the MC path
273 // does not track ranges nor terminate the line table. In that case,
274 // conservatively use the section end symbol to end the line table.
275 if (!EndEntryEmitted && !IsAtStartSeq)
276 MCOS->emitDwarfLineEndEntry(Section, LastLabel);
277}
278
280 SMLoc DefLoc,
281 StringRef Name) {
282 auto &ctx = MCOS->getContext();
283 auto *LineStreamLabel = ctx.getOrCreateSymbol(Name);
284 auto *LineSym = ctx.createTempSymbol();
285 MCOS->emitLabel(LineSym);
286 const MCDwarfLoc &DwarfLoc = ctx.getCurrentDwarfLoc();
287
288 // Create a 'fake' line entry by having LineStreamLabel be non-null. This
289 // won't actually emit any line information, it will reset the line table
290 // sequence and emit a label at the start of the new line table sequence.
291 MCDwarfLineEntry LineEntry(LineSym, DwarfLoc, LineStreamLabel, DefLoc);
293}
294
295//
296// This emits the Dwarf file and the line tables.
297//
299 MCContext &context = MCOS->getContext();
300
301 auto &LineTables = context.getMCDwarfLineTables();
302
303 // Bail out early so we don't switch to the debug_line section needlessly and
304 // in doing so create an unnecessary (if empty) section.
305 if (LineTables.empty())
306 return;
307
308 // In a v5 non-split line table, put the strings in a separate section.
309 std::optional<MCDwarfLineStr> LineStr;
310 if (context.getDwarfVersion() >= 5)
311 LineStr.emplace(context);
312
313 // Switch to the section where the table will be emitted into.
315
316 // Handle the rest of the Compile Units.
317 for (const auto &CUIDTablePair : LineTables) {
318 CUIDTablePair.second.emitCU(MCOS, Params, LineStr);
319 }
320
321 if (LineStr)
322 LineStr->emitSection(MCOS);
323}
324
326 MCSection *Section) const {
327 if (!HasSplitLineTable)
328 return;
329 std::optional<MCDwarfLineStr> NoLineStr(std::nullopt);
330 MCOS.switchSection(Section);
331 MCOS.emitLabel(Header.Emit(&MCOS, Params, {}, NoLineStr).second);
332}
333
334std::pair<MCSymbol *, MCSymbol *>
336 std::optional<MCDwarfLineStr> &LineStr) const {
337 static const char StandardOpcodeLengths[] = {
338 0, // length of DW_LNS_copy
339 1, // length of DW_LNS_advance_pc
340 1, // length of DW_LNS_advance_line
341 1, // length of DW_LNS_set_file
342 1, // length of DW_LNS_set_column
343 0, // length of DW_LNS_negate_stmt
344 0, // length of DW_LNS_set_basic_block
345 0, // length of DW_LNS_const_add_pc
346 1, // length of DW_LNS_fixed_advance_pc
347 0, // length of DW_LNS_set_prologue_end
348 0, // length of DW_LNS_set_epilogue_begin
349 1 // DW_LNS_set_isa
350 };
351 assert(std::size(StandardOpcodeLengths) >=
352 (Params.DWARF2LineOpcodeBase - 1U));
353 return Emit(MCOS, Params,
354 ArrayRef(StandardOpcodeLengths, Params.DWARF2LineOpcodeBase - 1),
355 LineStr);
356}
357
358static const MCExpr *forceExpAbs(MCStreamer &OS, const MCExpr* Expr) {
359 MCContext &Context = OS.getContext();
361 if (!Context.getAsmInfo()->doesSetDirectiveSuppressReloc())
362 return Expr;
363
364 // On Mach-O, try to avoid a relocation by using a set directive.
365 MCSymbol *ABS = Context.createTempSymbol();
366 OS.emitAssignment(ABS, Expr);
367 return MCSymbolRefExpr::create(ABS, Context);
368}
369
370static void emitAbsValue(MCStreamer &OS, const MCExpr *Value, unsigned Size) {
371 const MCExpr *ABS = forceExpAbs(OS, Value);
372 OS.emitValue(ABS, Size);
373}
374
376 // Switch to the .debug_line_str section.
377 MCOS->switchSection(
380 MCOS->emitBinaryData(Data.str());
381}
382
384 // Emit the strings without perturbing the offsets we used.
385 if (!LineStrings.isFinalized())
386 LineStrings.finalizeInOrder();
388 Data.resize(LineStrings.getSize());
389 LineStrings.write((uint8_t *)Data.data());
390 return Data;
391}
392
394 return LineStrings.add(Path);
395}
396
398 int RefSize =
400 size_t Offset = addString(Path);
401 if (UseRelocs) {
402 MCContext &Ctx = MCOS->getContext();
403 if (Ctx.getAsmInfo()->needsDwarfSectionOffsetDirective()) {
404 MCOS->emitCOFFSecRel32(LineStrLabel, Offset);
405 } else {
406 MCOS->emitValue(makeStartPlusIntExpr(Ctx, *LineStrLabel, Offset),
407 RefSize);
408 }
409 } else
410 MCOS->emitIntValue(Offset, RefSize);
411}
412
413void MCDwarfLineTableHeader::emitV2FileDirTables(MCStreamer *MCOS) const {
414 // First the directory table.
415 for (auto &Dir : MCDwarfDirs) {
416 MCOS->emitBytes(Dir); // The DirectoryName, and...
417 MCOS->emitBytes(StringRef("\0", 1)); // its null terminator.
418 }
419 MCOS->emitInt8(0); // Terminate the directory list.
420
421 // Second the file table.
422 for (unsigned i = 1; i < MCDwarfFiles.size(); i++) {
423 assert(!MCDwarfFiles[i].Name.empty());
424 MCOS->emitBytes(MCDwarfFiles[i].Name); // FileName and...
425 MCOS->emitBytes(StringRef("\0", 1)); // its null terminator.
426 MCOS->emitULEB128IntValue(MCDwarfFiles[i].DirIndex); // Directory number.
427 MCOS->emitInt8(0); // Last modification timestamp (always 0).
428 MCOS->emitInt8(0); // File size (always 0).
429 }
430 MCOS->emitInt8(0); // Terminate the file list.
431}
432
434 bool EmitMD5, bool HasAnySource,
435 std::optional<MCDwarfLineStr> &LineStr) {
436 assert(!DwarfFile.Name.empty());
437 if (LineStr)
438 LineStr->emitRef(MCOS, DwarfFile.Name);
439 else {
440 MCOS->emitBytes(DwarfFile.Name); // FileName and...
441 MCOS->emitBytes(StringRef("\0", 1)); // its null terminator.
442 }
443 MCOS->emitULEB128IntValue(DwarfFile.DirIndex); // Directory number.
444 if (EmitMD5) {
445 const MD5::MD5Result &Cksum = *DwarfFile.Checksum;
446 MCOS->emitBinaryData(
447 StringRef(reinterpret_cast<const char *>(Cksum.data()), Cksum.size()));
448 }
449 if (HasAnySource) {
450 // From https://dwarfstd.org/issues/180201.1.html
451 // * The value is an empty null-terminated string if no source is available
452 StringRef Source = DwarfFile.Source.value_or(StringRef());
453 // * If the source is available but is an empty file then the value is a
454 // null-terminated single "\n".
455 if (DwarfFile.Source && DwarfFile.Source->empty())
456 Source = "\n";
457 if (LineStr)
458 LineStr->emitRef(MCOS, Source);
459 else {
460 MCOS->emitBytes(Source); // Source and...
461 MCOS->emitBytes(StringRef("\0", 1)); // its null terminator.
462 }
463 }
464}
465
466void MCDwarfLineTableHeader::emitV5FileDirTables(
467 MCStreamer *MCOS, std::optional<MCDwarfLineStr> &LineStr) const {
468 // The directory format, which is just a list of the directory paths. In a
469 // non-split object, these are references to .debug_line_str; in a split
470 // object, they are inline strings.
471 MCOS->emitInt8(1);
472 MCOS->emitULEB128IntValue(dwarf::DW_LNCT_path);
473 MCOS->emitULEB128IntValue(LineStr ? dwarf::DW_FORM_line_strp
474 : dwarf::DW_FORM_string);
475 MCOS->emitULEB128IntValue(MCDwarfDirs.size() + 1);
476 // Try not to emit an empty compilation directory.
477 SmallString<256> Dir;
478 StringRef CompDir = MCOS->getContext().getCompilationDir();
479 if (!CompilationDir.empty()) {
480 Dir = CompilationDir;
481 MCOS->getContext().remapDebugPath(Dir);
482 CompDir = Dir.str();
483 if (LineStr)
484 CompDir = LineStr->getSaver().save(CompDir);
485 }
486 if (LineStr) {
487 // Record path strings, emit references here.
488 LineStr->emitRef(MCOS, CompDir);
489 for (const auto &Dir : MCDwarfDirs)
490 LineStr->emitRef(MCOS, Dir);
491 } else {
492 // The list of directory paths. Compilation directory comes first.
493 MCOS->emitBytes(CompDir);
494 MCOS->emitBytes(StringRef("\0", 1));
495 for (const auto &Dir : MCDwarfDirs) {
496 MCOS->emitBytes(Dir); // The DirectoryName, and...
497 MCOS->emitBytes(StringRef("\0", 1)); // its null terminator.
498 }
499 }
500
501 // The file format, which is the inline null-terminated filename and a
502 // directory index. We don't track file size/timestamp so don't emit them
503 // in the v5 table. Emit MD5 checksums and source if we have them.
504 uint64_t Entries = 2;
505 if (HasAllMD5)
506 Entries += 1;
507 if (HasAnySource)
508 Entries += 1;
509 MCOS->emitInt8(Entries);
510 MCOS->emitULEB128IntValue(dwarf::DW_LNCT_path);
511 MCOS->emitULEB128IntValue(LineStr ? dwarf::DW_FORM_line_strp
512 : dwarf::DW_FORM_string);
513 MCOS->emitULEB128IntValue(dwarf::DW_LNCT_directory_index);
514 MCOS->emitULEB128IntValue(dwarf::DW_FORM_udata);
515 if (HasAllMD5) {
516 MCOS->emitULEB128IntValue(dwarf::DW_LNCT_MD5);
517 MCOS->emitULEB128IntValue(dwarf::DW_FORM_data16);
518 }
519 if (HasAnySource) {
520 MCOS->emitULEB128IntValue(dwarf::DW_LNCT_LLVM_source);
521 MCOS->emitULEB128IntValue(LineStr ? dwarf::DW_FORM_line_strp
522 : dwarf::DW_FORM_string);
523 }
524 // Then the counted list of files. The root file is file #0, then emit the
525 // files as provide by .file directives.
526 // MCDwarfFiles has an unused element [0] so use size() not size()+1.
527 // But sometimes MCDwarfFiles is empty, in which case we still emit one file.
528 MCOS->emitULEB128IntValue(MCDwarfFiles.empty() ? 1 : MCDwarfFiles.size());
529 // To accommodate assembler source written for DWARF v4 but trying to emit
530 // v5: If we didn't see a root file explicitly, replicate file #1.
531 assert((!RootFile.Name.empty() || MCDwarfFiles.size() >= 1) &&
532 "No root file and no .file directives");
533 emitOneV5FileEntry(MCOS, RootFile.Name.empty() ? MCDwarfFiles[1] : RootFile,
534 HasAllMD5, HasAnySource, LineStr);
535 for (unsigned i = 1; i < MCDwarfFiles.size(); ++i)
536 emitOneV5FileEntry(MCOS, MCDwarfFiles[i], HasAllMD5, HasAnySource, LineStr);
537}
538
539std::pair<MCSymbol *, MCSymbol *>
541 ArrayRef<char> StandardOpcodeLengths,
542 std::optional<MCDwarfLineStr> &LineStr) const {
543 MCContext &context = MCOS->getContext();
544
545 // Create a symbol at the beginning of the line table.
546 MCSymbol *LineStartSym = Label;
547 if (!LineStartSym)
548 LineStartSym = context.createTempSymbol();
549
550 // Set the value of the symbol, as we are at the start of the line table.
551 MCOS->emitDwarfLineStartLabel(LineStartSym);
552
553 unsigned OffsetSize = dwarf::getDwarfOffsetByteSize(context.getDwarfFormat());
554
555 MCSymbol *LineEndSym = MCOS->emitDwarfUnitLength("debug_line", "unit length");
556
557 // Next 2 bytes is the Version.
558 unsigned LineTableVersion = context.getDwarfVersion();
559 MCOS->emitInt16(LineTableVersion);
560
561 // In v5, we get address info next.
562 if (LineTableVersion >= 5) {
563 MCOS->emitInt8(context.getAsmInfo()->getCodePointerSize());
564 MCOS->emitInt8(0); // Segment selector; same as EmitGenDwarfAranges.
565 }
566
567 // Create symbols for the start/end of the prologue.
568 MCSymbol *ProStartSym = context.createTempSymbol("prologue_start");
569 MCSymbol *ProEndSym = context.createTempSymbol("prologue_end");
570
571 // Length of the prologue, is the next 4 bytes (8 bytes for DWARF64). This is
572 // actually the length from after the length word, to the end of the prologue.
573 MCOS->emitAbsoluteSymbolDiff(ProEndSym, ProStartSym, OffsetSize);
574
575 MCOS->emitLabel(ProStartSym);
576
577 // Parameters of the state machine, are next.
578 MCOS->emitInt8(context.getAsmInfo()->getMinInstAlignment());
579 // maximum_operations_per_instruction
580 // For non-VLIW architectures this field is always 1.
581 // FIXME: VLIW architectures need to update this field accordingly.
582 if (LineTableVersion >= 4)
583 MCOS->emitInt8(1);
585 MCOS->emitInt8(Params.DWARF2LineBase);
586 MCOS->emitInt8(Params.DWARF2LineRange);
587 MCOS->emitInt8(StandardOpcodeLengths.size() + 1);
588
589 // Standard opcode lengths
590 for (char Length : StandardOpcodeLengths)
591 MCOS->emitInt8(Length);
592
593 // Put out the directory and file tables. The formats vary depending on
594 // the version.
595 if (LineTableVersion >= 5)
596 emitV5FileDirTables(MCOS, LineStr);
597 else
598 emitV2FileDirTables(MCOS);
599
600 // This is the end of the prologue, so set the value of the symbol at the
601 // end of the prologue (that was used in a previous expression).
602 MCOS->emitLabel(ProEndSym);
603
604 return std::make_pair(LineStartSym, LineEndSym);
605}
606
608 std::optional<MCDwarfLineStr> &LineStr) const {
609 MCSymbol *LineEndSym = Header.Emit(MCOS, Params, LineStr).second;
610
611 // Put out the line tables.
612 for (const auto &LineSec : MCLineSections.getMCLineEntries())
613 emitOne(MCOS, LineSec.first, LineSec.second);
614
615 // This is the end of the section, so set the value of the symbol at the end
616 // of this section (that was used in a previous expression).
617 MCOS->emitLabel(LineEndSym);
618}
619
622 std::optional<MD5::MD5Result> Checksum,
623 std::optional<StringRef> Source,
624 uint16_t DwarfVersion, unsigned FileNumber) {
625 return Header.tryGetFile(Directory, FileName, Checksum, Source, DwarfVersion,
626 FileNumber);
627}
628
629static bool isRootFile(const MCDwarfFile &RootFile, StringRef &Directory,
630 StringRef &FileName,
631 std::optional<MD5::MD5Result> Checksum) {
632 if (RootFile.Name.empty() || StringRef(RootFile.Name) != FileName)
633 return false;
634 return RootFile.Checksum == Checksum;
635}
636
639 std::optional<MD5::MD5Result> Checksum,
640 std::optional<StringRef> Source,
641 uint16_t DwarfVersion, unsigned FileNumber) {
642 if (Directory == CompilationDir)
643 Directory = "";
644 if (FileName.empty()) {
645 FileName = "<stdin>";
646 Directory = "";
647 }
648 assert(!FileName.empty());
649 // Keep track of whether any or all files have an MD5 checksum.
650 // If any files have embedded source, they all must.
651 if (MCDwarfFiles.empty()) {
652 trackMD5Usage(Checksum.has_value());
653 HasAnySource |= Source.has_value();
654 }
655 if (DwarfVersion >= 5 && isRootFile(RootFile, Directory, FileName, Checksum))
656 return 0;
657 if (FileNumber == 0) {
658 // File numbers start with 1 and/or after any file numbers
659 // allocated by inline-assembler .file directives.
660 FileNumber = MCDwarfFiles.empty() ? 1 : MCDwarfFiles.size();
661 SmallString<256> Buffer;
662 auto IterBool = SourceIdMap.insert(
663 std::make_pair((Directory + Twine('\0') + FileName).toStringRef(Buffer),
664 FileNumber));
665 if (!IterBool.second)
666 return IterBool.first->second;
667 }
668 // Make space for this FileNumber in the MCDwarfFiles vector if needed.
669 if (FileNumber >= MCDwarfFiles.size())
670 MCDwarfFiles.resize(FileNumber + 1);
671
672 // Get the new MCDwarfFile slot for this FileNumber.
673 MCDwarfFile &File = MCDwarfFiles[FileNumber];
674
675 // It is an error to see the same number more than once.
676 if (!File.Name.empty())
677 return make_error<StringError>("file number already allocated",
679
680 if (Directory.empty()) {
681 // Separate the directory part from the basename of the FileName.
682 StringRef tFileName = sys::path::filename(FileName);
683 if (!tFileName.empty()) {
684 Directory = sys::path::parent_path(FileName);
685 if (!Directory.empty())
686 FileName = tFileName;
687 }
688 }
689
690 // Find or make an entry in the MCDwarfDirs vector for this Directory.
691 // Capture directory name.
692 unsigned DirIndex;
693 if (Directory.empty()) {
694 // For FileNames with no directories a DirIndex of 0 is used.
695 DirIndex = 0;
696 } else {
697 DirIndex = llvm::find(MCDwarfDirs, Directory) - MCDwarfDirs.begin();
698 if (DirIndex >= MCDwarfDirs.size())
699 MCDwarfDirs.push_back(std::string(Directory));
700 // The DirIndex is one based, as DirIndex of 0 is used for FileNames with
701 // no directories. MCDwarfDirs[] is unlike MCDwarfFiles[] in that the
702 // directory names are stored at MCDwarfDirs[DirIndex-1] where FileNames
703 // are stored at MCDwarfFiles[FileNumber].Name .
704 DirIndex++;
705 }
706
707 File.Name = std::string(FileName);
708 File.DirIndex = DirIndex;
709 File.Checksum = Checksum;
710 trackMD5Usage(Checksum.has_value());
711 File.Source = Source;
712 if (Source.has_value())
713 HasAnySource = true;
714
715 // return the allocated FileNumber.
716 return FileNumber;
717}
718
719/// Utility function to emit the encoding to a streamer.
721 int64_t LineDelta, uint64_t AddrDelta) {
722 MCContext &Context = MCOS->getContext();
724 MCDwarfLineAddr::encode(Context, Params, LineDelta, AddrDelta, Tmp);
725 MCOS->emitBytes(Tmp);
726}
727
728/// Given a special op, return the address skip amount (in units of
729/// DWARF2_LINE_MIN_INSN_LENGTH).
731 return (op - Params.DWARF2LineOpcodeBase) / Params.DWARF2LineRange;
732}
733
734/// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas.
736 int64_t LineDelta, uint64_t AddrDelta,
738 uint8_t Buf[16];
739 uint64_t Temp, Opcode;
740 bool NeedCopy = false;
741
742 // The maximum address skip amount that can be encoded with a special op.
743 uint64_t MaxSpecialAddrDelta = SpecialAddr(Params, 255);
744
745 // Scale the address delta by the minimum instruction length.
746 AddrDelta = ScaleAddrDelta(Context, AddrDelta);
747
748 // A LineDelta of INT64_MAX is a signal that this is actually a
749 // DW_LNE_end_sequence. We cannot use special opcodes here, since we want the
750 // end_sequence to emit the matrix entry.
751 if (LineDelta == INT64_MAX) {
752 if (AddrDelta == MaxSpecialAddrDelta)
753 Out.push_back(dwarf::DW_LNS_const_add_pc);
754 else if (AddrDelta) {
755 Out.push_back(dwarf::DW_LNS_advance_pc);
756 Out.append(Buf, Buf + encodeULEB128(AddrDelta, Buf));
757 }
758 Out.push_back(dwarf::DW_LNS_extended_op);
759 Out.push_back(1);
760 Out.push_back(dwarf::DW_LNE_end_sequence);
761 return;
762 }
763
764 // Bias the line delta by the base.
765 Temp = LineDelta - Params.DWARF2LineBase;
766
767 // If the line increment is out of range of a special opcode, we must encode
768 // it with DW_LNS_advance_line.
769 if (Temp >= Params.DWARF2LineRange ||
770 Temp + Params.DWARF2LineOpcodeBase > 255) {
771 Out.push_back(dwarf::DW_LNS_advance_line);
772 Out.append(Buf, Buf + encodeSLEB128(LineDelta, Buf));
773
774 LineDelta = 0;
775 Temp = 0 - Params.DWARF2LineBase;
776 NeedCopy = true;
777 }
778
779 // Use DW_LNS_copy instead of a "line +0, addr +0" special opcode.
780 if (LineDelta == 0 && AddrDelta == 0) {
781 Out.push_back(dwarf::DW_LNS_copy);
782 return;
783 }
784
785 // Bias the opcode by the special opcode base.
786 Temp += Params.DWARF2LineOpcodeBase;
787
788 // Avoid overflow when addr_delta is large.
789 if (AddrDelta < 256 + MaxSpecialAddrDelta) {
790 // Try using a special opcode.
791 Opcode = Temp + AddrDelta * Params.DWARF2LineRange;
792 if (Opcode <= 255) {
793 Out.push_back(Opcode);
794 return;
795 }
796
797 // Try using DW_LNS_const_add_pc followed by special op.
798 Opcode = Temp + (AddrDelta - MaxSpecialAddrDelta) * Params.DWARF2LineRange;
799 if (Opcode <= 255) {
800 Out.push_back(dwarf::DW_LNS_const_add_pc);
801 Out.push_back(Opcode);
802 return;
803 }
804 }
805
806 // Otherwise use DW_LNS_advance_pc.
807 Out.push_back(dwarf::DW_LNS_advance_pc);
808 Out.append(Buf, Buf + encodeULEB128(AddrDelta, Buf));
809
810 if (NeedCopy)
811 Out.push_back(dwarf::DW_LNS_copy);
812 else {
813 assert(Temp <= 255 && "Buggy special opcode encoding.");
814 Out.push_back(Temp);
815 }
816}
817
818// Utility function to write a tuple for .debug_abbrev.
819static void EmitAbbrev(MCStreamer *MCOS, uint64_t Name, uint64_t Form) {
820 MCOS->emitULEB128IntValue(Name);
821 MCOS->emitULEB128IntValue(Form);
822}
823
824// When generating dwarf for assembly source files this emits
825// the data for .debug_abbrev section which contains three DIEs.
826static void EmitGenDwarfAbbrev(MCStreamer *MCOS) {
827 MCContext &context = MCOS->getContext();
829
830 // DW_TAG_compile_unit DIE abbrev (1).
831 MCOS->emitULEB128IntValue(1);
832 MCOS->emitULEB128IntValue(dwarf::DW_TAG_compile_unit);
834 dwarf::Form SecOffsetForm =
835 context.getDwarfVersion() >= 4
836 ? dwarf::DW_FORM_sec_offset
837 : (context.getDwarfFormat() == dwarf::DWARF64 ? dwarf::DW_FORM_data8
838 : dwarf::DW_FORM_data4);
839 EmitAbbrev(MCOS, dwarf::DW_AT_stmt_list, SecOffsetForm);
840 if (context.getGenDwarfSectionSyms().size() > 1 &&
841 context.getDwarfVersion() >= 3) {
842 EmitAbbrev(MCOS, dwarf::DW_AT_ranges, SecOffsetForm);
843 } else {
844 EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
845 EmitAbbrev(MCOS, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr);
846 }
847 EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
848 if (!context.getCompilationDir().empty())
849 EmitAbbrev(MCOS, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string);
850 StringRef DwarfDebugFlags = context.getDwarfDebugFlags();
851 if (!DwarfDebugFlags.empty())
852 EmitAbbrev(MCOS, dwarf::DW_AT_APPLE_flags, dwarf::DW_FORM_string);
853 EmitAbbrev(MCOS, dwarf::DW_AT_producer, dwarf::DW_FORM_string);
854 EmitAbbrev(MCOS, dwarf::DW_AT_language, dwarf::DW_FORM_data2);
855 EmitAbbrev(MCOS, 0, 0);
856
857 // DW_TAG_label DIE abbrev (2).
858 MCOS->emitULEB128IntValue(2);
859 MCOS->emitULEB128IntValue(dwarf::DW_TAG_label);
861 EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
862 EmitAbbrev(MCOS, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data4);
863 EmitAbbrev(MCOS, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data4);
864 EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
865 EmitAbbrev(MCOS, 0, 0);
866
867 // Terminate the abbreviations for this compilation unit.
868 MCOS->emitInt8(0);
869}
870
871// When generating dwarf for assembly source files this emits the data for
872// .debug_aranges section. This section contains a header and a table of pairs
873// of PointerSize'ed values for the address and size of section(s) with line
874// table entries.
876 const MCSymbol *InfoSectionSymbol) {
877 MCContext &context = MCOS->getContext();
878
879 auto &Sections = context.getGenDwarfSectionSyms();
880
882
883 unsigned UnitLengthBytes =
885 unsigned OffsetSize = dwarf::getDwarfOffsetByteSize(context.getDwarfFormat());
886
887 // This will be the length of the .debug_aranges section, first account for
888 // the size of each item in the header (see below where we emit these items).
889 int Length = UnitLengthBytes + 2 + OffsetSize + 1 + 1;
890
891 // Figure the padding after the header before the table of address and size
892 // pairs who's values are PointerSize'ed.
893 const MCAsmInfo *asmInfo = context.getAsmInfo();
894 int AddrSize = asmInfo->getCodePointerSize();
895 int Pad = 2 * AddrSize - (Length & (2 * AddrSize - 1));
896 if (Pad == 2 * AddrSize)
897 Pad = 0;
898 Length += Pad;
899
900 // Add the size of the pair of PointerSize'ed values for the address and size
901 // of each section we have in the table.
902 Length += 2 * AddrSize * Sections.size();
903 // And the pair of terminating zeros.
904 Length += 2 * AddrSize;
905
906 // Emit the header for this section.
907 if (context.getDwarfFormat() == dwarf::DWARF64)
908 // The DWARF64 mark.
910 // The 4 (8 for DWARF64) byte length not including the length of the unit
911 // length field itself.
912 MCOS->emitIntValue(Length - UnitLengthBytes, OffsetSize);
913 // The 2 byte version, which is 2.
914 MCOS->emitInt16(2);
915 // The 4 (8 for DWARF64) byte offset to the compile unit in the .debug_info
916 // from the start of the .debug_info.
917 if (InfoSectionSymbol)
918 MCOS->emitSymbolValue(InfoSectionSymbol, OffsetSize,
920 else
921 MCOS->emitIntValue(0, OffsetSize);
922 // The 1 byte size of an address.
923 MCOS->emitInt8(AddrSize);
924 // The 1 byte size of a segment descriptor, we use a value of zero.
925 MCOS->emitInt8(0);
926 // Align the header with the padding if needed, before we put out the table.
927 for(int i = 0; i < Pad; i++)
928 MCOS->emitInt8(0);
929
930 // Now emit the table of pairs of PointerSize'ed values for the section
931 // addresses and sizes.
932 for (MCSection *Sec : Sections) {
933 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
934 MCSymbol *EndSymbol = Sec->getEndSymbol(context);
935 assert(StartSymbol && "StartSymbol must not be NULL");
936 assert(EndSymbol && "EndSymbol must not be NULL");
937
938 const MCExpr *Addr = MCSymbolRefExpr::create(StartSymbol, context);
939 const MCExpr *Size =
940 makeEndMinusStartExpr(context, *StartSymbol, *EndSymbol, 0);
941 MCOS->emitValue(Addr, AddrSize);
942 emitAbsValue(*MCOS, Size, AddrSize);
943 }
944
945 // And finally the pair of terminating zeros.
946 MCOS->emitIntValue(0, AddrSize);
947 MCOS->emitIntValue(0, AddrSize);
948}
949
950// When generating dwarf for assembly source files this emits the data for
951// .debug_info section which contains three parts. The header, the compile_unit
952// DIE and a list of label DIEs.
953static void EmitGenDwarfInfo(MCStreamer *MCOS,
954 const MCSymbol *AbbrevSectionSymbol,
955 const MCSymbol *LineSectionSymbol,
956 const MCSymbol *RangesSymbol) {
957 MCContext &context = MCOS->getContext();
958
960
961 // Create a symbol at the start and end of this section used in here for the
962 // expression to calculate the length in the header.
963 MCSymbol *InfoStart = context.createTempSymbol();
964 MCOS->emitLabel(InfoStart);
965 MCSymbol *InfoEnd = context.createTempSymbol();
966
967 // First part: the header.
968
969 unsigned UnitLengthBytes =
971 unsigned OffsetSize = dwarf::getDwarfOffsetByteSize(context.getDwarfFormat());
972
973 if (context.getDwarfFormat() == dwarf::DWARF64)
974 // Emit DWARF64 mark.
976
977 // The 4 (8 for DWARF64) byte total length of the information for this
978 // compilation unit, not including the unit length field itself.
979 const MCExpr *Length =
980 makeEndMinusStartExpr(context, *InfoStart, *InfoEnd, UnitLengthBytes);
981 emitAbsValue(*MCOS, Length, OffsetSize);
982
983 // The 2 byte DWARF version.
984 MCOS->emitInt16(context.getDwarfVersion());
985
986 // The DWARF v5 header has unit type, address size, abbrev offset.
987 // Earlier versions have abbrev offset, address size.
988 const MCAsmInfo &AsmInfo = *context.getAsmInfo();
989 int AddrSize = AsmInfo.getCodePointerSize();
990 if (context.getDwarfVersion() >= 5) {
991 MCOS->emitInt8(dwarf::DW_UT_compile);
992 MCOS->emitInt8(AddrSize);
993 }
994 // The 4 (8 for DWARF64) byte offset to the debug abbrevs from the start of
995 // the .debug_abbrev.
996 if (AbbrevSectionSymbol)
997 MCOS->emitSymbolValue(AbbrevSectionSymbol, OffsetSize,
999 else
1000 // Since the abbrevs are at the start of the section, the offset is zero.
1001 MCOS->emitIntValue(0, OffsetSize);
1002 if (context.getDwarfVersion() <= 4)
1003 MCOS->emitInt8(AddrSize);
1004
1005 // Second part: the compile_unit DIE.
1006
1007 // The DW_TAG_compile_unit DIE abbrev (1).
1008 MCOS->emitULEB128IntValue(1);
1009
1010 // DW_AT_stmt_list, a 4 (8 for DWARF64) byte offset from the start of the
1011 // .debug_line section.
1012 if (LineSectionSymbol)
1013 MCOS->emitSymbolValue(LineSectionSymbol, OffsetSize,
1015 else
1016 // The line table is at the start of the section, so the offset is zero.
1017 MCOS->emitIntValue(0, OffsetSize);
1018
1019 if (RangesSymbol) {
1020 // There are multiple sections containing code, so we must use
1021 // .debug_ranges/.debug_rnglists. AT_ranges, the 4/8 byte offset from the
1022 // start of the .debug_ranges/.debug_rnglists.
1023 MCOS->emitSymbolValue(RangesSymbol, OffsetSize);
1024 } else {
1025 // If we only have one non-empty code section, we can use the simpler
1026 // AT_low_pc and AT_high_pc attributes.
1027
1028 // Find the first (and only) non-empty text section
1029 auto &Sections = context.getGenDwarfSectionSyms();
1030 const auto TextSection = Sections.begin();
1031 assert(TextSection != Sections.end() && "No text section found");
1032
1033 MCSymbol *StartSymbol = (*TextSection)->getBeginSymbol();
1034 MCSymbol *EndSymbol = (*TextSection)->getEndSymbol(context);
1035 assert(StartSymbol && "StartSymbol must not be NULL");
1036 assert(EndSymbol && "EndSymbol must not be NULL");
1037
1038 // AT_low_pc, the first address of the default .text section.
1039 const MCExpr *Start = MCSymbolRefExpr::create(StartSymbol, context);
1040 MCOS->emitValue(Start, AddrSize);
1041
1042 // AT_high_pc, the last address of the default .text section.
1043 const MCExpr *End = MCSymbolRefExpr::create(EndSymbol, context);
1044 MCOS->emitValue(End, AddrSize);
1045 }
1046
1047 // AT_name, the name of the source file. Reconstruct from the first directory
1048 // and file table entries.
1049 const SmallVectorImpl<std::string> &MCDwarfDirs = context.getMCDwarfDirs();
1050 if (MCDwarfDirs.size() > 0) {
1051 MCOS->emitBytes(MCDwarfDirs[0]);
1053 }
1054 const SmallVectorImpl<MCDwarfFile> &MCDwarfFiles = context.getMCDwarfFiles();
1055 // MCDwarfFiles might be empty if we have an empty source file.
1056 // If it's not empty, [0] is unused and [1] is the first actual file.
1057 assert(MCDwarfFiles.empty() || MCDwarfFiles.size() >= 2);
1058 const MCDwarfFile &RootFile =
1059 MCDwarfFiles.empty()
1060 ? context.getMCDwarfLineTable(/*CUID=*/0).getRootFile()
1061 : MCDwarfFiles[1];
1062 MCOS->emitBytes(RootFile.Name);
1063 MCOS->emitInt8(0); // NULL byte to terminate the string.
1064
1065 // AT_comp_dir, the working directory the assembly was done in.
1066 if (!context.getCompilationDir().empty()) {
1067 MCOS->emitBytes(context.getCompilationDir());
1068 MCOS->emitInt8(0); // NULL byte to terminate the string.
1069 }
1070
1071 // AT_APPLE_flags, the command line arguments of the assembler tool.
1072 StringRef DwarfDebugFlags = context.getDwarfDebugFlags();
1073 if (!DwarfDebugFlags.empty()){
1074 MCOS->emitBytes(DwarfDebugFlags);
1075 MCOS->emitInt8(0); // NULL byte to terminate the string.
1076 }
1077
1078 // AT_producer, the version of the assembler tool.
1079 StringRef DwarfDebugProducer = context.getDwarfDebugProducer();
1080 if (!DwarfDebugProducer.empty())
1081 MCOS->emitBytes(DwarfDebugProducer);
1082 else
1083 MCOS->emitBytes(StringRef("llvm-mc (based on LLVM " PACKAGE_VERSION ")"));
1084 MCOS->emitInt8(0); // NULL byte to terminate the string.
1085
1086 // AT_language, a 4 byte value. We use DW_LANG_Mips_Assembler as the dwarf2
1087 // draft has no standard code for assembler.
1088 MCOS->emitInt16(dwarf::DW_LANG_Mips_Assembler);
1089
1090 // Third part: the list of label DIEs.
1091
1092 // Loop on saved info for dwarf labels and create the DIEs for them.
1093 const std::vector<MCGenDwarfLabelEntry> &Entries =
1095 for (const auto &Entry : Entries) {
1096 // The DW_TAG_label DIE abbrev (2).
1097 MCOS->emitULEB128IntValue(2);
1098
1099 // AT_name, of the label without any leading underbar.
1100 MCOS->emitBytes(Entry.getName());
1101 MCOS->emitInt8(0); // NULL byte to terminate the string.
1102
1103 // AT_decl_file, index into the file table.
1104 MCOS->emitInt32(Entry.getFileNumber());
1105
1106 // AT_decl_line, source line number.
1107 MCOS->emitInt32(Entry.getLineNumber());
1108
1109 // AT_low_pc, start address of the label.
1110 const auto *AT_low_pc = MCSymbolRefExpr::create(Entry.getLabel(), context);
1111 MCOS->emitValue(AT_low_pc, AddrSize);
1112 }
1113
1114 // Add the NULL DIE terminating the Compile Unit DIE's.
1115 MCOS->emitInt8(0);
1116
1117 // Now set the value of the symbol at the end of the info section.
1118 MCOS->emitLabel(InfoEnd);
1119}
1120
1121// When generating dwarf for assembly source files this emits the data for
1122// .debug_ranges section. We only emit one range list, which spans all of the
1123// executable sections of this file.
1125 MCContext &context = MCOS->getContext();
1126 auto &Sections = context.getGenDwarfSectionSyms();
1127
1128 const MCAsmInfo *AsmInfo = context.getAsmInfo();
1129 int AddrSize = AsmInfo->getCodePointerSize();
1130 MCSymbol *RangesSymbol;
1131
1132 if (MCOS->getContext().getDwarfVersion() >= 5) {
1134 MCSymbol *EndSymbol = mcdwarf::emitListsTableHeaderStart(*MCOS);
1135 MCOS->AddComment("Offset entry count");
1136 MCOS->emitInt32(0);
1137 RangesSymbol = context.createTempSymbol("debug_rnglist0_start");
1138 MCOS->emitLabel(RangesSymbol);
1139 for (MCSection *Sec : Sections) {
1140 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
1141 const MCSymbol *EndSymbol = Sec->getEndSymbol(context);
1142 const MCExpr *SectionStartAddr =
1143 MCSymbolRefExpr::create(StartSymbol, context);
1144 const MCExpr *SectionSize =
1145 makeEndMinusStartExpr(context, *StartSymbol, *EndSymbol, 0);
1146 MCOS->emitInt8(dwarf::DW_RLE_start_length);
1147 MCOS->emitValue(SectionStartAddr, AddrSize);
1148 MCOS->emitULEB128Value(SectionSize);
1149 }
1150 MCOS->emitInt8(dwarf::DW_RLE_end_of_list);
1151 MCOS->emitLabel(EndSymbol);
1152 } else {
1154 RangesSymbol = context.createTempSymbol("debug_ranges_start");
1155 MCOS->emitLabel(RangesSymbol);
1156 for (MCSection *Sec : Sections) {
1157 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
1158 const MCSymbol *EndSymbol = Sec->getEndSymbol(context);
1159
1160 // Emit a base address selection entry for the section start.
1161 const MCExpr *SectionStartAddr =
1162 MCSymbolRefExpr::create(StartSymbol, context);
1163 MCOS->emitFill(AddrSize, 0xFF);
1164 MCOS->emitValue(SectionStartAddr, AddrSize);
1165
1166 // Emit a range list entry spanning this section.
1167 const MCExpr *SectionSize =
1168 makeEndMinusStartExpr(context, *StartSymbol, *EndSymbol, 0);
1169 MCOS->emitIntValue(0, AddrSize);
1170 emitAbsValue(*MCOS, SectionSize, AddrSize);
1171 }
1172
1173 // Emit end of list entry
1174 MCOS->emitIntValue(0, AddrSize);
1175 MCOS->emitIntValue(0, AddrSize);
1176 }
1177
1178 return RangesSymbol;
1179}
1180
1181//
1182// When generating dwarf for assembly source files this emits the Dwarf
1183// sections.
1184//
1186 MCContext &context = MCOS->getContext();
1187
1188 // Create the dwarf sections in this order (.debug_line already created).
1189 const MCAsmInfo *AsmInfo = context.getAsmInfo();
1190 bool CreateDwarfSectionSymbols =
1192 MCSymbol *LineSectionSymbol = nullptr;
1193 if (CreateDwarfSectionSymbols)
1194 LineSectionSymbol = MCOS->getDwarfLineTableSymbol(0);
1195 MCSymbol *AbbrevSectionSymbol = nullptr;
1196 MCSymbol *InfoSectionSymbol = nullptr;
1197 MCSymbol *RangesSymbol = nullptr;
1198
1199 // Create end symbols for each section, and remove empty sections
1200 MCOS->getContext().finalizeDwarfSections(*MCOS);
1201
1202 // If there are no sections to generate debug info for, we don't need
1203 // to do anything
1204 if (MCOS->getContext().getGenDwarfSectionSyms().empty())
1205 return;
1206
1207 // We only use the .debug_ranges section if we have multiple code sections,
1208 // and we are emitting a DWARF version which supports it.
1209 const bool UseRangesSection =
1210 MCOS->getContext().getGenDwarfSectionSyms().size() > 1 &&
1211 MCOS->getContext().getDwarfVersion() >= 3;
1212 CreateDwarfSectionSymbols |= UseRangesSection;
1213
1215 if (CreateDwarfSectionSymbols) {
1216 InfoSectionSymbol = context.createTempSymbol();
1217 MCOS->emitLabel(InfoSectionSymbol);
1218 }
1220 if (CreateDwarfSectionSymbols) {
1221 AbbrevSectionSymbol = context.createTempSymbol();
1222 MCOS->emitLabel(AbbrevSectionSymbol);
1223 }
1224
1226
1227 // Output the data for .debug_aranges section.
1228 EmitGenDwarfAranges(MCOS, InfoSectionSymbol);
1229
1230 if (UseRangesSection) {
1231 RangesSymbol = emitGenDwarfRanges(MCOS);
1232 assert(RangesSymbol);
1233 }
1234
1235 // Output the data for .debug_abbrev section.
1236 EmitGenDwarfAbbrev(MCOS);
1237
1238 // Output the data for .debug_info section.
1239 EmitGenDwarfInfo(MCOS, AbbrevSectionSymbol, LineSectionSymbol, RangesSymbol);
1240}
1241
1242//
1243// When generating dwarf for assembly source files this is called when symbol
1244// for a label is created. If this symbol is not a temporary and is in the
1245// section that dwarf is being generated for, save the needed info to create
1246// a dwarf label.
1247//
1250 // We won't create dwarf labels for temporary symbols.
1251 if (Symbol->isTemporary())
1252 return;
1253 MCContext &context = MCOS->getContext();
1254 // We won't create dwarf labels for symbols in sections that we are not
1255 // generating debug info for.
1256 if (!context.getGenDwarfSectionSyms().count(MCOS->getCurrentSectionOnly()))
1257 return;
1258
1259 // The dwarf label's name does not have the symbol name's leading
1260 // underbar if any.
1261 StringRef Name = Symbol->getName();
1262 if (Name.starts_with("_"))
1263 Name = Name.substr(1, Name.size()-1);
1264
1265 // Get the dwarf file number to be used for the dwarf label.
1266 unsigned FileNumber = context.getGenDwarfFileNumber();
1267
1268 // Finding the line number is the expensive part which is why we just don't
1269 // pass it in as for some symbols we won't create a dwarf label.
1270 unsigned CurBuffer = SrcMgr.FindBufferContainingLoc(Loc);
1271 unsigned LineNumber = SrcMgr.FindLineNumber(Loc, CurBuffer);
1272
1273 // We create a temporary symbol for use for the AT_high_pc and AT_low_pc
1274 // values so that they don't have things like an ARM thumb bit from the
1275 // original symbol. So when used they won't get a low bit set after
1276 // relocation.
1277 MCSymbol *Label = context.createTempSymbol();
1278 MCOS->emitLabel(Label);
1279
1280 // Create and entry for the info and add it to the other entries.
1282 MCGenDwarfLabelEntry(Name, FileNumber, LineNumber, Label));
1283}
1284
1285static int getDataAlignmentFactor(MCStreamer &streamer) {
1286 MCContext &context = streamer.getContext();
1287 const MCAsmInfo *asmInfo = context.getAsmInfo();
1288 int size = asmInfo->getCalleeSaveStackSlotSize();
1289 if (asmInfo->isStackGrowthDirectionUp())
1290 return size;
1291 else
1292 return -size;
1293}
1294
1295static unsigned getSizeForEncoding(MCStreamer &streamer,
1296 unsigned symbolEncoding) {
1297 MCContext &context = streamer.getContext();
1298 unsigned format = symbolEncoding & 0x0f;
1299 switch (format) {
1300 default: llvm_unreachable("Unknown Encoding");
1303 return context.getAsmInfo()->getCodePointerSize();
1306 return 2;
1309 return 4;
1312 return 8;
1313 }
1314}
1315
1316static void emitFDESymbol(MCObjectStreamer &streamer, const MCSymbol &symbol,
1317 unsigned symbolEncoding, bool isEH) {
1318 MCContext &context = streamer.getContext();
1319 const MCAsmInfo *asmInfo = context.getAsmInfo();
1320 const MCExpr *v = asmInfo->getExprForFDESymbol(&symbol,
1321 symbolEncoding,
1322 streamer);
1323 unsigned size = getSizeForEncoding(streamer, symbolEncoding);
1324 if (asmInfo->doDwarfFDESymbolsUseAbsDiff() && isEH)
1325 emitAbsValue(streamer, v, size);
1326 else
1327 streamer.emitValue(v, size);
1328}
1329
1330static void EmitPersonality(MCStreamer &streamer, const MCSymbol &symbol,
1331 unsigned symbolEncoding) {
1332 MCContext &context = streamer.getContext();
1333 const MCAsmInfo *asmInfo = context.getAsmInfo();
1334 const MCExpr *v = asmInfo->getExprForPersonalitySymbol(&symbol,
1335 symbolEncoding,
1336 streamer);
1337 unsigned size = getSizeForEncoding(streamer, symbolEncoding);
1338 streamer.emitValue(v, size);
1339}
1340
1341namespace {
1342
1343class FrameEmitterImpl {
1344 int64_t CFAOffset = 0;
1345 int64_t InitialCFAOffset = 0;
1346 bool IsEH;
1347 MCObjectStreamer &Streamer;
1348
1349public:
1350 FrameEmitterImpl(bool IsEH, MCObjectStreamer &Streamer)
1351 : IsEH(IsEH), Streamer(Streamer) {}
1352
1353 /// Emit the unwind information in a compact way.
1354 void EmitCompactUnwind(const MCDwarfFrameInfo &frame);
1355
1356 const MCSymbol &EmitCIE(const MCDwarfFrameInfo &F);
1357 void EmitFDE(const MCSymbol &cieStart, const MCDwarfFrameInfo &frame,
1358 bool LastInSection, const MCSymbol &SectionStart);
1359 void emitCFIInstructions(ArrayRef<MCCFIInstruction> Instrs,
1360 MCSymbol *BaseLabel);
1361 void emitCFIInstruction(const MCCFIInstruction &Instr);
1362};
1363
1364} // end anonymous namespace
1365
1366static void emitEncodingByte(MCObjectStreamer &Streamer, unsigned Encoding) {
1367 Streamer.emitInt8(Encoding);
1368}
1369
1370void FrameEmitterImpl::emitCFIInstruction(const MCCFIInstruction &Instr) {
1371 int dataAlignmentFactor = getDataAlignmentFactor(Streamer);
1372 auto *MRI = Streamer.getContext().getRegisterInfo();
1373
1374 switch (Instr.getOperation()) {
1376 unsigned Reg1 = Instr.getRegister();
1377 unsigned Reg2 = Instr.getRegister2();
1378 if (!IsEH) {
1379 Reg1 = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg1);
1380 Reg2 = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg2);
1381 }
1382 Streamer.emitInt8(dwarf::DW_CFA_register);
1383 Streamer.emitULEB128IntValue(Reg1);
1384 Streamer.emitULEB128IntValue(Reg2);
1385 return;
1386 }
1388 Streamer.emitInt8(dwarf::DW_CFA_GNU_window_save);
1389 return;
1390
1392 Streamer.emitInt8(dwarf::DW_CFA_AARCH64_negate_ra_state);
1393 return;
1394
1396 Streamer.emitInt8(dwarf::DW_CFA_AARCH64_negate_ra_state_with_pc);
1397 return;
1398
1400 unsigned Reg = Instr.getRegister();
1401 Streamer.emitInt8(dwarf::DW_CFA_undefined);
1402 Streamer.emitULEB128IntValue(Reg);
1403 return;
1404 }
1407 const bool IsRelative =
1409
1410 Streamer.emitInt8(dwarf::DW_CFA_def_cfa_offset);
1411
1412 if (IsRelative)
1413 CFAOffset += Instr.getOffset();
1414 else
1415 CFAOffset = Instr.getOffset();
1416
1417 Streamer.emitULEB128IntValue(CFAOffset);
1418
1419 return;
1420 }
1422 unsigned Reg = Instr.getRegister();
1423 if (!IsEH)
1424 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1425 Streamer.emitInt8(dwarf::DW_CFA_def_cfa);
1426 Streamer.emitULEB128IntValue(Reg);
1427 CFAOffset = Instr.getOffset();
1428 Streamer.emitULEB128IntValue(CFAOffset);
1429
1430 return;
1431 }
1433 unsigned Reg = Instr.getRegister();
1434 if (!IsEH)
1435 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1436 Streamer.emitInt8(dwarf::DW_CFA_def_cfa_register);
1437 Streamer.emitULEB128IntValue(Reg);
1438
1439 return;
1440 }
1441 // TODO: Implement `_sf` variants if/when they need to be emitted.
1443 unsigned Reg = Instr.getRegister();
1444 if (!IsEH)
1445 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1446 Streamer.emitIntValue(dwarf::DW_CFA_LLVM_def_aspace_cfa, 1);
1447 Streamer.emitULEB128IntValue(Reg);
1448 CFAOffset = Instr.getOffset();
1449 Streamer.emitULEB128IntValue(CFAOffset);
1450 Streamer.emitULEB128IntValue(Instr.getAddressSpace());
1451
1452 return;
1453 }
1456 const bool IsRelative =
1457 Instr.getOperation() == MCCFIInstruction::OpRelOffset;
1458
1459 unsigned Reg = Instr.getRegister();
1460 if (!IsEH)
1461 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1462
1463 int64_t Offset = Instr.getOffset();
1464 if (IsRelative)
1465 Offset -= CFAOffset;
1466 Offset = Offset / dataAlignmentFactor;
1467
1468 if (Offset < 0) {
1469 Streamer.emitInt8(dwarf::DW_CFA_offset_extended_sf);
1470 Streamer.emitULEB128IntValue(Reg);
1471 Streamer.emitSLEB128IntValue(Offset);
1472 } else if (Reg < 64) {
1473 Streamer.emitInt8(dwarf::DW_CFA_offset + Reg);
1474 Streamer.emitULEB128IntValue(Offset);
1475 } else {
1476 Streamer.emitInt8(dwarf::DW_CFA_offset_extended);
1477 Streamer.emitULEB128IntValue(Reg);
1478 Streamer.emitULEB128IntValue(Offset);
1479 }
1480 return;
1481 }
1483 Streamer.emitInt8(dwarf::DW_CFA_remember_state);
1484 return;
1486 Streamer.emitInt8(dwarf::DW_CFA_restore_state);
1487 return;
1489 unsigned Reg = Instr.getRegister();
1490 Streamer.emitInt8(dwarf::DW_CFA_same_value);
1491 Streamer.emitULEB128IntValue(Reg);
1492 return;
1493 }
1495 unsigned Reg = Instr.getRegister();
1496 if (!IsEH)
1497 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1498 if (Reg < 64) {
1499 Streamer.emitInt8(dwarf::DW_CFA_restore | Reg);
1500 } else {
1501 Streamer.emitInt8(dwarf::DW_CFA_restore_extended);
1502 Streamer.emitULEB128IntValue(Reg);
1503 }
1504 return;
1505 }
1507 Streamer.emitInt8(dwarf::DW_CFA_GNU_args_size);
1508 Streamer.emitULEB128IntValue(Instr.getOffset());
1509 return;
1510
1512 Streamer.emitBytes(Instr.getValues());
1513 return;
1515 Streamer.emitLabel(Instr.getCfiLabel(), Instr.getLoc());
1516 return;
1518 unsigned Reg = Instr.getRegister();
1519 if (!IsEH)
1520 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1521
1522 int Offset = Instr.getOffset();
1523 Offset = Offset / dataAlignmentFactor;
1524
1525 if (Offset < 0) {
1526 Streamer.emitInt8(dwarf::DW_CFA_val_offset_sf);
1527 Streamer.emitULEB128IntValue(Reg);
1528 Streamer.emitSLEB128IntValue(Offset);
1529 } else {
1530 Streamer.emitInt8(dwarf::DW_CFA_val_offset);
1531 Streamer.emitULEB128IntValue(Reg);
1532 Streamer.emitULEB128IntValue(Offset);
1533 }
1534 return;
1535 }
1536 }
1537 llvm_unreachable("Unhandled case in switch");
1538}
1539
1540/// Emit frame instructions to describe the layout of the frame.
1541void FrameEmitterImpl::emitCFIInstructions(ArrayRef<MCCFIInstruction> Instrs,
1542 MCSymbol *BaseLabel) {
1543 for (const MCCFIInstruction &Instr : Instrs) {
1544 MCSymbol *Label = Instr.getLabel();
1545 // Throw out move if the label is invalid.
1546 if (Label && !Label->isDefined()) continue; // Not emitted, in dead code.
1547
1548 // Advance row if new location.
1549 if (BaseLabel && Label) {
1550 MCSymbol *ThisSym = Label;
1551 if (ThisSym != BaseLabel) {
1552 Streamer.emitDwarfAdvanceFrameAddr(BaseLabel, ThisSym, Instr.getLoc());
1553 BaseLabel = ThisSym;
1554 }
1555 }
1556
1557 emitCFIInstruction(Instr);
1558 }
1559}
1560
1561/// Emit the unwind information in a compact way.
1562void FrameEmitterImpl::EmitCompactUnwind(const MCDwarfFrameInfo &Frame) {
1563 MCContext &Context = Streamer.getContext();
1564 const MCObjectFileInfo *MOFI = Context.getObjectFileInfo();
1565
1566 // range-start range-length compact-unwind-enc personality-func lsda
1567 // _foo LfooEnd-_foo 0x00000023 0 0
1568 // _bar LbarEnd-_bar 0x00000025 __gxx_personality except_tab1
1569 //
1570 // .section __LD,__compact_unwind,regular,debug
1571 //
1572 // # compact unwind for _foo
1573 // .quad _foo
1574 // .set L1,LfooEnd-_foo
1575 // .long L1
1576 // .long 0x01010001
1577 // .quad 0
1578 // .quad 0
1579 //
1580 // # compact unwind for _bar
1581 // .quad _bar
1582 // .set L2,LbarEnd-_bar
1583 // .long L2
1584 // .long 0x01020011
1585 // .quad __gxx_personality
1586 // .quad except_tab1
1587
1588 uint32_t Encoding = Frame.CompactUnwindEncoding;
1589 if (!Encoding) return;
1590 bool DwarfEHFrameOnly = (Encoding == MOFI->getCompactUnwindDwarfEHFrameOnly());
1591
1592 // The encoding needs to know we have an LSDA.
1593 if (!DwarfEHFrameOnly && Frame.Lsda)
1594 Encoding |= 0x40000000;
1595
1596 // Range Start
1597 unsigned FDEEncoding = MOFI->getFDEEncoding();
1598 unsigned Size = getSizeForEncoding(Streamer, FDEEncoding);
1599 Streamer.emitSymbolValue(Frame.Begin, Size);
1600
1601 // Range Length
1602 const MCExpr *Range =
1603 makeEndMinusStartExpr(Context, *Frame.Begin, *Frame.End, 0);
1604 emitAbsValue(Streamer, Range, 4);
1605
1606 // Compact Encoding
1608 Streamer.emitIntValue(Encoding, Size);
1609
1610 // Personality Function
1612 if (!DwarfEHFrameOnly && Frame.Personality)
1613 Streamer.emitSymbolValue(Frame.Personality, Size);
1614 else
1615 Streamer.emitIntValue(0, Size); // No personality fn
1616
1617 // LSDA
1618 Size = getSizeForEncoding(Streamer, Frame.LsdaEncoding);
1619 if (!DwarfEHFrameOnly && Frame.Lsda)
1620 Streamer.emitSymbolValue(Frame.Lsda, Size);
1621 else
1622 Streamer.emitIntValue(0, Size); // No LSDA
1623}
1624
1625static unsigned getCIEVersion(bool IsEH, unsigned DwarfVersion) {
1626 if (IsEH)
1627 return 1;
1628 switch (DwarfVersion) {
1629 case 2:
1630 return 1;
1631 case 3:
1632 return 3;
1633 case 4:
1634 case 5:
1635 return 4;
1636 }
1637 llvm_unreachable("Unknown version");
1638}
1639
1640const MCSymbol &FrameEmitterImpl::EmitCIE(const MCDwarfFrameInfo &Frame) {
1641 MCContext &context = Streamer.getContext();
1642 const MCRegisterInfo *MRI = context.getRegisterInfo();
1643 const MCObjectFileInfo *MOFI = context.getObjectFileInfo();
1644
1645 MCSymbol *sectionStart = context.createTempSymbol();
1646 Streamer.emitLabel(sectionStart);
1647
1648 MCSymbol *sectionEnd = context.createTempSymbol();
1649
1651 unsigned UnitLengthBytes = dwarf::getUnitLengthFieldByteSize(Format);
1652 unsigned OffsetSize = dwarf::getDwarfOffsetByteSize(Format);
1653 bool IsDwarf64 = Format == dwarf::DWARF64;
1654
1655 if (IsDwarf64)
1656 // DWARF64 mark
1657 Streamer.emitInt32(dwarf::DW_LENGTH_DWARF64);
1658
1659 // Length
1660 const MCExpr *Length = makeEndMinusStartExpr(context, *sectionStart,
1661 *sectionEnd, UnitLengthBytes);
1662 emitAbsValue(Streamer, Length, OffsetSize);
1663
1664 // CIE ID
1665 uint64_t CIE_ID =
1666 IsEH ? 0 : (IsDwarf64 ? dwarf::DW64_CIE_ID : dwarf::DW_CIE_ID);
1667 Streamer.emitIntValue(CIE_ID, OffsetSize);
1668
1669 // Version
1670 uint8_t CIEVersion = getCIEVersion(IsEH, context.getDwarfVersion());
1671 Streamer.emitInt8(CIEVersion);
1672
1673 if (IsEH) {
1674 SmallString<8> Augmentation;
1675 Augmentation += "z";
1676 if (Frame.Personality)
1677 Augmentation += "P";
1678 if (Frame.Lsda)
1679 Augmentation += "L";
1680 Augmentation += "R";
1681 if (Frame.IsSignalFrame)
1682 Augmentation += "S";
1683 if (Frame.IsBKeyFrame)
1684 Augmentation += "B";
1685 if (Frame.IsMTETaggedFrame)
1686 Augmentation += "G";
1687 Streamer.emitBytes(Augmentation);
1688 }
1689 Streamer.emitInt8(0);
1690
1691 if (CIEVersion >= 4) {
1692 // Address Size
1693 Streamer.emitInt8(context.getAsmInfo()->getCodePointerSize());
1694
1695 // Segment Descriptor Size
1696 Streamer.emitInt8(0);
1697 }
1698
1699 // Code Alignment Factor
1700 Streamer.emitULEB128IntValue(context.getAsmInfo()->getMinInstAlignment());
1701
1702 // Data Alignment Factor
1703 Streamer.emitSLEB128IntValue(getDataAlignmentFactor(Streamer));
1704
1705 // Return Address Register
1706 unsigned RAReg = Frame.RAReg;
1707 if (RAReg == static_cast<unsigned>(INT_MAX))
1708 RAReg = MRI->getDwarfRegNum(MRI->getRARegister(), IsEH);
1709
1710 if (CIEVersion == 1) {
1711 assert(RAReg <= 255 &&
1712 "DWARF 2 encodes return_address_register in one byte");
1713 Streamer.emitInt8(RAReg);
1714 } else {
1715 Streamer.emitULEB128IntValue(RAReg);
1716 }
1717
1718 // Augmentation Data Length (optional)
1719 unsigned augmentationLength = 0;
1720 if (IsEH) {
1721 if (Frame.Personality) {
1722 // Personality Encoding
1723 augmentationLength += 1;
1724 // Personality
1725 augmentationLength +=
1726 getSizeForEncoding(Streamer, Frame.PersonalityEncoding);
1727 }
1728 if (Frame.Lsda)
1729 augmentationLength += 1;
1730 // Encoding of the FDE pointers
1731 augmentationLength += 1;
1732
1733 Streamer.emitULEB128IntValue(augmentationLength);
1734
1735 // Augmentation Data (optional)
1736 if (Frame.Personality) {
1737 // Personality Encoding
1738 emitEncodingByte(Streamer, Frame.PersonalityEncoding);
1739 // Personality
1740 EmitPersonality(Streamer, *Frame.Personality, Frame.PersonalityEncoding);
1741 }
1742
1743 if (Frame.Lsda)
1744 emitEncodingByte(Streamer, Frame.LsdaEncoding);
1745
1746 // Encoding of the FDE pointers
1747 emitEncodingByte(Streamer, MOFI->getFDEEncoding());
1748 }
1749
1750 // Initial Instructions
1751
1752 const MCAsmInfo *MAI = context.getAsmInfo();
1753 if (!Frame.IsSimple) {
1754 const std::vector<MCCFIInstruction> &Instructions =
1755 MAI->getInitialFrameState();
1756 emitCFIInstructions(Instructions, nullptr);
1757 }
1758
1759 InitialCFAOffset = CFAOffset;
1760
1761 // Padding
1762 Streamer.emitValueToAlignment(Align(IsEH ? 4 : MAI->getCodePointerSize()));
1763
1764 Streamer.emitLabel(sectionEnd);
1765 return *sectionStart;
1766}
1767
1768void FrameEmitterImpl::EmitFDE(const MCSymbol &cieStart,
1769 const MCDwarfFrameInfo &frame,
1770 bool LastInSection,
1771 const MCSymbol &SectionStart) {
1772 MCContext &context = Streamer.getContext();
1773 MCSymbol *fdeStart = context.createTempSymbol();
1774 MCSymbol *fdeEnd = context.createTempSymbol();
1775 const MCObjectFileInfo *MOFI = context.getObjectFileInfo();
1776
1777 CFAOffset = InitialCFAOffset;
1778
1780 unsigned OffsetSize = dwarf::getDwarfOffsetByteSize(Format);
1781
1782 if (Format == dwarf::DWARF64)
1783 // DWARF64 mark
1784 Streamer.emitInt32(dwarf::DW_LENGTH_DWARF64);
1785
1786 // Length
1787 const MCExpr *Length = makeEndMinusStartExpr(context, *fdeStart, *fdeEnd, 0);
1788 emitAbsValue(Streamer, Length, OffsetSize);
1789
1790 Streamer.emitLabel(fdeStart);
1791
1792 // CIE Pointer
1793 const MCAsmInfo *asmInfo = context.getAsmInfo();
1794 if (IsEH) {
1795 const MCExpr *offset =
1796 makeEndMinusStartExpr(context, cieStart, *fdeStart, 0);
1797 emitAbsValue(Streamer, offset, OffsetSize);
1798 } else if (!asmInfo->doesDwarfUseRelocationsAcrossSections()) {
1799 const MCExpr *offset =
1800 makeEndMinusStartExpr(context, SectionStart, cieStart, 0);
1801 emitAbsValue(Streamer, offset, OffsetSize);
1802 } else {
1803 Streamer.emitSymbolValue(&cieStart, OffsetSize,
1805 }
1806
1807 // PC Begin
1808 unsigned PCEncoding =
1809 IsEH ? MOFI->getFDEEncoding() : (unsigned)dwarf::DW_EH_PE_absptr;
1810 unsigned PCSize = getSizeForEncoding(Streamer, PCEncoding);
1811 emitFDESymbol(Streamer, *frame.Begin, PCEncoding, IsEH);
1812
1813 // PC Range
1814 const MCExpr *Range =
1815 makeEndMinusStartExpr(context, *frame.Begin, *frame.End, 0);
1816 emitAbsValue(Streamer, Range, PCSize);
1817
1818 if (IsEH) {
1819 // Augmentation Data Length
1820 unsigned augmentationLength = 0;
1821
1822 if (frame.Lsda)
1823 augmentationLength += getSizeForEncoding(Streamer, frame.LsdaEncoding);
1824
1825 Streamer.emitULEB128IntValue(augmentationLength);
1826
1827 // Augmentation Data
1828 if (frame.Lsda)
1829 emitFDESymbol(Streamer, *frame.Lsda, frame.LsdaEncoding, true);
1830 }
1831
1832 // Call Frame Instructions
1833 emitCFIInstructions(frame.Instructions, frame.Begin);
1834
1835 // Padding
1836 // The size of a .eh_frame section has to be a multiple of the alignment
1837 // since a null CIE is interpreted as the end. Old systems overaligned
1838 // .eh_frame, so we do too and account for it in the last FDE.
1839 unsigned Alignment = LastInSection ? asmInfo->getCodePointerSize() : PCSize;
1840 Streamer.emitValueToAlignment(Align(Alignment));
1841
1842 Streamer.emitLabel(fdeEnd);
1843}
1844
1845namespace {
1846
1847struct CIEKey {
1848 CIEKey() = default;
1849
1850 explicit CIEKey(const MCDwarfFrameInfo &Frame)
1851 : Personality(Frame.Personality),
1852 PersonalityEncoding(Frame.PersonalityEncoding),
1853 LsdaEncoding(Frame.LsdaEncoding), IsSignalFrame(Frame.IsSignalFrame),
1854 IsSimple(Frame.IsSimple), RAReg(Frame.RAReg),
1855 IsBKeyFrame(Frame.IsBKeyFrame),
1856 IsMTETaggedFrame(Frame.IsMTETaggedFrame) {}
1857
1858 StringRef PersonalityName() const {
1859 if (!Personality)
1860 return StringRef();
1861 return Personality->getName();
1862 }
1863
1864 bool operator<(const CIEKey &Other) const {
1865 return std::make_tuple(PersonalityName(), PersonalityEncoding, LsdaEncoding,
1866 IsSignalFrame, IsSimple, RAReg, IsBKeyFrame,
1867 IsMTETaggedFrame) <
1868 std::make_tuple(Other.PersonalityName(), Other.PersonalityEncoding,
1869 Other.LsdaEncoding, Other.IsSignalFrame,
1870 Other.IsSimple, Other.RAReg, Other.IsBKeyFrame,
1871 Other.IsMTETaggedFrame);
1872 }
1873
1874 bool operator==(const CIEKey &Other) const {
1875 return Personality == Other.Personality &&
1876 PersonalityEncoding == Other.PersonalityEncoding &&
1877 LsdaEncoding == Other.LsdaEncoding &&
1878 IsSignalFrame == Other.IsSignalFrame && IsSimple == Other.IsSimple &&
1879 RAReg == Other.RAReg && IsBKeyFrame == Other.IsBKeyFrame &&
1880 IsMTETaggedFrame == Other.IsMTETaggedFrame;
1881 }
1882 bool operator!=(const CIEKey &Other) const { return !(*this == Other); }
1883
1884 const MCSymbol *Personality = nullptr;
1885 unsigned PersonalityEncoding = 0;
1886 unsigned LsdaEncoding = -1;
1887 bool IsSignalFrame = false;
1888 bool IsSimple = false;
1889 unsigned RAReg = UINT_MAX;
1890 bool IsBKeyFrame = false;
1891 bool IsMTETaggedFrame = false;
1892};
1893
1894} // end anonymous namespace
1895
1897 bool IsEH) {
1898 MCContext &Context = Streamer.getContext();
1899 const MCObjectFileInfo *MOFI = Context.getObjectFileInfo();
1900 const MCAsmInfo *AsmInfo = Context.getAsmInfo();
1901 FrameEmitterImpl Emitter(IsEH, Streamer);
1902 ArrayRef<MCDwarfFrameInfo> FrameArray = Streamer.getDwarfFrameInfos();
1903
1904 // Emit the compact unwind info if available.
1905 bool NeedsEHFrameSection = !MOFI->getSupportsCompactUnwindWithoutEHFrame();
1906 if (IsEH && MOFI->getCompactUnwindSection()) {
1907 Streamer.generateCompactUnwindEncodings(MAB);
1908 bool SectionEmitted = false;
1909 for (const MCDwarfFrameInfo &Frame : FrameArray) {
1910 if (Frame.CompactUnwindEncoding == 0) continue;
1911 if (!SectionEmitted) {
1912 Streamer.switchSection(MOFI->getCompactUnwindSection());
1913 Streamer.emitValueToAlignment(Align(AsmInfo->getCodePointerSize()));
1914 SectionEmitted = true;
1915 }
1916 NeedsEHFrameSection |=
1917 Frame.CompactUnwindEncoding ==
1919 Emitter.EmitCompactUnwind(Frame);
1920 }
1921 }
1922
1923 // Compact unwind information can be emitted in the eh_frame section or the
1924 // debug_frame section. Skip emitting FDEs and CIEs when the compact unwind
1925 // doesn't need an eh_frame section and the emission location is the eh_frame
1926 // section.
1927 if (!NeedsEHFrameSection && IsEH) return;
1928
1929 MCSection &Section =
1930 IsEH ? *const_cast<MCObjectFileInfo *>(MOFI)->getEHFrameSection()
1931 : *MOFI->getDwarfFrameSection();
1932
1933 Streamer.switchSection(&Section);
1934 MCSymbol *SectionStart = Context.createTempSymbol();
1935 Streamer.emitLabel(SectionStart);
1936
1937 bool CanOmitDwarf = MOFI->getOmitDwarfIfHaveCompactUnwind();
1938 // Sort the FDEs by their corresponding CIE before we emit them.
1939 // This isn't technically necessary according to the DWARF standard,
1940 // but the Android libunwindstack rejects eh_frame sections where
1941 // an FDE refers to a CIE other than the closest previous CIE.
1942 std::vector<MCDwarfFrameInfo> FrameArrayX(FrameArray.begin(), FrameArray.end());
1943 llvm::stable_sort(FrameArrayX,
1944 [](const MCDwarfFrameInfo &X, const MCDwarfFrameInfo &Y) {
1945 return CIEKey(X) < CIEKey(Y);
1946 });
1947 CIEKey LastKey;
1948 const MCSymbol *LastCIEStart = nullptr;
1949 for (auto I = FrameArrayX.begin(), E = FrameArrayX.end(); I != E;) {
1950 const MCDwarfFrameInfo &Frame = *I;
1951 ++I;
1952 if (CanOmitDwarf && Frame.CompactUnwindEncoding !=
1953 MOFI->getCompactUnwindDwarfEHFrameOnly() && IsEH)
1954 // CIEs and FDEs can be emitted in either the eh_frame section or the
1955 // debug_frame section, on some platforms (e.g. AArch64) the target object
1956 // file supports emitting a compact_unwind section without an associated
1957 // eh_frame section. If the eh_frame section is not needed, and the
1958 // location where the CIEs and FDEs are to be emitted is the eh_frame
1959 // section, do not emit anything.
1960 continue;
1961
1962 CIEKey Key(Frame);
1963 if (!LastCIEStart || (IsEH && Key != LastKey)) {
1964 LastKey = Key;
1965 LastCIEStart = &Emitter.EmitCIE(Frame);
1966 }
1967
1968 Emitter.EmitFDE(*LastCIEStart, Frame, I == E, *SectionStart);
1969 }
1970}
1971
1973 uint64_t AddrDelta,
1974 SmallVectorImpl<char> &Out) {
1975 // Scale the address delta by the minimum instruction length.
1976 AddrDelta = ScaleAddrDelta(Context, AddrDelta);
1977 if (AddrDelta == 0)
1978 return;
1979
1980 llvm::endianness E = Context.getAsmInfo()->isLittleEndian()
1983
1984 if (isUIntN(6, AddrDelta)) {
1985 uint8_t Opcode = dwarf::DW_CFA_advance_loc | AddrDelta;
1986 Out.push_back(Opcode);
1987 } else if (isUInt<8>(AddrDelta)) {
1988 Out.push_back(dwarf::DW_CFA_advance_loc1);
1989 Out.push_back(AddrDelta);
1990 } else if (isUInt<16>(AddrDelta)) {
1991 Out.push_back(dwarf::DW_CFA_advance_loc2);
1992 support::endian::write<uint16_t>(Out, AddrDelta, E);
1993 } else {
1994 assert(isUInt<32>(AddrDelta));
1995 Out.push_back(dwarf::DW_CFA_advance_loc4);
1996 support::endian::write<uint32_t>(Out, AddrDelta, E);
1997 }
1998}
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:1316
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:730
static void EmitGenDwarfAranges(MCStreamer *MCOS, const MCSymbol *InfoSectionSymbol)
Definition MCDwarf.cpp:875
static bool isRootFile(const MCDwarfFile &RootFile, StringRef &Directory, StringRef &FileName, std::optional< MD5::MD5Result > Checksum)
Definition MCDwarf.cpp:629
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:358
static void emitAbsValue(MCStreamer &OS, const MCExpr *Value, unsigned Size)
Definition MCDwarf.cpp:370
static void emitOneV5FileEntry(MCStreamer *MCOS, const MCDwarfFile &DwarfFile, bool EmitMD5, bool HasAnySource, std::optional< MCDwarfLineStr > &LineStr)
Definition MCDwarf.cpp:433
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:1625
static void EmitGenDwarfInfo(MCStreamer *MCOS, const MCSymbol *AbbrevSectionSymbol, const MCSymbol *LineSectionSymbol, const MCSymbol *RangesSymbol)
Definition MCDwarf.cpp:953
static void EmitAbbrev(MCStreamer *MCOS, uint64_t Name, uint64_t Form)
Definition MCDwarf.cpp:819
static void EmitPersonality(MCStreamer &streamer, const MCSymbol &symbol, unsigned symbolEncoding)
Definition MCDwarf.cpp:1330
static void emitEncodingByte(MCObjectStreamer &Streamer, unsigned Encoding)
Definition MCDwarf.cpp:1366
static int getDataAlignmentFactor(MCStreamer &streamer)
Definition MCDwarf.cpp:1285
static MCSymbol * emitGenDwarfRanges(MCStreamer *MCOS)
Definition MCDwarf.cpp:1124
static const MCExpr * makeStartPlusIntExpr(MCContext &Ctx, const MCSymbol &Start, int IntVal)
Definition MCDwarf.cpp:135
static void EmitGenDwarfAbbrev(MCStreamer *MCOS)
Definition MCDwarf.cpp:826
static unsigned getSizeForEncoding(MCStreamer &streamer, unsigned symbolEncoding)
Definition MCDwarf.cpp:1295
#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:785
const SmallVectorImpl< std::string > & getMCDwarfDirs(unsigned CUID=0)
Definition MCContext.h:727
StringRef getDwarfDebugProducer()
Definition MCContext.h:807
StringRef getDwarfDebugFlags()
Definition MCContext.h:804
bool getDwarfLocSeen()
Definition MCContext.h:768
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:678
void clearDwarfLocSeen()
Definition MCContext.h:766
MCDwarfLineTable & getMCDwarfLineTable(unsigned CUID)
Definition MCContext.h:713
unsigned getDwarfCompileUnitID()
Definition MCContext.h:731
const MCRegisterInfo * getRegisterInfo() const
Definition MCContext.h:414
const SmallVectorImpl< MCDwarfFile > & getMCDwarfFiles(unsigned CUID=0)
Definition MCContext.h:723
const std::map< unsigned, MCDwarfLineTable > & getMCDwarfLineTables() const
Definition MCContext.h:709
unsigned getGenDwarfFileNumber()
Definition MCContext.h:773
uint16_t getDwarfVersion() const
Definition MCContext.h:813
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:799
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
const MCDwarfLoc & getCurrentDwarfLoc()
Definition MCContext.h:769
dwarf::DwarfFormat getDwarfFormat() const
Definition MCContext.h:810
const std::vector< MCGenDwarfLabelEntry > & getMCGenDwarfLabelEntries() const
Definition MCContext.h:795
LLVM_ABI void Emit(MCStreamer &MCOS, MCDwarfLineTableParams Params, MCSection *Section) const
Definition MCDwarf.cpp:325
static LLVM_ABI void Emit(MCObjectStreamer &streamer, MCAsmBackend *MAB, bool isEH)
Definition MCDwarf.cpp:1896
static LLVM_ABI void encodeAdvanceLoc(MCContext &Context, uint64_t AddrDelta, SmallVectorImpl< char > &OS)
Definition MCDwarf.cpp:1972
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:720
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:735
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:375
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:383
LLVM_ABI void emitRef(MCStreamer *MCOS, StringRef Path)
Emit a reference to the string.
Definition MCDwarf.cpp:397
LLVM_ABI size_t addString(StringRef Path)
Adds path Path to the line string.
Definition MCDwarf.cpp:393
LLVM_ABI void endCurrentSeqAndEmitLineStreamLabel(MCStreamer *MCOS, SMLoc DefLoc, StringRef Name)
Definition MCDwarf.cpp:279
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:298
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:621
LLVM_ABI void emitCU(MCStreamer *MCOS, MCDwarfLineTableParams Params, std::optional< MCDwarfLineStr > &LineStr) const
Definition MCDwarf.cpp:607
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:1185
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:1248
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:496
MCSymbol * getBeginSymbol()
Definition MCSection.h:568
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:97
uint8_t getUnitLengthFieldByteSize(DwarfFormat Format)
Get the byte size of the unit length field depending on the DWARF format.
Definition Dwarf.h:1119
const uint64_t DW64_CIE_ID
Definition Dwarf.h:98
DwarfFormat
Constants that define the DWARF format as 32 or 64 bit.
Definition Dwarf.h:92
@ DWARF64
Definition Dwarf.h:92
@ DWARF32
Definition Dwarf.h:92
uint8_t getDwarfOffsetByteSize(DwarfFormat Format)
The size of a reference determined by the DWARF 32/64-bit format.
Definition Dwarf.h:1080
@ DW_CHILDREN_no
Definition Dwarf.h:851
@ DW_EH_PE_signed
Definition Dwarf.h:864
@ DW_CHILDREN_yes
Definition Dwarf.h:852
@ DW_EH_PE_sdata4
Definition Dwarf.h:862
@ DW_EH_PE_udata2
Definition Dwarf.h:857
@ DW_EH_PE_sdata8
Definition Dwarf.h:863
@ DW_EH_PE_absptr
Definition Dwarf.h:854
@ DW_EH_PE_sdata2
Definition Dwarf.h:861
@ DW_EH_PE_udata4
Definition Dwarf.h:858
@ DW_EH_PE_udata8
Definition Dwarf.h:859
@ DW_LENGTH_DWARF64
Indicator of 64-bit DWARF format.
Definition Dwarf.h:56
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:2040
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:1733
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:1665
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:335
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:638
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