-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsyscall.c
110 lines (96 loc) · 1.99 KB
/
syscall.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include "defs.h"
#include "proc.h"
#include "syscall.h"
extern struct proc *cp;
int
fetchint(uint32_t addr, uint32_t *ip)
{
//kprintf("fetchinit: addr: %h", addr);
//kprintf("fetchinit: cp->sz: %h", cp->sz);
//kprintf("fetchinit: cp->sz: %h", cp->tf->esp);
if(addr >= cp->sz || addr+4 > cp->sz) {
PANIC("fetchint");
return -1;
}
//kprintf("addr: %h", addr);
*ip = *(uint32_t*)(addr);
return 0;
}
int
fetchstr(uint32_t addr, char **pp)
{
char *s, *ep;
//kprintf("fetchstr: addr: %h", addr);
//kprintf("fetchstr: cp->sz: %h", cp->sz);
if(addr >= cp->sz) {
PANIC("fetchstr: addr > cp->sz");
return -1;
}
*pp = (char*)addr;
ep = (char*)cp->sz;
//kprintf("fetchstr: *pp",0);
fb_write(*pp);
for(s = *pp; s < ep; s++)
if(*s == 0)
return s - *pp;
PANIC("fetchstr");
return -1;
}
//
int argint(uint32_t n, uint32_t *ip)
{
fetchint(cp->tf->esp + 4 + 4*n, ip);
}
int
argptr(int n, char **pp, int size)
{
int i;
if(argint(n, &i) < 0)
return -1;
if((uint32_t)i >= cp->sz || (uint32_t)i+size > cp->sz)
return -1;
*pp = (char*)i;
return 0;
}
int
argstr(int n, char **pp)
{
int addr;
char *buf;
if(argint(n, &addr) < 0) {
PANIC("argstr: no arguments");
return -1;
}
return fetchstr(addr, pp);
}
// the actual sys call functions are found in sys_file, sys_proc and exec
extern int sys_write(void);
extern int sys_read();
extern int sys_exec(void);
extern int sys_fork(void);
extern int sys_sbrk(void);
extern int sys_wait(void);
extern int sys_exit(void);
// Syscall table
static int (*syscalls[])(void) = {
[SYS_write] sys_write,
[SYS_exec] sys_exec,
[SYS_fork] sys_fork,
[SYS_read] sys_read,
[SYS_sbrk] sys_sbrk,
[SYS_wait] sys_wait,
[SYS_exit] sys_exit
};
int syscall(void)
{
int num;
num = cp->tf->eax; // sys call number is stored here
if ( num > 0 && num < NELEM(syscalls) && syscalls[num] ) {
cp->tf->eax = syscalls[num]();
if(num == 1)
kprintf("syscall: eax: %d", cp->tf->eax);
} else {
kprintf("syscall: unhandled syscall.",0);
bbrk();
}
}