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 | 37 | #include <sys/ucontext.h> |
| 38 | 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 | 46 | int tb_invalidated_flag; |
| 41 | 47 | static unsigned long next_tb; |
| 42 | 48 | |
| 43 | 49 | //#define DEBUG_EXEC |
| 44 | 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 | 52 | void cpu_loop_exit(void) |
| 88 | 53 | { |
| 89 | 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 | 141 | tb->tc_ptr = tc_ptr; |
| 177 | 142 | tb->cs_base = cs_base; |
| 178 | 143 | tb->flags = flags; |
| 179 | - SAVE_GLOBALS(); | |
| 180 | 144 | cpu_gen_code(env, tb, &code_gen_size); |
| 181 | - RESTORE_GLOBALS(); | |
| 182 | 145 | code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1)); |
| 183 | 146 | |
| 184 | 147 | /* check next page if needed */ |
| ... | ... | @@ -302,7 +265,6 @@ int cpu_exec(CPUState *env1) |
| 302 | 265 | #define SAVE_HOST_REGS 1 |
| 303 | 266 | #include "hostregs_helper.h" |
| 304 | 267 | env = env1; |
| 305 | - SAVE_GLOBALS(); | |
| 306 | 268 | |
| 307 | 269 | env_to_regs(); |
| 308 | 270 | #if defined(TARGET_I386) |
| ... | ... | @@ -414,7 +376,6 @@ int cpu_exec(CPUState *env1) |
| 414 | 376 | |
| 415 | 377 | next_tb = 0; /* force lookup of first TB */ |
| 416 | 378 | for(;;) { |
| 417 | - SAVE_GLOBALS(); | |
| 418 | 379 | interrupt_request = env->interrupt_request; |
| 419 | 380 | if (__builtin_expect(interrupt_request, 0) |
| 420 | 381 | #if defined(TARGET_I386) |
| ... | ... | @@ -633,7 +594,6 @@ int cpu_exec(CPUState *env1) |
| 633 | 594 | lookup_symbol(tb->pc)); |
| 634 | 595 | } |
| 635 | 596 | #endif |
| 636 | - RESTORE_GLOBALS(); | |
| 637 | 597 | /* see if we can patch the calling TB. When the TB |
| 638 | 598 | spans two pages, we cannot safely do a direct |
| 639 | 599 | jump. */ |
| ... | ... | @@ -651,6 +611,11 @@ int cpu_exec(CPUState *env1) |
| 651 | 611 | tc_ptr = tb->tc_ptr; |
| 652 | 612 | env->current_tb = tb; |
| 653 | 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 | 619 | next_tb = tcg_qemu_tb_exec(tc_ptr); |
| 655 | 620 | env->current_tb = NULL; |
| 656 | 621 | /* reset soft MMU for next block (it can currently |
| ... | ... | @@ -701,7 +666,6 @@ int cpu_exec(CPUState *env1) |
| 701 | 666 | #endif |
| 702 | 667 | |
| 703 | 668 | /* restore global registers */ |
| 704 | - RESTORE_GLOBALS(); | |
| 705 | 669 | #include "hostregs_helper.h" |
| 706 | 670 | |
| 707 | 671 | /* fail safe : never use cpu_single_env outside cpu_exec() */ | ... | ... |