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