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