12#if defined(__aarch64__) && defined(__linux)
20#include <asm/sigcontext.h>
30static constexpr uint32_t ESR_ELx_EC_SHIFT = 26;
31static constexpr uint32_t ESR_ELx_EC_MASK = 0x3Ful << ESR_ELx_EC_SHIFT;
32inline uint32_t ESR_ELx_EC (uint32_t esr) {
33 return (esr & ESR_ELx_EC_MASK) >> ESR_ELx_EC_SHIFT;
36static constexpr uint32_t ESR_ELx_IL_SHIFT = 25;
37static constexpr uint32_t ESR_ELx_IL = 1ul << ESR_ELx_IL_SHIFT;
38static constexpr uint32_t ESR_ELx_ISS_MASK = ESR_ELx_IL - 1;
41static constexpr uint32_t ESR_ELx_SET_SHIFT = 11;
42static constexpr uint32_t ESR_ELx_SET_MASK = 3ul << ESR_ELx_SET_SHIFT;
43static constexpr uint32_t ESR_ELx_FnV_SHIFT = 10;
44static constexpr uint32_t ESR_ELx_FnV = 1ul << ESR_ELx_FnV_SHIFT;
45static constexpr uint32_t ESR_ELx_EA_SHIFT = 9;
46static constexpr uint32_t ESR_ELx_EA = 1ul << ESR_ELx_EA_SHIFT;
47static constexpr uint32_t ESR_ELx_S1PTW_SHIFT = 7;
48static constexpr uint32_t ESR_ELx_S1PTW = 1ul << ESR_ELx_S1PTW_SHIFT;
51static constexpr uint32_t ESR_ELx_ISV_SHIFT = 24;
52static constexpr uint32_t ESR_ELx_ISV = 1ul << ESR_ELx_ISV_SHIFT;
53static constexpr uint32_t ESR_ELx_SAS_SHIFT = 22;
54static constexpr uint32_t ESR_ELx_SAS = 3ul << ESR_ELx_SAS_SHIFT;
55static constexpr uint32_t ESR_ELx_SSE_SHIFT = 21;
56static constexpr uint32_t ESR_ELx_SSE = 1ul << ESR_ELx_SSE_SHIFT;
57static constexpr uint32_t ESR_ELx_SRT_SHIFT = 16;
58static constexpr uint32_t ESR_ELx_SRT_MASK = 0x1Ful << ESR_ELx_SRT_SHIFT;
59static constexpr uint32_t ESR_ELx_SF_SHIFT = 15;
60static constexpr uint32_t ESR_ELx_SF = 1u << ESR_ELx_SF_SHIFT;
61static constexpr uint32_t ESR_ELx_AR_SHIFT = 14;
62static constexpr uint32_t ESR_ELx_AR = 1u << ESR_ELx_AR_SHIFT;
63static constexpr uint32_t ESR_ELx_CM_SHIFT = 8;
64static constexpr uint32_t ESR_ELx_CM = 1u << ESR_ELx_CM_SHIFT;
67static constexpr uint32_t ESR_ELx_WNR_SHIFT = 6;
68static constexpr uint32_t ESR_ELx_WNR = 1u << ESR_ELx_WNR_SHIFT;
71static 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)",
136static constexpr uint32_t ESR_ELx_EC_DABT_LOW = 0x24;
137static constexpr uint32_t ESR_ELx_EC_DABT_CUR = 0x25;
141const char* esr_get_class_string (uint32_t esr)
144 if (code >= std::size (esr_class_str))
145 return esr_class_str[2];
146 return esr_class_str[code];
150inline 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;
157void 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 1u << ((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));
192void 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]));
215void 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);
248void 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"));
int IOFD
Type the system uses for channel descriptors.
This are the SEAL debug aids, adapted to build in Atlas, after the drop of that project.
#define MYWRITE(fd, data, n)