On 8 March 2017 at 00:40, Henry Wertz <hwert...@gmail.com> wrote: > I have a trivial, 1-line patch for getdents function; due to use of > unsigned long, the struct on 64-bit and 32-bit systems is not the same. > qemu is aware of this, however it currently only checks for a 32-bit target > on 64-bit host case; in my case, I'm running 64-bit target on 32-bit host > (x86-64 binaries on a 32-bit ARM). > > My use case for this patch, I have Android Studio on my (32-bit ARM) > chromebook -- thank goodness I got the 4GB model! Since Android Studio is > java, that worked; but it calls aapt from build tools. Up through 23.x.x > (which is build for 32-bit x86) it worked. With 25.0.0 (and 24.x.x > version) aapt is now built for 64-bit x86-64; it would give an odd error > about a directory being invalid. By comparing strace between qemu and real > x86-64, I found getdents was behaving differently. WIth this patch aapt > completes. > > I really wasn't sure if this would be better this way ("if target != host") > or if something like "if (target==32 && host==64) || (target==64 && > host==32)" would be preferrable. > --------------------------------------------------- > > Signed-off-by: Henry Wertz <hwert...@gmail.com> > > *** linux-user/syscall.c~ 2017-03-04 10:31:14.000000000 -0600 > --- linux-user/syscall.c 2017-03-07 17:08:24.615399116 -0600 > *************** > *** 9913,9921 **** > #endif > #ifdef TARGET_NR_getdents > case TARGET_NR_getdents: > #ifdef __NR_getdents > ! #if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64 > { > struct target_dirent *target_dirp; > struct linux_dirent *dirp; > abi_long count = arg3; > --- 9913,9921 ---- > #endif > #ifdef TARGET_NR_getdents > case TARGET_NR_getdents: > #ifdef __NR_getdents > ! #if TARGET_ABI_BITS != HOST_LONG_BITS > { > struct target_dirent *target_dirp; > struct linux_dirent *dirp; > abi_long count = arg3;
There is a theoretically better way to handle the 64-bit guest on 32-bit host case: since here you know that the guest dirent struct is bigger than the host dirent struct you could read them directly into the guest buffer and then convert in-place rather than having to malloc a temporary buffer. The conversion code is a little bit awkward though because you have to make sure you don't overwrite host data you haven't read yet, so I think you would need to start at the end of the buffer and work backwards. This is basically fixing the #else part of this code to work for guest > host as well as for guest == host. However, since 64-bit-on-32 is not exactly a very common use case these days I think your patch is an OK fix for things. Reviewed-by: Peter Maydell <peter.mayd...@linaro.org> PS: we prefer 'unified' format diffs; git format-patch should produce those by default. thanks -- PMM