00001 #include "types.h"
00002 #include "defs.h"
00003 #include "param.h"
00004 #include "mmu.h"
00005 #include "proc.h"
00006 #include "x86.h"
00007 #include "syscall.h"
00008
00009
00010
00011
00012
00013
00014
00015
00016 int
00017 fetchint(struct proc *p, uint addr, int *ip)
00018 {
00019 if(addr >= p->sz || addr+4 > p->sz)
00020 return -1;
00021 *ip = *(int*)(p->mem + addr);
00022 return 0;
00023 }
00024
00025
00026
00027
00028 int
00029 fetchstr(struct proc *p, uint addr, char **pp)
00030 {
00031 char *s, *ep;
00032
00033 if(addr >= p->sz)
00034 return -1;
00035 *pp = p->mem + addr;
00036 ep = p->mem + p->sz;
00037 for(s = *pp; s < ep; s++)
00038 if(*s == 0)
00039 return s - *pp;
00040 return -1;
00041 }
00042
00043
00044 int
00045 argint(int n, int *ip)
00046 {
00047 return fetchint(proc, proc->tf->esp + 4 + 4*n, ip);
00048 }
00049
00050
00051
00052
00053 int
00054 argptr(int n, char **pp, int size)
00055 {
00056 int i;
00057
00058 if(argint(n, &i) < 0)
00059 return -1;
00060 if((uint)i >= proc->sz || (uint)i+size >= proc->sz)
00061 return -1;
00062 *pp = proc->mem + i;
00063 return 0;
00064 }
00065
00066
00067
00068
00069
00070 int
00071 argstr(int n, char **pp)
00072 {
00073 int addr;
00074 if(argint(n, &addr) < 0)
00075 return -1;
00076 return fetchstr(proc, addr, pp);
00077 }
00078
00079 extern int sys_chdir(void);
00080 extern int sys_close(void);
00081 extern int sys_dup(void);
00082 extern int sys_exec(void);
00083 extern int sys_exit(void);
00084 extern int sys_fork(void);
00085 extern int sys_fstat(void);
00086 extern int sys_getpid(void);
00087 extern int sys_kill(void);
00088 extern int sys_link(void);
00089 extern int sys_mkdir(void);
00090 extern int sys_mknod(void);
00091 extern int sys_open(void);
00092 extern int sys_pipe(void);
00093 extern int sys_read(void);
00094 extern int sys_sbrk(void);
00095 extern int sys_sleep(void);
00096 extern int sys_unlink(void);
00097 extern int sys_wait(void);
00098 extern int sys_write(void);
00099
00100 static int (*syscalls[])(void) = {
00101 [SYS_chdir] sys_chdir,
00102 [SYS_close] sys_close,
00103 [SYS_dup] sys_dup,
00104 [SYS_exec] sys_exec,
00105 [SYS_exit] sys_exit,
00106 [SYS_fork] sys_fork,
00107 [SYS_fstat] sys_fstat,
00108 [SYS_getpid] sys_getpid,
00109 [SYS_kill] sys_kill,
00110 [SYS_link] sys_link,
00111 [SYS_mkdir] sys_mkdir,
00112 [SYS_mknod] sys_mknod,
00113 [SYS_open] sys_open,
00114 [SYS_pipe] sys_pipe,
00115 [SYS_read] sys_read,
00116 [SYS_sbrk] sys_sbrk,
00117 [SYS_sleep] sys_sleep,
00118 [SYS_unlink] sys_unlink,
00119 [SYS_wait] sys_wait,
00120 [SYS_write] sys_write,
00121 };
00122
00123 void
00124 syscall(void)
00125 {
00126 int num;
00127
00128 num = proc->tf->eax;
00129 if(num >= 0 && num < NELEM(syscalls) && syscalls[num])
00130 proc->tf->eax = syscalls[num]();
00131 else {
00132 cprintf("%d %s: unknown sys call %d\n",
00133 proc->pid, proc->name, num);
00134 proc->tf->eax = -1;
00135 }
00136 }