Skip to content
Snippets Groups Projects
Commit 6b1d440f authored by wlott's avatar wlott
Browse files

Fixed function-end and after breakpoints to work.

parent ad72810b
No related branches found
No related tags found
No related merge requests found
...@@ -69,6 +69,7 @@ void arch_remove_breakpoint(void *pc, unsigned long orig_inst) ...@@ -69,6 +69,7 @@ void arch_remove_breakpoint(void *pc, unsigned long orig_inst)
} }
static unsigned long *skipped_break_addr, displaced_after_inst; static unsigned long *skipped_break_addr, displaced_after_inst;
static int orig_sigmask;
void arch_do_displaced_inst(struct sigcontext *scp, void arch_do_displaced_inst(struct sigcontext *scp,
unsigned long orig_inst) unsigned long orig_inst)
...@@ -79,6 +80,9 @@ void arch_do_displaced_inst(struct sigcontext *scp, ...@@ -79,6 +80,9 @@ void arch_do_displaced_inst(struct sigcontext *scp,
int opcode; int opcode;
struct sigcontext tmp; struct sigcontext tmp;
orig_sigmask = scp->sc_mask;
scp->sc_mask = BLOCKABLE;
/* Figure out where the breakpoint is, and what happens next. */ /* Figure out where the breakpoint is, and what happens next. */
if (scp->sc_cause & CAUSE_BD) { if (scp->sc_cause & CAUSE_BD) {
break_pc = pc+1; break_pc = pc+1;
...@@ -98,7 +102,7 @@ void arch_do_displaced_inst(struct sigcontext *scp, ...@@ -98,7 +102,7 @@ void arch_do_displaced_inst(struct sigcontext *scp,
if (opcode == 1 || ((opcode & 0x3c) == 0x4) || ((next_inst & 0xf00e0000) == 0x80000000)) { if (opcode == 1 || ((opcode & 0x3c) == 0x4) || ((next_inst & 0xf00e0000) == 0x80000000)) {
tmp = *scp; tmp = *scp;
emulate_branch(&tmp, next_inst); emulate_branch(&tmp, next_inst);
next_pc = (unsigned long *)scp->sc_pc; next_pc = (unsigned long *)tmp.sc_pc;
} }
else else
next_pc = pc+1; next_pc = pc+1;
...@@ -111,6 +115,10 @@ void arch_do_displaced_inst(struct sigcontext *scp, ...@@ -111,6 +115,10 @@ void arch_do_displaced_inst(struct sigcontext *scp,
static void sigtrap_handler(int signal, int code, struct sigcontext *scp) static void sigtrap_handler(int signal, int code, struct sigcontext *scp)
{ {
/* Don't disallow recursive breakpoint traps. Otherwise, we can't */
/* use debugger breakpoints anywhere in here. */
sigsetmask(scp->sc_mask);
switch (code) { switch (code) {
case trap_PendingInterrupt: case trap_PendingInterrupt:
interrupt_handle_pending(scp); interrupt_handle_pending(scp);
...@@ -126,23 +134,18 @@ static void sigtrap_handler(int signal, int code, struct sigcontext *scp) ...@@ -126,23 +134,18 @@ static void sigtrap_handler(int signal, int code, struct sigcontext *scp)
break; break;
case trap_Breakpoint: case trap_Breakpoint:
sigsetmask(scp->sc_mask);
fake_foreign_function_call(scp);
handle_breakpoint(signal, code, scp); handle_breakpoint(signal, code, scp);
undo_fake_foreign_function_call(scp);
break; break;
case trap_FunctionEndBreakpoint: case trap_FunctionEndBreakpoint:
sigsetmask(scp->sc_mask); scp->sc_pc = (int)handle_function_end_breakpoint(signal, code, scp);
fake_foreign_function_call(scp);
handle_function_end_breakpoint(signal, code, scp);
undo_fake_foreign_function_call(scp);
break; break;
case trap_AfterBreakpoint: case trap_AfterBreakpoint:
*skipped_break_addr = (trap_Breakpoint << 16) | 0xd; *skipped_break_addr = (trap_Breakpoint << 16) | 0xd;
skipped_break_addr = NULL; skipped_break_addr = NULL;
*(unsigned long *)scp->sc_pc = displaced_after_inst; *(unsigned long *)scp->sc_pc = displaced_after_inst;
scp->sc_mask = orig_sigmask;
break; break;
default: default:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment