X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Farm26%2Fkernel%2Fsys_arm.c;h=e7edd201579abd9ea2f3c0b898c08957898c2cf3;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=431f9f85e0693a7697b3499225b6ca9e8670bcee;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/arch/arm26/kernel/sys_arm.c b/arch/arm26/kernel/sys_arm.c index 431f9f85e..e7edd2015 100644 --- a/arch/arm26/kernel/sys_arm.c +++ b/arch/arm26/kernel/sys_arm.c @@ -13,6 +13,7 @@ * have a non-standard calling sequence on the Linux/arm * platform. */ +#include #include #include #include @@ -281,3 +282,43 @@ asmlinkage int sys_execve(char *filenamei, char **argv, char **envp, struct pt_r out: return error; } + +/* FIXME - see if this is correct for arm26 */ +long execve(const char *filename, char **argv, char **envp) +{ + struct pt_regs regs; + int ret; + memset(®s, 0, sizeof(struct pt_regs)); + ret = do_execve((char *)filename, (char __user * __user *)argv, (char __user * __user *)envp, ®s); + if (ret < 0) + goto out; + + /* + * Save argc to the register structure for userspace. + */ + regs.ARM_r0 = ret; + + /* + * We were successful. We won't be returning to our caller, but + * instead to user space by manipulating the kernel stack. + */ + asm( "add r0, %0, %1\n\t" + "mov r1, %2\n\t" + "mov r2, %3\n\t" + "bl memmove\n\t" /* copy regs to top of stack */ + "mov r8, #0\n\t" /* not a syscall */ + "mov r9, %0\n\t" /* thread structure */ + "mov sp, r0\n\t" /* reposition stack pointer */ + "b ret_to_user" + : + : "r" (current_thread_info()), + "Ir" (THREAD_SIZE - 8 - sizeof(regs)), + "r" (®s), + "Ir" (sizeof(regs)) + : "r0", "r1", "r2", "r3", "ip", "memory"); + + out: + return ret; +} + +EXPORT_SYMBOL(execve);