libc: pick IPC_64 by what the headers offer, not by the word size
sparc64 returns garbage from every *ctl call -- tst-semctl reports
sem_perm.uid as -2957503, sem_nsems as 0 and sem_otime in year ???? --
because the kernel filled the pre-IPC_64 structure. ipc.h decides the
bit by word size, so 64-bit targets do not set it, and without the bit
sys_ipc's ipc_parse_version() selects the ancient layout.
Which is right depends on the route, and the route depends on the
headers. sparc has no direct semctl in 4.19, only __NR_ipc 215, so the
call goes through the multiplexer where the kernel reads the bit out of
cmd; from the 6.x headers semctl is 394 and points at sys_semctl, which
sets IPC_64 itself and answers EINVAL to a cmd that carries the bit.
Measured with the same library, toolchain and qemu image, only the
headers swapped:
4.19.56 headers 6.5.10 headers
sparc32 4 pass 4 fail (EINVAL)
sparc64 2 fail (garbage) 4 pass
A clean diagonal, and identical for both word sizes -- so __WORDSIZE was
never the criterion. Use "#ifdef __NR_semctl" for the architectures
whose direct number points at sys_*ctl: i386, m68k, mips o32, sh,
powerpc, sparc, hppa. It is more accurate than a configured version
number, because the headers are what the build actually sees.
That replaces the per-arch cascade this grew over the last months:
42c80560f gave i386 a __LINUX_KERNEL_VERSION test, e4391b9b8 made hppa an
unconditional 0x0, and 1cea0a036 with 97958e275 sorted out mips o32
against n32/n64. Each was right for its target, but they were three
answers to one question -- and the version test coincides with the header
test anyway, since i386 and m68k got their direct numbers in 5.1.
Left alone deliberately: arm, xtensa, microblaze and alpha have had a
direct number all along, but it points at sys_old_*ctl, which parses the
version and wants the bit either way -- arm's semctl is 300 and was
sys_semctl in 4.19 and sys_old_semctl from 5.1, because that is when the
kernel swapped the two names. mips n32/n64 keep their own case above,
and everything without ARCH_HAS_DEPRECATED_SYSCALLS keeps 0x0.
powerpc and sh had the same latent bug as sparc32, and this fixes them
too: their 394/396/402 point at sys_semctl, sys_shmctl and sys_msgctl,
read off the kernel's syscall.tbl the same way as the sys_old_semctl of
the four above, so the old word-size rule was right for them only for as
long as the build stayed on pre-5.1 headers.
Signed-off-by: Ramin Moussavi <lordrasmus@gmail.com>