Commit 66f1cdbde44b82e53b5337981f38ca9e837cd5f7

Authored by blueswir1
1 parent d07bde88

Partial fix to Sparc32 Linux host global register mangling problem


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3806 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile.target
@@ -161,7 +161,7 @@ ifeq ($(ARCH),sparc) @@ -161,7 +161,7 @@ ifeq ($(ARCH),sparc)
161 OP_CFLAGS+=-fno-omit-frame-pointer 161 OP_CFLAGS+=-fno-omit-frame-pointer
162 else 162 else
163 BASE_CFLAGS+=-ffixed-g1 -ffixed-g6 163 BASE_CFLAGS+=-ffixed-g1 -ffixed-g6
164 - HELPER_CFLAGS=$(CFLAGS) -ffixed-i0 -mflat 164 + HELPER_CFLAGS=$(CFLAGS) -ffixed-i0
165 # -static is used to avoid g1/g3 usage by the dynamic linker 165 # -static is used to avoid g1/g3 usage by the dynamic linker
166 BASE_LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH).ld -static 166 BASE_LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH).ld -static
167 endif 167 endif
cpu-exec.c
@@ -40,6 +40,52 @@ int tb_invalidated_flag; @@ -40,6 +40,52 @@ int tb_invalidated_flag;
40 //#define DEBUG_EXEC 40 //#define DEBUG_EXEC
41 //#define DEBUG_SIGNAL 41 //#define DEBUG_SIGNAL
42 42
  43 +#define SAVE_GLOBALS()
  44 +#define RESTORE_GLOBALS()
  45 +
  46 +#if defined(__sparc__) && !defined(HOST_SOLARIS)
  47 +#include <features.h>
  48 +#if defined(__GLIBC__) && ((__GLIBC__ < 2) || \
  49 + ((__GLIBC__ == 2) && (__GLIBC_MINOR__ <= 90)))
  50 +// Work around ugly bugs in glibc that mangle global register contents
  51 +
  52 +static volatile void *saved_env;
  53 +static volatile unsigned long saved_t0, saved_i7;
  54 +#undef SAVE_GLOBALS
  55 +#define SAVE_GLOBALS() do { \
  56 + saved_env = env; \
  57 + saved_t0 = T0; \
  58 + asm volatile ("st %%i7, [%0]" : : "r" (&saved_i7)); \
  59 + } while(0)
  60 +
  61 +#undef RESTORE_GLOBALS
  62 +#define RESTORE_GLOBALS() do { \
  63 + env = (void *)saved_env; \
  64 + T0 = saved_t0; \
  65 + asm volatile ("ld [%0], %%i7" : : "r" (&saved_i7)); \
  66 + } while(0)
  67 +
  68 +static int sparc_setjmp(jmp_buf buf)
  69 +{
  70 + int ret;
  71 +
  72 + SAVE_GLOBALS();
  73 + ret = setjmp(buf);
  74 + RESTORE_GLOBALS();
  75 + return ret;
  76 +}
  77 +#undef setjmp
  78 +#define setjmp(jmp_buf) sparc_setjmp(jmp_buf)
  79 +
  80 +static void sparc_longjmp(jmp_buf buf, int val)
  81 +{
  82 + SAVE_GLOBALS();
  83 + longjmp(buf, val);
  84 +}
  85 +#define longjmp(jmp_buf, val) sparc_longjmp(jmp_buf, val)
  86 +#endif
  87 +#endif
  88 +
