From 5b7b15afee89d6940482259b54d0864b7b2302b0 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 18 Dec 2005 17:50:39 +0100 Subject: [PATCH] uml skas0: stop gcc's insanity With Paolo 'Blaisorblade' Giarrusso UML skas0 stub has been miscompiling for many people (incidentally not the authors), depending on the used GCC versions. I think (and testing on some GCC versions shows) this patch avoids the fundamental issue which is behind this, namely gcc using the stack when we have just replaced it, behind gcc's back. The remapping and storage of the return value is hidden in a blob of asm, hopefully giving gcc no room for creativity. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Linus Torvalds --- arch/um/kernel/skas/clone.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'arch/um/kernel') diff --git a/arch/um/kernel/skas/clone.c b/arch/um/kernel/skas/clone.c index cb37ce9124a..47b812b3bca 100644 --- a/arch/um/kernel/skas/clone.c +++ b/arch/um/kernel/skas/clone.c @@ -18,11 +18,10 @@ * on some systems. */ -#define STUB_DATA(field) (((struct stub_data *) UML_CONFIG_STUB_DATA)->field) - void __attribute__ ((__section__ (".__syscall_stub"))) stub_clone_handler(void) { + struct stub_data *data = (struct stub_data *) UML_CONFIG_STUB_DATA; long err; err = stub_syscall2(__NR_clone, CLONE_PARENT | CLONE_FILES | SIGCHLD, @@ -35,17 +34,21 @@ stub_clone_handler(void) if(err) goto out; - err = stub_syscall3(__NR_setitimer, ITIMER_VIRTUAL, - (long) &STUB_DATA(timer), 0); + err = stub_syscall3(__NR_setitimer, ITIMER_VIRTUAL, + (long) &data->timer, 0); if(err) goto out; - err = stub_syscall6(STUB_MMAP_NR, UML_CONFIG_STUB_DATA, - UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE, - MAP_FIXED | MAP_SHARED, STUB_DATA(fd), - STUB_DATA(offset)); + remap_stack(data->fd, data->offset); + goto done; + out: - /* save current result. Parent: pid; child: retcode of mmap */ - STUB_DATA(err) = err; + /* save current result. + * Parent: pid; + * child: retcode of mmap already saved and it jumps around this + * assignment + */ + data->err = err; + done: trap_myself(); } -- cgit v1.2.3