ncrypt/tests: Test for symmetric keys support.
[wine.git] / programs / winedbg / be_arm64.c
blobab64801e6db6fc499ace2905183dc35df9522285
1 /*
2 * Debugger ARM64 specific functions
4 * Copyright 2010-2013 André Hentschel
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "debugger.h"
23 #if defined(__aarch64__) && !defined(__AARCH64EB__)
25 static BOOL be_arm64_get_addr(HANDLE hThread, const dbg_ctx_t *ctx,
26 enum be_cpu_addr bca, ADDRESS64* addr)
28 switch (bca)
30 case be_cpu_addr_pc:
31 return be_cpu_build_addr(hThread, ctx, addr, 0, ctx->ctx.Pc);
32 case be_cpu_addr_stack:
33 return be_cpu_build_addr(hThread, ctx, addr, 0, ctx->ctx.Sp);
34 case be_cpu_addr_frame:
35 return be_cpu_build_addr(hThread, ctx, addr, 0, ctx->ctx.u.s.Fp);
36 break;
38 return FALSE;
41 static BOOL be_arm64_get_register_info(int regno, enum be_cpu_addr* kind)
43 switch (regno)
45 case CV_ARM64_PC: *kind = be_cpu_addr_pc; return TRUE;
46 case CV_ARM64_SP: *kind = be_cpu_addr_stack; return TRUE;
47 case CV_ARM64_FP: *kind = be_cpu_addr_frame; return TRUE;
49 return FALSE;
52 static void be_arm64_single_step(dbg_ctx_t *ctx, BOOL enable)
54 dbg_printf("be_arm64_single_step: not done\n");
57 static void be_arm64_print_context(HANDLE hThread, const dbg_ctx_t *ctx, int all_regs)
59 static const char condflags[] = "NZCV";
60 int i;
61 char buf[8];
63 switch (ctx->ctx.Cpsr & 0x0f)
65 case 0: strcpy(buf, "EL0t"); break;
66 case 4: strcpy(buf, "EL1t"); break;
67 case 5: strcpy(buf, "EL1t"); break;
68 case 8: strcpy(buf, "EL2t"); break;
69 case 9: strcpy(buf, "EL2t"); break;
70 case 12: strcpy(buf, "EL3t"); break;
71 case 13: strcpy(buf, "EL3t"); break;
72 default: strcpy(buf, "UNKNWN"); break;
75 dbg_printf("Register dump:\n");
76 dbg_printf("%s %s Mode\n", (ctx->ctx.Cpsr & 0x10) ? "ARM" : "ARM64", buf);
78 strcpy(buf, condflags);
79 for (i = 0; buf[i]; i++)
80 if (!((ctx->ctx.Cpsr >> 26) & (1 << (sizeof(condflags) - i))))
81 buf[i] = '-';
83 dbg_printf(" Pc:%016I64x Sp:%016I64x Lr:%016I64x Cpsr:%08x(%s)\n",
84 ctx->ctx.Pc, ctx->ctx.Sp, ctx->ctx.u.s.Lr, ctx->ctx.Cpsr, buf);
85 dbg_printf(" x0: %016I64x x1: %016I64x x2: %016I64x x3: %016I64x x4: %016I64x\n",
86 ctx->ctx.u.s.X0, ctx->ctx.u.s.X1, ctx->ctx.u.s.X2, ctx->ctx.u.s.X3, ctx->ctx.u.s.X4);
87 dbg_printf(" x5: %016I64x x6: %016I64x x7: %016I64x x8: %016I64x x9: %016I64x\n",
88 ctx->ctx.u.s.X5, ctx->ctx.u.s.X6, ctx->ctx.u.s.X7, ctx->ctx.u.s.X8, ctx->ctx.u.s.X9);
89 dbg_printf(" x10:%016I64x x11:%016I64x x12:%016I64x x13:%016I64x x14:%016I64x\n",
90 ctx->ctx.u.s.X10, ctx->ctx.u.s.X11, ctx->ctx.u.s.X12, ctx->ctx.u.s.X13, ctx->ctx.u.s.X14);
91 dbg_printf(" x15:%016I64x ip0:%016I64x ip1:%016I64x x18:%016I64x x19:%016I64x\n",
92 ctx->ctx.u.s.X15, ctx->ctx.u.s.X16, ctx->ctx.u.s.X17, ctx->ctx.u.s.X18, ctx->ctx.u.s.X19);
93 dbg_printf(" x20:%016I64x x21:%016I64x x22:%016I64x x23:%016I64x x24:%016I64x\n",
94 ctx->ctx.u.s.X20, ctx->ctx.u.s.X21, ctx->ctx.u.s.X22, ctx->ctx.u.s.X23, ctx->ctx.u.s.X24);
95 dbg_printf(" x25:%016I64x x26:%016I64x x27:%016I64x x28:%016I64x Fp:%016I64x\n",
96 ctx->ctx.u.s.X25, ctx->ctx.u.s.X26, ctx->ctx.u.s.X27, ctx->ctx.u.s.X28, ctx->ctx.u.s.Fp);
98 if (all_regs) dbg_printf( "Floating point ARM64 dump not implemented\n" );
101 static void be_arm64_print_segment_info(HANDLE hThread, const dbg_ctx_t *ctx)
105 static struct dbg_internal_var be_arm64_ctx[] =
107 {CV_ARM64_PSTATE, "cpsr", (void*)FIELD_OFFSET(CONTEXT, Cpsr), dbg_itype_unsigned_int},
108 {CV_ARM64_X0 + 0, "x0", (void*)FIELD_OFFSET(CONTEXT, u.s.X0), dbg_itype_unsigned_long_int},
109 {CV_ARM64_X0 + 1, "x1", (void*)FIELD_OFFSET(CONTEXT, u.s.X1), dbg_itype_unsigned_long_int},
110 {CV_ARM64_X0 + 2, "x2", (void*)FIELD_OFFSET(CONTEXT, u.s.X2), dbg_itype_unsigned_long_int},
111 {CV_ARM64_X0 + 3, "x3", (void*)FIELD_OFFSET(CONTEXT, u.s.X3), dbg_itype_unsigned_long_int},
112 {CV_ARM64_X0 + 4, "x4", (void*)FIELD_OFFSET(CONTEXT, u.s.X4), dbg_itype_unsigned_long_int},
113 {CV_ARM64_X0 + 5, "x5", (void*)FIELD_OFFSET(CONTEXT, u.s.X5), dbg_itype_unsigned_long_int},
114 {CV_ARM64_X0 + 6, "x6", (void*)FIELD_OFFSET(CONTEXT, u.s.X6), dbg_itype_unsigned_long_int},
115 {CV_ARM64_X0 + 7, "x7", (void*)FIELD_OFFSET(CONTEXT, u.s.X7), dbg_itype_unsigned_long_int},
116 {CV_ARM64_X0 + 8, "x8", (void*)FIELD_OFFSET(CONTEXT, u.s.X8), dbg_itype_unsigned_long_int},
117 {CV_ARM64_X0 + 9, "x9", (void*)FIELD_OFFSET(CONTEXT, u.s.X9), dbg_itype_unsigned_long_int},
118 {CV_ARM64_X0 + 10, "x10", (void*)FIELD_OFFSET(CONTEXT, u.s.X10), dbg_itype_unsigned_long_int},
119 {CV_ARM64_X0 + 11, "x11", (void*)FIELD_OFFSET(CONTEXT, u.s.X11), dbg_itype_unsigned_long_int},
120 {CV_ARM64_X0 + 12, "x12", (void*)FIELD_OFFSET(CONTEXT, u.s.X12), dbg_itype_unsigned_long_int},
121 {CV_ARM64_X0 + 13, "x13", (void*)FIELD_OFFSET(CONTEXT, u.s.X13), dbg_itype_unsigned_long_int},
122 {CV_ARM64_X0 + 14, "x14", (void*)FIELD_OFFSET(CONTEXT, u.s.X14), dbg_itype_unsigned_long_int},
123 {CV_ARM64_X0 + 15, "x15", (void*)FIELD_OFFSET(CONTEXT, u.s.X15), dbg_itype_unsigned_long_int},
124 {CV_ARM64_X0 + 16, "x16", (void*)FIELD_OFFSET(CONTEXT, u.s.X16), dbg_itype_unsigned_long_int},
125 {CV_ARM64_X0 + 17, "x17", (void*)FIELD_OFFSET(CONTEXT, u.s.X17), dbg_itype_unsigned_long_int},
126 {CV_ARM64_X0 + 18, "x18", (void*)FIELD_OFFSET(CONTEXT, u.s.X18), dbg_itype_unsigned_long_int},
127 {CV_ARM64_X0 + 19, "x19", (void*)FIELD_OFFSET(CONTEXT, u.s.X19), dbg_itype_unsigned_long_int},
128 {CV_ARM64_X0 + 20, "x20", (void*)FIELD_OFFSET(CONTEXT, u.s.X20), dbg_itype_unsigned_long_int},
129 {CV_ARM64_X0 + 21, "x21", (void*)FIELD_OFFSET(CONTEXT, u.s.X21), dbg_itype_unsigned_long_int},
130 {CV_ARM64_X0 + 22, "x22", (void*)FIELD_OFFSET(CONTEXT, u.s.X22), dbg_itype_unsigned_long_int},
131 {CV_ARM64_X0 + 23, "x23", (void*)FIELD_OFFSET(CONTEXT, u.s.X23), dbg_itype_unsigned_long_int},
132 {CV_ARM64_X0 + 24, "x24", (void*)FIELD_OFFSET(CONTEXT, u.s.X24), dbg_itype_unsigned_long_int},
133 {CV_ARM64_X0 + 25, "x25", (void*)FIELD_OFFSET(CONTEXT, u.s.X25), dbg_itype_unsigned_long_int},
134 {CV_ARM64_X0 + 26, "x26", (void*)FIELD_OFFSET(CONTEXT, u.s.X26), dbg_itype_unsigned_long_int},
135 {CV_ARM64_X0 + 27, "x27", (void*)FIELD_OFFSET(CONTEXT, u.s.X27), dbg_itype_unsigned_long_int},
136 {CV_ARM64_X0 + 28, "x28", (void*)FIELD_OFFSET(CONTEXT, u.s.X28), dbg_itype_unsigned_long_int},
137 {CV_ARM64_FP, "fp", (void*)FIELD_OFFSET(CONTEXT, u.s.Fp), dbg_itype_unsigned_long_int},
138 {CV_ARM64_LR, "lr", (void*)FIELD_OFFSET(CONTEXT, u.s.Lr), dbg_itype_unsigned_long_int},
139 {CV_ARM64_SP, "sp", (void*)FIELD_OFFSET(CONTEXT, Sp), dbg_itype_unsigned_long_int},
140 {CV_ARM64_PC, "pc", (void*)FIELD_OFFSET(CONTEXT, Pc), dbg_itype_unsigned_long_int},
141 {0, NULL, 0, dbg_itype_none}
144 static BOOL be_arm64_is_step_over_insn(const void* insn)
146 dbg_printf("be_arm64_is_step_over_insn: not done\n");
147 return FALSE;
150 static BOOL be_arm64_is_function_return(const void* insn)
152 dbg_printf("be_arm64_is_function_return: not done\n");
153 return FALSE;
156 static BOOL be_arm64_is_break_insn(const void* insn)
158 dbg_printf("be_arm64_is_break_insn: not done\n");
159 return FALSE;
162 static BOOL be_arm64_is_func_call(const void* insn, ADDRESS64* callee)
164 return FALSE;
167 static BOOL be_arm64_is_jump(const void* insn, ADDRESS64* jumpee)
169 return FALSE;
172 static BOOL be_arm64_insert_Xpoint(HANDLE hProcess, const struct be_process_io* pio,
173 dbg_ctx_t *ctx, enum be_xpoint_type type,
174 void* addr, unsigned *val, unsigned size)
176 SIZE_T sz;
178 switch (type)
180 case be_xpoint_break:
181 if (!size) return FALSE;
182 if (!pio->read(hProcess, addr, val, 4, &sz) || sz != 4) return FALSE;
183 default:
184 dbg_printf("Unknown/unsupported bp type %c\n", type);
185 return FALSE;
187 return TRUE;
190 static BOOL be_arm64_remove_Xpoint(HANDLE hProcess, const struct be_process_io* pio,
191 dbg_ctx_t *ctx, enum be_xpoint_type type,
192 void* addr, unsigned val, unsigned size)
194 SIZE_T sz;
196 switch (type)
198 case be_xpoint_break:
199 if (!size) return FALSE;
200 if (!pio->write(hProcess, addr, &val, 4, &sz) || sz == 4) return FALSE;
201 break;
202 default:
203 dbg_printf("Unknown/unsupported bp type %c\n", type);
204 return FALSE;
206 return TRUE;
209 static BOOL be_arm64_is_watchpoint_set(const dbg_ctx_t *ctx, unsigned idx)
211 dbg_printf("be_arm64_is_watchpoint_set: not done\n");
212 return FALSE;
215 static void be_arm64_clear_watchpoint(dbg_ctx_t *ctx, unsigned idx)
217 dbg_printf("be_arm64_clear_watchpoint: not done\n");
220 static int be_arm64_adjust_pc_for_break(dbg_ctx_t *ctx, BOOL way)
222 if (way)
224 ctx->ctx.Pc -= 4;
225 return -4;
227 ctx->ctx.Pc += 4;
228 return 4;
231 void be_arm64_disasm_one_insn(ADDRESS64 *addr, int display)
233 dbg_printf("be_arm64_disasm_one_insn: not done\n");
236 static BOOL be_arm64_get_context(HANDLE thread, dbg_ctx_t *ctx)
238 ctx->ctx.ContextFlags = CONTEXT_ALL;
239 return GetThreadContext(thread, &ctx->ctx);
242 static BOOL be_arm64_set_context(HANDLE thread, const dbg_ctx_t *ctx)
244 return SetThreadContext(thread, &ctx->ctx);
247 #define REG(f,n,t,r) {f, n, t, FIELD_OFFSET(CONTEXT, r), sizeof(((CONTEXT*)NULL)->r)}
249 static struct gdb_register be_arm64_gdb_register_map[] = {
250 REG("core", "x0", NULL, u.s.X0),
251 REG(NULL, "x1", NULL, u.s.X1),
252 REG(NULL, "x2", NULL, u.s.X2),
253 REG(NULL, "x3", NULL, u.s.X3),
254 REG(NULL, "x4", NULL, u.s.X4),
255 REG(NULL, "x5", NULL, u.s.X5),
256 REG(NULL, "x6", NULL, u.s.X6),
257 REG(NULL, "x7", NULL, u.s.X7),
258 REG(NULL, "x8", NULL, u.s.X8),
259 REG(NULL, "x9", NULL, u.s.X9),
260 REG(NULL, "x10", NULL, u.s.X10),
261 REG(NULL, "x11", NULL, u.s.X11),
262 REG(NULL, "x12", NULL, u.s.X12),
263 REG(NULL, "x13", NULL, u.s.X13),
264 REG(NULL, "x14", NULL, u.s.X14),
265 REG(NULL, "x15", NULL, u.s.X15),
266 REG(NULL, "x16", NULL, u.s.X16),
267 REG(NULL, "x17", NULL, u.s.X17),
268 REG(NULL, "x18", NULL, u.s.X18),
269 REG(NULL, "x19", NULL, u.s.X19),
270 REG(NULL, "x20", NULL, u.s.X20),
271 REG(NULL, "x21", NULL, u.s.X21),
272 REG(NULL, "x22", NULL, u.s.X22),
273 REG(NULL, "x23", NULL, u.s.X23),
274 REG(NULL, "x24", NULL, u.s.X24),
275 REG(NULL, "x25", NULL, u.s.X25),
276 REG(NULL, "x26", NULL, u.s.X26),
277 REG(NULL, "x27", NULL, u.s.X27),
278 REG(NULL, "x28", NULL, u.s.X28),
279 REG(NULL, "x29", NULL, u.s.Fp),
280 REG(NULL, "x30", NULL, u.s.Lr),
281 REG(NULL, "sp", "data_ptr", Sp),
282 REG(NULL, "pc", "code_ptr", Pc),
283 REG(NULL, "cpsr", "cpsr_flags", Cpsr),
286 struct backend_cpu be_arm64 =
288 IMAGE_FILE_MACHINE_ARM64,
290 be_cpu_linearize,
291 be_cpu_build_addr,
292 be_arm64_get_addr,
293 be_arm64_get_register_info,
294 be_arm64_single_step,
295 be_arm64_print_context,
296 be_arm64_print_segment_info,
297 be_arm64_ctx,
298 be_arm64_is_step_over_insn,
299 be_arm64_is_function_return,
300 be_arm64_is_break_insn,
301 be_arm64_is_func_call,
302 be_arm64_is_jump,
303 be_arm64_disasm_one_insn,
304 be_arm64_insert_Xpoint,
305 be_arm64_remove_Xpoint,
306 be_arm64_is_watchpoint_set,
307 be_arm64_clear_watchpoint,
308 be_arm64_adjust_pc_for_break,
309 be_arm64_get_context,
310 be_arm64_set_context,
311 be_arm64_gdb_register_map,
312 ARRAY_SIZE(be_arm64_gdb_register_map),
314 #endif