Danny Milosavljevic writes: > + ;; QEMU transparent emulation is in somewhat of a pickle sometimes. > + ;; There is no support in the kernel syscalls of specifying what > + ;; kind of userspace you are emulating. Some parts of the > + ;; structures passed back-and-forth between kernel and guest > + ;; userspace can change size (including size of individual fields). > + ;; > + ;; One of the affected structures is "struct dirent". The ext4 > + ;; file system puts a 64 bit hash into "d_off" on the kernel side. > + ;; If the guest system's glibc is 32 bit it is going to be very > + ;; confused (it does check whether d_off fits into the structure > + ;; it gives back to the user--and it doesn't fit. Hence readdir > + ;; fails). > + ;; This manifests itself in simple directory reads not working > + ;; anymore in parts of cmake, for example. Note that for CMake in particular, this problem will be fixed in 3.19: https://gitlab.kitware.com/cmake/cmake/-/issues/20568 As mentioned in that issue, and which this patch states on no uncertain terms, a workaround is to use -D_FILE_OFFSET_BITS=64 on 32-bit platforms. > + ;; > + ;; There is a very simple and complete way to avoid this problem: > + ;; Just always use 64 bit offsets in user space programs (also > + ;; on 32 bit machines). > + ;; > + ;; Note: We might want to avoid using 64 bit when bootstrapping > + ;; using mescc (since mescc doesn't directly support 64 bit > + ;; values)--but then bootstrapping has to be done on a > + ;; file system other than ext4, or on ext4 with the feature > + ;; "dir_index" disabled. > + ;; > + ;; The change below does not affect 64 bit users. > + ;; > + ;; See . > + (let ((port (open-file "include/dirent.h" "a"))) > + (display " > +#if __SIZEOF_LONG__ < 8 > +#ifndef __USE_FILE_OFFSET64 > +#undef readdir > +#define readdir @READDIR_WITHOUT_FILE_OFFSET64_IS_A_REALLY_BAD_IDEA@ Won't this break _everything_ that uses readdir() without 64-bit offsets? Or does that @@ string get substituted by the glibc build system somehow. > +#endif > +#endif > +" port) > + (close-port port)) > + ;; This file includes and thus checks sanity already. > + ;; TODO: Check dirent/scandir-tail.c, dirent/scandir64-tail.c. > + (substitute* "posix/glob.c" > + (("(#[ ]*define[ ][ ]*readdir)") " > +#undef readdir > +#define readdir")) Can you file a bug report upstream about the duplicate definition(s)? Enforcing this restriction in glibc feels rather sledgehammer-y. Would it make sense to introduce a GCC warning instead? I'm sure there are legitimate uses of smaller file offsets (i.e. embedded). A GCC warning will still break -Werror, but that's a lot more manageable than breaking almost every use of readdir() on 32-bit platforms.