aboutsummaryrefslogtreecommitdiff
path: root/linux-user
diff options
context:
space:
mode:
Diffstat (limited to 'linux-user')
-rw-r--r--linux-user/sh4/signal.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/linux-user/sh4/signal.c b/linux-user/sh4/signal.c
index c4ba962708..c16c2c2d57 100644
--- a/linux-user/sh4/signal.c
+++ b/linux-user/sh4/signal.c
@@ -104,6 +104,14 @@ static void unwind_gusa(CPUSH4State *regs)
/* Reset the SP to the saved version in R1. */
regs->gregs[15] = regs->gregs[1];
+ } else if (regs->gregs[15] >= -128u && regs->pc == regs->gregs[0]) {
+ /* If we are on the last instruction of a gUSA region, we must reset
+ the SP, otherwise we would be pushing the signal context to
+ invalid memory. */
+ regs->gregs[15] = regs->gregs[1];
+ } else if (regs->flags & TB_FLAG_DELAY_SLOT) {
+ /* If we are in a delay slot, push the previous instruction. */
+ regs->pc -= 2;
}
}