|
From: Nicholas N. <nj...@ca...> - 2004-07-28 17:34:36
|
Hi,
The x86 asm for VG_(clone) looks like this:
VG_(clone):
#define FSZ (4+4+4) /* frame size = retaddr+ebx+edi */
push %ebx
push %edi
/* set up child stack with function and arg */
movl 4+FSZ(%esp), %ecx /* child stack */
movl 12+FSZ(%esp), %ebx /* fn arg */
movl 0+FSZ(%esp), %eax /* fn */
lea -8(%ecx), %ecx /* make space on stack */
movl %ebx, 4(%ecx) /* fn arg */
movl %eax, 0(%ecx) /* fn */
/* get other args to clone */
movl 8+FSZ(%esp), %ebx /* flags */
movl 20+FSZ(%esp), %edx /* parent tid * */ ???
movl 16+FSZ(%esp), %edi /* child tid * */ ???
movl $__NR_clone, %eax
int $0x80
testl %eax, %eax
jnz 1f
/* CHILD - call thread function */
popl %eax
call *%eax
/* exit with result */
movl %eax, %ebx
movl $__NR_exit, %eax
int $0x80
/* Hm, exit returned */
ud2
1: /* PARENT or ERROR */
pop %edi
pop %ebx
ret
I understand it all except the two lines marked '???'. AIUI, the clone()
system call (as opposed to the library function) only takes two args,
'flags' and 'childstack', so %edx and %edi won't be used by it.
And those registers aren't used again later in the function. But if I
remove those two lines, some of the reg tests fail so they're obviously
doing something useful, possibly returning a value? Can someone explain
what they are doing?
Thanks.
N
|
|
From: Tom H. <th...@cy...> - 2004-07-28 17:51:08
|
In message <Pin...@he...>
Nicholas Nethercote <nj...@ca...> wrote:
> I understand it all except the two lines marked '???'. AIUI, the clone()
> system call (as opposed to the library function) only takes two args,
> 'flags' and 'childstack', so %edx and %edi won't be used by it.
> And those registers aren't used again later in the function. But if I
> remove those two lines, some of the reg tests fail so they're obviously
> doing something useful, possibly returning a value? Can someone explain
> what they are doing?
The manual page is out of date - there are extra arguments now
which are used to store the parent and child TIDs depending on
what flags are set - see sys_clone in arch/i386/kernel/process.c
for code that extracts those pointers.
Tom
--
Tom Hughes (th...@cy...)
Software Engineer, Cyberscience Corporation
http://www.cyberscience.com/
|
|
From: Nicholas N. <nj...@ca...> - 2004-07-28 18:03:59
|
On Wed, 28 Jul 2004, Tom Hughes wrote: >> I understand it all except the two lines marked '???'. AIUI, the clone() >> system call (as opposed to the library function) only takes two args, >> 'flags' and 'childstack', so %edx and %edi won't be used by it. >> And those registers aren't used again later in the function. But if I >> remove those two lines, some of the reg tests fail so they're obviously >> doing something useful, possibly returning a value? Can someone explain >> what they are doing? > > The manual page is out of date - there are extra arguments now > which are used to store the parent and child TIDs depending on > what flags are set - see sys_clone in arch/i386/kernel/process.c > for code that extracts those pointers. Erk, and so it seems %ecx gets passed to sys_clone too. Any ideas why they didn't use %esi for the 4th arg as usual, but used %edi instead? N |
|
From: Jeremy F. <je...@go...> - 2004-07-28 21:03:51
|
On Wed, 2004-07-28 at 19:03 +0100, Nicholas Nethercote wrote: > Erk, and so it seems %ecx gets passed to sys_clone too. Any ideas why > they didn't use %esi for the 4th arg as usual, but used %edi instead? clone() (along with fork and vfork) has an unusual calling convention because it isn't passed args as such, but the complete register set. It then picks out the registers it wants; the child ends up with a copy of all the parent's registers. %esi is used for the TLS info, so %edi is really the "fifth" argument. Note that VG_(clone) is just something I wrote, and it doesn't necessarily conform to any other clone-like function API, and the order of its args are arbitrary. As an aside, this isn't really a different calling convention. All syscalls are passed a struct pt_regs argument, which is placed on the stack. If the function is prototyped to take separate args, it gets the first members of struct pt_regs: ebx, ecx, edx, esi... J |