|
From: Greg P. <gp...@us...> - 2006-04-01 03:08:11
|
Darwin/x86 syscalls are going to be fun to implement. Here's why: 1. Darwin's BSD calls and Mach traps are slightly different. I already have the machinery to handle this from the PPC32 side, so it shouldn't be too bad (except for signal management, which I'm ignoring for now because signals are relatively rare on Darwin). 2. Darwin/x86 uses `sysenter` for most syscalls. Valgrind doesn't support sysenter yet (according to scheduler.c). This shouldn't be too bad either, I think. 3. Darwin/x86 syscalls pass their parameters on the stack instead of in registers, except for the syscall number in %eax. This is where the real fun begins. First, do_syscall_for_client needs to read and write the arguments in memory instead of in the VEX state. This is a problem if a syscall is made with a shallow client stack and we naively copy the max argument count (8 words afaik) from the too-small stack. It's also a problem if the client's %esp is totally trashed, but I'm willing to forgo that error check. Second, the PRE_REG_READ macros are all wrong. Redefining them to use mem_read instead of reg_read might work. I don't want to have to rewrite the syscall wrappers themselves. (PRE_REG_READ would then be a misnomer; perhaps PRE_ARG_READ would be better.) -- Greg Parker gp...@us... |
|
From: Tom H. <to...@co...> - 2006-04-01 08:56:41
|
In message <200...@ka...>
Greg Parker <gp...@us...> wrote:
> 2. Darwin/x86 uses `sysenter` for most syscalls. Valgrind doesn't support
> sysenter yet (according to scheduler.c). This shouldn't be too bad
> either, I think.
There are various threads about sysenter/syscall support in the
archives - mostly relating to solaris/x86 and solaris/amd64 but
we worked out most of the questions about how to handle it I think.
As I recall the trickiest thing with sysenter is knowing where
the kernel returns to after the call? Because it uses sysexit and
can return to an arbitrary address if I recall correctly.
Tom
--
Tom Hughes (to...@co...)
http://www.compton.nu/
|
|
From: Julian S. <js...@ac...> - 2006-04-01 13:26:44
|
> As I recall the trickiest thing with sysenter is knowing where > the kernel returns to after the call? Because it uses sysexit and > can return to an arbitrary address if I recall correctly. I think sysenter is pretty much ready to go, or trivially fixable to be. Here's what vex thinks: Implementation of sysenter is necessarily partial. sysenter is a kind of system call entry. When doing a sysenter, the return address is not known -- that is something that is beyond Vex's knowledge. So the generated IR forces a return to the scheduler, which can do what it likes to simulate the sysenter, but it MUST set this thread's guest_EIP field with the continuation address before resuming execution. If that doesn't happen, the thread will jump to address zero, which is probably fatal. Hence you can make sysenter behave how you like by filling in the relevant case in scheduler.c. J |
|
From: Nicholas N. <nj...@cs...> - 2006-04-01 22:44:27
|
On Sat, 1 Apr 2006, Greg Parker wrote: > Darwin/x86 syscalls are going to be fun to implement. Here's why: > > Second, the PRE_REG_READ macros are all wrong. Redefining them to > use mem_read instead of reg_read might work. I don't want to have > to rewrite the syscall wrappers themselves. (PRE_REG_READ would > then be a misnomer; perhaps PRE_ARG_READ would be better.) Yes, PRE_ARG_READ would be better. There is a problem in Memcheck with using pre_mem_read instead of pre_reg_read, though. If you use pre_reg_read, if it finds an error it will say: Syscall param XXX contains uninitialised byte(s) If you use pre_mem_read, it will say: Syscall param XXX points to uninitialised byte(s) which is incorrect in this case. One way to fix it is to change the "CorePart" type by breaking the "Vg_CoreSysCall" type into "Vg_CoreSysCallRegArg" and "Vg_CoreSysCallMemArg". Then pre_mem_read can do the right thing. Nick |