syscall.c (7316B)
1 /* 2 * core/syscall.c 3 * 4 * Copyright (C) 2009 stateless 5 */ 6 7 #include <syscall.h> 8 #include <string.h> 9 #include <x86.h> 10 #include <common.h> 11 #include <tss.h> 12 #include <serial.h> 13 #include <rtc.h> 14 #include <mm.h> 15 #include <tty.h> 16 #include <errno.h> 17 #include <pipe.h> 18 19 extern int f_kdb; 20 21 static void __sys_write(struct trapframe_t *regs); 22 static void __sys_read(struct trapframe_t *regs); 23 static void __sys_exit(struct trapframe_t *regs); 24 static void __sys_fork(struct trapframe_t *regs); 25 static void __sys_waitpid(struct trapframe_t *regs); 26 static void __sys_reschedule(struct trapframe_t *regs); 27 static void __sys_open(struct trapframe_t *regs); 28 static void __sys_close(struct trapframe_t *regs); 29 static void __sys_creat(struct trapframe_t *regs); 30 static void __sys_execve(struct trapframe_t *regs); 31 static void __sys_isatty(struct trapframe_t *regs); 32 static void __sys_getpid(struct trapframe_t *regs); 33 static void __sys_getppid(struct trapframe_t *regs); 34 static void __sys_readdir(struct trapframe_t *regs); 35 static void __sys_dup(struct trapframe_t *regs); 36 static void __sys_dup2(struct trapframe_t *regs); 37 static void __sys_stat(struct trapframe_t *regs); 38 static void __sys_fstat(struct trapframe_t *regs); 39 static void __sys_seeder(struct trapframe_t *regs); 40 static void __sys_sbrk(struct trapframe_t *regs); 41 static void __sys_getuid(struct trapframe_t *regs); 42 static void __sys_setuid(struct trapframe_t *regs); 43 static void __sys_getgid(struct trapframe_t *regs); 44 static void __sys_setgid(struct trapframe_t *regs); 45 static void __sys_suspend_task(struct trapframe_t *regs); 46 static void __sys_resume_task(struct trapframe_t *regs); 47 static void __sys_pipe(struct trapframe_t *regs); 48 49 static void *syscall_table[SYSCALL_NR] = { 50 [__NR_exit] = &__sys_exit, 51 [__NR_fork] = &__sys_fork, 52 [__NR_read] = &__sys_read, 53 [__NR_write] = &__sys_write, 54 [__NR_waitpid] = &__sys_waitpid, 55 [__NR_reschedule] = &__sys_reschedule, 56 [__NR_open] = &__sys_open, 57 [__NR_close] = &__sys_close, 58 [__NR_creat] = &__sys_creat, 59 [__NR_execve] = &__sys_execve, 60 [__NR_isatty] = &__sys_isatty, 61 [__NR_getpid] = &__sys_getpid, 62 [__NR_getppid] = &__sys_getppid, 63 [__NR_readdir] = &__sys_readdir, 64 [__NR_dup] = &__sys_dup, 65 [__NR_dup2] = &__sys_dup2, 66 [__NR_stat] = &__sys_stat, 67 [__NR_fstat] = &__sys_fstat, 68 [__NR_seeder] = &__sys_seeder, 69 [__NR_sbrk] = &__sys_sbrk, 70 [__NR_getuid] = &__sys_getuid, 71 [__NR_setuid] = &__sys_setuid, 72 [__NR_getgid] = &__sys_getgid, 73 [__NR_setgid] = &__sys_setgid, 74 [__NR_suspend_task] = &__sys_suspend_task, 75 [__NR_resume_task] = &__sys_resume_task, 76 [__NR_pipe] = &__sys_pipe 77 }; 78 79 #ifdef BSYSCALL_TRACE 80 static const char *syscall_names[SYSCALL_NR] = { 81 [__NR_exit] = "sys_exit", 82 [__NR_fork] = "sys_fork", 83 [__NR_read] = "sys_read", 84 [__NR_write] = "sys_write", 85 [__NR_waitpid] = "sys_waitpid", 86 [__NR_reschedule] = "sys_reschedule", 87 [__NR_open] = "sys_open", 88 [__NR_close] = "sys_close", 89 [__NR_creat] = "sys_creat", 90 [__NR_execve] = "sys_execve", 91 [__NR_isatty] = "sys_isatty", 92 [__NR_getpid] = "sys_getpid", 93 [__NR_getppid] = "sys_getppid", 94 [__NR_readdir] = "sys_readdir", 95 [__NR_dup] = "sys_dup", 96 [__NR_dup2] = "sys_dup2", 97 [__NR_stat] = "sys_stat", 98 [__NR_fstat] = "sys_fstat", 99 [__NR_seeder] = "sys_seeder", 100 [__NR_sbrk] = "sys_sbrk", 101 [__NR_getuid] = "sys_getuid", 102 [__NR_setuid] = "sys_setuid", 103 [__NR_getgid] = "sys_getgid", 104 [__NR_setgid] = "sys_setgid", 105 [__NR_suspend_task] = "sys_suspend_task", 106 [__NR_resume_task] = "sys_resume_task", 107 [__NR_pipe] = "sys_pipe" 108 }; 109 #endif 110 111 static void 112 __sys_write(struct trapframe_t *regs) 113 { 114 regs->eax = (uint32_t)write((int)regs->ebx, (const void *)regs->ecx, (size_t)regs->edx); 115 } 116 117 static void 118 __sys_read(struct trapframe_t *regs) 119 { 120 regs->eax = (uint32_t)read((int)regs->ebx, (void *)regs->ecx, (size_t)regs->edx); 121 } 122 123 static void 124 __sys_exit(struct trapframe_t *regs) 125 { 126 if (!strcmp(curr_proc->name, "kdb")) { 127 unfreeze_tasks(); 128 f_kdb = 0; 129 } 130 curr_proc->state = TASK_ZOMBIE; 131 curr_proc->status = (int)regs->ebx; 132 attach_tty(curr_proc->parent); 133 tty_resume(); 134 closefds(); 135 remove_proc_mappings(); 136 schedule(); 137 } 138 139 static void 140 __sys_fork(struct trapframe_t *regs) 141 { 142 regs->eax = (uint32_t)fork(); 143 } 144 145 static void 146 __sys_waitpid(struct trapframe_t *regs) 147 { 148 regs->eax = (uint32_t)waitpid((pid_t)regs->ebx, (int *)regs->ecx, (int)regs->edx); 149 } 150 151 static void 152 __sys_reschedule(__attribute__ ((unused)) struct trapframe_t *regs) 153 { 154 schedule(); 155 } 156 157 static void 158 __sys_open(struct trapframe_t *regs) 159 { 160 regs->eax = (uint32_t)open((const char *)regs->ebx, (int)regs->ecx, (mode_t)regs->edx); 161 } 162 163 static void 164 __sys_close(struct trapframe_t *regs) 165 { 166 regs->eax = (uint32_t)close((int)regs->ebx); 167 } 168 169 static void 170 __sys_creat(struct trapframe_t *regs) 171 { 172 regs->eax = (int)creat((const char *)regs->ebx, (mode_t)regs->ecx); 173 } 174 175 static void 176 __sys_execve(__attribute__ ((unused)) struct trapframe_t *regs) 177 { 178 regs->eax = execve((const char *)regs->ebx, 0, 0); /* FIXME */ 179 } 180 181 static void 182 __sys_isatty(struct trapframe_t *regs) 183 { 184 regs->eax = 1; 185 } 186 187 static void 188 __sys_getpid(struct trapframe_t *regs) 189 { 190 regs->eax = (uint32_t)curr_proc->pid; 191 } 192 193 static void 194 __sys_getppid(struct trapframe_t *regs) 195 { 196 regs->eax = (!curr_proc->parent) ? 0 : (uint32_t)curr_proc->parent->pid; 197 } 198 199 static void 200 __sys_readdir(struct trapframe_t *regs) 201 { 202 /* I will probably need to change the prototype of readdir to not depend on DIR */ 203 regs->eax = (uint32_t)readdir((DIR *)regs->ebx); 204 } 205 206 static void 207 __sys_dup(struct trapframe_t *regs) 208 { 209 regs->eax = (uint32_t)dup((int)regs->ebx); 210 } 211 212 static void 213 __sys_dup2(struct trapframe_t *regs) 214 { 215 regs->eax = (uint32_t)dup2((int)regs->ebx, (int)regs->ecx); 216 } 217 218 static void 219 __sys_stat(struct trapframe_t *regs) 220 { 221 regs->eax = (uint32_t)stat((const char *)regs->ebx, (struct stat *)regs->ecx); 222 } 223 224 static void 225 __sys_fstat(struct trapframe_t *regs) 226 { 227 regs->eax = (uint32_t)fstat((int)regs->ebx, (struct stat *)regs->ecx); 228 } 229 230 static void 231 __sys_seeder(struct trapframe_t *regs) 232 { 233 regs->eax = systimer ^ (uint32_t)curr_proc; 234 } 235 236 static void 237 __sys_sbrk(struct trapframe_t *regs) 238 { 239 regs->eax = (uint32_t)sbrk((intptr_t)regs->ebx); 240 } 241 242 static void 243 __sys_getuid(struct trapframe_t *regs) 244 { 245 regs->eax = (uint32_t)getuid(); 246 } 247 248 static void 249 __sys_setuid(struct trapframe_t *regs) 250 { 251 regs->eax = (uint32_t)setuid((uid_t)regs->ebx); 252 } 253 254 static void 255 __sys_getgid(struct trapframe_t *regs) 256 { 257 regs->eax = (uint32_t)getgid(); 258 } 259 260 static void 261 __sys_setgid(struct trapframe_t *regs) 262 { 263 regs->eax = (uint32_t)setgid((uid_t)regs->ebx); 264 } 265 266 static void 267 __sys_suspend_task(struct trapframe_t *regs) 268 { 269 suspend_task((void *)regs->ebx); 270 } 271 272 static void 273 __sys_resume_task(struct trapframe_t *regs) 274 { 275 regs->eax = (uint32_t)resume_task((void *)regs->ebx); 276 } 277 278 static void 279 __sys_pipe(struct trapframe_t *regs) 280 { 281 regs->eax = (uint32_t)pipe((int *)regs->ebx); 282 } 283 284 void 285 syscall_dispatcher(struct trapframe_t *regs) 286 { 287 if (regs->eax > 0 && regs->eax < SYSCALL_NR && syscall_table[regs->eax]) { 288 if (curr_proc) { 289 TRACE_SYSCALL(serial_dump("tracing[%s with pid %d]: %s [eax = %08lx, ebx = %08lx, ecx = %08lx, edx = %08lx]\n", 290 curr_proc->name, curr_proc->pid, syscall_names[regs->eax], 291 regs->eax, regs->ebx, regs->ecx, regs->edx);) 292 } 293 void (*fp)(struct trapframe_t * regs) = (void (*)(struct trapframe_t *))syscall_table[regs->eax]; 294 fp(regs); 295 } else { 296 regs->eax = -ENOSYS; 297 } 298 } 299