2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
6 * Copyright (C) 1995 - 2000 by Ralf Baechle
7 * Copyright (C) 2000 Silicon Graphics, Inc.
9 * TODO: Implement the compatibility syscalls.
10 * Don't waste that much memory for empty entries in the syscall
13 #undef CONF_PRINT_SYSCALLS
14 #undef CONF_DEBUG_IRIX
16 #include <linux/config.h>
17 #include <linux/compiler.h>
18 #include <linux/linkage.h>
20 #include <linux/smp.h>
21 #include <linux/smp_lock.h>
22 #include <linux/mman.h>
23 #include <linux/sched.h>
24 #include <linux/file.h>
25 #include <linux/slab.h>
26 #include <linux/utsname.h>
27 #include <linux/unistd.h>
28 #include <asm/branch.h>
29 #include <asm/offset.h>
30 #include <asm/ptrace.h>
31 #include <asm/signal.h>
32 #include <asm/shmparam.h>
33 #include <asm/uaccess.h>
35 extern asmlinkage void syscall_trace(void);
36 typedef asmlinkage int (*syscall_t)(void *a0,...);
37 extern asmlinkage int (*do_syscalls)(struct pt_regs *regs, syscall_t fun,
39 extern syscall_t sys_call_table[];
40 extern unsigned char sys_narg_table[];
42 asmlinkage int sys_pipe(volatile struct pt_regs regs)
58 unsigned long shm_align_mask = PAGE_SIZE - 1; /* Sane caches */
60 #define COLOUR_ALIGN(addr,pgoff) \
61 ((((addr) + shm_align_mask) & ~shm_align_mask) + \
62 (((pgoff) << PAGE_SHIFT) & shm_align_mask))
64 unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
65 unsigned long len, unsigned long pgoff, unsigned long flags)
67 struct vm_area_struct * vmm;
70 if (flags & MAP_FIXED) {
72 * We do not accept a shared mapping if it would violate
73 * cache aliasing constraints.
75 if ((flags & MAP_SHARED) && (addr & shm_align_mask))
83 if (filp || (flags & MAP_SHARED))
87 addr = COLOUR_ALIGN(addr, pgoff);
89 addr = PAGE_ALIGN(addr);
90 vmm = find_vma(current->mm, addr);
91 if (TASK_SIZE - len >= addr &&
92 (!vmm || addr + len <= vmm->vm_start))
95 addr = TASK_UNMAPPED_BASE;
97 addr = COLOUR_ALIGN(addr, pgoff);
99 addr = PAGE_ALIGN(addr);
101 for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) {
102 /* At this point: (!vmm || addr < vmm->vm_end). */
103 if (TASK_SIZE - len < addr)
105 if (!vmm || addr + len <= vmm->vm_start)
109 addr = COLOUR_ALIGN(addr, pgoff);
113 /* common code for old and new mmaps */
115 do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
116 unsigned long flags, unsigned long fd, unsigned long pgoff)
119 struct file * file = NULL;
121 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
122 if (!(flags & MAP_ANONYMOUS)) {
128 down_write(¤t->mm->mmap_sem);
129 error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
130 up_write(¤t->mm->mmap_sem);
138 asmlinkage unsigned long old_mmap(unsigned long addr, size_t len, int prot,
139 int flags, int fd, off_t offset)
144 if (offset & ~PAGE_MASK)
147 result = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
154 sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
155 unsigned long flags, unsigned long fd, unsigned long pgoff)
157 return do_mmap2(addr, len, prot, flags, fd, pgoff);
160 save_static_function(sys_fork);
161 static_unused int _sys_fork(struct pt_regs regs)
165 res = do_fork(SIGCHLD, regs.regs[29], ®s, 0);
170 save_static_function(sys_clone);
171 static_unused int _sys_clone(struct pt_regs regs)
173 unsigned long clone_flags;
177 clone_flags = regs.regs[4];
178 newsp = regs.regs[5];
180 newsp = regs.regs[29];
181 res = do_fork(clone_flags, newsp, ®s, 0);
186 * sys_execve() executes a new program.
188 asmlinkage int sys_execve(struct pt_regs regs)
193 filename = getname((char *) (long)regs.regs[4]);
194 error = PTR_ERR(filename);
195 if (IS_ERR(filename))
197 error = do_execve(filename, (char **) (long)regs.regs[5],
198 (char **) (long)regs.regs[6], ®s);
206 * Compacrapability ...
208 asmlinkage int sys_uname(struct old_utsname * name)
210 if (name && !copy_to_user(name, &system_utsname, sizeof (*name)))
216 * Compacrapability ...
218 asmlinkage int sys_olduname(struct oldold_utsname * name)
224 if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
227 error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
228 error -= __put_user(0,name->sysname+__OLD_UTS_LEN);
229 error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
230 error -= __put_user(0,name->nodename+__OLD_UTS_LEN);
231 error -= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
232 error -= __put_user(0,name->release+__OLD_UTS_LEN);
233 error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
234 error -= __put_user(0,name->version+__OLD_UTS_LEN);
235 error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
236 error = __put_user(0,name->machine+__OLD_UTS_LEN);
237 error = error ? -EFAULT : 0;
243 * If we ever come here the user sp is bad. Zap the process right away.
244 * Due to the bad stack signaling wouldn't work.
245 * XXX kernel locking???
247 asmlinkage void bad_stack(void)
253 * Build the string table for the builtin "poor man's strace".
255 #ifdef CONF_PRINT_SYSCALLS
256 #define SYS(fun, narg) #fun,
257 static char *sfnames[] = {
258 #include "syscalls.h"
262 #if defined(CONFIG_BINFMT_IRIX) && defined(CONF_DEBUG_IRIX)
263 #define SYS(fun, narg) #fun,
264 static char *irix_sys_names[] = {
265 #include "irix5sys.h"