Added magic breakpoint to SYS_CLONE, cleaned up other debug
[tpg/acess2.git] / Kernel / syscalls.c
1 /*
2  * AcessOS Microkernel Version
3  * syscalls.c
4  */
5 #define DEBUG   0
6
7 #include <common.h>
8 #include <syscalls.h>
9 #include <proc.h>
10 #include <errno.h>
11
12 // === IMPORTS ===
13 extern int      Proc_Clone(Uint *Err, Uint Flags);
14 extern int      Threads_WaitTID(int TID, int *status);
15 extern Uint     Proc_SendMessage(Uint *Err, Uint Dest, Uint Length, void *Data);
16 extern int      Proc_GetMessage(Uint *Err, Uint *Source, void *Buffer);
17 extern int      Proc_Execve(char *File, char **ArgV, char **EnvP);
18 extern Uint     Binary_Load(char *file, Uint *entryPoint);
19 extern int      VFS_FInfo(int FD, void *Dest, int MaxACLs);
20 extern int      VFS_GetACL(int FD, void *Dest);
21 extern int      VFS_ChDir(char *Dest);
22 extern int      Threads_SetName(char *NewName);
23 extern int      Threads_GetPID();
24 extern int      Threads_GetTID();
25 extern int      Threads_GetUID();
26 extern int      Threads_GetGID();
27
28 // === PROTOTYPES ===
29  int    Syscall_ValidString(Uint Addr);
30  int    Syscall_Valid(int Size, Uint Addr);
31
32 // === CODE ===
33 // TODO: Do sanity checking on arguments, ATM the user can really fuck with the kernel
34 void SyscallHandler(tSyscallRegs *Regs)
35 {
36         Uint64  ret = 0;
37         Uint    err = 0;
38         #if DEBUG
39         ENTER("iThread iNum", Threads_GetTID(), Regs->Num);
40         if(Regs->Num < NUM_SYSCALLS)
41                 LOG("Syscall %s", cSYSCALL_NAMES[Regs->Num]);
42         LOG("Arg1: 0x%x, Arg2: 0x%x, Arg3: 0x%x", Regs->Arg1, Regs->Arg2, Regs->Arg3);
43         #endif
44         
45         switch(Regs->Num)
46         {
47         // -- Exit the current thread
48         case SYS_EXIT:  Threads_Exit(); break;
49         
50         // -- Put the current thread to sleep
51         case SYS_SLEEP: Threads_Sleep();        break;
52         
53         // -- Yield current timeslice
54         case SYS_YIELD: Threads_Yield();        break;
55         
56         // -- Clone the current thread
57         case SYS_CLONE:
58                 // Call clone system call
59                 ret = Proc_Clone(&err, Regs->Arg1);
60                 Log("ret = %i", ret);
61                 __asm__ __volatile__("xchg %bx, %bx");
62                 // Change user stack if requested
63                 if(ret == 0 && !(Regs->Arg1 & CLONE_VM))
64                         Regs->StackPointer = Regs->Arg2;
65                 break;
66         
67         // -- Send a signal
68         case SYS_KILL:
69                 err = -ENOSYS;
70                 ret = -1;
71                 break;
72         
73         // -- Wait for a thread
74         case SYS_WAITTID:
75                 ret = Threads_WaitTID(Regs->Arg1, (void*)Regs->Arg2);
76                 break;
77         
78         // -- Get the physical address of a page
79         case SYS_GETPHYS:
80                 ret = MM_GetPhysAddr(Regs->Arg1);
81                 break;
82         
83         // -- Map an address
84         case SYS_MAP:   MM_Map(Regs->Arg1, Regs->Arg2); break;
85         
86         // -- Allocate an address
87         case SYS_ALLOCATE:      ret = MM_Allocate(Regs->Arg1);  break;
88         
89         // -- Unmap an address
90         case SYS_UNMAP:         MM_Deallocate(Regs->Arg1);      break;
91         
92         // -- Get Thread/Process IDs
93         case SYS_GETTID:        ret = Threads_GetTID(); break;
94         case SYS_GETPID:        ret = Threads_GetPID(); break;
95         
96         // -- Get User/Group IDs
97         case SYS_GETUID:        ret = Threads_GetUID(); break;
98         case SYS_GETGID:        ret = Threads_GetGID(); break;
99         
100         // -- Send Message
101         case SYS_SENDMSG:
102                 ret = Proc_SendMessage(&err, Regs->Arg1, Regs->Arg2, (void*)Regs->Arg3);
103                 break;
104         // -- Check for messages
105         case SYS_GETMSG:
106                 ret = Proc_GetMessage(&err, (Uint*)Regs->Arg1, (void*)Regs->Arg2);
107                 break;
108         
109         // -- Set the thread's name
110         case SYS_SETNAME:
111                 // Sanity Check
112                 if(!Regs->Arg1) {       ret = -1;       err = -EINVAL;  break;  }
113                 Threads_SetName( (void*)Regs->Arg1 );
114                 break;
115         
116         // ---
117         // Binary Control
118         // ---
119         case SYS_EXECVE:
120                 ret = Proc_Execve((char*)Regs->Arg1, (char**)Regs->Arg2, (char**)Regs->Arg3);
121                 break;
122         case SYS_LOADBIN:
123                 ret = Binary_Load((char*)Regs->Arg1, (Uint*)Regs->Arg2);
124                 break;
125         
126         // ---
127         // Virtual Filesystem
128         // ---
129         case SYS_OPEN:
130                 ret = VFS_Open((char*)Regs->Arg1, Regs->Arg2 | VFS_OPENFLAG_USER);
131                 break;
132         
133         case SYS_CLOSE:
134                 VFS_Close( Regs->Arg1 );
135                 break;
136         
137         case SYS_WRITE:
138                 #if BITS < 64
139                 VFS_Write( Regs->Arg1, Regs->Arg2|((Uint64)Regs->Arg3<<32), (void*)Regs->Arg4 );
140                 #else
141                 VFS_Write( Regs->Arg1, Regs->Arg2, (void*)Regs->Arg3 );
142                 #endif
143                 break;
144         
145         case SYS_READ:
146                 #if BITS < 64
147                 VFS_Read( Regs->Arg1, Regs->Arg2|((Uint64)Regs->Arg3<<32), (void*)Regs->Arg4 );
148                 #else
149                 VFS_Read( Regs->Arg1, Regs->Arg2, (void*)Regs->Arg3 );
150                 #endif
151                 break;
152         
153         case SYS_FINFO:
154                 ret = VFS_FInfo( Regs->Arg1, (void*)Regs->Arg2, Regs->Arg3 );
155                 break;
156         
157         // Get ACL Value
158         case SYS_GETACL:
159                 if( !Syscall_Valid(8, Regs->Arg1) ) {
160                         err = -EINVAL;
161                         ret = -1;
162                         break;
163                 }
164                 ret = VFS_GetACL( Regs->Arg1, (void*)Regs->Arg2 );
165                 break;
166         
167         // Read Directory
168         case SYS_READDIR:
169                 if( !Syscall_ValidString(Regs->Arg2) ) {
170                         err = -EINVAL;
171                         ret = -1;
172                         break;
173                 }
174                 ret = VFS_ReadDir( Regs->Arg1, (void*)Regs->Arg2 );
175                 break;
176         
177         // Change Directory
178         case SYS_CHDIR:
179                 if( !Syscall_ValidString(Regs->Arg1) ) {
180                         err = -EINVAL;
181                         ret = -1;
182                         break;
183                 }
184                 ret = VFS_ChDir( (void*)Regs->Arg1 );
185                 break;
186         
187         // -- Debug
188         case SYS_DEBUG:
189                 Log((char*)Regs->Arg1,
190                         Regs->Arg2, Regs->Arg3, Regs->Arg4, Regs->Arg5, Regs->Arg6);
191                 break;
192         
193         // -- Default (Return Error)
194         default:
195                 Warning("SyscallHandler: Unknown System Call %i", Regs->Num);
196                 if(Regs->Num < NUM_SYSCALLS)
197                         Warning(" Syscall '%s'", cSYSCALL_NAMES[Regs->Num]);
198                 err = -ENOSYS;
199                 ret = -1;
200                 break;
201         }
202         #if BITS < 64
203         Regs->Return = ret&0xFFFFFFFF;
204         Regs->RetHi = ret >> 32;
205         #else
206         Regs->Return = ret;
207         #endif
208         Regs->Error = err;
209         #if DEBUG
210         LOG("SyscallHandler: err = %i", err);
211         LEAVE('x', ret);
212         #endif
213 }
214
215 /**
216  * \fn int Syscall_ValidString(Uint Addr)
217  * \brief Checks if a memory address contains a valid string
218  */
219 int Syscall_ValidString(Uint Addr)
220 {
221         // Check 1st page
222         if(!MM_GetPhysAddr(Addr))       return 0;
223         
224         // Traverse String
225         while(*(char*)Addr)
226         {
227                 if(!MM_GetPhysAddr(Addr))       return 0;
228                 // Increment string pointer
229                 Addr ++;
230         }
231         
232         return 1;
233 }
234
235 /**
236  * \fn int Syscall_Valid(int Size, Uint Addr)
237  * \brief Checks if a memory address is valid
238  */
239 int Syscall_Valid(int Size, Uint Addr)
240 {
241         while(Size--)
242         {
243                 if(!MM_GetPhysAddr(Addr))       return 0;
244                 Addr ++;
245         }
246         return 1;
247 }

UCC git Repository :: git.ucc.asn.au