-
Notifications
You must be signed in to change notification settings - Fork 154
linux-user riscv32 stat structure doesn't match glibc/musl #135
Comments
Found it. It is sizeof(st_dev) and sizeof(st_ino) as they come before st_mode. musl and glibc on riscv32 expect them to be 64-bits (8-bytes) but QEMU defines them to be abi_ulong, and unsigned long on 32-bit systems is 32-bits (4 bytes) This is from musl:
Add the following two lines to the stat.c test:
This is from QEMU (we are using asm-generic):
Note that abi_ulong on riscv32 will be 32-bits or 4-bytes. |
QEMU appears to match asm-generic in Linux which uses unsigned long (32-bits on riscv32) unless I suspect QEMU might match Linux on riscv32 and the stat test may work correctly in a Linux full-system. We should run the test in a riscv32 Linux system. It's probably not too late to change to 64-bits (8-bytes) if Linux is currently 32-bits (4-bytes).
At least from my read of the linux asm-generic header is that the 64-bit stat isn't defined unless
The question is less about whether it's Linux, glibc or QEMU that is wrong, but is more whether we want 64-bit stat. Perhaps the riscv32 linux somehow pulls in a 64-bit definition of Next step is to run the test in riscv32 linux full system emulator... we indeed might have to Linux and/or QEMU to match glibc/musl given 64-bit stat structure makes sense. We'd only change musl or glibc if we decided we wanted 32-bit stat, but that makes less sense for a new port. |
I keep remembering about this bug and thought to remind @jim-wilson and @palmer-dabbelt From my analysis, it seems we need to add a define to #define __ARCH_WANT_STAT64 I believe QEMU matches Linux kernel, but glibc and musl are expecting 64-bit stat. @jim-wilson We should run your glibc test case in Linux vs qemu-user. |
I don't have a 32-bit linux I can use for testing. I can only do 32-bit qemu-user testing. Andes is in the process of submitting 32-bit glibc support upstream. It is possible that they have a fix for this in their glibc patches. We should probably wait until the glibc patch submission gets sorted out, and then check again using upstream glibc. |
On Wed, 1 Aug 2018 at 4:40 AM, Jim Wilson ***@***.***> wrote:
I don't have a 32-bit linux I can use for testing. I can only do 32-bit
qemu-user testing. Andes is in the process of submitting 32-bit glibc
support upstream. It is possible that they have a fix for this in their
glibc patches. We should probably wait until the glibc patch submission
gets sorted out, and then check again using upstream glibc.
Well that was the problem we want to avoid. If Andes upstream glibc that
matches the current 32-bit Linux kernel then we may be stuck with 32-bit
stat.
Most architectures want 64-bit stat. It would be nice to verify this part
of the ABI before it is upstream, when it is then too late to change
mjc@miqi:~/src/sifive/riscv-linux$ grep -r __ARCH_WANT_STAT64 arch/
arch/m68k/include/asm/unistd.h:#define __ARCH_WANT_STAT64
arch/x86/include/asm/unistd.h:# define __ARCH_WANT_STAT64
arch/parisc/include/asm/unistd.h:#define __ARCH_WANT_STAT64
arch/tile/include/uapi/asm/stat.h:#define __ARCH_WANT_STAT64 /* Used for
compat_sys_stat64() etc. */
arch/sparc/include/asm/unistd.h:#define __ARCH_WANT_STAT64
arch/xtensa/include/asm/unistd.h:#define __ARCH_WANT_STAT64
arch/microblaze/include/asm/unistd.h:#define __ARCH_WANT_STAT64
arch/m32r/include/asm/unistd.h:#define __ARCH_WANT_STAT64
arch/alpha/include/asm/unistd.h:#define __ARCH_WANT_STAT64
arch/mips/include/asm/unistd.h:# define __ARCH_WANT_STAT64
arch/powerpc/include/asm/unistd.h:#define __ARCH_WANT_STAT64
arch/sh/include/asm/unistd.h:# define __ARCH_WANT_STAT64
arch/frv/include/asm/unistd.h:#define __ARCH_WANT_STAT64
arch/arm/include/asm/unistd.h:#define __ARCH_WANT_STAT64
arch/blackfin/include/asm/unistd.h:#define __ARCH_WANT_STAT64
arch/cris/include/asm/unistd.h:#define __ARCH_WANT_STAT64
arch/mn10300/include/asm/unistd.h:#define __ARCH_WANT_STAT64
|
Linux is authoritative for the ABI, given that glibc requires Linux to be
upstream first. Therein lies the problem. A potential ABI mistake.
I can perhaps try your test with musl libc against current linux and see
whether musl matches the kernel.
I think musl libc matches glibc. I think QEMU matches Linux. I'm not
certain.
We definitely should sort this out before glibc is upstream.
|
I posted a message to the libc-alpha thread for the 32-bit RISC-V glibc submission, to let them know about the problem. I'm not sure if there is much else I can easily do. |
riscv32 is an unusual port which confused me. All pre-existing Linux 32-bit ports have 32-bit stat and define __ARCH_WANT_STAT64 for additional 64-bit interfaces, however riscv32 has a 64-bit stat structure using the normal stat interfaces. @palmer-dabbelt mentioned that riscv32 Linux wanted to get rid of the legacy interfaces although I was not certain of the details e.g. how and where it has been implemented, hence my note about getting riscv32 Linux running in "full system mode" so we can run authoritative tests. This message on the musl list gives some background on 32-bit ports. This is about time_t. Both time_t and the 64-bit default stat on rv32 are unique (vs stat and stat64): Apparently there are issues that may crop up with this approach, and it may affect porting as many Linux 32-bit apps assume 32-bit for various things, and add -D_FILE_OFFSET_BITS=64 to use the *64 abis, which riscv32 appears not to have. As I mentioned before, linux-kernel is authoritative for the ABI and I just wanted to test on rv32 linux, however that wasn't building at the time so I couldn't test. I managed to get rv32 linux building and booting over the weekend, with a couple of minor patches, and ran your test case and found that riscv32 indeed doesn't have stat/32-bit and stat64/64-bit, rather it has stat/64-bit like rv64. In any case, now I have tested it, and have made a fix: Having the exact details help. I was not involved in the riscv32 Linux port, and the ABI is not described anywhere and the sizes are hidden behind several layers of typedefs. I did not know little details like the fact that the stat64 structure was being used with the stat interface. riscv32 is the first port that does this. Apologies Jim, however at no point did I make any assumptions here, rather I wanted to test in riscv32 QEMU Full System. I can share my image build scripts after i've tidied them up so we can run glibc tests in full system vs qemu-riscv32... |
We're using the generic Linux ABI, which we haven't frozen for our 32-bit port. Here's the mailing list post where we talk about the stat shakeup: https://www.spinics.net/lists/kernel/msg2897588.html |
QEMU linux-user emulation has a problem with the
stat
system call onriscv32
. It is likely that QEMU has the wrong structure. RISC-V is using Linux asm-genericstat
.riscv-qemu is using the default
stat
implementation forriscv32
however it appears one of the QEMU structure members likely has a different size in thestruct stat
definition inriscv-qemu/linux-user/syscall.c
vs thestruct stat
used byriscv32
glibc and musl-libc.Both musl and glibc have the same problem (correct result is 1):
musl:
glibc:
control (x86_64 Linux):
The text was updated successfully, but these errors were encountered: