1 #include "types.h" 2 #include "defs.h" 3 #include "param.h" 4 #include "memlayout.h" 5 #include "mmu.h" 6 #include "proc.h" 7 #include "x86.h" 8 #include "syscall.h" 9 10 // User code makes a system call with INT T_SYSCALL. 11 // System call number in %eax. 12 // Arguments on the stack, from the user call to the C 13 // library system call function. The saved user %esp points 14 // to a saved program counter, and then the first argument. 15 16 // Fetch the int at addr from the current process. 17 int 18 fetchint(uint addr, int *ip) 19 { 20 if(addr >= myproc()->sz || addr+4 > myproc()->sz) 21 return -1; 22 *ip = *(int*)(addr); 23 return 0; 24 } 25 26 // Fetch the nul-terminated string at addr from the current process. 27 // Doesn't actually copy the string - just sets *pp to point at it. 28 // Returns length of string, not including nul. 29 int 30 fetchstr(uint addr, char **pp) 31 { 32 char *s, *ep; 33 34 if(addr >= myproc()->sz) 35 return -1; 36 *pp = (char*)addr; 37 ep = (char*)myproc()->sz; 38 for(s = *pp; s < ep; s++){ 39 if(*s == 0) 40 return s - *pp; 41 } 42 return -1; 43 } 44 45 // Fetch the nth 32-bit system call argument. 46 int 47 argint(int n, int *ip) 48 { 49 return fetchint((myproc()->tf->esp) + 4 + 4*n, ip); 50 } 51 52 // Fetch the nth word-sized system call argument as a pointer 53 // to a block of memory of size bytes. Check that the pointer 54 // lies within the process address space. 55 int 56 argptr(int n, char **pp, int size) 57 { 58 int i; 59 60 if(argint(n, &i) < 0) 61 return -1; 62 if(size < 0 || (uint)i >= myproc()->sz || (uint)i+size > myproc()->sz) 63 return -1; 64 *pp = (char*)i; 65 return 0; 66 } 67 68 // Fetch the nth word-sized system call argument as a string pointer. 69 // Check that the pointer is valid and the string is nul-terminated. 70 // (There is no shared writable memory, so the string can't change 71 // between this check and being used by the kernel.) 72 int 73 argstr(int n, char **pp) 74 { 75 int addr; 76 if(argint(n, &addr) < 0) 77 return -1; 78 return fetchstr(addr, pp); 79 } 80 81 extern int sys_chdir(void); 82 extern int sys_close(void); 83 extern int sys_dup(void); 84 extern int sys_exec(void); 85 extern int sys_exit(void); 86 extern int sys_fork(void); 87 extern int sys_fstat(void); 88 extern int sys_getpid(void); 89 extern int sys_kill(void); 90 extern int sys_link(void); 91 extern int sys_mkdir(void); 92 extern int sys_mknod(void); 93 extern int sys_open(void); 94 extern int sys_pipe(void); 95 extern int sys_read(void); 96 extern int sys_sbrk(void); 97 extern int sys_sleep(void); 98 extern int sys_unlink(void); 99 extern int sys_wait(void); 100 extern int sys_write(void); 101 extern int sys_uptime(void); 102 103 static int (*syscalls[])(void) = { 104 [SYS_fork] sys_fork, 105 [SYS_exit] sys_exit, 106 [SYS_wait] sys_wait, 107 [SYS_pipe] sys_pipe, 108 [SYS_read] sys_read, 109 [SYS_kill] sys_kill, 110 [SYS_exec] sys_exec, 111 [SYS_fstat] sys_fstat, 112 [SYS_chdir] sys_chdir, 113 [SYS_dup] sys_dup, 114 [SYS_getpid] sys_getpid, 115 [SYS_sbrk] sys_sbrk, 116 [SYS_sleep] sys_sleep, 117 [SYS_uptime] sys_uptime, 118 [SYS_open] sys_open, 119 [SYS_write] sys_write, 120 [SYS_mknod] sys_mknod, 121 [SYS_unlink] sys_unlink, 122 [SYS_link] sys_link, 123 [SYS_mkdir] sys_mkdir, 124 [SYS_close] sys_close, 125 }; 126 127 void 128 syscall(void) 129 { 130 int num; 131 132 num = myproc()->tf->eax; 133 if(num > 0 && num < NELEM(syscalls) && syscalls[num]) { 134 myproc()->tf->eax = syscalls[num](); 135 } else { 136 cprintf("%d %s: unknown sys call %d\n", 137 myproc()->pid, myproc()->name, num); 138 myproc()->tf->eax = -1; 139 } 140 } 141