3 #define DONT_INCLUDE_SYSCALL_NAMES 1
4 #include "../../Usermode/include/acess/sys.h"
13 #include "../syscalls.h"
15 #define DEBUG(x...) printf(x)
17 #define NATIVE_FILE_MASK 0x40000000
23 extern int giSyscall_ClientID; // Needed for execve
26 FILE *gaSyscall_LocalFPs[MAX_FPS];
29 const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const char *ArgTypes, va_list *Args)
33 int direction = 0; // 0: Invalid, 1: Out, 2: In, 3: Out
38 while(*ArgTypes && *ArgTypes == ' ') ArgTypes ++;
39 if( *ArgTypes == '\0' ) return ArgTypes;
44 default: // Defaults to output
45 case '>': direction = 1; break;
46 case '<': direction = 2; break;
47 case '?': direction = 3; break;
52 while(*ArgTypes && *ArgTypes == ' ') ArgTypes ++;
53 if( *ArgTypes == '\0' ) return ArgTypes;
61 if( direction != 1 ) {
62 fprintf(stderr, "ReadEntry: Recieving an integer is not defined\n");
66 val32 = va_arg(*Args, uint32_t);
68 Dest->Type = ARG_TYPE_INT32;
69 Dest->Length = sizeof(uint32_t);
73 *(uint32_t*)DataDest = val32;
78 if( direction != 1 ) {
79 fprintf(stderr, "ReadEntry: Recieving an integer is not defined\n");
83 val64 = va_arg(*Args, uint64_t);
85 Dest->Type = ARG_TYPE_INT64;
86 Dest->Length = sizeof(uint64_t);
89 *(uint64_t*)DataDest = val64;
93 // Input string makes no sense!
94 if( direction != 1 ) {
95 fprintf(stderr, "ReadEntry: Recieving a string is not defined\n");
99 str = va_arg(*Args, char*);
101 Dest->Type = ARG_TYPE_STRING;
102 Dest->Length = strlen(str) + 1;
107 memcpy(DataDest, str, Dest->Length);
110 // Data (special handling)
112 len = va_arg(*Args, int);
113 str = va_arg(*Args, char*);
115 // Save the pointer for later
116 if( PtrDest ) *PtrDest = str;
118 // Create parameter block
119 Dest->Type = ARG_TYPE_DATA;
123 Dest->Flags |= ARG_FLAG_RETURN;
129 memcpy(DataDest, str, len);
132 Dest->Flags |= ARG_FLAG_ZEROED;
146 * Whitespace is ignored
147 * >i: Input Integer (32-bits)
148 * >I: Input Long Integer (64-bits)
150 * >d: Input Buffer (Preceded by valid size)
151 * <I: Output long integer
152 * <d: Output Buffer (Preceded by valid size)
153 * ?d: Bi-directional buffer (Preceded by valid size), buffer contents
156 uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...)
159 int paramCount, dataLength;
160 int retCount = 1, retLength = sizeof(uint64_t);
161 void **retPtrs; // Pointers to return buffers
169 // printf("&tRequestHeader->Params = %i\n", offsetof(tRequestHeader, Params));
170 // printf("&tRequestValue->Flags = %i\n", offsetof(tRequestValue, Flags));
171 // printf("&tRequestValue->Length = %i\n", offsetof(tRequestValue, Length));
174 va_start(args, ArgTypes);
180 tRequestValue tmpVal;
182 str = ReadEntry(&tmpVal, NULL, NULL, str, &args);
184 fprintf(stderr, "syscalls.c: ReadEntry failed (SyscallID = %i)\n", SyscallID);
188 if( !(tmpVal.Flags & ARG_FLAG_ZEROED) )
189 dataLength += tmpVal.Length;
191 if( tmpVal.Flags & ARG_FLAG_RETURN ) {
192 retLength += tmpVal.Length;
198 dataLength += sizeof(tRequestHeader) + paramCount*sizeof(tRequestValue);
199 retLength += sizeof(tRequestHeader) + retCount*sizeof(tRequestValue);
202 retPtrs = malloc( sizeof(void*) * (retCount+1) );
203 if( dataLength > retLength)
204 req = malloc( dataLength );
206 req = malloc( retLength );
207 req->ClientID = 0; //< Filled later
208 req->CallID = SyscallID;
209 req->NParams = paramCount;
210 dataPtr = &req->Params[paramCount];
212 // Fill `output` and `input`
213 va_start(args, ArgTypes);
215 // - re-zero so they can be used as indicies
220 str = ReadEntry(&req->Params[paramCount], dataPtr, &retPtrs[retCount], str, &args);
223 if( !(req->Params[paramCount].Flags & ARG_FLAG_ZEROED) )
224 dataPtr += req->Params[paramCount].Length;
225 if( req->Params[paramCount].Flags & ARG_FLAG_RETURN )
232 // Send syscall request
233 if( SendRequest(req, dataLength, retLength) < 0 ) {
234 fprintf(stderr, "syscalls.c: SendRequest failed (SyscallID = %i)\n", SyscallID);
238 // Parse return value
239 dataPtr = &req->Params[req->NParams];
241 if( req->NParams >= 1 )
243 switch(req->Params[0].Type)
246 retValue = *(uint64_t*)dataPtr;
247 dataPtr += req->Params[0].Length;
250 retValue = *(uint32_t*)dataPtr;
251 dataPtr += req->Params[0].Length;
256 // Write changes to buffers
258 for( i = 1; i < req->NParams; i ++ )
262 printf("Return Data %i: (%i)", i, req->Params[i].Length);
263 for( j = 0; j < req->Params[i].Length; j ++ )
264 printf(" %02x", ((uint8_t*)dataPtr)[j]);
267 memcpy( retPtrs[retCount++], dataPtr, req->Params[i].Length );
268 dataPtr += req->Params[i].Length;
274 printf("Return %llx\n", retValue);
280 int acess_open(const char *Path, int Flags)
282 if( strncmp(Path, "$$$$", 4) == 0 )
285 for(ret = 0; ret < MAX_FPS && gaSyscall_LocalFPs[ret]; ret ++ ) ;
286 if(ret == MAX_FPS) return -1;
287 // TODO: Handle directories
288 gaSyscall_LocalFPs[ret] = fopen(&Path[4], "r+");
289 if(!gaSyscall_LocalFPs[ret]) return -1;
290 return ret|NATIVE_FILE_MASK;
292 DEBUG("open(\"%s\", 0x%x)\n", Path, Flags);
293 return _Syscall(SYS_OPEN, ">s >i", Path, Flags);
296 void acess_close(int FD) {
297 if(FD & NATIVE_FILE_MASK) {
298 fclose( gaSyscall_LocalFPs[FD & (NATIVE_FILE_MASK-1)] );
299 gaSyscall_LocalFPs[FD & (NATIVE_FILE_MASK-1)] = NULL;
302 DEBUG("close(%i)\n", FD);
303 _Syscall(SYS_CLOSE, ">i", FD);
306 int acess_reopen(int FD, const char *Path, int Flags) {
307 DEBUG("reopen(0x%x, \"%s\", 0x%x)\n", FD, Path, Flags);
308 return _Syscall(SYS_REOPEN, ">i >s >i", FD, Path, Flags);
311 size_t acess_read(int FD, size_t Bytes, void *Dest) {
312 if(FD & NATIVE_FILE_MASK)
313 return fread( Dest, Bytes, 1, gaSyscall_LocalFPs[FD & (NATIVE_FILE_MASK-1)] );
314 DEBUG("read(0x%x, 0x%x, *%p)\n", FD, Bytes, Dest);
315 return _Syscall(SYS_READ, ">i >i <d", FD, Bytes, Bytes, Dest);
318 size_t acess_write(int FD, size_t Bytes, void *Src) {
319 if(FD & NATIVE_FILE_MASK)
320 return fwrite( Src, Bytes, 1, gaSyscall_LocalFPs[FD & (NATIVE_FILE_MASK-1)] );
321 DEBUG("write(0x%x, 0x%x, %p(\"%.*s\"))\n", FD, Bytes, Src, Bytes, (char*)Src);
322 return _Syscall(SYS_WRITE, ">i >i >d", FD, Bytes, Bytes, Src);
325 int acess_seek(int FD, int64_t Ofs, int Dir) {
326 if(FD & NATIVE_FILE_MASK) {
328 case ACESS_SEEK_SET: Dir = SEEK_SET; break;
330 case ACESS_SEEK_CUR: Dir = SEEK_CUR; break;
331 case ACESS_SEEK_END: Dir = SEEK_END; break;
333 return fseek( gaSyscall_LocalFPs[FD & (NATIVE_FILE_MASK-1)], Ofs, Dir );
335 DEBUG("seek(0x%x, 0x%llx, %i)\n", FD, Ofs, Dir);
336 return _Syscall(SYS_SEEK, ">i >I >i", FD, Ofs, Dir);
339 uint64_t acess_tell(int FD) {
340 if(FD & NATIVE_FILE_MASK)
341 return ftell( gaSyscall_LocalFPs[FD & (NATIVE_FILE_MASK-1)] );
342 return _Syscall(SYS_TELL, ">i", FD);
345 int acess_ioctl(int fd, int id, void *data) {
346 // NOTE: 1024 byte size is a hack
347 return _Syscall(SYS_IOCTL, ">i >i ?d", fd, id, 1024, data);
349 int acess_finfo(int fd, t_sysFInfo *info, int maxacls) {
350 return _Syscall(SYS_FINFO, ">i <d >i",
352 sizeof(t_sysFInfo)+maxacls*sizeof(t_sysACL), info,
356 int acess_readdir(int fd, char *dest) {
357 return _Syscall(SYS_READDIR, ">i <d", fd, 256, dest);
360 int acess__SysOpenChild(int fd, char *name, int flags) {
361 return _Syscall(SYS_OPENCHILD, ">i >s >i", fd, name, flags);
364 int acess__SysGetACL(int fd, t_sysACL *dest) {
365 return _Syscall(SYS_GETACL, "<i >i <d", fd, sizeof(t_sysACL), dest);
368 int acess__SysMount(const char *Device, const char *Directory, const char *Type, const char *Options) {
369 return _Syscall(SYS_MOUNT, ">s >s >s >s", Device, Directory, Type, Options);
374 int acess__SysSetFaultHandler(int (*Handler)(int)) {
378 // --- Memory Management ---
379 uint64_t acess__SysAllocate(uint vaddr)
381 if( AllocateMemory(vaddr, 0x1000) == -1 ) // Allocate a page
384 return vaddr; // Just ignore the need for paddrs :)
387 // --- Process Management ---
388 int acess_clone(int flags, void *stack)
390 extern int fork(void);
391 if(flags & CLONE_VM) {
392 int ret, newID, kernel_tid=0;
395 newID = _Syscall(SYS_FORK, "<i", &kernel_tid);
397 if(ret < 0) return ret;
401 giSyscall_ClientID = newID;
405 // TODO: Return the acess TID instead
410 fprintf(stderr, "ERROR: Threads currently unsupported\n");
415 int acess_execve(char *path, char **argv, char **envp)
419 printf("acess_execve: (path='%s', argv=%p, envp=%p)\n", path, argv, envp);
421 // Get argument count
422 for( argc = 0; argv[argc]; argc ++ ) ;
423 printf(" acess_execve: argc = %i\n", argc);
425 char *new_argv[5+argc+1];
427 sprintf(key, "%i", giSyscall_ClientID);
428 new_argv[0] = "ld-acess"; // TODO: Get path to ld-acess executable
429 new_argv[1] = "--key"; // Set socket/client ID for Request.c
431 new_argv[3] = "--binary"; // Set the binary path (instead of using argv[0])
433 for( i = 0; i < argc; i ++ ) new_argv[5+i] = argv[i];
434 new_argv[5+i] = NULL;
438 for( i = 0; i < argc; i ++ )
439 printf("\"%s\" ", new_argv[i]);
443 // Call actual execve
444 return execve("./ld-acess", new_argv, envp);
447 void acess_sleep(void)
449 _Syscall(SYS_SLEEP, "");
452 int acess_waittid(int TID, int *ExitStatus)
454 return _Syscall(SYS_WAITTID, ">i <i", TID, ExitStatus);
457 int acess_setuid(int ID)
459 return _Syscall(SYS_SETUID, ">i", ID);
462 int acess_setgid(int ID)
464 return _Syscall(SYS_SETGID, ">i", ID);
468 void acess__SysDebug(const char *Format, ...)
472 va_start(args, Format);
474 printf("[_SysDebug] ");
475 vprintf(Format, args);
481 void acess__exit(int Status)
483 _Syscall(SYS_EXIT, ">i", Status);
488 // === Symbol List ===
489 #define DEFSYM(name) {#name, acess_##name}
490 const tSym caBuiltinSymbols[] = {
503 DEFSYM(_SysOpenChild),
515 DEFSYM(_SysAllocate),
517 DEFSYM(_SysSetFaultHandler)
520 const int ciNumBuiltinSymbols = sizeof(caBuiltinSymbols)/sizeof(caBuiltinSymbols[0]);