Re: [Qemu-devel] RFC: fix run of 32 bits Linux executables on 64 bits targets
Blue Swirl wrote: [snip] Index: qemu/linux-user/mipsn32/syscall.h === --- qemu.orig/linux-user/mipsn32/syscall.h2007-10-11 19:17:14.0 + +++ qemu/linux-user/mipsn32/syscall.h 2007-10-11 19:17:46.0 + @@ -4,15 +4,15 @@ struct target_pt_regs { /* Saved main processor registers. */ - target_ulong regs[32]; + abi_ulong regs[32]; /* Saved special registers. */ - target_ulong cp0_status; - target_ulong lo; - target_ulong hi; - target_ulong cp0_badvaddr; - target_ulong cp0_cause; - target_ulong cp0_epc; + abi_ulong cp0_status; + abi_ulong lo; + abi_ulong hi; + abi_ulong cp0_badvaddr; + abi_ulong cp0_cause; + abi_ulong cp0_epc; }; This is broken. n32 has 64bit wide registers (and uses them for long long). /* Target errno definitions taken from asm-mips/errno.h */ Index: qemu/linux-user/mipsn32/target_signal.h === --- qemu.orig/linux-user/mipsn32/target_signal.h 2007-10-11 19:17:14.0 + +++ qemu/linux-user/mipsn32/target_signal.h 2007-10-11 19:17:46.0 + @@ -21,7 +21,7 @@ #define TARGET_MINSIGSTKSZ2048 #define TARGET_SIGSTKSZ 8192 -static inline target_ulong get_sp_from_cpustate(CPUMIPSState *state) +static inline abi_ulong get_sp_from_cpustate(CPUMIPSState *state) { return state-gpr[29][state-current_tc]; } Same problem. [snip] Index: qemu/linux-user/signal.c === --- qemu.orig/linux-user/signal.c 2007-10-11 19:17:13.0 + +++ qemu/linux-user/signal.c 2007-10-12 15:58:08.0 + [snip] @@ -2013,12 +2013,12 @@ uint32_t sc_dsp; /* dsp status, was sc_ssflags */ uint64_t sc_mdhi; uint64_t sc_mdlo; -target_ulong sc_hi1; /* Was sc_cause */ -target_ulong sc_lo1; /* Was sc_badvaddr */ -target_ulong sc_hi2; /* Was sc_sigset[4] */ -target_ulong sc_lo2; -target_ulong sc_hi3; -target_ulong sc_lo3; +abi_ulong sc_hi1; /* Was sc_cause */ +abi_ulong sc_lo1; /* Was sc_badvaddr */ +abi_ulong sc_hi2; /* Was sc_sigset[4] */ +abi_ulong sc_lo2; +abi_ulong sc_hi3; +abi_ulong sc_lo3; }; Likewise. When comparing with Linux kernel headers keep in mind that a 64bit MIPS kernel is always n64, so the data types used on the kernel side don't match the n32 userland ones. I'm probably just too used to it to find it confusing, taking the glibc headers as a guideline might be easier for you. :-) [snip] Index: qemu/linux-user/syscall_defs.h === --- qemu.orig/linux-user/syscall_defs.h 2007-10-11 19:17:13.0 + +++ qemu/linux-user/syscall_defs.h2007-10-12 16:08:10.0 + [snip] @@ -1272,7 +1272,7 @@ unsigned intst_dev; unsigned intst_pad0[3]; /* Reserved for st_dev expansion */ - target_ulongst_ino; + abi_ulong st_ino; unsigned int st_mode; unsigned int st_nlink; Another one. I leave out a few more instances which also break n32. [snip] Index: qemu/configure === --- qemu.orig/configure 2007-10-11 19:17:14.0 + +++ qemu/configure2007-10-12 15:38:15.0 + @@ -504,7 +504,7 @@ fi # the following are Linux specific if [ $linux_user = yes ] ; then -target_list=i386-linux-user arm-linux-user armeb-linux-user sparc-linux-user ppc-linux-user mips-linux-user mipsel-linux-user m68k-linux-user alpha-linux-user ppc64-linux-user sh4-linux-user cris-linux-user $target_list +target_list=i386-linux-user arm-linux-user armeb-linux-user sparc-linux-user sparc64-linux-user sparc32plus-linux-user ppc-linux-user mips-linux-user mipsel-linux-user m68k-linux-user alpha-linux-user ppc64-linux-user sh4-linux-user cris-linux-user $target_list fi # the following are Darwin specific if [ $darwin_user = yes ] ; then @@ -933,6 +933,7 @@ [ $target_cpu = armeb ] target_bigendian=yes [ $target_cpu = sparc ] target_bigendian=yes [ $target_cpu = sparc64 ] target_bigendian=yes +[ $target_cpu = sparc32plus ] target_bigendian=yes [ $target_cpu = ppc ] target_bigendian=yes [ $target_cpu = ppc64 ] target_bigendian=yes [ $target_cpu = ppcemb ] target_bigendian=yes @@ -1005,6 +1006,7 @@ if test $target_cpu = i386 ; then echo TARGET_ARCH=i386 $config_mak + echo TARGET_ABI_DIR=i386 $config_mak echo #define TARGET_ARCH \i386\ $config_h echo #define TARGET_I386 1 $config_h if test $kqemu = yes -a $target_softmmu = yes -a $cpu = i386 ; then It would
Re: [Qemu-devel] RFC: fix run of 32 bits Linux executables on 64 bits targets
Blue Swirl wrote: On 10/12/07, Thiemo Seufer [EMAIL PROTECTED] wrote: Blue Swirl wrote: [snip] Index: qemu/linux-user/mipsn32/syscall.h === --- qemu.orig/linux-user/mipsn32/syscall.h2007-10-11 19:17:14.0 + +++ qemu/linux-user/mipsn32/syscall.h 2007-10-11 19:17:46.0 + @@ -4,15 +4,15 @@ struct target_pt_regs { /* Saved main processor registers. */ - target_ulong regs[32]; + abi_ulong regs[32]; /* Saved special registers. */ - target_ulong cp0_status; - target_ulong lo; - target_ulong hi; - target_ulong cp0_badvaddr; - target_ulong cp0_cause; - target_ulong cp0_epc; + abi_ulong cp0_status; + abi_ulong lo; + abi_ulong hi; + abi_ulong cp0_badvaddr; + abi_ulong cp0_cause; + abi_ulong cp0_epc; }; This is broken. n32 has 64bit wide registers (and uses them for long long). If target_ulong is 64 bits, then abi_ulong is 64 bits too and therefore correct. Unless you want to enable the ABI32 feature? It is only enabled for the new Sparc32plus and PPC targets for now. But I put the original target_ulongs back. I probably should have written looks broken than is broken. In any case, having abi_ulong not matching the ABI's unsigned long is even more confusing than target_ulong not matching the ABI's unsigned long. Now that I think of it again I believe the ABI32 feature isn't usable for mips. The ABI-mandated structures are too different. Thiemo
Re: [Qemu-devel] RFC: fix run of 32 bits Linux executables on 64 bits targets
Fabrice Bellard wrote: Thiemo Seufer wrote: Fabrice Bellard wrote: J. Mayer wrote: Following the patches done for elfload32, it appeared to me that there were still problems that would prevent 32 bits executables to run on 64 bits target in linux user mode emulation. [...] Are you sure it is a good idea to try to add 32 bit executable support to a 64 bit target ? In the end you will need to write a 64 bit to 32 bit linux syscall converter which would mean duplicating all the linux-user code of the corresponding 32 bit target (think of ioctls with strutures, signals frames, etc...). I would think this feature will be limited to platforms which can handle 32bit and 64bit binaries with a single personality. I am not sure it is a common case ! However, I suggest to emulate a 32 bit user linux system with a 64 bit guest CPU running in 32 bit compatibily mode. It would be useful to test 64 bit CPUs in 32 bit compatibility mode. The only required modification in linux user is to rename target_ulong so that it can have a different size of the CPU word default size. Doesn't work for MIPS64, since it doesn't quite have a compatibility mode in the traditional sense. It needs to retain 64bit register width when running N32 ABI binaries. (Thus the somewhat odd overrides I added for the preliminary N32 support.) Thiemo
Re: [Qemu-devel] RFC: fix run of 32 bits Linux executables on 64 bits targets
On 10/11/07, Thiemo Seufer [EMAIL PROTECTED] wrote: Fabrice Bellard wrote: Thiemo Seufer wrote: Fabrice Bellard wrote: J. Mayer wrote: Following the patches done for elfload32, it appeared to me that there were still problems that would prevent 32 bits executables to run on 64 bits target in linux user mode emulation. [...] Are you sure it is a good idea to try to add 32 bit executable support to a 64 bit target ? In the end you will need to write a 64 bit to 32 bit linux syscall converter which would mean duplicating all the linux-user code of the corresponding 32 bit target (think of ioctls with strutures, signals frames, etc...). I would think this feature will be limited to platforms which can handle 32bit and 64bit binaries with a single personality. I am not sure it is a common case ! However, I suggest to emulate a 32 bit user linux system with a 64 bit guest CPU running in 32 bit compatibily mode. It would be useful to test 64 bit CPUs in 32 bit compatibility mode. The only required modification in linux user is to rename target_ulong so that it can have a different size of the CPU word default size. Doesn't work for MIPS64, since it doesn't quite have a compatibility mode in the traditional sense. It needs to retain 64bit register width when running N32 ABI binaries. (Thus the somewhat odd overrides I added for the preliminary N32 support.) CPU registers (and storage for full width registers) would still be 64 bits. The ABI uses of target_ulong need to be changed to, for example abi_ulong so that the size can be changed. Sparc64 does not have a compatibility mode either (except for address masking), it can run Sparc32 binaries because of the cleverly designed instruction set. Ops use full 64 bits of a register, but there are two sets of CPU flags, 32 and 64 bits.
Re: [Qemu-devel] RFC: fix run of 32 bits Linux executables on 64 bits targets
Blue Swirl wrote: [snip] I would think this feature will be limited to platforms which can handle 32bit and 64bit binaries with a single personality. I am not sure it is a common case ! However, I suggest to emulate a 32 bit user linux system with a 64 bit guest CPU running in 32 bit compatibily mode. It would be useful to test 64 bit CPUs in 32 bit compatibility mode. The only required modification in linux user is to rename target_ulong so that it can have a different size of the CPU word default size. Doesn't work for MIPS64, since it doesn't quite have a compatibility mode in the traditional sense. It needs to retain 64bit register width when running N32 ABI binaries. (Thus the somewhat odd overrides I added for the preliminary N32 support.) CPU registers (and storage for full width registers) would still be 64 bits. The ABI uses of target_ulong need to be changed to, for example abi_ulong so that the size can be changed. I see. Sparc64 does not have a compatibility mode either (except for address masking), it can run Sparc32 binaries because of the cleverly designed instruction set. Ops use full 64 bits of a register, but there are two sets of CPU flags, 32 and 64 bits. For MIPS it's not even that much, sign-extension magic handles everything. Thiemo
Re: [Qemu-devel] RFC: fix run of 32 bits Linux executables on 64 bits targets
On Thu, 2007-10-11 at 22:26 +0300, Blue Swirl wrote: On 10/10/07, Fabrice Bellard [EMAIL PROTECTED] wrote: Thiemo Seufer wrote: Fabrice Bellard wrote: J. Mayer wrote: Following the patches done for elfload32, it appeared to me that there were still problems that would prevent 32 bits executables to run on 64 bits target in linux user mode emulation. [...] Are you sure it is a good idea to try to add 32 bit executable support to a 64 bit target ? In the end you will need to write a 64 bit to 32 bit linux syscall converter which would mean duplicating all the linux-user code of the corresponding 32 bit target (think of ioctls with strutures, signals frames, etc...). I would think this feature will be limited to platforms which can handle 32bit and 64bit binaries with a single personality. I am not sure it is a common case ! However, I suggest to emulate a 32 bit user linux system with a 64 bit guest CPU running in 32 bit compatibily mode. It would be useful to test 64 bit CPUs in 32 bit compatibility mode. The only required modification in linux user is to rename target_ulong so that it can have a different size of the CPU word default size. I made a patch to rename target_ulong/long to abi_ulong/long and also add a new emulator target that uses the 32 bit ABI with 64 bit CPU. Some Sparc32 binaries run, others don't, possibly indicating bugs in the Sparc64 emulation! The patch is quite large because of the renaming, but this shouldn't have effect to any other target. Any comments? Great ! The patch seems safe, at first look, then I noticed a few things that are not correct or may be improved: * In linux-user/main.c: PowerPC DCR access should keep using target_ulong. This is a hardware bus, not an ABI dependent stuff. If a 32 bits cast is needed, it would be done in the micro-ops that handle the DCR bus accesses. * in linux-user/qemu.h: why is there still a OVERRIDE_ELF_CLASS variable, when checking TARGET_ABI32 should be sufficient ? It seems to me that having 2 defines which are, in fact, synonymous may be a source of confusion. * in configure: you also added a sparc64-softmmu target, which seems not related with this particular patch. * in configure: why add a specific TARGET_ABI32_DIR variable for that case ? It seems to me that a TARGET_ABI_DIR variable could be useful for all targets. Let me give an example: I want to add a ppcemb-linux-user target, emulating a PowerPC 32 with 64 bits registers and SIMD extensions but I don't want to duplicate the linux-user/ppc subdirectory. Having a TARGET_ABI_DIR available for all targets would solve my problem. In fact, even ppc and ppc64 could be merged... As you need this feature in your case, I think it would be a good idea to add it for all targets. And then, the kludge in Makefile.target could be replaced by: -CPPFLAGS+=-I$(SRC_PATH)/linux-user -I $(SRC_PATH)/linux-user/$(TARGET_ARCH) +CPPFLAGS+=-I$(SRC_PATH)/linux-user -I $(SRC_PATH)/linux-user/$(TARGET_ABI_DIR) which is simpler and easier to understand, imho. -- J. Mayer [EMAIL PROTECTED] Never organized
Re: [Qemu-devel] RFC: fix run of 32 bits Linux executables on 64 bits targets
J. Mayer wrote: Following the patches done for elfload32, it appeared to me that there were still problems that would prevent 32 bits executables to run on 64 bits target in linux user mode emulation. [...] Are you sure it is a good idea to try to add 32 bit executable support to a 64 bit target ? In the end you will need to write a 64 bit to 32 bit linux syscall converter which would mean duplicating all the linux-user code of the corresponding 32 bit target (think of ioctls with strutures, signals frames, etc...). Fabrice.
Re: [Qemu-devel] RFC: fix run of 32 bits Linux executables on 64 bits targets
On 10/10/07, J. Mayer [EMAIL PROTECTED] wrote: Following the patches done for elfload32, it appeared to me that there were still problems that would prevent 32 bits executables to run on 64 bits target in linux user mode emulation. First of all, the personality was never set to PER_LINUX32 It's set in elfload32.c, but I think your approach is better. The check for elf_ex-e_ident[EI_CLASS] == ELFCLASS64 could be moved from elfload32.c. The second problem was that pointers used to set the values on the stack were still of target_ulong size, which lead 32 bits executable crash dereferencing NULL pointers as soon as they wanted to parse their arguments. Nice, I was wondering why my test program crashed.
Re: [Qemu-devel] RFC: fix run of 32 bits Linux executables on 64 bits targets
On 10/10/07, Fabrice Bellard [EMAIL PROTECTED] wrote: J. Mayer wrote: Following the patches done for elfload32, it appeared to me that there were still problems that would prevent 32 bits executables to run on 64 bits target in linux user mode emulation. [...] Are you sure it is a good idea to try to add 32 bit executable support to a 64 bit target ? In the end you will need to write a 64 bit to 32 bit linux syscall converter which would mean duplicating all the linux-user code of the corresponding 32 bit target (think of ioctls with strutures, signals frames, etc...). True. But I hope some day we have Solaris binary execution support, and we need this 32+64 mode for that. I think Linux can emulate Solaris system calls.
Re: [Qemu-devel] RFC: fix run of 32 bits Linux executables on 64 bits targets
Fabrice Bellard wrote: J. Mayer wrote: Following the patches done for elfload32, it appeared to me that there were still problems that would prevent 32 bits executables to run on 64 bits target in linux user mode emulation. [...] Are you sure it is a good idea to try to add 32 bit executable support to a 64 bit target ? In the end you will need to write a 64 bit to 32 bit linux syscall converter which would mean duplicating all the linux-user code of the corresponding 32 bit target (think of ioctls with strutures, signals frames, etc...). I would think this feature will be limited to platforms which can handle 32bit and 64bit binaries with a single personality. Thiemo
Re: [Qemu-devel] RFC: fix run of 32 bits Linux executables on 64 bits targets
On Wed, 2007-10-10 at 19:01 +0300, Blue Swirl wrote: On 10/10/07, J. Mayer [EMAIL PROTECTED] wrote: Following the patches done for elfload32, it appeared to me that there were still problems that would prevent 32 bits executables to run on 64 bits target in linux user mode emulation. First of all, the personality was never set to PER_LINUX32 It's set in elfload32.c, but I think your approach is better. The check for elf_ex-e_ident[EI_CLASS] == ELFCLASS64 could be moved from elfload32.c. Well, it is overriden just before the create_elf_table call... And it's especially needed there and in the start_thread code, at least for PowerPC. As the kernel set it up at this point, it seems to be a good idea to do the same ! The second problem was that pointers used to set the values on the stack were still of target_ulong size, which lead 32 bits executable crash dereferencing NULL pointers as soon as they wanted to parse their arguments. Nice, I was wondering why my test program crashed. I realized there are tons of unneeded checks/code in my patch, as this code is compiled twice. I will repost a cleaned one soon... -- J. Mayer [EMAIL PROTECTED] Never organized
Re: [Qemu-devel] RFC: fix run of 32 bits Linux executables on 64 bits targets
Thiemo Seufer wrote: Fabrice Bellard wrote: J. Mayer wrote: Following the patches done for elfload32, it appeared to me that there were still problems that would prevent 32 bits executables to run on 64 bits target in linux user mode emulation. [...] Are you sure it is a good idea to try to add 32 bit executable support to a 64 bit target ? In the end you will need to write a 64 bit to 32 bit linux syscall converter which would mean duplicating all the linux-user code of the corresponding 32 bit target (think of ioctls with strutures, signals frames, etc...). I would think this feature will be limited to platforms which can handle 32bit and 64bit binaries with a single personality. I am not sure it is a common case ! However, I suggest to emulate a 32 bit user linux system with a 64 bit guest CPU running in 32 bit compatibily mode. It would be useful to test 64 bit CPUs in 32 bit compatibility mode. The only required modification in linux user is to rename target_ulong so that it can have a different size of the CPU word default size. Regards, Fabrice.
Re: [Qemu-devel] RFC: fix run of 32 bits Linux executables on 64 bits targets
On 10/10/07, Fabrice Bellard [EMAIL PROTECTED] wrote: Thiemo Seufer wrote: Fabrice Bellard wrote: J. Mayer wrote: Following the patches done for elfload32, it appeared to me that there were still problems that would prevent 32 bits executables to run on 64 bits target in linux user mode emulation. [...] Are you sure it is a good idea to try to add 32 bit executable support to a 64 bit target ? In the end you will need to write a 64 bit to 32 bit linux syscall converter which would mean duplicating all the linux-user code of the corresponding 32 bit target (think of ioctls with strutures, signals frames, etc...). I would think this feature will be limited to platforms which can handle 32bit and 64bit binaries with a single personality. I am not sure it is a common case ! However, I suggest to emulate a 32 bit user linux system with a 64 bit guest CPU running in 32 bit compatibily mode. It would be useful to test 64 bit CPUs in 32 bit compatibility mode. The only required modification in linux user is to rename target_ulong so that it can have a different size of the CPU word default size. I think this would be sufficient for the Sparc and this way there would be no need to convert the structures. Brilliant! Should we revert the elfload32 patch? What about PPC?
Re: [Qemu-devel] RFC: fix run of 32 bits Linux executables on 64 bits targets
On Wed, 2007-10-10 at 22:02 +0300, Blue Swirl wrote: On 10/10/07, Fabrice Bellard [EMAIL PROTECTED] wrote: Thiemo Seufer wrote: Fabrice Bellard wrote: J. Mayer wrote: Following the patches done for elfload32, it appeared to me that there were still problems that would prevent 32 bits executables to run on 64 bits target in linux user mode emulation. [...] Are you sure it is a good idea to try to add 32 bit executable support to a 64 bit target ? In the end you will need to write a 64 bit to 32 bit linux syscall converter which would mean duplicating all the linux-user code of the corresponding 32 bit target (think of ioctls with strutures, signals frames, etc...). I would think this feature will be limited to platforms which can handle 32bit and 64bit binaries with a single personality. I am not sure it is a common case ! However, I suggest to emulate a 32 bit user linux system with a 64 bit guest CPU running in 32 bit compatibily mode. It would be useful to test 64 bit CPUs in 32 bit compatibility mode. The only required modification in linux user is to rename target_ulong so that it can have a different size of the CPU word default size. I think this would be sufficient for the Sparc and this way there would be no need to convert the structures. Brilliant! Should we revert the elfload32 patch? What about PPC? We can keep the elfload32 for now, it does not hurt. This approach is OK for PPC too. And as I got some 32 bits programs running in the 64 bits linux-user emulator, the same programs behavior can be compared to find eventual issues... -- J. Mayer [EMAIL PROTECTED] Never organized