* Andy Lutomirski:
The kernel has:
struct rt_sigframe {
char __user *pretcode;
struct ucontext uc;
struct siginfo info;
/* fp state follows here */
};
This is roughly the actual signal frame. But userspace does not have
this struct declared, and user code does not know the sizes of the
fields. So it's accessed in a nonsensical way. The signal handler
function is passed a pointer to the whole sigframe implicitly in RSP,
a pointer to &frame->info in RSI, anda pointer to &frame->uc in RDX.
User code can *find* the fp state by following a pointer from
mcontext, which is, in turn, found via uc:
struct ucontext {
unsigned long uc_flags;
struct ucontext *uc_link;
stack_t uc_stack;
struct sigcontext uc_mcontext; <-- fp pointer is in here
sigset_t uc_sigmask; /* mask last for extensibility */
};
I must say that I haven't reviewed this in detail, but for historic
reasons, glibc userspace has a differently-sized sigset_t. So the
kernel ucontext (used in signals) and user ucontext (used for
swapcontext et al.) are already fully decoupled?
Thanks,
Florian