qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] qemu-mips on x86: stat() broken in 0.8.2


From: Dave Denholm
Subject: [Qemu-devel] qemu-mips on x86: stat() broken in 0.8.2
Date: Tue, 10 Oct 2006 13:23:56 +0100
User-agent: Gnus/5.1002 (Gnus v5.10.2) Emacs/21.4 (gnu/linux)

Hi,
   I think emulation of stat() on qemu-mips (big-endian) hosted on x86
is broken. Or more generally, probably either-endian mips on the
opposite-endian host.


In linux-user/syscall.c around line 2892 in the 0.8.2 release, it uses
tswapl() for ppc, and tswap16() for all other targets. But target_stat.t_mode
is 32-bit on both mips and ppc, and so I think mips also needs a 32-bit
swap.My local fix is just to change

#if defined(TARGET_PPC)

to

#if defined(TARGET_PPC) || defined(TARGET_MIPS)

and that seems to fix the problem I was seeing. A slightly more
general test might be

  if (sizeof(target_st->st_mode) == 4) {
     ... tswapl();
  } else {
     ... tswap16();
  }

but I'll leave that up to you.


I was confused about why the busybox executable in the prebuilt tests
seemed to work, and worked the same with both the original executable
and my modified version, but it uses fstat64() rather than stat(), and
that of course is a different code path. (fstat64() uses the put_user
macro which automatically senses the width of the target. Any particular
reason for the difference ?)


Another small change I have locally is to suppress warnings about
unimplemented mips system call 4147 (cache flush). Since qemu handles
self-modifying code transparently (in effect, a coherent cache, or
no cache at all), the flush can be implemented as a no-op.

In fact, it might be mildly interesting if the detection of
self-modifying code was turned off for non-x86 targets, and
cache-flush calls were required to discarded generated code, since
that would make it possible to detect missed calls to cache-flush on
programs with self-modifying code. But perhaps I have a different
agenda from other users in this area ;-)


diff below

dd
-- 
Dave Denholm              <address@hidden>       http://www.esmertec.com


$ diff --unified syscall.c.~1~ syscall.c
--- syscall.c.~1~       2006-07-22 18:23:34.000000000 +0100
+++ syscall.c   2006-10-10 13:00:56.695069058 +0100
@@ -2889,7 +2889,7 @@
                 lock_user_struct(target_st, arg2, 0);
                 target_st->st_dev = tswap16(st.st_dev);
                 target_st->st_ino = tswapl(st.st_ino);
-#if defined(TARGET_PPC)
+#if defined(TARGET_PPC) || defined(TARGET_MIPS)
                 target_st->st_mode = tswapl(st.st_mode); /* XXX: check this */
                 target_st->st_uid = tswap32(st.st_uid);
                 target_st->st_gid = tswap32(st.st_gid);
@@ -3785,6 +3785,12 @@
        break;
     }
 #endif
+#ifdef TARGET_NR_cacheflush
+    case TARGET_NR_cacheflush:
+        /* self-modifying code is handled automatically, so nothing needed */
+        ret = 0;
+        break;
+#endif
 #ifdef TARGET_NR_security
     case TARGET_NR_security:
         goto unimplemented;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]