Xv6 with picoc & Linkage editor
v1.0
The project delineate mutual cohesion between c library, linkage editor ( linker), interpreter and operating system by porting the same on xv6 kernel
|
00001 #include "types.h" 00002 #include "defs.h" 00003 #include "param.h" 00004 #include "memlayout.h" 00005 #include "mmu.h" 00006 #include "proc.h" 00007 #include "x86.h" 00008 #include "syscall.h" 00009 00010 // User code makes a system call with INT T_SYSCALL. 00011 // System call number in %eax. 00012 // Arguments on the stack, from the user call to the C 00013 // library system call function. The saved user %esp points 00014 // to a saved program counter, and then the first argument. 00015 00016 // Fetch the int at addr from the current process. 00017 int 00018 fetchint(uint addr, int *ip) 00019 { 00020 if(addr >= proc->sz || addr+4 > proc->sz) 00021 return -1; 00022 *ip = *(int*)(addr); 00023 return 0; 00024 } 00025 00026 // Fetch the nul-terminated string at addr from the current process. 00027 // Doesn't actually copy the string - just sets *pp to point at it. 00028 // Returns length of string, not including nul. 00029 int 00030 fetchstr(uint addr, char **pp) 00031 { 00032 char *s, *ep; 00033 00034 if(addr >= proc->sz) 00035 return -1; 00036 *pp = (char*)addr; 00037 ep = (char*)proc->sz; 00038 for(s = *pp; s < ep; s++) 00039 if(*s == 0) 00040 return s - *pp; 00041 return -1; 00042 } 00043 00044 // Fetch the nth 32-bit system call argument. 00045 int 00046 argint(int n, int *ip) 00047 { 00048 return fetchint(proc->tf->esp + 4 + 4*n, ip); 00049 } 00050 00051 // Fetch the nth word-sized system call argument as a pointer 00052 // to a block of memory of size n bytes. Check that the pointer 00053 // lies within the process address space. 00054 int 00055 argptr(int n, char **pp, int size) 00056 { 00057 int i; 00058 00059 if(argint(n, &i) < 0) 00060 return -1; 00061 if((uint)i >= proc->sz || (uint)i+size > proc->sz) 00062 return -1; 00063 *pp = (char*)i; 00064 return 0; 00065 } 00066 00067 // Fetch the nth word-sized system call argument as a string pointer. 00068 // Check that the pointer is valid and the string is nul-terminated. 00069 // (There is no shared writable memory, so the string can't change 00070 // between this check and being used by the kernel.) 00071 int 00072 argstr(int n, char **pp) 00073 { 00074 int addr; 00075 if(argint(n, &addr) < 0) 00076 return -1; 00077 return fetchstr(addr, pp); 00078 } 00079 00080 extern int sys_chdir(void); 00081 extern int sys_close(void); 00082 extern int sys_dup(void); 00083 extern int sys_exec(void); 00084 extern int sys_exit(void); 00085 extern int sys_fork(void); 00086 extern int sys_fstat(void); 00087 extern int sys_getpid(void); 00088 extern int sys_kill(void); 00089 extern int sys_link(void); 00090 extern int sys_mkdir(void); 00091 extern int sys_mknod(void); 00092 extern int sys_open(void); 00093 extern int sys_pipe(void); 00094 extern int sys_read(void); 00095 extern int sys_sbrk(void); 00096 extern int sys_sleep(void); 00097 extern int sys_unlink(void); 00098 extern int sys_wait(void); 00099 extern int sys_write(void); 00100 extern int sys_uptime(void); 00101 extern int sys_old_mmap(void); 00102 extern int sys_execve(void); 00103 extern int sys_lseek(void); 00104 00105 static int (*syscalls[])(void) = { 00106 [SYS_fork] sys_fork, 00107 [SYS_exit] sys_exit, 00108 [SYS__exit] sys_exit, 00109 [SYS_wait] sys_wait, 00110 [SYS_pipe] sys_pipe, 00111 [SYS_read] sys_read, 00112 [SYS_kill] sys_kill, 00113 [SYS_exec] sys_exec, 00114 [SYS_execve] sys_exec, 00115 [SYS_fstat] sys_fstat, 00116 [SYS_chdir] sys_chdir, 00117 [SYS_dup] sys_dup, 00118 [SYS_getpid] sys_getpid, 00119 [SYS_sbrk] sys_sbrk, 00120 [SYS_sleep] sys_sleep, 00121 [SYS_uptime] sys_uptime, 00122 [SYS_open] sys_open, 00123 [SYS_write] sys_write, 00124 [SYS_mknod] sys_mknod, 00125 [SYS_unlink] sys_unlink, 00126 [SYS_link] sys_link, 00127 [SYS_mkdir] sys_mkdir, 00128 [SYS_close] sys_close, 00129 [SYS_mmap] sys_old_mmap, 00130 [SYS_lseek] sys_lseek, 00131 }; 00132 00133 void 00134 syscall(void) 00135 { 00136 int num; 00137 00138 num = proc->tf->eax; 00139 if(num >= 0 && num < SYS_open && syscalls[num]) { 00140 proc->tf->eax = syscalls[num](); 00141 } else if (num >= SYS_open && num < NELEM(syscalls) && syscalls[num]) { 00142 proc->tf->eax = syscalls[num](); 00143 } else { 00144 cprintf("%d %s: unknown sys call %d\n", 00145 proc->pid, proc->name, num); 00146 proc->tf->eax = -1; 00147 } 00148 }