diff options
author | Jason Wessel <jason.wessel@windriver.com> | 2010-01-26 16:29:50 -0600 |
---|---|---|
committer | Aurelien Jarno <aurelien@aurel32.net> | 2010-02-28 19:20:02 +0100 |
commit | 63a54736f31f9e11da6fb52319bba26e7d24f571 (patch) | |
tree | 230a6acdea201b38b7b3373c34d4ac2acd8c3e5d /target-i386/helper.c | |
parent | 6049f4f831c6f409031dfa09282b38d0cbaecad8 (diff) |
target-i386: fix crash on x86 32bit linux host with hw breakpoint exceptions
If you make use of hw breakpoints on a 32bit x86 linux host, qemu
will segmentation fault when processing the exception.
The problem is that the value of env is stored in $ebp in the op_helper
raise_exception() function, and it can have the wrong value when
calling it from non generated code.
It is possible to work around the problem by restoring the value of
env before calling raise_exception() using a new helper function that
takes (CPUState *) as one of the arguments.
Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Diffstat (limited to 'target-i386/helper.c')
-rw-r--r-- | target-i386/helper.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/target-i386/helper.c b/target-i386/helper.c index 080d2b8c7d..ce2b5eb346 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -1862,7 +1862,7 @@ int check_hw_breakpoints(CPUState *env, int force_dr6_update) static CPUDebugExcpHandler *prev_debug_excp_handler; -void raise_exception(int exception_index); +void raise_exception_env(int exception_index, CPUState *env); static void breakpoint_handler(CPUState *env) { @@ -1872,7 +1872,7 @@ static void breakpoint_handler(CPUState *env) if (env->watchpoint_hit->flags & BP_CPU) { env->watchpoint_hit = NULL; if (check_hw_breakpoints(env, 0)) - raise_exception(EXCP01_DB); + raise_exception_env(EXCP01_DB, env); else cpu_resume_from_signal(env, NULL); } @@ -1881,7 +1881,7 @@ static void breakpoint_handler(CPUState *env) if (bp->pc == env->eip) { if (bp->flags & BP_CPU) { check_hw_breakpoints(env, 1); - raise_exception(EXCP01_DB); + raise_exception_env(EXCP01_DB, env); } break; } |