On Monday 13 April 2009 09:29:00 Jamie Lokier wrote: > Mike Frysinger wrote: > > > You have to test the result of clone() before calling _exit(). How do > > > you guarantee the compiler inserts no memory writes in that sequence > > > using just INTERNAL_SYSCALL on all architectures? > > > > there is no guarantee of course, but i declare the storage of the > > return value of clone with "register", so that seems to be "good > > enough". i reviewed the disassembly on a few arches and they all > > look correct. just dont build with optimization turned off ;). > > I think it's a really bad idea to depend on optimization (and no > bb-profiling perhaps?) for correct code!
in general, sure. when talking low level C library, not really. the ldso already requires -O1+ in order to operate correctly. glibc requires -O1+ for pretty much everything. the Linux kernel too (although in many cases there, i think people are just being lazy). > The x86 syscall does touch the stack: it pushes %ebx when __PIC__. I > know we're not doing NOMMU x86, but it shows how fragile depending on > the C macros is. indeed. that'll probably not work, but as you point out, ive never heard of a x86 w/out a mmu let alone Linux support for it ... > I think it would be best to have arch-specific fork_exit.S, in the > same way that there's arch-specific vfork.S. It's obviously very > small, and it's easy to use the compiler output from your C version to > check and write the .S for all architectures :-) easier to be lazy: have common/fork_exit.c which uses my existing C implementation and then each arch can override it if they want with arch/fork_exit.S. > Alternatively, a kernel flag CLONE_PARENT_EXIT would be a nice generic > solution, but that doesn't have the niceness of working with old > kernels. yeah, that would be nicer, but i dont want to go through the lkml hassle trying to convince them too ;) > > the Blackfin assembly for example is: > > 18: a0 00 EXCPT 0x0; /* syscall(clone) */ > > 1a: ea 63 R2 = -0x3 (X); > > 1c: 08 30 R1 = R0; > > 1e: f8 67 R0 += -0x1; > > 20: 10 0a CC = R0 <= R2 (IU); > > 22: 03 14 IF !CC JUMP 0x28 <_daemon+0x28> (BP); > > 24: 08 68 P0 = 0x1 (X); > > 26: a0 00 EXCPT 0x0; /* syscall(exit) */ > > no stack usage by the parent > > I'm sure it does work on all the architectures where it's needed. > (For now). But it's dubious, and someday someone will add an > architecture where INTERNAL_SYSCALL touches the stack, causing a rare > heisenbug in this generic code by accident. > > Is that Blackfin code correct? Wouldn't tight code simply check for > any result > 0, like this: the Blackfin code is correct according to the C code that was used. if (ret != -1 && ret != 0) i was thinking of INLINE_SYSCALL() when i wrote the code rather than INTERNAL_SYSCALL() (20$ if you deduced the behavior difference without ever seeing the code :P). so the code should read: if (ret <= 0) since the kernel returns negative errno values ... and we make the assumption that all negative values are errors for clone() rather than the typical range of -1...-4096. -mike
signature.asc
Description: This is a digitally signed message part.
_______________________________________________ uClinux-dev mailing list uClinux-dev@uclinux.org http://mailman.uclinux.org/mailman/listinfo/uclinux-dev This message was resent by uclinux-dev@uclinux.org To unsubscribe see: http://mailman.uclinux.org/mailman/options/uclinux-dev