2 * Copyright 2014 Google Inc.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of
7 * the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but without any warranty; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
15 #include <exception.h>
17 #include <libpayload.h>
20 static const u8 type_to_signal
[] = {
21 [EXC_DE
] = GDB_SIGFPE
,
22 [EXC_DB
] = GDB_SIGTRAP
,
23 [EXC_NMI
] = GDB_SIGKILL
,
24 [EXC_BP
] = GDB_SIGTRAP
,
25 [EXC_OF
] = GDB_SIGFPE
,
26 [EXC_BR
] = GDB_SIGSEGV
,
27 [EXC_UD
] = GDB_SIGILL
,
28 [EXC_NM
] = GDB_SIGEMT
,
29 [EXC_DF
] = GDB_SIGKILL
,
30 [EXC_TS
] = GDB_SIGSEGV
,
31 [EXC_NP
] = GDB_SIGSEGV
,
32 [EXC_SS
] = GDB_SIGBUS
,
33 [EXC_GP
] = GDB_SIGSEGV
,
34 [EXC_PF
] = GDB_SIGSEGV
,
35 [EXC_MF
] = GDB_SIGEMT
,
36 [EXC_AC
] = GDB_SIGBUS
,
37 [EXC_MC
] = GDB_SIGKILL
,
38 [EXC_XF
] = GDB_SIGFPE
,
39 [EXC_SX
] = GDB_SIGFPE
,
42 static void gdb_exception_hook(u8 vector
)
44 gdb_command_loop(type_to_signal
[vector
]);
47 void gdb_arch_init(void)
49 for (int vector
= 0; vector
< ARRAY_SIZE(type_to_signal
); ++vector
) {
50 if (type_to_signal
[vector
])
51 set_interrupt_handler(vector
, &gdb_exception_hook
);
55 void gdb_arch_enter(void)
58 #if CONFIG(LP_ARCH_X86_64)
59 asm volatile ("movq %%rsp, %0" : "=r"(stack_pointer
));
61 asm volatile ("mov %%esp, %0" : "=r"(stack_pointer
));
64 /* Avoid reentrant exceptions, just call the hook if in one already. */
65 if (stack_pointer
>= exception_stack
&& stack_pointer
<= exception_stack_end
)
66 gdb_exception_hook(EXC_BP
);
68 asm volatile ("int3");
71 int gdb_arch_set_single_step(int on
)
73 const size_t tf_bit
= 1 << 8;
76 exception_state
->regs
.reg_flags
|= tf_bit
;
78 exception_state
->regs
.reg_flags
&= ~tf_bit
;
83 void gdb_arch_encode_regs(struct gdb_message
*message
)
85 gdb_message_encode_bytes(message
, &exception_state
->regs
,
86 sizeof(exception_state
->regs
));
89 void gdb_arch_decode_regs(int offset
, struct gdb_message
*message
)
91 gdb_message_decode_bytes(message
, offset
, &exception_state
->regs
,
92 sizeof(exception_state
->regs
));