LLVM 23.0.0git
DWARFCFIPrinter.cpp
Go to the documentation of this file.
1//===- DWARFCFIPrinter.cpp - Print the cfi-portions of .debug_frame -------===//
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
15#include "llvm/Support/Format.h"
18#include <cassert>
19#include <cinttypes>
20#include <cstdint>
21#include <optional>
22
23using namespace llvm;
24using namespace dwarf;
25
26static void printRegister(raw_ostream &OS, const DIDumpOptions &DumpOpts,
27 unsigned RegNum) {
28 if (DumpOpts.GetNameForDWARFReg) {
29 auto RegName = DumpOpts.GetNameForDWARFReg(RegNum, DumpOpts.IsEH);
30 if (!RegName.empty()) {
31 OS << RegName;
32 return;
33 }
34 }
35 OS << "reg" << RegNum;
36}
37
38/// Print \p Opcode's operand number \p OperandIdx which has value \p Operand.
39static void printOperand(raw_ostream &OS, const DIDumpOptions &DumpOpts,
40 const CFIProgram &P,
41 const CFIProgram::Instruction &Instr,
42 unsigned OperandIdx, uint64_t Operand,
43 std::optional<uint64_t> &Address) {
44 assert(OperandIdx < CFIProgram::MaxOperands);
45 uint8_t Opcode = Instr.Opcode;
46 CFIProgram::OperandType Type = P.getOperandTypes()[Opcode][OperandIdx];
47
48 switch (Type) {
50 OS << " Unsupported " << (OperandIdx ? "second" : "first") << " operand to";
51 auto OpcodeName = P.callFrameString(Opcode);
52 if (!OpcodeName.empty())
53 OS << " " << OpcodeName;
54 else
55 OS << format(" Opcode %x", Opcode);
56 break;
57 }
59 break;
61 OS << format(" %" PRIx64, Operand);
62 Address = Operand;
63 break;
65 // The offsets are all encoded in a unsigned form, but in practice
66 // consumers use them signed. It's most certainly legacy due to
67 // the lack of signed variants in the first Dwarf standards.
68 OS << formatv(" {0:+d}", int64_t(Operand));
69 break;
70 case CFIProgram::OT_FactoredCodeOffset: // Always Unsigned
71 if (P.codeAlign())
72 OS << format(" %" PRId64, Operand * P.codeAlign());
73 else
74 OS << format(" %" PRId64 "*code_alignment_factor", Operand);
75 if (Address && P.codeAlign()) {
76 *Address += Operand * P.codeAlign();
77 OS << format(" to 0x%" PRIx64, *Address);
78 }
79 break;
81 if (P.dataAlign())
82 OS << format(" %" PRId64, int64_t(Operand) * P.dataAlign());
83 else
84 OS << format(" %" PRId64 "*data_alignment_factor", int64_t(Operand));
85 break;
87 if (P.dataAlign())
88 OS << format(" %" PRId64, Operand * P.dataAlign());
89 else
90 OS << format(" %" PRId64 "*data_alignment_factor", Operand);
91 break;
93 OS << ' ';
94 printRegister(OS, DumpOpts, Operand);
95 break;
97 OS << format(" in addrspace%" PRId64, Operand);
98 break;
100 assert(Instr.Expression && "missing DWARFExpression object");
101 OS << " ";
102 printDwarfExpression(&Instr.Expression.value(), OS, DumpOpts, nullptr);
103 break;
104 }
105}
106
108 const DIDumpOptions &DumpOpts,
109 unsigned IndentLevel,
110 std::optional<uint64_t> Address) {
111 for (const auto &Instr : P) {
112 uint8_t Opcode = Instr.Opcode;
113 OS.indent(2 * IndentLevel);
114 OS << P.callFrameString(Opcode) << ":";
115 for (size_t i = 0; i < Instr.Ops.size(); ++i)
116 printOperand(OS, DumpOpts, P, Instr, i, Instr.Ops[i], Address);
117 OS << '\n';
118 }
119}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static void printOperand(raw_ostream &OS, const DIDumpOptions &DumpOpts, const CFIProgram &P, const CFIProgram::Instruction &Instr, unsigned OperandIdx, uint64_t Operand, std::optional< uint64_t > &Address)
Print Opcode's operand number OperandIdx which has value Operand.
static void printRegister(raw_ostream &OS, const DIDumpOptions &DumpOpts, unsigned RegNum)
#define RegName(no)
#define P(N)
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
Represent a sequence of Call Frame Information instructions that, when read in order,...
OperandType
Types of operands to CFI instructions In DWARF, this type is implicitly tied to a CFI instruction opc...
static constexpr size_t MaxOperands
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
Calculates the starting offsets for various sections within the .debug_names section.
Definition Dwarf.h:35
LLVM_ABI void printCFIProgram(const CFIProgram &P, raw_ostream &OS, const DIDumpOptions &DumpOpts, unsigned IndentLevel, std::optional< uint64_t > Address)
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
LLVM_ABI void printDwarfExpression(const DWARFExpression *E, raw_ostream &OS, DIDumpOptions DumpOpts, DWARFUnit *U, bool IsEH=false)
Print a Dwarf expression/.
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition Format.h:129
Container for dump options that control which debug information will be dumped.
Definition DIContext.h:196
std::function< llvm::StringRef(uint64_t DwarfRegNum, bool IsEH)> GetNameForDWARFReg
Definition DIContext.h:217
An instruction consists of a DWARF CFI opcode and an optional sequence of operands.