LLVM 24.0.0git
DWARFCFIProgram.cpp
Go to the documentation of this file.
1//===- DWARFCFIProgram.cpp - Parsing 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
11#include "llvm/Support/Errc.h"
14#include <cassert>
15#include <cinttypes>
16#include <cstdint>
17
18using namespace llvm;
19using namespace dwarf;
20
21StringRef CFIProgram::callFrameString(unsigned Opcode) const {
22 return dwarf::CallFrameString(Opcode, Arch);
23}
24
45
48 uint32_t OperandIdx) const {
49 if (OperandIdx >= MaxOperands)
51 "operand index %" PRIu32 " is not valid",
52 OperandIdx);
53 OperandType Type = CFIP.getOperandTypes()[Opcode][OperandIdx];
54 uint64_t Operand = Ops[OperandIdx];
55 switch (Type) {
56 case OT_Unset:
57 case OT_None:
58 case OT_Expression:
60 "op[%" PRIu32 "] has type %s which has no value",
62
63 case OT_Offset:
67 return createStringError(
69 "op[%" PRIu32 "] has OperandType OT_Offset which produces a signed "
70 "result, call getOperandAsSigned instead",
71 OperandIdx);
72
73 case OT_Address:
74 case OT_Register:
75 case OT_AddressSpace:
76 case OT_RAState:
77 return Operand;
78
80 const uint64_t CodeAlignmentFactor = CFIP.codeAlign();
81 if (CodeAlignmentFactor == 0)
82 return createStringError(
84 "op[%" PRIu32 "] has type OT_FactoredCodeOffset but code alignment "
85 "is zero",
86 OperandIdx);
87 return Operand * CodeAlignmentFactor;
88 }
89 }
90 llvm_unreachable("invalid operand type");
91}
92
95 uint32_t OperandIdx) const {
96 if (OperandIdx >= MaxOperands)
98 "operand index %" PRIu32 " is not valid",
99 OperandIdx);
100 OperandType Type = CFIP.getOperandTypes()[Opcode][OperandIdx];
101 uint64_t Operand = Ops[OperandIdx];
102 switch (Type) {
103 case OT_Unset:
104 case OT_None:
105 case OT_Expression:
107 "op[%" PRIu32 "] has type %s which has no value",
109
110 case OT_Address:
111 case OT_Register:
112 case OT_AddressSpace:
113 case OT_RAState:
114 return createStringError(
116 "op[%" PRIu32 "] has OperandType %s which produces an unsigned result, "
117 "call getOperandAsUnsigned instead",
119
120 case OT_Offset:
121 return (int64_t)Operand;
122
125 const int64_t DataAlignmentFactor = CFIP.dataAlign();
126 if (DataAlignmentFactor == 0)
128 "op[%" PRIu32 "] has type %s but data "
129 "alignment is zero",
131 return int64_t(Operand) * DataAlignmentFactor;
132 }
133
135 const int64_t CodeAlignmentFactor = CFIP.codeAlign();
136 if (CodeAlignmentFactor == 0)
138 "op[%" PRIu32 "] has type %s but code "
139 "alignment is zero",
141 return int64_t(Operand) * CodeAlignmentFactor;
142 }
143
145 const int64_t DataAlignmentFactor = CFIP.dataAlign();
146 if (DataAlignmentFactor == 0)
148 "op[%" PRIu32
149 "] has type OT_UnsignedFactDataOffset but data "
150 "alignment is zero",
151 OperandIdx);
152 return Operand * DataAlignmentFactor;
153 }
154 }
155 llvm_unreachable("invalid operand type");
156}
157
160 static OperandType OpTypes[DW_CFA_restore + 1][MaxOperands];
161 static bool Initialized = false;
162 if (Initialized) {
163 return ArrayRef<OperandType[MaxOperands]>(&OpTypes[0], DW_CFA_restore + 1);
164 }
165 Initialized = true;
166
167#define DECLARE_OP3(OP, OPTYPE0, OPTYPE1, OPTYPE2) \
168 do { \
169 OpTypes[OP][0] = OPTYPE0; \
170 OpTypes[OP][1] = OPTYPE1; \
171 OpTypes[OP][2] = OPTYPE2; \
172 } while (false)
173#define DECLARE_OP2(OP, OPTYPE0, OPTYPE1) \
174 DECLARE_OP3(OP, OPTYPE0, OPTYPE1, OT_None)
175#define DECLARE_OP1(OP, OPTYPE0) DECLARE_OP2(OP, OPTYPE0, OT_None)
176#define DECLARE_OP0(OP) DECLARE_OP1(OP, OT_None)
177
178 DECLARE_OP1(DW_CFA_set_loc, OT_Address);
179 DECLARE_OP1(DW_CFA_advance_loc, OT_FactoredCodeOffset);
180 DECLARE_OP1(DW_CFA_advance_loc1, OT_FactoredCodeOffset);
181 DECLARE_OP1(DW_CFA_advance_loc2, OT_FactoredCodeOffset);
182 DECLARE_OP1(DW_CFA_advance_loc4, OT_FactoredCodeOffset);
183 DECLARE_OP1(DW_CFA_MIPS_advance_loc8, OT_FactoredCodeOffset);
184 DECLARE_OP2(DW_CFA_def_cfa, OT_Register, OT_Offset);
186 DECLARE_OP1(DW_CFA_def_cfa_register, OT_Register);
187 DECLARE_OP3(DW_CFA_LLVM_def_aspace_cfa, OT_Register, OT_Offset,
189 DECLARE_OP3(DW_CFA_LLVM_def_aspace_cfa_sf, OT_Register,
191 DECLARE_OP1(DW_CFA_def_cfa_offset, OT_Offset);
192 DECLARE_OP1(DW_CFA_def_cfa_offset_sf, OT_SignedFactDataOffset);
193 DECLARE_OP1(DW_CFA_def_cfa_expression, OT_Expression);
194 DECLARE_OP1(DW_CFA_undefined, OT_Register);
195 DECLARE_OP1(DW_CFA_same_value, OT_Register);
197 DECLARE_OP2(DW_CFA_offset_extended, OT_Register, OT_UnsignedFactDataOffset);
198 DECLARE_OP2(DW_CFA_offset_extended_sf, OT_Register, OT_SignedFactDataOffset);
200 DECLARE_OP2(DW_CFA_val_offset_sf, OT_Register, OT_SignedFactDataOffset);
201 DECLARE_OP2(DW_CFA_register, OT_Register, OT_Register);
202 DECLARE_OP2(DW_CFA_expression, OT_Register, OT_Expression);
203 DECLARE_OP2(DW_CFA_val_expression, OT_Register, OT_Expression);
204 DECLARE_OP1(DW_CFA_restore, OT_Register);
205 DECLARE_OP1(DW_CFA_restore_extended, OT_Register);
206 DECLARE_OP0(DW_CFA_remember_state);
207 DECLARE_OP0(DW_CFA_restore_state);
208 DECLARE_OP0(DW_CFA_GNU_window_save);
209 DECLARE_OP0(DW_CFA_AARCH64_negate_ra_state_with_pc);
210 DECLARE_OP2(DW_CFA_AARCH64_set_ra_state, OT_RAState, OT_SignedFactCodeOffset);
211 DECLARE_OP1(DW_CFA_GNU_args_size, OT_Offset);
212 DECLARE_OP0(DW_CFA_nop);
213
214#undef DECLARE_OP0
215#undef DECLARE_OP1
216#undef DECLARE_OP2
217
218 return ArrayRef<OperandType[MaxOperands]>(&OpTypes[0], DW_CFA_restore + 1);
219}
#define DECLARE_OP3(OP, OPTYPE0, OPTYPE1, OPTYPE2)
#define DECLARE_OP2(OP, OPTYPE0, OPTYPE1)
#define DECLARE_OP0(OP)
#define ENUM_TO_CSTR(e)
#define DECLARE_OP1(OP, OPTYPE0)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
Tagged union holding either a T or a Error.
Definition Error.h:485
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
OperandType
Types of operands to CFI instructions In DWARF, this type is implicitly tied to a CFI instruction opc...
uint64_t codeAlign() const
static constexpr size_t MaxOperands
static LLVM_ABI ArrayRef< OperandType[MaxOperands]> getOperandTypes()
Retrieve the array describing the types of operands according to the enum above.
CFIProgram(uint64_t CodeAlignmentFactor, int64_t DataAlignmentFactor, Triple::ArchType Arch)
int64_t dataAlign() const
static LLVM_ABI const char * operandTypeString(OperandType OT)
Get the OperandType as a "const char *".
LLVM_ABI StringRef callFrameString(unsigned Opcode) const
Get a DWARF CFI call frame string for the given DW_CFA opcode.
LLVM_ABI StringRef CallFrameString(unsigned Encoding, Triple::ArchType Arch)
Definition Dwarf.cpp:800
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Calculates the starting offsets for various sections within the .debug_names section.
Definition Dwarf.h:35
This is an optimization pass for GlobalISel generic memory operations.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition Error.h:1321
@ invalid_argument
Definition Errc.h:56
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI Expected< uint64_t > getOperandAsUnsigned(const CFIProgram &CFIP, uint32_t OperandIdx) const
LLVM_ABI Expected< int64_t > getOperandAsSigned(const CFIProgram &CFIP, uint32_t OperandIdx) const