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>
19 static const u8 type_to_signal
[] = {
20 [EXC_DE
] = GDB_SIGFPE
,
21 [EXC_DB
] = GDB_SIGTRAP
,
22 [EXC_NMI
] = GDB_SIGKILL
,
23 [EXC_BP
] = GDB_SIGTRAP
,
24 [EXC_OF
] = GDB_SIGFPE
,
25 [EXC_BR
] = GDB_SIGSEGV
,
26 [EXC_UD
] = GDB_SIGILL
,
27 [EXC_NM
] = GDB_SIGEMT
,
28 [EXC_DF
] = GDB_SIGKILL
,
29 [EXC_TS
] = GDB_SIGSEGV
,
30 [EXC_NP
] = GDB_SIGSEGV
,
31 [EXC_SS
] = GDB_SIGBUS
,
32 [EXC_GP
] = GDB_SIGSEGV
,
33 [EXC_PF
] = GDB_SIGSEGV
,
34 [EXC_MF
] = GDB_SIGEMT
,
35 [EXC_AC
] = GDB_SIGBUS
,
36 [EXC_MC
] = GDB_SIGKILL
,
37 [EXC_XF
] = GDB_SIGFPE
,
38 [EXC_SX
] = GDB_SIGFPE
,
41 static void gdb_exception_hook(u8 vector
)
43 gdb_command_loop(type_to_signal
[vector
]);
46 void gdb_arch_init(void)
48 for (int vector
= 0; vector
< ARRAY_SIZE(type_to_signal
); ++vector
) {
49 if (type_to_signal
[vector
])
50 set_interrupt_handler(vector
, &gdb_exception_hook
);
54 void gdb_arch_enter(void)
58 asm volatile ("mov %%esp, %0" : "=r"(esp
) );
60 /* Avoid reentrant exceptions, just call the hook if in one already. */
61 if (esp
>= exception_stack
&& esp
<= exception_stack_end
)
62 gdb_exception_hook(EXC_BP
);
64 asm volatile ("int3");
67 int gdb_arch_set_single_step(int on
)
69 const u32 tf_bit
= 1 << 8;
72 exception_state
->regs
.eflags
|= tf_bit
;
74 exception_state
->regs
.eflags
&= ~tf_bit
;
79 void gdb_arch_encode_regs(struct gdb_message
*message
)
81 gdb_message_encode_bytes(message
, &exception_state
->regs
,
82 sizeof(exception_state
->regs
));
85 void gdb_arch_decode_regs(int offset
, struct gdb_message
*message
)
87 gdb_message_decode_bytes(message
, offset
, &exception_state
->regs
,
88 sizeof(exception_state
->regs
));