AcessNative - Hexdump sycall, stub shm
[tpg/acess2.git] / AcessNative / ld-acess_src / syscalls.c
index 5460956..965cc4a 100644 (file)
@@ -1,7 +1,6 @@
 /*
  */
 #define DONT_INCLUDE_SYSCALL_NAMES 1
-#include "../../Usermode/include/acess/sys.h"
 #include "common.h"
 #include <stdio.h>
 #include <stdlib.h>
@@ -9,18 +8,25 @@
 #include <stdarg.h>
 #include <string.h>
 #include <stddef.h>
+#include <unistd.h>
+#ifndef __WIN32__
+# include <spawn.h>    // posix_spawn
+#endif
 #include "request.h"
-#include "../syscalls.h"
 
-#define DEBUG(str, x...)       Debug(str, x)
+#define assert(cnd) do{ \
+       if( !(cnd) ) { \
+               fprintf(stderr, "%s:%i - assert failed - " #cnd"\n", __FILE__, __LINE__);\
+               exit(-1); \
+       } \
+}while(0)
 
-#define NATIVE_FILE_MASK       0x40000000
 #define        MAX_FPS 16
 
 // === Types ===
 
 // === IMPORTS ===
-extern int     giSyscall_ClientID;     // Needed for execve
+extern int     gbSyscallDebugEnabled;
 
 // === GLOBALS ===
 FILE   *gaSyscall_LocalFPs[MAX_FPS];
