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