* have a non-standard calling sequence on the Linux/arm
* platform.
*/
+#include <linux/module.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/slab.h>
union semun fourth;
if (!ptr)
return -EINVAL;
- if (get_user(fourth.__pad, (void __user **) ptr))
+ if (get_user(fourth.__pad, (void __user * __user *) ptr))
return -EFAULT;
return sys_semctl (first, second, third, fourth);
}
return ret;
return put_user(raddr, (ulong __user *)third);
}
- case 1: /* iBCS2 emulator entry point */
- if (!segment_eq(get_fs(), get_ds()))
- return -EINVAL;
- return do_shmat(first, (char __user *) ptr,
- second, (ulong __user *) third);
+ case 1: /* Of course, we don't support iBCS2! */
+ return -EINVAL;
}
case SHMDT:
return sys_shmdt ((char __user *)ptr);
if (!newsp)
newsp = regs->ARM_sp;
- return do_fork(clone_flags & ~CLONE_IDLETASK, newsp, regs, 0, NULL, NULL);
+ return do_fork(clone_flags, newsp, regs, 0, NULL, NULL);
}
asmlinkage int sys_vfork(struct pt_regs *regs)
out:
return error;
}
+
+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);