|
From: Julian S. <js...@ac...> - 2006-08-25 10:24:18
|
> > The SfMayBlock case is the general case and always safe. The
> > shortcut just-do-the-syscall-directly version is an optimisation used
> > for syscalls we're sure won't block and for which (get getpid) the
> > overhead of messing with signal masks etc is a bit silly.
> >
> > You unfortunately need to implement the general case (eventually);
> > but to get started you could just hardwire the syswrap-main logic to
> > use the shortcut scheme for now.
>
> FWIW, I finally got this sorted out today. I've got async mode syscalls
> working at last. You don't want to know what unspeakable evil I had to
> do in the machine dependent code.
Well actually .. will need to at some point.
> I'm familiar with that kind program counter magic - I've done similar
> things in the FreeBSD kernel before.
>
> I've got signals about 90% working now too, if only I can track down
> what the heck I've done to corrupt the stack with sigreturn(). The
> last 10% is probably going to cause more hair loss though.
There's a bunch of weird crap to do with the fake sigreturn syscall,
which I finally understood whilst hacking on AIX recently. I plan to
clean it up at some point. If you look at PRE(sys_sigreturn) in
syswrap-x86-linux.c (or any equivalent one) there is this:
/* For unclear reasons, it appears we need the syscall to return
without changing %EAX. Since %EAX is the return value, and can
denote either success or failure, we must set up so that the
driver logic copies it back unchanged. Also, note %EAX is of
the guest registers written by VG_(sigframe_destroy). */
SET_STATUS_from_SysRes( VG_(mk_SysRes_x86_linux)(
tst->arch.vex.guest_EAX ) );
Now I understand it. sys_sigreturn is really just a way to get V to
copy the thread's register state out of the signal frame and back into
the simulated registers (and remove the signal frame) as the kernel would
do when a sighandler returns.
In particular it's not a real system call and we don't want to 'return'
any value to user space. But the generic system call marshalling code
doesn't have the notion of a system call which doesn't return a value.
Hence the SET_STATUS_from_SysRes( VG_(mk_SysRes_x86_linux)(
tst->arch.vex.guest_EAX ) );
The idea is to cook up a fake return value for the syscall, which,
when put back into EAX (which is what the syscall driver will do)
leaves EAX unchanged. Sucky, huh?! It would be better to add an
SfNoWriteback flag.
Anyway, for FreeBSD you will have to do similar: cook up a SysRes
for sys_sigreturn which, when written back, does not change the
register state. That might be the cause of the corruption.
> FreeBSD has no sa_restorer field in its sigact records. I haven't
> figured out why Linux needs this on non-ppc64 yet, so I don't yet know
> if I'm in trouble or not. It looks like it isn't going to be a problem
> though.
I have no idea what it's for; ppc64-linux works perfectly well without
it. Perhaps PaulM knows?
J
|