12 #if defined(__aarch64__) && defined(__linux)
20 #include <asm/sigcontext.h>
30 static constexpr
uint32_t ESR_ELx_EC_SHIFT = 26;
31 static constexpr
uint32_t ESR_ELx_EC_MASK = 0x3F
ul << ESR_ELx_EC_SHIFT;
33 return (esr & ESR_ELx_EC_MASK) >> ESR_ELx_EC_SHIFT;
36 static constexpr
uint32_t ESR_ELx_IL_SHIFT = 25;
37 static constexpr
uint32_t ESR_ELx_IL = 1
ul << ESR_ELx_IL_SHIFT;
38 static constexpr
uint32_t ESR_ELx_ISS_MASK = ESR_ELx_IL - 1;
41 static constexpr
uint32_t ESR_ELx_SET_SHIFT = 11;
42 static constexpr
uint32_t ESR_ELx_SET_MASK = 3
ul << ESR_ELx_SET_SHIFT;
43 static constexpr
uint32_t ESR_ELx_FnV_SHIFT = 10;
44 static constexpr
uint32_t ESR_ELx_FnV = 1
ul << ESR_ELx_FnV_SHIFT;
45 static constexpr
uint32_t ESR_ELx_EA_SHIFT = 9;
46 static constexpr
uint32_t ESR_ELx_EA = 1
ul << ESR_ELx_EA_SHIFT;
47 static constexpr
uint32_t ESR_ELx_S1PTW_SHIFT = 7;
48 static constexpr
uint32_t ESR_ELx_S1PTW = 1
ul << ESR_ELx_S1PTW_SHIFT;
51 static constexpr
uint32_t ESR_ELx_ISV_SHIFT = 24;
52 static constexpr
uint32_t ESR_ELx_ISV = 1
ul << ESR_ELx_ISV_SHIFT;
53 static constexpr
uint32_t ESR_ELx_SAS_SHIFT = 22;
54 static constexpr
uint32_t ESR_ELx_SAS = 3
ul << ESR_ELx_SAS_SHIFT;
55 static constexpr
uint32_t ESR_ELx_SSE_SHIFT = 21;
56 static constexpr
uint32_t ESR_ELx_SSE = 1
ul << ESR_ELx_SSE_SHIFT;
57 static constexpr
uint32_t ESR_ELx_SRT_SHIFT = 16;
58 static constexpr
uint32_t ESR_ELx_SRT_MASK = 0x1F
ul << ESR_ELx_SRT_SHIFT;
59 static constexpr
uint32_t ESR_ELx_SF_SHIFT = 15;
60 static constexpr
uint32_t ESR_ELx_SF = 1
u << ESR_ELx_SF_SHIFT;
61 static constexpr
uint32_t ESR_ELx_AR_SHIFT = 14;
62 static constexpr
uint32_t ESR_ELx_AR = 1
u << ESR_ELx_AR_SHIFT;
63 static constexpr
uint32_t ESR_ELx_CM_SHIFT = 8;
64 static constexpr
uint32_t ESR_ELx_CM = 1
u << ESR_ELx_CM_SHIFT;
67 static constexpr
uint32_t ESR_ELx_WNR_SHIFT = 6;
68 static constexpr
uint32_t ESR_ELx_WNR = 1
u << ESR_ELx_WNR_SHIFT;
71 static const char*
const esr_class_str[] =
73 "Unknown/Uncategorized",
121 "Breakpoint (lower EL)",
122 "Breakpoint (current EL)",
123 "Software Step (lower EL)",
124 "Software Step (current EL)",
125 "Watchpoint (lower EL)",
126 "Watchpoint (current EL)",
131 "Vector catch (AArch32)",
136 static constexpr
uint32_t ESR_ELx_EC_DABT_LOW = 0x24;
137 static constexpr
uint32_t ESR_ELx_EC_DABT_CUR = 0x25;
141 const char* esr_get_class_string (
uint32_t esr)
145 return esr_class_str[2];
146 return esr_class_str[
code];
150 inline bool esr_is_data_abort(
uint32_t esr)
152 const uint32_t ec = ESR_ELx_EC(esr);
153 return ec == ESR_ELx_EC_DABT_LOW || ec == ESR_ELx_EC_DABT_CUR;
157 void esr_data_abort_decode (
IOFD fd,
158 char* buf,
unsigned int buf_size,
161 if (esr & ESR_ELx_ISV) {
162 MYWRITE (
fd, buf, snprintf (buf, buf_size,
163 "\n Access size = %u byte(s)",
164 1
u << ((esr & ESR_ELx_SAS) >> ESR_ELx_SAS_SHIFT)));
165 MYWRITE (
fd, buf, snprintf (buf, buf_size,
166 "\n SSE = %u, SRT = %u",
167 (esr & ESR_ELx_SSE) >> ESR_ELx_SSE_SHIFT,
168 (esr & ESR_ELx_SRT_MASK) >> ESR_ELx_SRT_SHIFT));
169 MYWRITE (
fd, buf, snprintf (buf, buf_size,
170 "\n SF = %u, AR = %u",
171 (esr & ESR_ELx_SF) >> ESR_ELx_SF_SHIFT,
172 (esr & ESR_ELx_AR) >> ESR_ELx_AR_SHIFT));
174 MYWRITE (
fd, buf, snprintf (buf, buf_size,
175 "\n ISV = 0, ISS = 0x%08x",
176 esr & ESR_ELx_ISS_MASK));
179 MYWRITE (
fd, buf, snprintf (buf, buf_size,
180 "\n CM = %u, WnR = %u",
181 (esr & ESR_ELx_CM) >> ESR_ELx_CM_SHIFT,
182 (esr & ESR_ELx_WNR) >> ESR_ELx_WNR_SHIFT));
192 void aarch64_dump_fpsimd (
IOFD fd,
193 char* buf,
unsigned int buf_size,
194 const fpsimd_context& ctx)
196 MYWRITE (
fd, buf, snprintf (buf, buf_size,
198 "\n fpsr: %08x fpcr: %08x",
199 ctx.fpsr, ctx.fpcr));
200 for (
int i = 0;
i < 32; ++
i) {
205 c.u128 = ctx.vregs[
i];
206 MYWRITE (
fd, buf, snprintf (buf, buf_size,
207 "\n v%d:%s [%08x %08x %08x %08x]",
210 c.u32[0],
c.u32[1],
c.u32[2],
c.u32[3]));
215 void aarch64_dump_esr (
IOFD fd,
216 char* buf,
unsigned int buf_size,
217 const esr_context& ctx)
219 MYWRITE (
fd, buf, snprintf (buf, buf_size,
220 "\n\n Mem abort info --- ESR: %016llx",
222 MYWRITE (
fd, buf, snprintf (buf, buf_size,
223 "\n Exception class = %s, IL = %u bits",
224 esr_get_class_string (ctx.esr),
225 (ctx.esr & ESR_ELx_IL) ? 32 : 16));
226 MYWRITE (
fd, buf, snprintf (buf, buf_size,
227 "\n SET = %llu, FnV = %llu",
228 (ctx.esr & ESR_ELx_SET_MASK) >> ESR_ELx_SET_SHIFT,
229 (ctx.esr & ESR_ELx_FnV) >> ESR_ELx_FnV_SHIFT));
230 MYWRITE (
fd, buf, snprintf (buf, buf_size,
231 "\n EA = %llu, S1PTW = %llu",
232 (ctx.esr & ESR_ELx_EA) >> ESR_ELx_EA_SHIFT,
233 (ctx.esr & ESR_ELx_S1PTW) >> ESR_ELx_S1PTW_SHIFT));
235 if (esr_is_data_abort (ctx.esr)) {
236 esr_data_abort_decode (
fd, buf, buf_size, ctx.esr);
248 void aarch64_dump_registers (
IOFD fd,
249 char* buf,
unsigned int buf_size,
250 const mcontext_t&
mc)
252 MYWRITE (
fd, buf, snprintf (buf, buf_size,
253 "\n pc: %016llx pstate: %016llx",
255 for (
int i = 0;
i < 30;
i += 2) {
256 MYWRITE (
fd, buf, snprintf (buf, buf_size,
257 "\n x%d:%s %016llx x%d:%s %016llx",
258 i,
i < 10 ?
" " :
"",
mc.regs[
i],
259 i+1,
i+1 < 10 ?
" " :
"",
mc.regs[
i+1]));
261 MYWRITE (
fd, buf, snprintf (buf, buf_size,
262 "\n x30: %016llx sp: %016llx",
263 mc.regs[30],
mc.sp));
266 while (ipos +
sizeof(_aarch64_ctx) <=
sizeof (
mc.__reserved)) {
267 const _aarch64_ctx* ctx =
reinterpret_cast<const _aarch64_ctx*
> (&
mc.__reserved[ipos]);
268 if (ctx->magic == 0 || ipos + ctx->size > sizeof (
mc.__reserved)) {
271 if (ctx->magic == FPSIMD_MAGIC) {
272 aarch64_dump_fpsimd (
fd, buf, buf_size, *
reinterpret_cast<const fpsimd_context*
>(ctx));
274 else if (ctx->magic == ESR_MAGIC) {
275 aarch64_dump_esr (
fd, buf, buf_size, *
reinterpret_cast<const esr_context*
>(ctx));
277 else if (ctx->magic == EXTRA_MAGIC) {
278 MYWRITE (
fd, buf, snprintf (buf, buf_size,
"\n\n[extra dump not implemented]\n"));
280 else if (ctx->magic == SVE_MAGIC) {
281 MYWRITE (
fd, buf, snprintf (buf, buf_size,
"\n\n[SVE dump not implemented]\n"));
291 #endif // __aarch64__ && __linux