X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=AcessNative%2Fld-acess_src%2Fsyscalls.c;h=c649f28f600cc5c2880c7c6a7de75185acb14bb4;hb=c7acbe49842c871244d76ce9dd7e4e9e70ec3a97;hp=50352f8740b6148a9b0d53989179a0e1c61dc7c5;hpb=d599a063b3b453b705925c58180c93e1f9cb3d79;p=tpg%2Facess2.git diff --git a/AcessNative/ld-acess_src/syscalls.c b/AcessNative/ld-acess_src/syscalls.c index 50352f87..c649f28f 100644 --- a/AcessNative/ld-acess_src/syscalls.c +++ b/AcessNative/ld-acess_src/syscalls.c @@ -1,32 +1,56 @@ /* */ -#include "../../Usermode/include/acess/sys.h" +#define DONT_INCLUDE_SYSCALL_NAMES 1 #include "common.h" #include #include #include #include #include +#include +#include +#ifndef __WIN32__ +# include // posix_spawn +#endif #include "request.h" -#include "../syscalls.h" + +#if SYSCALL_TRACE +#define DEBUG(str, x...) Debug(str, x) +#else +#define DEBUG(...) do{}while(0) +#endif + +#define assert(cnd) do{ \ + if( !(cnd) ) { \ + fprintf(stderr, "%s:%i - assert failed - " #cnd, __FILE__, __LINE__);\ + exit(-1); \ + } \ +}while(0) + +#define MAX_FPS 16 // === Types === // === IMPORTS === +// === GLOBALS === +FILE *gaSyscall_LocalFPs[MAX_FPS]; + // === CODE === -const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const char *ArgTypes, va_list Args) +const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const char *ArgTypes, va_list *Args) { uint64_t val64; uint32_t val32; int direction = 0; // 0: Invalid, 1: Out, 2: In, 3: Out char *str; int len; - + // Eat whitespace while(*ArgTypes && *ArgTypes == ' ') ArgTypes ++; if( *ArgTypes == '\0' ) return ArgTypes; +// DEBUG("ArgTypes = '%s'", ArgTypes); + // Get direction switch(*ArgTypes) { @@ -48,11 +72,11 @@ const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const case 'i': if( direction != 1 ) { - fprintf(stderr, "ReadEntry: Recieving an integer is not defined\n"); + Warning("ReadEntry: Recieving an integer is not defined"); return NULL; } - val32 = va_arg(Args, uint32_t); + val32 = va_arg(*Args, uint32_t); Dest->Type = ARG_TYPE_INT32; Dest->Length = sizeof(uint32_t); @@ -69,7 +93,7 @@ const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const return NULL; } - val64 = va_arg(Args, uint64_t); + val64 = va_arg(*Args, uint64_t); Dest->Type = ARG_TYPE_INT64; Dest->Length = sizeof(uint64_t); @@ -85,7 +109,7 @@ const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const return NULL; } - str = va_arg(Args, char*); + str = va_arg(*Args, char*); Dest->Type = ARG_TYPE_STRING; Dest->Length = strlen(str) + 1; @@ -98,15 +122,15 @@ const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const break; // Data (special handling) case 'd': - len = va_arg(Args, int); - str = va_arg(Args, char*); + len = va_arg(*Args, size_t); + str = va_arg(*Args, char*); // Save the pointer for later if( PtrDest ) *PtrDest = str; // Create parameter block - Dest->Type = ARG_TYPE_INT64; - Dest->Length = sizeof(uint64_t); + Dest->Type = ARG_TYPE_DATA; + Dest->Length = str ? len : 0; Dest->Flags = 0; if( direction & 2 ) Dest->Flags |= ARG_FLAG_RETURN; @@ -114,7 +138,7 @@ const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const // Has data? if( direction & 1 ) { - if( DataDest ) + if( DataDest && str ) memcpy(DataDest, str, len); } else @@ -146,7 +170,7 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...) { va_list args; int paramCount, dataLength; - int retCount = 1, retLength = sizeof(uint64_t); + int retCount = 2, retLength = sizeof(uint64_t) + sizeof(uint32_t); void **retPtrs; // Pointers to return buffers const char *str; tRequestHeader *req; @@ -154,6 +178,11 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...) uint64_t retValue; int i; + // DEBUG! +// printf("&tRequestHeader->Params = %i\n", offsetof(tRequestHeader, Params)); +// printf("&tRequestValue->Flags = %i\n", offsetof(tRequestValue, Flags)); +// printf("&tRequestValue->Length = %i\n", offsetof(tRequestValue, Length)); + // Get data size va_start(args, ArgTypes); str = ArgTypes; @@ -163,7 +192,7 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...) { tRequestValue tmpVal; - str = ReadEntry(&tmpVal, NULL, NULL, str, args); + str = ReadEntry(&tmpVal, NULL, NULL, str, &args); if( !str ) { fprintf(stderr, "syscalls.c: ReadEntry failed (SyscallID = %i)\n", SyscallID); exit(127); @@ -191,6 +220,7 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...) req->ClientID = 0; //< Filled later req->CallID = SyscallID; req->NParams = paramCount; + req->MessageLength = dataLength; dataPtr = &req->Params[paramCount]; // Fill `output` and `input` @@ -201,7 +231,7 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...) retCount = 0; while(*str) { - str = ReadEntry(&req->Params[paramCount], dataPtr, &retPtrs[retCount], str, args); + str = ReadEntry(&req->Params[paramCount], dataPtr, &retPtrs[retCount], str, &args); if( !str ) break; if( !(req->Params[paramCount].Flags & ARG_FLAG_ZEROED) ) @@ -213,135 +243,114 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...) } va_end(args); - // Send syscall request - if( SendRequest(req, dataLength) ) { + // --- Send syscall request + if( SendRequest(req, dataLength, retLength) < 0 ) { fprintf(stderr, "syscalls.c: SendRequest failed (SyscallID = %i)\n", SyscallID); exit(127); } - // Parse return value - dataPtr = &req->Params[req->NParams]; - retValue = 0; - if( req->NParams > 1 ) - { - switch(req->Params[0].Type) - { - case ARG_TYPE_INT64: - retValue = *(uint64_t*)dataPtr; - dataPtr += req->Params[0].Length; - break; - case ARG_TYPE_INT32: - retValue = *(uint32_t*)dataPtr; - dataPtr += req->Params[0].Length; - break; - } - } + Debug("req->NParams = %i", req->NParams); + assert(req->NParams >= 2); + // return + assert(req->Params[0].Type == ARG_TYPE_INT64); + assert(req->Params[0].Length == sizeof(uint64_t)); + retValue = *(uint64_t*)dataPtr; + dataPtr += sizeof(uint64_t); + // errno + assert(req->Params[1].Type == ARG_TYPE_INT32); + assert(req->Params[1].Length == sizeof(uint32_t)); + acess__errno = *(uint32_t*)dataPtr; + dataPtr += sizeof(uint32_t); // Write changes to buffers - va_start(args, ArgTypes); - for( i = 1; i < req->NParams; i ++ ) + if( req->NParams - 2 != retCount ) { + fprintf(stderr, "syscalls.c: Return count inbalance (%i - 1 != exp %i) [Call %i]\n", + req->NParams, retCount, SyscallID); + exit(127); + } + retCount = 0; + for( i = 2; i < req->NParams; i ++ ) { - memcpy( retPtrs[i-1], dataPtr, req->Params[i].Length ); + #if 0 + int j; + printf("Return Data %i: (%i)", i, req->Params[i].Length); + for( j = 0; j < req->Params[i].Length; j ++ ) + printf(" %02x", ((uint8_t*)dataPtr)[j]); + printf("\n"); + #endif + assert( req->Params[i].Type == ARG_TYPE_DATA ); + memcpy( retPtrs[retCount++], dataPtr, req->Params[i].Length ); dataPtr += req->Params[i].Length; } - va_end(args); free( req ); + free( retPtrs ); - return 0; -} - -// --- VFS Calls -int open(const char *Path, int Flags) { - return _Syscall(SYS_OPEN, ">s >i", Path, Flags); -} - -void close(int FD) { - _Syscall(SYS_CLOSE, ">i", FD); -} - -size_t read(int FD, size_t Bytes, void *Dest) { - return _Syscall(SYS_READ, "i >i i >i >d", FD, Bytes, Bytes, Src); -} -int seek(int FD, int64_t Ofs, int Dir) { - return _Syscall(SYS_SEEK, ">i >I >i", FD, Ofs, Dir); +int native_open(const char *Path, int Flags) +{ + int ret; + for(ret = 0; ret < MAX_FPS && gaSyscall_LocalFPs[ret]; ret ++ ) ; + if(ret == MAX_FPS) return -1; + // TODO: Handle directories + gaSyscall_LocalFPs[ret] = fopen(&Path[4], "r+"); + if(!gaSyscall_LocalFPs[ret]) return -1; + return ret; } -uint64_t tell(int FD) { - return _Syscall(SYS_TELL, ">i", FD); +void native_close(int FD) +{ + fclose( gaSyscall_LocalFPs[FD] ); + gaSyscall_LocalFPs[FD] = NULL; } -int ioctl(int fd, int id, void *data) { - int ret = 0; - // NOTE: 1024 byte size is a hack - _Syscall(SYS_IOCTL, "i >i ?d", &ret, fd, id, 1024, data); - return ret; -} -int finfo(int fd, t_sysFInfo *info, int maxacls) { - int ret = 0; - _Syscall(SYS_FINFO, "i i", - &ret, fd, - sizeof(t_sysFInfo)+maxacls*sizeof(t_sysACL), info, - maxacls); - return ret; +size_t native_read(int FD, void *Dest, size_t Bytes) +{ + return fread( Dest, Bytes, 1, gaSyscall_LocalFPs[FD] ); } -int readdir(int fd, char *dest) { - int ret = 0; - _Syscall(SYS_READDIR, "i i >s >i", &ret, fd, name, flags); - return ret; +int native_seek(int FD, int64_t Ofs, int Dir) +{ + if(Dir == 0) + return fseek( gaSyscall_LocalFPs[FD], Ofs, SEEK_CUR ); + else if(Dir > 0) + return fseek( gaSyscall_LocalFPs[FD], Ofs, SEEK_SET ); + else + return fseek( gaSyscall_LocalFPs[FD], Ofs, SEEK_END ); } -int _SysGetACL(int fd, t_sysACL *dest) { - int ret = 0; - _Syscall(SYS_GETACL, "i s >s >s >s", &ret, Device, Directory, Type, Options); +int native_execve(const char *filename, const char *const argv[], const char *const envp[]) +{ + int ret; + ret = execve(filename, (void*)argv, (void*)envp); + perror("native_execve"); return ret; } - -// --- Error Handler -int _SysSetFaultHandler(int (*Handler)(int)) { - return 0; -} - - -// === Symbol List === -#define DEFSYM(name) {#name, name} -const tSym caBuiltinSymbols[] = { - {"_exit", exit}, +int native_spawn(const char *filename, const char *const argv[], const char *const envp[]) +{ + int rv; - DEFSYM(open), - DEFSYM(close), - DEFSYM(read), - DEFSYM(write), - DEFSYM(seek), - DEFSYM(tell), - DEFSYM(ioctl), - DEFSYM(finfo), - DEFSYM(readdir), - DEFSYM(_SysOpenChild), - DEFSYM(_SysGetACL), - DEFSYM(_SysMount), + #if __WIN32__ + rv = _spawnve(_P_NOWAIT, filename, argv, envp); + #else + rv = posix_spawn(NULL, filename, NULL, NULL, (void*)argv, (void*)envp); + #endif - {"_SysSetFaultHandler", _SysSetFaultHandler} -}; - -const int ciNumBuiltinSymbols = sizeof(caBuiltinSymbols)/sizeof(caBuiltinSymbols[0]); - + return rv; +}