Hello, I am evaluating the possibility to use linux-user emulation in qemu for automatic regression testing for some embedded linux projects in the company I work for. I've encountered some problems with syscall interface while testing mips(el), powerpc and arm code, and I am willing to fix them. This is the first patch, I'd appeciate any comments.
Best regards, Tomasz Lukaszewski In 32-bit ABIs 64-bit arguments are passed in a pair of registers (ra, rb), where ra is an odd numbered one. This patch fixes such case for truncate64, ftruncate64, pread64 and pwrite64 for mips, ppc and arm-eabi. --- linux-user/syscall.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 62 insertions(+), 2 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 80d8633..0bf146d 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -3922,6 +3922,7 @@ static inline abi_long target_truncate64(void *cpu_env, const char *arg1, abi_long arg3, abi_long arg4) { +#if TARGET_ABI_BITS == 32 #ifdef TARGET_ARM if (((CPUARMState *)cpu_env)->eabi) { @@ -3929,6 +3930,11 @@ static inline abi_long target_truncate64(void *cpu_env, const char *arg1, arg3 = arg4; } #endif +#if defined TARGET_PPC || defined TARGET_MIPS + arg2 = arg3; + arg3 = arg4; +#endif +#endif return get_errno(truncate64(arg1, target_offset64(arg2, arg3))); } #endif @@ -3939,6 +3945,7 @@ static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1, abi_long arg3, abi_long arg4) { +#if TARGET_ABI_BITS == 32 #ifdef TARGET_ARM if (((CPUARMState *)cpu_env)->eabi) { @@ -3946,10 +3953,63 @@ static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1, arg3 = arg4; } #endif +#if defined TARGET_PPC || defined TARGET_MIPS + arg2 = arg3; + arg3 = arg4; +#endif +#endif return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3))); } #endif +#ifdef TARGET_NR_pread64 +static inline abi_long target_pread64(void *cpu_env, abi_long arg1, + void *arg2, + abi_long arg3, + abi_long arg4, + abi_long arg5, + abi_long arg6) +{ +#if TARGET_ABI_BITS == 32 +#ifdef TARGET_ARM + if (((CPUARMState *)cpu_env)->eabi) + { + arg4 = arg5; + arg5 = arg6; + } +#endif +#if defined TARGET_PPC || defined TARGET_MIPS + arg4 = arg5; + arg5 = arg6; +#endif +#endif + return get_errno(pread64(arg1, arg2, arg3, target_offset64(arg4, arg5))); +} + +static inline abi_long target_pwrite64(void *cpu_env, abi_long arg1, + const void *arg2, + abi_long arg3, + abi_long arg4, + abi_long arg5, + abi_long arg6) +{ +#if TARGET_ABI_BITS == 32 +#ifdef TARGET_ARM + if (((CPUARMState *)cpu_env)->eabi) + { + arg4 = arg5; + arg5 = arg6; + } +#endif +#if defined TARGET_PPC || defined TARGET_MIPS + arg4 = arg5; + arg5 = arg6; +#endif +#endif + return get_errno(pwrite64(arg1, arg2, arg3, target_offset64(arg4, arg5))); +} +#endif + static inline abi_long target_to_host_timespec(struct timespec *host_ts, abi_ulong target_addr) { @@ -6166,13 +6226,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, case TARGET_NR_pread64: if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0))) goto efault; - ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5))); + ret = target_pread64(cpu_env, arg1, p, arg3, arg4, arg5, arg6); unlock_user(p, arg2, ret); break; case TARGET_NR_pwrite64: if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1))) goto efault; - ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5))); + ret = target_pwrite64(cpu_env, arg1, p, arg3, arg4, arg5, arg6); unlock_user(p, arg2, 0); break; #endif -- 1.6.4.2