host_to_target_stat64 is used for both stat64 and newfstatat syscalls. In the latter case we don't actually have a struct stat64. The current TARGET_ABI_BITS test is wrong for some 64-bit ILP32 targets (in particular MIPS N32). Check for TARGET_NR_newfstatat instead.
This will all break horribly if both newfstatat and stat64 are defined, so also add a check for that. Signed-off-by: Paul Brook <p...@codesourcery.com> --- linux-user/syscall.c | 12 +++++++++++- 1 files changed, 11 insertions(+), 1 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index ee32089..6e0999b 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -4474,6 +4474,16 @@ static inline abi_long host_to_target_timespec(abi_ulong target_addr, return 0; } +/* The newfstatat syscall uses regular struct stat. However it never + occurs on targets with a struct stat64. This allows us to share + host_to_target_stat64 between newfstatat and fstatat64. */ + +#if defined(TARGET_NR_newfstatat) && (defined(TARGET_NR_fstatat64) \ + || defined(TARGET_NR_stat64) || defined(TARGET_NR_fstat64) \ + || defined(TARGET_NR_lstat64)) +#error mismatched stat syscalls. +#endif + #if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat) static inline abi_long host_to_target_stat64(void *cpu_env, abi_ulong target_addr, @@ -4506,7 +4516,7 @@ static inline abi_long host_to_target_stat64(void *cpu_env, } else #endif { -#if TARGET_ABI_BITS == 64 && !defined(TARGET_ALPHA) +#if defined(TARGET_NR_newfstatat) struct target_stat *target_st; #else struct target_stat64 *target_st; -- 1.7.8.3