@@ -39,9 +39,14 @@
#endif
#if defined(__sparc__) && !defined(CONFIG_SOLARIS)
-// Work around ugly bugs in glibc that mangle global register contents
-#undef env
+/* glibc will mangle global register contents. To work around this,
+ * we avoid using the global register in this file, and place back
+ * cpu_single_env in AREG0 before giving control to target-* routines.
+ */
+#define export_env() asm ("mov %0, %%" AREG0 : : "r" (cpu_single_env) : AREG0);
#define env cpu_single_env
+#else
+#define export_env()
#endif
int tb_invalidated_flag;
@@ -257,11 +262,7 @@ int cpu_exec(CPUState *env1)
/* prepare setjmp context for exception handling */
for(;;) {
if (setjmp(env->jmp_env) == 0) {
-#if defined(__sparc__) && !defined(CONFIG_SOLARIS)
-#undef env
- env = cpu_single_env;
-#define env cpu_single_env
-#endif
+ export_env();
/* if an exception is pending, we execute it here */
if (env->exception_index >= 0) {
if (env->exception_index >= EXCP_INTERRUPT) {
@@ -387,11 +388,7 @@ int cpu_exec(CPUState *env1)
env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ);
intno = cpu_get_pic_interrupt(env);
qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing hardware INT=0x%02x\n", intno);
-#if defined(__sparc__) && !defined(CONFIG_SOLARIS)
-#undef env
- env = cpu_single_env;
-#define env cpu_single_env
-#endif
+ export_env();
do_interrupt(intno, 0, 0, 0, 1);
/* ensure that no TB jump will be modified as
the program flow was changed */
@@ -603,12 +600,8 @@ int cpu_exec(CPUState *env1)
if (!unlikely (env->exit_request)) {
env->current_tb = tb;
tc_ptr = tb->tc_ptr;
- /* execute the generated code */
-#if defined(__sparc__) && !defined(CONFIG_SOLARIS)
-#undef env
- env = cpu_single_env;
-#define env cpu_single_env
-#endif
+ /* execute the generated code */
+ export_env();
next_tb = tcg_qemu_tb_exec(tc_ptr);
env->current_tb = NULL;
if ((next_tb & 3) == 2) {
On 02/13/2010 06:58 PM, Blue Swirl wrote: > V9 ABI gives more registers to application use. Except that glibc uses those---in theory, as I see it, it should be compiled with fixed g2 and g3 to leave them to the application. I get it now. It may be possible to make the workaround a big less ugly (I'm thinking of avoiding #undef/#define by using assembly). I made a patch (see attachment, just FYI), maybe sometime I'll try it using self-virtualized qemu. Paolo commit 59ca12838278bed97ce5cc311f90ddfec7953047 Author: Paolo Bonzini <pbonzini@redhat.com> Date: Sat Feb 13 21:13:12 2010 +0100 make sparc workaround less ugly Not-quite-signed-off-by: Paolo Bonzini <pbonzini@redhat.com>