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