Message ID | 20230707131928.89500-2-deller@gmx.de |
---|---|
State | New |
Headers | show |
Series | linux-user: Fix fcntl64() and accept4() for 32-bit targets | expand |
On 7/7/23 14:19, Helge Deller wrote: > On a 64-bit host, O_LARGEFILE has the value 0. > When running a 32-bit guest on a 64-bit host, fcntl64(F_GETFL) should > return with the O_LARGEFILE flag set, because the 64-bit host supports > large files unconditionally. > > The flag translation should have happened in do_fcntl(), but since O_LARGEFILE > is zero for 64-bit hosts, the translation can't be done with the > translation table. But surely add the code to do_fcntl, right after the host_to_target_bitmask, so that it's present for fcntl64 as well? r~ > > Fix it by setting the TARGET_O_LARGEFILE flag unconditionally for > 32-bit guests on 64-bit hosts when fcntl64() is called. > > Signed-off-by: Helge Deller <deller@gmx.de> > --- > linux-user/syscall.c | 9 +++++++++ > 1 file changed, 9 insertions(+) > > diff --git a/linux-user/syscall.c b/linux-user/syscall.c > index 08162cc966..3f1e8e7ad9 100644 > --- a/linux-user/syscall.c > +++ b/linux-user/syscall.c > @@ -12328,6 +12328,15 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1, > } > > switch(arg2) { > +#if HOST_LONG_BITS == 64 && TARGET_LONG_BITS == 32 && \ > + O_LARGEFILE == 0 && TARGET_O_LARGEFILE != 0 > + case TARGET_F_GETFL: > + ret = do_fcntl(arg1, arg2, arg3); > + if (ret > 0) { > + ret |= TARGET_O_LARGEFILE; > + } > + break; > +#endif > case TARGET_F_GETLK64: > ret = copyfrom(&fl, arg3); > if (ret) { > -- > 2.41.0 >
diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 08162cc966..3f1e8e7ad9 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -12328,6 +12328,15 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1, } switch(arg2) { +#if HOST_LONG_BITS == 64 && TARGET_LONG_BITS == 32 && \ + O_LARGEFILE == 0 && TARGET_O_LARGEFILE != 0 + case TARGET_F_GETFL: + ret = do_fcntl(arg1, arg2, arg3); + if (ret > 0) { + ret |= TARGET_O_LARGEFILE; + } + break; +#endif case TARGET_F_GETLK64: ret = copyfrom(&fl, arg3); if (ret) {
On a 64-bit host, O_LARGEFILE has the value 0. When running a 32-bit guest on a 64-bit host, fcntl64(F_GETFL) should return with the O_LARGEFILE flag set, because the 64-bit host supports large files unconditionally. The flag translation should have happened in do_fcntl(), but since O_LARGEFILE is zero for 64-bit hosts, the translation can't be done with the translation table. Fix it by setting the TARGET_O_LARGEFILE flag unconditionally for 32-bit guests on 64-bit hosts when fcntl64() is called. Signed-off-by: Helge Deller <deller@gmx.de> --- linux-user/syscall.c | 9 +++++++++ 1 file changed, 9 insertions(+) -- 2.41.0