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 <array>
15#include <cassert>
16#include <cinttypes>
17#include <cstdint>
18
19using namespace llvm;
20using namespace dwarf;
21
22StringRef CFIProgram::callFrameString(unsigned Opcode) const {
23 return dwarf::CallFrameString(Opcode, Arch);
24}
25
46
49 uint32_t OperandIdx) const {
50 if (OperandIdx >= MaxOperands)
52 "operand index %" PRIu32 " is not valid",
53 OperandIdx);
54 OperandType Type = CFIP.getOperandTypes()[Opcode][OperandIdx];
55 uint64_t Operand = Ops[OperandIdx];
56 switch (Type) {
57 case OT_Unset:
58 case OT_None:
59 case OT_Expression:
61 "op[%" PRIu32 "] has type %s which has no value",
63
64 case OT_Offset:
68 return createStringError(
70 "op[%" PRIu32 "] has OperandType OT_Offset which produces a signed "
71 "result, call getOperandAsSigned instead",
72 OperandIdx);
73
74 case OT_Address:
75 case OT_Register:
76 case OT_AddressSpace:
77 case OT_RAState:
78 return Operand;
79
81 const uint64_t CodeAlignmentFactor = CFIP.codeAlign();
82 if (CodeAlignmentFactor == 0)
83 return createStringError(
85 "op[%" PRIu32 "] has type OT_FactoredCodeOffset but code alignment "
86 "is zero",
87 OperandIdx);
88 return Operand * CodeAlignmentFactor;
89 }
90 }
91 llvm_unreachable("invalid operand type");
92}
93
96 uint32_t OperandIdx) const {
97 if (OperandIdx >= MaxOperands)
99 "operand index %" PRIu32 " is not valid",
100 OperandIdx);
101 OperandType Type = CFIP.getOperandTypes()[Opcode][OperandIdx];
102 uint64_t Operand = Ops[OperandIdx];
103 switch (Type) {
104 case OT_Unset:
105 case OT_None:
106 case OT_Expression:
108 "op[%" PRIu32 "] has type %s which has no value",
110
111 case OT_Address:
112 case OT_Register:
113 case OT_AddressSpace:
114 case OT_RAState:
115 return createStringError(
117 "op[%" PRIu32 "] has OperandType %s which produces an unsigned result, "
118 "call getOperandAsUnsigned instead",
120
121 case OT_Offset:
122 return (int64_t)Operand;
123
126 const int64_t DataAlignmentFactor = CFIP.dataAlign();
127 if (DataAlignmentFactor == 0)
129 "op[%" PRIu32 "] has type %s but data "
130 "alignment is zero",
132 return int64_t(Operand) * DataAlignmentFactor;
133 }
134
136 const int64_t CodeAlignmentFactor = CFIP.codeAlign();
137 if (CodeAlignmentFactor == 0)
139 "op[%" PRIu32 "] has type %s but code "
140 "alignment is zero",
142 return int64_t(Operand) * CodeAlignmentFactor;
143 }
144
146 const int64_t DataAlignmentFactor = CFIP.dataAlign();
147 if (DataAlignmentFactor == 0)
149 "op[%" PRIu32
150 "] has type OT_UnsignedFactDataOffset but data "
151 "alignment is zero",
152 OperandIdx);
153 return Operand * DataAlignmentFactor;
154 }
155 }
156 llvm_unreachable("invalid operand type");
157}
158
161 static constexpr auto Table = [] {
162 std::array<OperandType[MaxOperands], DW_CFA_restore + 1> OpTypes{};
163
164#define DECLARE_OP3(OP, OPTYPE0, OPTYPE1, OPTYPE2) \
165 do { \
166 OpTypes[OP][0] = OPTYPE0; \
167 OpTypes[OP][1] = OPTYPE1; \
168 OpTypes[OP][2] = OPTYPE2; \
169 } while (false)
170#define DECLARE_OP2(OP, OPTYPE0, OPTYPE1) \
171 DECLARE_OP3(OP, OPTYPE0, OPTYPE1, OT_None)
172#define DECLARE_OP1(OP, OPTYPE0) DECLARE_OP2(OP, OPTYPE0, OT_None)
173#define DECLARE_OP0(OP) DECLARE_OP1(OP, OT_None)
174
175 DECLARE_OP1(DW_CFA_set_loc, OT_Address);
176 DECLARE_OP1(DW_CFA_advance_loc, OT_FactoredCodeOffset);
177 DECLARE_OP1(DW_CFA_advance_loc1, OT_FactoredCodeOffset);
178 DECLARE_OP1(DW_CFA_advance_loc2, OT_FactoredCodeOffset);
179 DECLARE_OP1(DW_CFA_advance_loc4, OT_FactoredCodeOffset);
180 DECLARE_OP1(DW_CFA_MIPS_advance_loc8, OT_FactoredCodeOffset);
181 DECLARE_OP2(DW_CFA_def_cfa, OT_Register, OT_Offset);
183 DECLARE_OP1(DW_CFA_def_cfa_register, OT_Register);
184 DECLARE_OP3(DW_CFA_LLVM_def_aspace_cfa, OT_Register, OT_Offset,
186 DECLARE_OP3(DW_CFA_LLVM_def_aspace_cfa_sf, OT_Register,
188 DECLARE_OP1(DW_CFA_def_cfa_offset, OT_Offset);
189 DECLARE_OP1(DW_CFA_def_cfa_offset_sf, OT_SignedFactDataOffset);
190 DECLARE_OP1(DW_CFA_def_cfa_expression, OT_Expression);
191 DECLARE_OP1(DW_CFA_undefined, OT_Register);
192 DECLARE_OP1(DW_CFA_same_value, OT_Register);
194 DECLARE_OP2(DW_CFA_offset_extended, OT_Register, OT_UnsignedFactDataOffset);
195 DECLARE_OP2(DW_CFA_offset_extended_sf, OT_Register,
198 DECLARE_OP2(DW_CFA_val_offset_sf, OT_Register, OT_SignedFactDataOffset);
199 DECLARE_OP2(DW_CFA_register, OT_Register, OT_Register);
200 DECLARE_OP2(DW_CFA_expression, OT_Register, OT_Expression);
201 DECLARE_OP2(DW_CFA_val_expression, OT_Register, OT_Expression);
202 DECLARE_OP1(DW_CFA_restore, OT_Register);
203 DECLARE_OP1(DW_CFA_restore_extended, OT_Register);
204 DECLARE_OP0(DW_CFA_remember_state);
205 DECLARE_OP0(DW_CFA_restore_state);
206 DECLARE_OP0(DW_CFA_GNU_window_save);
207 DECLARE_OP0(DW_CFA_AARCH64_negate_ra_state_with_pc);
208 DECLARE_OP2(DW_CFA_AARCH64_set_ra_state, OT_RAState,
210 DECLARE_OP1(DW_CFA_GNU_args_size, OT_Offset);
211 DECLARE_OP0(DW_CFA_nop);
212
213#undef DECLARE_OP0
214#undef DECLARE_OP1
215#undef DECLARE_OP2
216
217 return OpTypes;
218 }();
219 return Table;
220}
#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:802
#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
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