I'm investigating why shmat() isn't working for me. I'm running glibc
2.5 with glibc-ports 2.5, n32 ABI, on a 184.108.40.206 kernel.
What happens is that the underlying do_shmat() works, but then
ultimately, the glibc function fails, and errno is EFAULT.
I suspect that something is screwing up above do_shmat() related to 32
versus 64 bit issues.
The thing is, that glibc uses the sys_ipc dispatcher system call to call
shmat and other functions. On MIPS, this is only defined in the o32
system call table.
The dispatch opcode for the shmat service uses a
pointer-to-user-space-pointer argument, but it doesn't look like the
implementation of sys_ipc has no corresponding compat_sys_ipc flavor
which understands that.
I don't even know where glibc is getting the __NR_ number for the
sys_ipc call, since it should not be visible from the <asm/unistd.h>
kernel header if the O32 ABI isn't being used, but it might just be
defining it for itself. (Glibc tends to do stupid things like that:
#ifndef __NR_some_syscall ... #define __NR_some_syscall <wild-ass-guess>
So I have an unconfirmed suspicion that the n32 glibc might actually be
landing into the o32 sys_ipc (a suspiction which I'm about to test right
Would it be reasonable to write a compat_sys_ipc, and wire that into the
n32 system call table, or am I barking up the wrong tree? Also wouldn't
the o32 syscall table need such a compat_sys_ipc also? If o32 user space
makes calls to a 64 bit sys_ipc, I don't see how some of those calls can
I'd be in favor of just making a single do_ipc function which takes an
extra parameter that indicates whether the client is 32 or 64. The
sys_ipc and compat_sys_ipc can just be stub wrappers which call that one
with the correct value of that parameter. Then those cases in sys_ipc
which are sensitive to 32/64 issues can implement variation based on
that flag, all at the cost of a few cycles.
I don't feel like fixing glibc to avoid using the IPC dispatcher. Mainly
because the glibc code is harder to work with, and I would want this to
be right. I.e. adding the right files under the right sysdeps/* etc.