Commit 572a9d4a880bdcc71c1880ee7416308259bda0d9
1 parent
79c63858
Improved workaround for the annoying glibc global register mangling bug
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4465 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
11 additions
and
47 deletions
cpu-exec.c
@@ -37,53 +37,18 @@ | @@ -37,53 +37,18 @@ | ||
37 | #include <sys/ucontext.h> | 37 | #include <sys/ucontext.h> |
38 | #endif | 38 | #endif |
39 | 39 | ||
40 | +#if defined(__sparc__) && !defined(HOST_SOLARIS) | ||
41 | +// Work around ugly bugs in glibc that mangle global register contents | ||
42 | +#undef env | ||
43 | +#define env cpu_single_env | ||
44 | +#endif | ||
45 | + | ||
40 | int tb_invalidated_flag; | 46 | int tb_invalidated_flag; |
41 | static unsigned long next_tb; | 47 | static unsigned long next_tb; |
42 | 48 | ||
43 | //#define DEBUG_EXEC | 49 | //#define DEBUG_EXEC |
44 | //#define DEBUG_SIGNAL | 50 | //#define DEBUG_SIGNAL |
45 | 51 | ||
46 | -#define SAVE_GLOBALS() | ||
47 | -#define RESTORE_GLOBALS() | ||
48 | - | ||
49 | -#if defined(__sparc__) && !defined(HOST_SOLARIS) | ||
50 | -#include <features.h> | ||
51 | -#if defined(__GLIBC__) && ((__GLIBC__ < 2) || \ | ||
52 | - ((__GLIBC__ == 2) && (__GLIBC_MINOR__ <= 90))) | ||
53 | -// Work around ugly bugs in glibc that mangle global register contents | ||
54 | - | ||
55 | -static volatile void *saved_env; | ||
56 | -#undef SAVE_GLOBALS | ||
57 | -#define SAVE_GLOBALS() do { \ | ||
58 | - saved_env = env; \ | ||
59 | - } while(0) | ||
60 | - | ||
61 | -#undef RESTORE_GLOBALS | ||
62 | -#define RESTORE_GLOBALS() do { \ | ||
63 | - env = (void *)saved_env; \ | ||
64 | - } while(0) | ||
65 | - | ||
66 | -static int sparc_setjmp(jmp_buf buf) | ||
67 | -{ | ||
68 | - int ret; | ||
69 | - | ||
70 | - SAVE_GLOBALS(); | ||
71 | - ret = setjmp(buf); | ||
72 | - RESTORE_GLOBALS(); | ||
73 | - return ret; | ||
74 | -} | ||
75 | -#undef setjmp | ||
76 | -#define setjmp(jmp_buf) sparc_setjmp(jmp_buf) | ||
77 | - | ||
78 | -static void sparc_longjmp(jmp_buf buf, int val) | ||
79 | -{ | ||
80 | - SAVE_GLOBALS(); | ||
81 | - longjmp(buf, val); | ||
82 | -} | ||
83 | -#define longjmp(jmp_buf, val) sparc_longjmp(jmp_buf, val) | ||
84 | -#endif | ||
85 | -#endif | ||
86 | - | ||
87 | void cpu_loop_exit(void) | 52 | void cpu_loop_exit(void) |
88 | { | 53 | { |
89 | /* NOTE: the register at this point must be saved by hand because | 54 | /* NOTE: the register at this point must be saved by hand because |
@@ -176,9 +141,7 @@ static TranslationBlock *tb_find_slow(target_ulong pc, | @@ -176,9 +141,7 @@ static TranslationBlock *tb_find_slow(target_ulong pc, | ||
176 | tb->tc_ptr = tc_ptr; | 141 | tb->tc_ptr = tc_ptr; |
177 | tb->cs_base = cs_base; | 142 | tb->cs_base = cs_base; |
178 | tb->flags = flags; | 143 | tb->flags = flags; |
179 | - SAVE_GLOBALS(); | ||
180 | cpu_gen_code(env, tb, &code_gen_size); | 144 | cpu_gen_code(env, tb, &code_gen_size); |
181 | - RESTORE_GLOBALS(); | ||
182 | code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1)); | 145 | code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1)); |
183 | 146 | ||
184 | /* check next page if needed */ | 147 | /* check next page if needed */ |
@@ -302,7 +265,6 @@ int cpu_exec(CPUState *env1) | @@ -302,7 +265,6 @@ int cpu_exec(CPUState *env1) | ||
302 | #define SAVE_HOST_REGS 1 | 265 | #define SAVE_HOST_REGS 1 |
303 | #include "hostregs_helper.h" | 266 | #include "hostregs_helper.h" |
304 | env = env1; | 267 | env = env1; |
305 | - SAVE_GLOBALS(); | ||
306 | 268 | ||
307 | env_to_regs(); | 269 | env_to_regs(); |
308 | #if defined(TARGET_I386) | 270 | #if defined(TARGET_I386) |
@@ -414,7 +376,6 @@ int cpu_exec(CPUState *env1) | @@ -414,7 +376,6 @@ int cpu_exec(CPUState *env1) | ||
414 | 376 | ||
415 | next_tb = 0; /* force lookup of first TB */ | 377 | next_tb = 0; /* force lookup of first TB */ |
416 | for(;;) { | 378 | for(;;) { |
417 | - SAVE_GLOBALS(); | ||
418 | interrupt_request = env->interrupt_request; | 379 | interrupt_request = env->interrupt_request; |
419 | if (__builtin_expect(interrupt_request, 0) | 380 | if (__builtin_expect(interrupt_request, 0) |
420 | #if defined(TARGET_I386) | 381 | #if defined(TARGET_I386) |
@@ -633,7 +594,6 @@ int cpu_exec(CPUState *env1) | @@ -633,7 +594,6 @@ int cpu_exec(CPUState *env1) | ||
633 | lookup_symbol(tb->pc)); | 594 | lookup_symbol(tb->pc)); |
634 | } | 595 | } |
635 | #endif | 596 | #endif |
636 | - RESTORE_GLOBALS(); | ||
637 | /* see if we can patch the calling TB. When the TB | 597 | /* see if we can patch the calling TB. When the TB |
638 | spans two pages, we cannot safely do a direct | 598 | spans two pages, we cannot safely do a direct |
639 | jump. */ | 599 | jump. */ |
@@ -651,6 +611,11 @@ int cpu_exec(CPUState *env1) | @@ -651,6 +611,11 @@ int cpu_exec(CPUState *env1) | ||
651 | tc_ptr = tb->tc_ptr; | 611 | tc_ptr = tb->tc_ptr; |
652 | env->current_tb = tb; | 612 | env->current_tb = tb; |
653 | /* execute the generated code */ | 613 | /* execute the generated code */ |
614 | +#if defined(__sparc__) && !defined(HOST_SOLARIS) | ||
615 | +#undef env | ||
616 | + env = cpu_single_env; | ||
617 | +#define env cpu_single_env | ||
618 | +#endif | ||
654 | next_tb = tcg_qemu_tb_exec(tc_ptr); | 619 | next_tb = tcg_qemu_tb_exec(tc_ptr); |
655 | env->current_tb = NULL; | 620 | env->current_tb = NULL; |
656 | /* reset soft MMU for next block (it can currently | 621 | /* reset soft MMU for next block (it can currently |
@@ -701,7 +666,6 @@ int cpu_exec(CPUState *env1) | @@ -701,7 +666,6 @@ int cpu_exec(CPUState *env1) | ||
701 | #endif | 666 | #endif |
702 | 667 | ||
703 | /* restore global registers */ | 668 | /* restore global registers */ |
704 | - RESTORE_GLOBALS(); | ||
705 | #include "hostregs_helper.h" | 669 | #include "hostregs_helper.h" |
706 | 670 | ||
707 | /* fail safe : never use cpu_single_env outside cpu_exec() */ | 671 | /* fail safe : never use cpu_single_env outside cpu_exec() */ |