43 void cpu_loop_exit(void) 89 void cpu_loop_exit(void)
44 { 90 {
45 /* NOTE: the register at this point must be saved by hand because 91 /* NOTE: the register at this point must be saved by hand because
@@ -133,7 +179,9 @@ static TranslationBlock *tb_find_slow(target_ulong pc, @@ -133,7 +179,9 @@ static TranslationBlock *tb_find_slow(target_ulong pc,
133 tb->tc_ptr = tc_ptr; 179 tb->tc_ptr = tc_ptr;
134 tb->cs_base = cs_base; 180 tb->cs_base = cs_base;
135 tb->flags = flags; 181 tb->flags = flags;
  182 + SAVE_GLOBALS();
136 cpu_gen_code(env, tb, &code_gen_size); 183 cpu_gen_code(env, tb, &code_gen_size);
  184 + RESTORE_GLOBALS();
137 code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1)); 185 code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
138 186
139 /* check next page if needed */ 187 /* check next page if needed */
@@ -232,11 +280,7 @@ static inline TranslationBlock *tb_find_fast(void) @@ -232,11 +280,7 @@ static inline TranslationBlock *tb_find_fast(void)
232 return tb; 280 return tb;
233 } 281 }
234 282
235 -#if defined(__sparc__) && !defined(HOST_SOLARIS)  
236 -#define BREAK_CHAIN tmp_T0 = 0  
237 -#else  
238 #define BREAK_CHAIN T0 = 0 283 #define BREAK_CHAIN T0 = 0
239 -#endif  
240 284
241 /* main execution loop */ 285 /* main execution loop */
242 286
@@ -249,10 +293,6 @@ int cpu_exec(CPUState *env1) @@ -249,10 +293,6 @@ int cpu_exec(CPUState *env1)
249 uint32_t *saved_regwptr; 293 uint32_t *saved_regwptr;
250 #endif 294 #endif
251 #endif 295 #endif
252 -#if defined(__sparc__) && !defined(HOST_SOLARIS)  
253 - int saved_i7;  
254 - target_ulong tmp_T0;  
255 -#endif  
256 int ret, interrupt_request; 296 int ret, interrupt_request;
257 void (*gen_func)(void); 297 void (*gen_func)(void);
258 TranslationBlock *tb; 298 TranslationBlock *tb;
@@ -267,10 +307,7 @@ int cpu_exec(CPUState *env1) @@ -267,10 +307,7 @@ int cpu_exec(CPUState *env1)
267 #define SAVE_HOST_REGS 1 307 #define SAVE_HOST_REGS 1
268 #include "hostregs_helper.h" 308 #include "hostregs_helper.h"
269 env = env1; 309 env = env1;
270 -#if defined(__sparc__) && !defined(HOST_SOLARIS)  
271 - /* we also save i7 because longjmp may not restore it */  
272 - asm volatile ("mov %%i7, %0" : "=r" (saved_i7));  
273 -#endif 310 + SAVE_GLOBALS();
274 311
275 env_to_regs(); 312 env_to_regs();
276 #if defined(TARGET_I386) 313 #if defined(TARGET_I386)
@@ -380,10 +417,7 @@ int cpu_exec(CPUState *env1) @@ -380,10 +417,7 @@ int cpu_exec(CPUState *env1)
380 417
381 T0 = 0; /* force lookup of first TB */ 418 T0 = 0; /* force lookup of first TB */
382 for(;;) { 419 for(;;) {
383 -#if defined(__sparc__) && !defined(HOST_SOLARIS)  
384 - /* g1 can be modified by some libc? functions */  
385 - tmp_T0 = T0;  
386 -#endif 420 + SAVE_GLOBALS();
387 interrupt_request = env->interrupt_request; 421 interrupt_request = env->interrupt_request;
388 if (__builtin_expect(interrupt_request, 0) 422 if (__builtin_expect(interrupt_request, 0)
389 #if defined(TARGET_I386) 423 #if defined(TARGET_I386)
@@ -597,9 +631,7 @@ int cpu_exec(CPUState *env1) @@ -597,9 +631,7 @@ int cpu_exec(CPUState *env1)
597 lookup_symbol(tb->pc)); 631 lookup_symbol(tb->pc));
598 } 632 }
599 #endif 633 #endif
600 -#if defined(__sparc__) && !defined(HOST_SOLARIS)  
601 - T0 = tmp_T0;  
602 -#endif 634 + RESTORE_GLOBALS();
603 /* see if we can patch the calling TB. When the TB 635 /* see if we can patch the calling TB. When the TB
604 spans two pages, we cannot safely do a direct 636 spans two pages, we cannot safely do a direct
605 jump. */ 637 jump. */
@@ -695,9 +727,7 @@ int cpu_exec(CPUState *env1) @@ -695,9 +727,7 @@ int cpu_exec(CPUState *env1)
695 #endif 727 #endif
696 728
697 /* restore global registers */ 729 /* restore global registers */
698 -#if defined(__sparc__) && !defined(HOST_SOLARIS)  
699 - asm volatile ("mov %0, %%i7" : : "r" (saved_i7));  
700 -#endif 730 + RESTORE_GLOBALS();
701 #include "hostregs_helper.h" 731 #include "hostregs_helper.h"
702 732
703 /* fail safe : never use cpu_single_env outside cpu_exec() */ 733 /* fail safe : never use cpu_single_env outside cpu_exec() */
target-sparc/op.c
@@ -1244,12 +1244,14 @@ void OPPROTO op_exception(void) @@ -1244,12 +1244,14 @@ void OPPROTO op_exception(void)
1244 { 1244 {
1245 env->exception_index = PARAM1; 1245 env->exception_index = PARAM1;
1246 cpu_loop_exit(); 1246 cpu_loop_exit();
  1247 + FORCE_RET();
1247 } 1248 }
1248 1249
1249 void OPPROTO op_trap_T0(void) 1250 void OPPROTO op_trap_T0(void)
1250 { 1251 {
1251 env->exception_index = TT_TRAP + (T0 & 0x7f); 1252 env->exception_index = TT_TRAP + (T0 & 0x7f);
1252 cpu_loop_exit(); 1253 cpu_loop_exit();
  1254 + FORCE_RET();
1253 } 1255 }
1254 1256
1255 void OPPROTO op_trapcc_T0(void) 1257 void OPPROTO op_trapcc_T0(void)