Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.cpp
213845 views
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
9
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFCFIProgram.h"
10
#include "llvm/Support/Compiler.h"
11
#include "llvm/Support/Errc.h"
12
#include "llvm/Support/ErrorHandling.h"
13
#include "llvm/Support/raw_ostream.h"
14
#include <cassert>
15
#include <cinttypes>
16
#include <cstdint>
17
18
using namespace llvm;
19
using namespace dwarf;
20
21
StringRef CFIProgram::callFrameString(unsigned Opcode) const {
22
return dwarf::CallFrameString(Opcode, Arch);
23
}
24
25
const char *CFIProgram::operandTypeString(CFIProgram::OperandType OT) {
26
#define ENUM_TO_CSTR(e) \
27
case e: \
28
return #e;
29
switch (OT) {
30
ENUM_TO_CSTR(OT_Unset);
31
ENUM_TO_CSTR(OT_None);
32
ENUM_TO_CSTR(OT_Address);
33
ENUM_TO_CSTR(OT_Offset);
34
ENUM_TO_CSTR(OT_FactoredCodeOffset);
35
ENUM_TO_CSTR(OT_SignedFactDataOffset);
36
ENUM_TO_CSTR(OT_UnsignedFactDataOffset);
37
ENUM_TO_CSTR(OT_Register);
38
ENUM_TO_CSTR(OT_AddressSpace);
39
ENUM_TO_CSTR(OT_Expression);
40
}
41
return "<unknown CFIProgram::OperandType>";
42
}
43
44
llvm::Expected<uint64_t>
45
CFIProgram::Instruction::getOperandAsUnsigned(const CFIProgram &CFIP,
46
uint32_t OperandIdx) const {
47
if (OperandIdx >= MaxOperands)
48
return createStringError(errc::invalid_argument,
49
"operand index %" PRIu32 " is not valid",
50
OperandIdx);
51
OperandType Type = CFIP.getOperandTypes()[Opcode][OperandIdx];
52
uint64_t Operand = Ops[OperandIdx];
53
switch (Type) {
54
case OT_Unset:
55
case OT_None:
56
case OT_Expression:
57
return createStringError(errc::invalid_argument,
58
"op[%" PRIu32 "] has type %s which has no value",
59
OperandIdx, CFIProgram::operandTypeString(Type));
60
61
case OT_Offset:
62
case OT_SignedFactDataOffset:
63
case OT_UnsignedFactDataOffset:
64
return createStringError(
65
errc::invalid_argument,
66
"op[%" PRIu32 "] has OperandType OT_Offset which produces a signed "
67
"result, call getOperandAsSigned instead",
68
OperandIdx);
69
70
case OT_Address:
71
case OT_Register:
72
case OT_AddressSpace:
73
return Operand;
74
75
case OT_FactoredCodeOffset: {
76
const uint64_t CodeAlignmentFactor = CFIP.codeAlign();
77
if (CodeAlignmentFactor == 0)
78
return createStringError(
79
errc::invalid_argument,
80
"op[%" PRIu32 "] has type OT_FactoredCodeOffset but code alignment "
81
"is zero",
82
OperandIdx);
83
return Operand * CodeAlignmentFactor;
84
}
85
}
86
llvm_unreachable("invalid operand type");
87
}
88
89
llvm::Expected<int64_t>
90
CFIProgram::Instruction::getOperandAsSigned(const CFIProgram &CFIP,
91
uint32_t OperandIdx) const {
92
if (OperandIdx >= MaxOperands)
93
return createStringError(errc::invalid_argument,
94
"operand index %" PRIu32 " is not valid",
95
OperandIdx);
96
OperandType Type = CFIP.getOperandTypes()[Opcode][OperandIdx];
97
uint64_t Operand = Ops[OperandIdx];
98
switch (Type) {
99
case OT_Unset:
100
case OT_None:
101
case OT_Expression:
102
return createStringError(errc::invalid_argument,
103
"op[%" PRIu32 "] has type %s which has no value",
104
OperandIdx, CFIProgram::operandTypeString(Type));
105
106
case OT_Address:
107
case OT_Register:
108
case OT_AddressSpace:
109
return createStringError(
110
errc::invalid_argument,
111
"op[%" PRIu32 "] has OperandType %s which produces an unsigned result, "
112
"call getOperandAsUnsigned instead",
113
OperandIdx, CFIProgram::operandTypeString(Type));
114
115
case OT_Offset:
116
return (int64_t)Operand;
117
118
case OT_FactoredCodeOffset:
119
case OT_SignedFactDataOffset: {
120
const int64_t DataAlignmentFactor = CFIP.dataAlign();
121
if (DataAlignmentFactor == 0)
122
return createStringError(errc::invalid_argument,
123
"op[%" PRIu32 "] has type %s but data "
124
"alignment is zero",
125
OperandIdx, CFIProgram::operandTypeString(Type));
126
return int64_t(Operand) * DataAlignmentFactor;
127
}
128
129
case OT_UnsignedFactDataOffset: {
130
const int64_t DataAlignmentFactor = CFIP.dataAlign();
131
if (DataAlignmentFactor == 0)
132
return createStringError(errc::invalid_argument,
133
"op[%" PRIu32
134
"] has type OT_UnsignedFactDataOffset but data "
135
"alignment is zero",
136
OperandIdx);
137
return Operand * DataAlignmentFactor;
138
}
139
}
140
llvm_unreachable("invalid operand type");
141
}
142
143
ArrayRef<CFIProgram::OperandType[CFIProgram::MaxOperands]>
144
CFIProgram::getOperandTypes() {
145
static OperandType OpTypes[DW_CFA_restore + 1][MaxOperands];
146
static bool Initialized = false;
147
if (Initialized) {
148
return ArrayRef<OperandType[MaxOperands]>(&OpTypes[0], DW_CFA_restore + 1);
149
}
150
Initialized = true;
151
152
#define DECLARE_OP3(OP, OPTYPE0, OPTYPE1, OPTYPE2) \
153
do { \
154
OpTypes[OP][0] = OPTYPE0; \
155
OpTypes[OP][1] = OPTYPE1; \
156
OpTypes[OP][2] = OPTYPE2; \
157
} while (false)
158
#define DECLARE_OP2(OP, OPTYPE0, OPTYPE1) \
159
DECLARE_OP3(OP, OPTYPE0, OPTYPE1, OT_None)
160
#define DECLARE_OP1(OP, OPTYPE0) DECLARE_OP2(OP, OPTYPE0, OT_None)
161
#define DECLARE_OP0(OP) DECLARE_OP1(OP, OT_None)
162
163
DECLARE_OP1(DW_CFA_set_loc, OT_Address);
164
DECLARE_OP1(DW_CFA_advance_loc, OT_FactoredCodeOffset);
165
DECLARE_OP1(DW_CFA_advance_loc1, OT_FactoredCodeOffset);
166
DECLARE_OP1(DW_CFA_advance_loc2, OT_FactoredCodeOffset);
167
DECLARE_OP1(DW_CFA_advance_loc4, OT_FactoredCodeOffset);
168
DECLARE_OP1(DW_CFA_MIPS_advance_loc8, OT_FactoredCodeOffset);
169
DECLARE_OP2(DW_CFA_def_cfa, OT_Register, OT_Offset);
170
DECLARE_OP2(DW_CFA_def_cfa_sf, OT_Register, OT_SignedFactDataOffset);
171
DECLARE_OP1(DW_CFA_def_cfa_register, OT_Register);
172
DECLARE_OP3(DW_CFA_LLVM_def_aspace_cfa, OT_Register, OT_Offset,
173
OT_AddressSpace);
174
DECLARE_OP3(DW_CFA_LLVM_def_aspace_cfa_sf, OT_Register,
175
OT_SignedFactDataOffset, OT_AddressSpace);
176
DECLARE_OP1(DW_CFA_def_cfa_offset, OT_Offset);
177
DECLARE_OP1(DW_CFA_def_cfa_offset_sf, OT_SignedFactDataOffset);
178
DECLARE_OP1(DW_CFA_def_cfa_expression, OT_Expression);
179
DECLARE_OP1(DW_CFA_undefined, OT_Register);
180
DECLARE_OP1(DW_CFA_same_value, OT_Register);
181
DECLARE_OP2(DW_CFA_offset, OT_Register, OT_UnsignedFactDataOffset);
182
DECLARE_OP2(DW_CFA_offset_extended, OT_Register, OT_UnsignedFactDataOffset);
183
DECLARE_OP2(DW_CFA_offset_extended_sf, OT_Register, OT_SignedFactDataOffset);
184
DECLARE_OP2(DW_CFA_val_offset, OT_Register, OT_UnsignedFactDataOffset);
185
DECLARE_OP2(DW_CFA_val_offset_sf, OT_Register, OT_SignedFactDataOffset);
186
DECLARE_OP2(DW_CFA_register, OT_Register, OT_Register);
187
DECLARE_OP2(DW_CFA_expression, OT_Register, OT_Expression);
188
DECLARE_OP2(DW_CFA_val_expression, OT_Register, OT_Expression);
189
DECLARE_OP1(DW_CFA_restore, OT_Register);
190
DECLARE_OP1(DW_CFA_restore_extended, OT_Register);
191
DECLARE_OP0(DW_CFA_remember_state);
192
DECLARE_OP0(DW_CFA_restore_state);
193
DECLARE_OP0(DW_CFA_GNU_window_save);
194
DECLARE_OP0(DW_CFA_AARCH64_negate_ra_state_with_pc);
195
DECLARE_OP1(DW_CFA_GNU_args_size, OT_Offset);
196
DECLARE_OP0(DW_CFA_nop);
197
198
#undef DECLARE_OP0
199
#undef DECLARE_OP1
200
#undef DECLARE_OP2
201
202
return ArrayRef<OperandType[MaxOperands]>(&OpTypes[0], DW_CFA_restore + 1);
203
}
204
205