@@ -33,11 +39,13 @@ const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const
         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)
        {
@@ -109,7 +117,7 @@ const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const
                break;
        // Data (special handling)
        case 'd':
-               len = va_arg(*Args, int);
+               len = va_arg(*Args, size_t);
                str = va_arg(*Args, char*);
                
                // Save the pointer for later
@@ -117,7 +125,7 @@ const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const
                
                // Create parameter block
                Dest->Type = ARG_TYPE_DATA;
-               Dest->Length = len;
+               Dest->Length = str ? len : 0;
                Dest->Flags = 0;
                if( direction & 2 )
                        Dest->Flags |= ARG_FLAG_RETURN;
@@ -125,7 +133,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
@@ -157,13 +165,12 @@ 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;
        void    *dataPtr;
        uint64_t        retValue;
-        int    i;
        
        // DEBUG!
 //     printf("&tRequestHeader->Params = %i\n", offsetof(tRequestHeader, Params));
@@ -207,6 +214,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`
@@ -229,33 +237,36 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...)
        }
        va_end(args);
        
-       // Send syscall request
+       // --- 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;
-               }       
+       if( !(req->NParams >= 2) ) {
+               fprintf(stderr, "syscalls.c: Too few return params (%i)", req->NParams);
+               exit(127);
        }
+       dataPtr = (void*)&req->Params[req->NParams];
+       // 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
+       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 = 1; i < req->NParams; i ++ )
+       for( unsigned int i = 2; i < req->NParams; i ++ )
        {
                #if 0
                 int     j;
@@ -264,6 +275,7 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...)
                        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;
        }
@@ -271,289 +283,101 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...)
        free( req );
        free( retPtrs );
        
-       DEBUG(": %llx", retValue);
+       if( gbSyscallDebugEnabled ) {
+               SYSTRACE(": %i 0x%llx", SyscallID, retValue);
+       }
        
        return retValue;
 }
 
-// --- VFS Calls
-int acess_chdir(const char *Path)
+int native_int_getfd(void)
 {
-       return _Syscall(SYS_CHDIR, ">s", Path);
+       for(int ret = 0; ret < MAX_FPS; ret ++ )
+               if( gaSyscall_LocalFPs[ret] == NULL )
+                       return ret;
+       return -1;
 }
 
-int acess_open(const char *Path, int Flags)
+int native_open(const char *Path, int Flags)
 {
-       if( strncmp(Path, "$$$$", 4) == 0 )
-       {
-                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|NATIVE_FILE_MASK;
-       }
-       DEBUG("open(\"%s\", 0x%x)", Path, Flags);
-       return _Syscall(SYS_OPEN, ">s >i", Path, Flags);
+       int     ret = native_int_getfd();
+       if(ret == -1)   return -1;
+       // TODO: Handle directories
+       gaSyscall_LocalFPs[ret] = fopen(Path, "r+");
+       if(!gaSyscall_LocalFPs[ret])    return -1;
+       return ret;
 }
 
-void acess_close(int FD) {
-       if(FD & NATIVE_FILE_MASK) {
-               fclose( gaSyscall_LocalFPs[FD & (NATIVE_FILE_MASK-1)] );
-               gaSyscall_LocalFPs[FD & (NATIVE_FILE_MASK-1)] = NULL;
-               return ;
-       }
-       DEBUG("close(%i)", FD);
-       _Syscall(SYS_CLOSE, ">i", FD);
-}
-
-int acess_reopen(int FD, const char *Path, int Flags) {
-       DEBUG("reopen(0x%x, \"%s\", 0x%x)", FD, Path, Flags);
-       return _Syscall(SYS_REOPEN, ">i >s >i", FD, Path, Flags);
-}
-
-size_t acess_read(int FD, size_t Bytes, void *Dest) {
-       if(FD & NATIVE_FILE_MASK)
-               return fread( Dest, Bytes, 1, gaSyscall_LocalFPs[FD & (NATIVE_FILE_MASK-1)] );
-       DEBUG("read(0x%x, 0x%x, *%p)", FD, Bytes, Dest);
-       return _Syscall(SYS_READ, ">i >i <d", FD, Bytes, Bytes, Dest);
-}
-
-size_t acess_write(int FD, size_t Bytes, void *Src) {
-       if(FD & NATIVE_FILE_MASK)
-               return fwrite( Src, Bytes, 1, gaSyscall_LocalFPs[FD & (NATIVE_FILE_MASK-1)] );
-       DEBUG("write(0x%x, 0x%x, %p\"%.*s\")", FD, Bytes, Src, Bytes, (char*)Src);
-       return _Syscall(SYS_WRITE, ">i >i >d", FD, Bytes, Bytes, Src);
-}
-
-int acess_seek(int FD, int64_t Ofs, int Dir) {
-       if(FD & NATIVE_FILE_MASK) {
-               switch(Dir) {
-               case ACESS_SEEK_SET:    Dir = SEEK_SET; break;
-               default:
-               case ACESS_SEEK_CUR:    Dir = SEEK_CUR; break;
-               case ACESS_SEEK_END:    Dir = SEEK_END; break;
-               }
-               return fseek( gaSyscall_LocalFPs[FD & (NATIVE_FILE_MASK-1)], Ofs, Dir );
-       }
-       DEBUG("seek(0x%x, 0x%llx, %i)", FD, Ofs, Dir);
-       return _Syscall(SYS_SEEK, ">i >I >i", FD, Ofs, Dir);
-}
-
-uint64_t acess_tell(int FD) {
-       if(FD & NATIVE_FILE_MASK)
-               return ftell( gaSyscall_LocalFPs[FD & (NATIVE_FILE_MASK-1)] );
-       return _Syscall(SYS_TELL, ">i", FD);
-}
-
-int acess_ioctl(int fd, int id, void *data) {
-       // NOTE: 1024 byte size is a hack
-       DEBUG("ioctl(%i, %i, %p)", fd, id, data);
-       return _Syscall(SYS_IOCTL, ">i >i ?d", fd, id, 1024, data);
-}
-int acess_finfo(int fd, t_sysFInfo *info, int maxacls) {
-       return _Syscall(SYS_FINFO, ">i <d >i",
-               fd,
-               sizeof(t_sysFInfo)+maxacls*sizeof(t_sysACL), info,
-               maxacls);
-}
-
-int acess_readdir(int fd, char *dest) {
-       DEBUG("readdir(%i, %p)", fd, dest);
-       return _Syscall(SYS_READDIR, ">i <d", fd, 256, dest);
-}
-
-int acess_select(int nfds, fd_set *read, fd_set *write, fd_set *error, time_t *timeout)
+int native_shm(const char *Tag, int Flags)
 {
-       DEBUG("select(%i, %p, %p, %p, %p)", nfds, read, write, error, timeout);
-       return _Syscall(SYS_SELECT, ">i ?d ?d ?d >d", nfds,
-               read ? (nfds+7)/8 : 0, read,
-               write ? (nfds+7)/8 : 0, write,
-               error ? (nfds+7)/8 : 0, error,
-               sizeof(*timeout), timeout
-               );
+       // int ret = native_int_getfd();
+       //if(ret == -1) return -1;
+       //if( strcmp(Tag, "anon") == 0 )
+       //      path = "/AcessNative/anon/RAND";
+       //      FD = shm_open(path, O_RDWD);
+       //shm_unlink(path);
+       //else
+       //      path = "/Acessnative/named/<TAG>";
+       // int FD = shm_open(path, O_RDWD);
+       //shm_unlink(path);
+       //gaSyscall_LocalFPs[ret] = 
+       return -1;
 }
 
-int acess__SysOpenChild(int fd, char *name, int flags) {
-       return _Syscall(SYS_OPENCHILD, ">i >s >i", fd, name, flags);
-}
-
-int acess__SysGetACL(int fd, t_sysACL *dest) {
-       return _Syscall(SYS_GETACL, "<i >i <d", fd, sizeof(t_sysACL), dest);
-}
-
-int acess__SysMount(const char *Device, const char *Directory, const char *Type, const char *Options) {
-       return _Syscall(SYS_MOUNT, ">s >s >s >s", Device, Directory, Type, Options);
-}
-
-
-// --- Error Handler
-int    acess__SysSetFaultHandler(int (*Handler)(int)) {
-       printf("TODO: Set fault handler (asked to set to %p)\n", Handler);
-       return 0;
-}
-
-// --- Memory Management ---
-uint64_t acess__SysAllocate(uint vaddr)
+void native_close(int FD)
 {
-       if( AllocateMemory(vaddr, 0x1000) == -1 )       // Allocate a page
-               return 0;
-               
-       return vaddr;   // Just ignore the need for paddrs :)
+       fclose( gaSyscall_LocalFPs[FD] );
+       gaSyscall_LocalFPs[FD] = NULL;
 }
 
-// --- Process Management ---
-int acess_clone(int flags, void *stack)
+size_t native_read(int FD, void *Dest, size_t Bytes)
 {
-       extern int fork(void);
-       if(flags & CLONE_VM) {
-                int    ret, newID, kernel_tid=0;
-               printf("fork()");
-               
-               newID = _Syscall(SYS_FORK, "<d", sizeof(int), &kernel_tid);
-               ret = fork();
-               if(ret < 0)     return ret;
-               
-               if(ret == 0)
-               {
-                       giSyscall_ClientID = newID;
-                       return 0;
-               }
-               
-               // Return the acess TID instead
-               return kernel_tid;
-       }
-       else
-       {
-               fprintf(stderr, "ERROR: Threads currently unsupported\n");
-               exit(-1);
-       }
-}
-
-int acess_execve(char *path, char **argv, char **envp)
-{
-        int    i, argc;
-       
-       DEBUG("acess_execve: (path='%s', argv=%p, envp=%p)", path, argv, envp);
-       
-       // Get argument count
-       for( argc = 0; argv[argc]; argc ++ ) ;
-       DEBUG(" acess_execve: argc = %i", argc);
-       
-       char    *new_argv[5+argc+1];
-       char    key[11];
-       sprintf(key, "%i", giSyscall_ClientID);
-       new_argv[0] = "ld-acess";       // TODO: Get path to ld-acess executable
-       new_argv[1] = "--key";  // Set socket/client ID for Request.c
-       new_argv[2] = key;
-       new_argv[3] = "--binary";       // Set the binary path (instead of using argv[0])
-       new_argv[4] = path;
-       for( i = 0; i < argc; i ++ )    new_argv[5+i] = argv[i];
-       new_argv[5+i] = NULL;
-       
-       #if 1
-       argc += 5;
-       for( i = 0; i < argc; i ++ )
-               printf("\"%s\" ", new_argv[i]);
-       printf("\n");
-       #endif
-       
-       // Call actual execve
-       return execve("./ld-acess", new_argv, envp);
+       return fread( Dest, Bytes, 1, gaSyscall_LocalFPs[FD] );
 }
 
-void acess_sleep(void)
+size_t native_write(int FD, const void *Src, size_t Bytes)
 {
-       _Syscall(SYS_SLEEP, "");
+       return fwrite( Src, Bytes, 1, gaSyscall_LocalFPs[FD] );
 }
 
-int acess_waittid(int TID, int *ExitStatus)
+int native_seek(int FD, int64_t Ofs, int Dir)
 {
-       return _Syscall(SYS_WAITTID, ">i <d", TID, sizeof(int), &ExitStatus);
+       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 acess_setuid(int ID)
+uint64_t native_tell(int FD)
 {
-       return _Syscall(SYS_SETUID, ">i", ID);
+       return ftell( gaSyscall_LocalFPs[FD] );
 }
 
-int acess_setgid(int ID)
+int native_execve(const char *filename, const char *const argv[], const char *const envp[])
 {
-       return _Syscall(SYS_SETGID, ">i", ID);
+       int ret;
+       ret = execve(filename, (void*)argv, (void*)envp);
+       perror("native_execve");
+       return ret;
 }
 
-int acess_SysSendMessage(int DestTID, int Length, void *Data)
+int native_spawn(const char *filename, const char *const argv[], const char *const envp[])
 {
-       return _Syscall(SYS_SENDMSG, ">i >d", DestTID, Length, Data);
-}
+       int rv;
 
-int acess_SysGetMessage(int *SourceTID, void *Data)
-{
-       return _Syscall(SYS_GETMSG, "<d <d",
-               SourceTID ? sizeof(int) : 0, SourceTID,
-               Data ? 4096 : 0, Data
-               );
-}
+       fprintf(stderr, "native_spawn('%s')\n", filename);
 
-// --- Logging
-void acess__SysDebug(const char *Format, ...)
-{
-       va_list args;
-       
-       va_start(args, Format);
+       #if __WIN32__
+       rv = _spawnve(_P_NOWAIT, filename, argv, envp);
+       #else
+       rv = posix_spawn(NULL, filename, NULL, NULL, (void*)argv, (void*)envp);
+       #endif
        
-       printf("[_SysDebug %i]", giSyscall_ClientID);
-       vprintf(Format, args);
-       printf("\n");
+       if( rv == 0 ) {
+               perror("native_spawn");
+       }
        
-       va_end(args);
-}
-
-void acess__exit(int Status)
-{
-       DEBUG("_exit(%i)", Status);
-       _Syscall(SYS_EXIT, ">i", Status);
-       exit(Status);
+       return rv;
 }
-
-
-// === Symbol List ===
-#define DEFSYM(name)   {#name, acess_##name}
-const tSym     caBuiltinSymbols[] = {
-       DEFSYM(_exit),
-       
-       DEFSYM(chdir),
-       DEFSYM(open),
-       DEFSYM(close),
-       DEFSYM(reopen),
-       DEFSYM(read),
-       DEFSYM(write),
-       DEFSYM(seek),
-       DEFSYM(tell),
-       DEFSYM(ioctl),
-       DEFSYM(finfo),
-       DEFSYM(readdir),
-       DEFSYM(select),
-       DEFSYM(_SysOpenChild),
-       DEFSYM(_SysGetACL),
-       DEFSYM(_SysMount),
-       
-       DEFSYM(clone),
-       DEFSYM(execve),
-       DEFSYM(sleep),
-       
-       DEFSYM(waittid),
-       DEFSYM(setuid),
-       DEFSYM(setgid),
-
-       DEFSYM(SysSendMessage),
-       DEFSYM(SysGetMessage),
-       
-       DEFSYM(_SysAllocate),
-       DEFSYM(_SysDebug),
-       DEFSYM(_SysSetFaultHandler)
-};
-
-const int      ciNumBuiltinSymbols = sizeof(caBuiltinSymbols)/sizeof(caBuiltinSymbols[0]);
-

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