From: John Hodge Date: Sat, 7 May 2011 10:05:04 +0000 (+0800) Subject: AcessNative - Huge changes, cleaning up and getting it to work X-Git-Tag: rel0.10~126 X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=7f80ab30017689efe0aaaab18abc7ceda689d859;p=tpg%2Facess2.git AcessNative - Huge changes, cleaning up and getting it to work - Restructure to the client IDs (now Acess PIDs) - Fixing up fork() behavior - Implemented waittid() - Fixed some bugs with video - Implemented NativeFS - Many other changes that I can't remember --- diff --git a/AcessNative/acesskernel_src/Makefile b/AcessNative/acesskernel_src/Makefile index c69cf066..1c92b476 100644 --- a/AcessNative/acesskernel_src/Makefile +++ b/AcessNative/acesskernel_src/Makefile @@ -7,8 +7,9 @@ endif KERNEL_SRC = ../../Kernel/ -KERNEL_OBJ := logging.o adt.o lib.o drvutil.o -KERNEL_OBJ += vfs/main.o vfs/open.o vfs/acls.o vfs/io.o vfs/dir.o vfs/nodecache.o vfs/mount.o vfs/memfile.o +KERNEL_OBJ := logging.o adt.o lib.o drvutil.o debug.o +KERNEL_OBJ += vfs/main.o vfs/open.o vfs/acls.o vfs/io.o vfs/dir.o +KERNEL_OBJ += vfs/nodecache.o vfs/mount.o vfs/memfile.o vfs/select.o KERNEL_OBJ += vfs/fs/root.o vfs/fs/devfs.o KERNEL_OBJ += drv/vterm.o drv/fifo.o drv/proc.o @@ -17,6 +18,8 @@ OBJ += video.o keyboard.o mouse.o nativefs.o vfs_handle.o ui_sdl.o OBJ += $(addprefix $(KERNEL_SRC),$(KERNEL_OBJ)) OBJ := $(addsuffix .$(PLATFORM),$(OBJ)) +DEPFILES = $(filter %.o.$(PLATFORM),$(OBJ)) +DEPFILES := $(DEPFILES:%.o.$(PLATFORM)=%.d.$(PLATFORM)) CPPFLAGS += -I include/ -I $(KERNEL_SRC)include/ CFLAGS += -Wall -g @@ -38,7 +41,10 @@ clean: $(RM) $(BIN) $(OBJ) $(BIN): $(OBJ) - $(CC) $(LDFLAGS) -o $@ $(OBJ) + @echo [LINK] -o $@ + @$(CC) $(LDFLAGS) -o $@ $(OBJ) %.o.$(PLATFORM): %.c - $(CC) -c $< -o $@ $(CFLAGS) $(CPPFLAGS) + @echo [CC] -o $@ + @$(CC) -c $< -o $@ $(CFLAGS) $(CPPFLAGS) + @$(CC) -M $(CPPFLAGS) -MT $@ -o $*.d.$(PLATFORM) $< diff --git a/AcessNative/acesskernel_src/helpers.c b/AcessNative/acesskernel_src/helpers.c index e598ef15..b08906c4 100644 --- a/AcessNative/acesskernel_src/helpers.c +++ b/AcessNative/acesskernel_src/helpers.c @@ -10,6 +10,7 @@ #include #include +#if 0 void LogF(const char *Fmt, ...) { va_list args; @@ -51,7 +52,25 @@ void Panic(const char *Format, ...) void Debug_SetKTerminal(const char *Path) { - // Ignored, kernel debug goes to stdout + // Ignored, kernel debug goes to stdout instead of a virtual terminal +} +#endif + +void KernelPanic_SetMode(void) +{ + // NOP - No need +} +void KernelPanic_PutChar(char ch) +{ + fprintf(stderr, "%c", ch); +} +void Debug_PutCharDebug(char ch) +{ + printf("%c", ch); +} +void Debug_PutStringDebug(const char *String) +{ + printf("%s", String); } void *Heap_Allocate(const char *File, int Line, int ByteCount) @@ -59,6 +78,21 @@ void *Heap_Allocate(const char *File, int Line, int ByteCount) return malloc(ByteCount); } +void *Heap_AllocateZero(const char *File, int Line, int ByteCount) +{ + return calloc(ByteCount, 1); +} + +void *Heap_Reallocate(const char *File, int Line, void *Ptr, int Bytes) +{ + return realloc(Ptr, Bytes); +} + +void Heap_Deallocate(void *Ptr) +{ + free(Ptr); +} + tPAddr MM_GetPhysAddr(tVAddr VAddr) { return VAddr; // HACK! diff --git a/AcessNative/acesskernel_src/include/arch.h b/AcessNative/acesskernel_src/include/arch.h index a6685b2d..849eba82 100644 --- a/AcessNative/acesskernel_src/include/arch.h +++ b/AcessNative/acesskernel_src/include/arch.h @@ -28,10 +28,10 @@ typedef intptr_t tPAddr; typedef int BOOL; -typedef uint32_t tTID; -typedef uint32_t tPID; -typedef uint32_t tUID; -typedef uint32_t tGID; +//typedef uint32_t tTID; +//typedef uint32_t tPID; +//typedef uint32_t tUID; +//typedef uint32_t tGID; struct sShortSpinlock { @@ -42,7 +42,7 @@ struct sShortSpinlock #define SHORTLOCK(...) #define SHORTREL(...) -#define NUM_CFG_ENTRIES 10 +//#define NUM_CFG_ENTRIES 10 #endif diff --git a/AcessNative/acesskernel_src/include/heap.h b/AcessNative/acesskernel_src/include/heap.h index 9315142e..287250ca 100644 --- a/AcessNative/acesskernel_src/include/heap.h +++ b/AcessNative/acesskernel_src/include/heap.h @@ -6,5 +6,18 @@ // NOP (stdlib.h defines the heap functions) // Heap_Allocate is used in _strdup extern void *Heap_Allocate(const char *File, int Line, int ByteCount); +extern void *Heap_AllocateZero(const char *File, int Line, size_t Bytes); +extern void *Heap_Reallocate(const char *File, int Line, void *Ptr, size_t Bytes); +extern void Heap_Deallocate(void *Ptr); +extern int Heap_IsHeapAddr(void *Ptr); +extern void Heap_Validate(void); + +#define malloc(size) Heap_Allocate(_MODULE_NAME_"/"__FILE__, __LINE__, (size)) +#define calloc(num,size) Heap_AllocateZero(_MODULE_NAME_"/"__FILE__, __LINE__, (num)*(size)) +#define realloc(ptr,size) Heap_Reallocate(_MODULE_NAME_"/"__FILE__, __LINE__, (ptr), (size)) +#define free(ptr) Heap_Deallocate((ptr)) +#define IsHeap(ptr) Heap_IsHeapAddr((ptr)) + +#define strdup(Str) _strdup(_MODULE_NAME_"/"__FILE__, __LINE__, (Str)) #endif diff --git a/AcessNative/acesskernel_src/keyboard.c b/AcessNative/acesskernel_src/keyboard.c index 76894831..86f37874 100644 --- a/AcessNative/acesskernel_src/keyboard.c +++ b/AcessNative/acesskernel_src/keyboard.c @@ -35,7 +35,7 @@ int NativeKeyboard_Install(char **Arguments) return MODULE_ERR_OK; } -static const char * const csaIOCTL_NAMES[] = { +static const char * csaIOCTL_NAMES[] = { DRV_IOCTLNAMES, DRV_KEYBAORD_IOCTLNAMES, NULL diff --git a/AcessNative/acesskernel_src/main.c b/AcessNative/acesskernel_src/main.c index 3f152efa..363fea1f 100644 --- a/AcessNative/acesskernel_src/main.c +++ b/AcessNative/acesskernel_src/main.c @@ -13,21 +13,26 @@ extern int VFS_Init(void); extern int Video_Install(char **Arguments); extern int NativeKeyboard_Install(char **Arguments); extern int VT_Install(char **Arguments); +extern int VFS_Mount(const char *Device, const char *MountPoint, const char *Filesystem, const char *Options); extern int SyscallServer(void); +// === GLOBALS === +const char *gsAcessDir = "../Usermode/Output/i386"; + // === CODE === int main(int argc, char *argv[]) { // Parse command line settings // Start UI subsystem - UI_Initialise(640, 480); + UI_Initialise(800, 480); // Initialise VFS VFS_Init(); // - Start IO Drivers Video_Install(NULL); NativeKeyboard_Install(NULL); + NativeFS_Install(NULL); // - Start VTerm { char *args[] = { @@ -38,6 +43,10 @@ int main(int argc, char *argv[]) VT_Install(args); } + VFS_Mount(gsAcessDir, "/Acess", "nativefs", ""); + + Debug_SetKTerminal("/Devices/VTerm/8"); + // Start syscall server // - Blocks SyscallServer(); diff --git a/AcessNative/acesskernel_src/nativefs.c b/AcessNative/acesskernel_src/nativefs.c index 71774e23..6d6e2fed 100644 --- a/AcessNative/acesskernel_src/nativefs.c +++ b/AcessNative/acesskernel_src/nativefs.c @@ -5,13 +5,156 @@ * nativefs.c * - Host filesystem access */ -#include -#include +#define DEBUG 1 +#include // Acess +#include // Acess +#include // Posix +#include // Posix +#include // Posix + +//NOTES: +// tVFS_Node->ImplPtr is a pointer to the filesystem flags (tNativeFS) +// tVFS_Node->Data is the path string (heap string) +// tVFS_Node->ImplInt is the path length + +// === STRUCTURES === +typedef struct +{ + int InodeHandle; + int bReadOnly; +} tNativeFS; + +// === PROTOTYPES === + int NativeFS_Install(char **Arguments); +tVFS_Node *NativeFS_Mount(const char *Device, const char **Arguments); +void NativeFS_Unmount(tVFS_Node *Node); +tVFS_Node *NativeFS_FindDir(tVFS_Node *Node, const char *Name); +char *NativeFS_ReadDir(tVFS_Node *Node, int Position); +Uint64 NativeFS_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer); // === GLOBALS === +tVFS_Driver gNativeFS_Driver = { + "nativefs", 0, + NativeFS_Mount, NativeFS_Unmount, + NULL, +}; // === CODE === -tVFS_Node *Native_Mount(const char *Device, const char **Arguments) +int NativeFS_Install(char **Arguments) +{ + VFS_AddDriver(&gNativeFS_Driver); + return 0; +} + +tVFS_Node *NativeFS_Mount(const char *Device, const char **Arguments) +{ + tVFS_Node *ret; + tNativeFS *info; + DIR *dp; + + dp = opendir(Device); + if(!dp) return NULL; + + // Check if directory exists + // Parse flags from arguments + info = malloc(sizeof(tNativeFS)); + info->InodeHandle = Inode_GetHandle(); + info->bReadOnly = 0; + // Create node + ret = malloc(sizeof(tVFS_Node)); + memset(ret, 0, sizeof(tVFS_Node)); + ret->Data = strdup(Device); + ret->ImplInt = strlen(ret->Data); + ret->ImplPtr = info; + ret->Inode = (Uint64)dp; + + ret->FindDir = NativeFS_FindDir; + ret->ReadDir = NativeFS_ReadDir; + + return ret; +} + +void NativeFS_Unmount(tVFS_Node *Node) { + tNativeFS *info = Node->ImplPtr; + Inode_ClearCache( info->InodeHandle ); + closedir( (void *)Node->Inode ); + free(Node->Data); + free(Node); + free(info); +} + +void NativeFS_Close(tVFS_Node *Node) +{ + tNativeFS *info = Node->ImplPtr; + Inode_UncacheNode( info->InodeHandle, Node->Inode ); +} + +tVFS_Node *NativeFS_FindDir(tVFS_Node *Node, const char *Name) +{ + char *path = malloc(Node->ImplInt + 1 + strlen(Name) + 1); + tNativeFS *info = Node->ImplPtr; + tVFS_Node baseRet; + struct stat statbuf; + + ENTER("pNode sName", Node, Name); + + // Create path + strcpy(path, Node->Data); + path[Node->ImplInt] = '/'; + strcpy(path + Node->ImplInt + 1, Name); + + LOG("path = '%s'", path); + + // Check if file exists + if( stat(path, &statbuf) ) { + free(path); + LOG("Doesn't exist"); + LEAVE('n'); + return NULL; + } + + memset(&baseRet, 0, sizeof(tVFS_Node)); + + // Check file type + if( S_ISDIR(statbuf.st_mode) ) + { + LOG("Directory"); + baseRet.Inode = (Uint64) opendir(path); + baseRet.FindDir = NativeFS_FindDir; + baseRet.ReadDir = NativeFS_ReadDir; + baseRet.Flags |= VFS_FFLAG_DIRECTORY; + } + else + { + LOG("File"); + baseRet.Inode = (Uint64) fopen(path, "r+"); + baseRet.Read = NativeFS_Read; + } + + // Create new node + baseRet.ImplPtr = info; + baseRet.ImplInt = strlen(path); + baseRet.Data = path; + + LEAVE('-'); + return Inode_CacheNode(info->InodeHandle, &baseRet); +} + +char *NativeFS_ReadDir(tVFS_Node *Node, int Position) +{ + // Keep track of the current directory position return NULL; } + +Uint64 NativeFS_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) +{ + ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer); + if( fseek( (void *)Node->Inode, Offset, SEEK_SET ) != 0 ) + { + LEAVE('i', 0); + return 0; + } + LEAVE('-'); + return fread( Buffer, 1, Length, (void *)Node->Inode ); +} diff --git a/AcessNative/acesskernel_src/server.c b/AcessNative/acesskernel_src/server.c index 5d46f200..725a326b 100644 --- a/AcessNative/acesskernel_src/server.c +++ b/AcessNative/acesskernel_src/server.c @@ -17,6 +17,7 @@ # include #endif #include "../syscalls.h" +//#include #define USE_TCP 0 #define MAX_CLIENTS 16 @@ -36,6 +37,10 @@ typedef struct { // === IMPORTS === extern tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength); +extern int Threads_CreateRootProcess(void); +// HACK: Should have these in a header +extern void Log_Debug(const char *Subsys, const char *Message, ...); +extern void Log_Notice(const char *Subsys, const char *Message, ...); // === PROTOTYPES === tClient *Server_GetClient(int ClientID); @@ -50,7 +55,6 @@ SOCKET gSocket = INVALID_SOCKET; # define INVALID_SOCKET -1 int gSocket = INVALID_SOCKET; #endif - int giServer_NextClientID = 1; tClient gaServer_Clients[MAX_CLIENTS]; // === CODE === @@ -75,12 +79,17 @@ tClient *Server_GetClient(int ClientID) tClient *ret = NULL; int i; + // Allocate an ID if needed + if(ClientID == 0) + ClientID = Threads_CreateRootProcess(); + for( i = 0; i < MAX_CLIENTS; i ++ ) { if( gaServer_Clients[i].ClientID == ClientID ) { - ret = &gaServer_Clients[i]; - break; + return &gaServer_Clients[i]; } + if(!ret && gaServer_Clients[i].ClientID == 0) + ret = &gaServer_Clients[i]; } // Uh oh, no free slots @@ -88,20 +97,18 @@ tClient *Server_GetClient(int ClientID) if( !ret ) return NULL; - if( ClientID == 0 ) - { - ret->ClientID = giServer_NextClientID ++; - ret->CurrentRequest = NULL; + // Allocate a thread for the process + ret->ClientID = ClientID; + ret->CurrentRequest = NULL; - if( !ret->WorkerThread ) { - ret->WaitFlag = SDL_CreateCond(); - ret->Mutex = SDL_CreateMutex(); - SDL_mutexP( ret->Mutex ); - ret->WorkerThread = SDL_CreateThread( Server_WorkerThread, ret ); - } + if( !ret->WorkerThread ) { + ret->WaitFlag = SDL_CreateCond(); + ret->Mutex = SDL_CreateMutex(); + SDL_mutexP( ret->Mutex ); + ret->WorkerThread = SDL_CreateThread( Server_WorkerThread, ret ); } - return &gaServer_Clients[i]; + return ret; } int Server_WorkerThread(void *ClientPtr) @@ -120,14 +127,15 @@ int Server_WorkerThread(void *ClientPtr) while( Client->CurrentRequest == NULL ) SDL_CondWait(Client->WaitFlag, Client->Mutex); - printf("Worker for %i, Job: %p\n", Client->ClientID, Client->CurrentRequest); + Log_Debug("AcessSrv", "Worker %i takes %p", + Client->ClientID, Client->CurrentRequest); // Get the response retHeader = SyscallRecieve(Client->CurrentRequest, &retSize); if( !retHeader ) { // Return an error to the client - printf("Error returned by SyscallRecieve\n"); + printf("ERROR: SyscallRecieve failed\n"); errorHeader.CallID = Client->CurrentRequest->CallID; errorHeader.NParams = 0; retHeader = &errorHeader; @@ -140,9 +148,10 @@ int Server_WorkerThread(void *ClientPtr) // Mark the thread as ready for another job Client->CurrentRequest = 0; - printf("Sending %i to %x:%i\n", + Log_Debug("AcessSrv", "Sending %i to %x:%i (Client %i)", retSize, ntohl(Client->ClientAddr.sin_addr.s_addr), - ntohs(Client->ClientAddr.sin_port) + ntohs(Client->ClientAddr.sin_port), + Client->ClientID ); // Return the data @@ -213,7 +222,7 @@ int SyscallServer(void) listen(gSocket, 5); #endif - Log_Notice("Syscall", "Listening on 0.0.0.0:%i\n", SERVER_PORT); + Log_Notice("AcessSrv", "Listening on 0.0.0.0:%i", SERVER_PORT); // Wait for something to do :) for( ;; ) @@ -227,7 +236,7 @@ int SyscallServer(void) break ; } - printf("Client connection %x:%i", + Log("Client connection %x:%i\n", ntohl(client.sin_addr), ntohs(client.sin_port) ); @@ -269,7 +278,8 @@ int SyscallServer(void) continue; } - printf("client = %p, ClientID = %i\n", client, client->ClientID); + Log_Debug("AcessSrv", "Message from Client %i (%p)", + client->ClientID, client); client->CurrentRequest = req; SDL_CondSignal(client->WaitFlag); diff --git a/AcessNative/acesskernel_src/syscalls.c b/AcessNative/acesskernel_src/syscalls.c index eb9d8a2d..f48b1a98 100644 --- a/AcessNative/acesskernel_src/syscalls.c +++ b/AcessNative/acesskernel_src/syscalls.c @@ -5,13 +5,27 @@ * Syscall Distribution */ #include +#include #include "../syscalls.h" +// === IMPORTS === +extern int Threads_Fork(void); // AcessNative only function + // === TYPES === -typedef int (*tSyscallHandler)(const char *Format, void *Args, int *Sizes); +typedef int (*tSyscallHandler)(Uint *Errno, const char *Format, void *Args, int *Sizes); // === MACROS === -#define SYSCALL3(_name, _fmtstr, _t0, _t1, _t2, _call) int _name(const char*Fmt,void*Args,int*Sizes){\ +#define SYSCALL4(_name, _fmtstr, _t0, _t1, _t2, _t3, _call) int _name(Uint*Errno,const char*Fmt,void*Args,int*Sizes){\ + _t0 a0;_t1 a1;_t2 a2;_t3 a3;\ + if(strcmp(Fmt,_fmtstr)!=0)return 0;\ + a0 = *(_t0*)Args;Args+=sizeof(_t0);\ + a1 = *(_t1*)Args;Args+=sizeof(_t1);\ + a2 = *(_t2*)Args;Args+=sizeof(_t2);\ + a3 = *(_t3*)Args;Args+=sizeof(_t3);\ + _call\ +} + +#define SYSCALL3(_name, _fmtstr, _t0, _t1, _t2, _call) int _name(Uint*Errno,const char*Fmt,void*Args,int*Sizes){\ _t0 a0;_t1 a1;_t2 a2;\ if(strcmp(Fmt,_fmtstr)!=0)return 0;\ a0 = *(_t0*)Args;Args+=sizeof(_t0);\ @@ -20,7 +34,7 @@ typedef int (*tSyscallHandler)(const char *Format, void *Args, int *Sizes); _call\ } -#define SYSCALL2(_name, _fmtstr, _t0, _t1, _call) int _name(const char*Fmt,void*Args,int*Sizes){\ +#define SYSCALL2(_name, _fmtstr, _t0, _t1, _call) int _name(Uint*Errno,const char*Fmt,void*Args,int*Sizes){\ _t0 a0;_t1 a1;\ if(strcmp(Fmt,_fmtstr)!=0)return 0;\ a0 = *(_t0*)Args;Args+=sizeof(_t0);\ @@ -28,19 +42,29 @@ typedef int (*tSyscallHandler)(const char *Format, void *Args, int *Sizes); _call;\ } -#define SYSCALL1(_name, _fmtstr, _t0, _call) int _name(const char*Fmt, void*Args,int*Sizes){\ +#define SYSCALL1(_name, _fmtstr, _t0, _call) int _name(Uint*Errno,const char*Fmt, void*Args,int*Sizes){\ _t0 a0;\ if(strcmp(Fmt,_fmtstr)!=0)return 0;\ a0 = *(_t0*)Args;Args+=sizeof(_t0);\ _call;\ } +#define SYSCALL0(_name, _call) int _name(Uint*Errno,const char*Fmt, void*Args,int*Sizes){\ + if(strcmp(Fmt,"")!=0)return 0;\ + _call;\ +} + // === CODE === -int Syscall_Null(const char *Format, void *Args, int *Sizes) +int Syscall_Null(Uint*Errno, const char *Format, void *Args, int *Sizes) { return 0; } +SYSCALL1(Syscall_Exit, "i", int, + Threads_Exit(0, a0); + return 0; +); + SYSCALL2(Syscall_Open, "si", const char *, int, return VFS_Open(a0, a1|VFS_OPENFLAG_USER); ); @@ -49,12 +73,12 @@ SYSCALL1(Syscall_Close, "i", int, return 0; ); SYSCALL3(Syscall_Read, "iid", int, int, void *, - if( Sizes[2] <= a1 ) + if( Sizes[2] < a1 ) return -1; return VFS_Read(a0, a1, a2); ); SYSCALL3(Syscall_Write, "iid", int, int, const void *, - if( Sizes[2] <= a1 ) + if( Sizes[2] < a1 ) return -1; return VFS_Write(a0, a1, a2); ); @@ -72,10 +96,53 @@ SYSCALL3(Syscall_FInfo, "idi", int, void *, int, return -1; return VFS_FInfo(a0, a1, a2); ); +SYSCALL2(Syscall_ReadDir, "id", int, char *, + if(Sizes[1] < 255) + return -1; + return VFS_ReadDir(a0, a1); +); +SYSCALL3(Syscall_OpenChild, "isi", int, const char *, int, + return VFS_OpenChild(NULL, a0, a1, a2|VFS_OPENFLAG_USER); +); +SYSCALL2(Syscall_GetACL, "id", int, void *, + if(Sizes[1] < sizeof(tVFS_ACL)) + return -1; + return VFS_GetACL(a0, (void*)a1); +); +SYSCALL4(Syscall_Mount, "ssss", const char *, const char *, const char *, const char *, + return VFS_Mount(a0, a1, a2, a3); +); +SYSCALL0(Syscall_Sleep, + Threads_Sleep(); + return 0; +); +SYSCALL2(Syscall_WaitTID, "id", int, int *, + if(Sizes[1] < sizeof(int)) + return -1; + return Threads_WaitTID(a0, a1); +); +SYSCALL1(Syscall_SetUID, "i", int, + if(Sizes[0] < sizeof(int)) { + *Errno = -EINVAL; // TODO: Better message + return -1; + } + return Threads_SetUID(Errno, a0); +); +SYSCALL1(Syscall_SetGID, "i", int, + if(Sizes[0] < sizeof(int)) { + *Errno = -EINVAL; // TODO: Better message + return -1; + } + return Threads_SetGID(Errno, a0); +); +SYSCALL0(Syscall_Fork, + return Threads_Fork(); +); const tSyscallHandler caSyscalls[] = { Syscall_Null, + Syscall_Exit, Syscall_Open, Syscall_Close, Syscall_Read, @@ -83,7 +150,19 @@ const tSyscallHandler caSyscalls[] = { Syscall_Seek, Syscall_Tell, Syscall_IOCtl, - Syscall_FInfo + Syscall_FInfo, + Syscall_ReadDir, + Syscall_OpenChild, + Syscall_GetACL, + Syscall_Mount, + NULL, // SYS_REOPEN + + Syscall_WaitTID, + Syscall_SetUID, + Syscall_SetGID, + + Syscall_Sleep, + Syscall_Fork }; const int ciNumSyscalls = sizeof(caSyscalls)/sizeof(caSyscalls[0]); /** @@ -100,6 +179,7 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength) int retDataLen = sizeof(Uint64); void *returnData[Request->NParams]; int argSizes[Request->NParams]; + Uint ret_errno = 0; // Sanity check if( Request->CallID >= ciNumSyscalls ) { @@ -107,6 +187,11 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength) return NULL; } + if( !caSyscalls[Request->CallID] ) { + Log_Notice("Syscalls", "Unimplemented syscall %i", Request->CallID); + return NULL; + } + // Get size of argument list for( i = 0; i < Request->NParams; i ++ ) { @@ -138,7 +223,7 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength) } formatString[i] = '\0'; - Log_Debug("Syscalls", "Request %i '%s'", Request->CallID, formatString); + LOG("Request %i(%s) '%s'", Request->CallID, casSYSCALL_NAMES[Request->CallID], formatString); { char argListData[argListLen]; @@ -152,19 +237,19 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength) case ARG_TYPE_VOID: break; case ARG_TYPE_INT32: - Log_Debug("Syscalls", "Arg %i: 0x%x", i, *(Uint32*)inData); + LOG("Syscalls", "%i INT32: 0x%x", i, *(Uint32*)inData); *(Uint32*)&argListData[argListLen] = *(Uint32*)inData; argListLen += sizeof(Uint32); inData += sizeof(Uint32); break; case ARG_TYPE_INT64: - Log_Debug("Syscalls", "Arg %i: 0x%llx", i, *(Uint64*)inData); + LOG("Syscalls", "%i INT64: 0x%llx", i, *(Uint64*)inData); *(Uint64*)&argListData[argListLen] = *(Uint64*)inData; argListLen += sizeof(Uint64); inData += sizeof(Uint64); break; case ARG_TYPE_STRING: - Log_Debug("Syscalls", "Arg %i: '%s'", i, (char*)inData); + LOG("Syscalls", "%i STR: '%s'", i, (char*)inData); *(char**)&argListData[argListLen] = (char*)inData; argListLen += sizeof(void*); inData += Request->Params[i].Length; @@ -185,7 +270,7 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength) { // Allocate and zero the buffer returnData[i] = calloc(1, Request->Params[i].Length); - Log_Debug("Syscalls", "Arg %i: %i %p", i, + LOG("Syscalls", "%i ZDAT: %i %p", i, Request->Params[i].Length, returnData[i]); *(void**)&argListData[argListLen] = returnData[i]; argListLen += sizeof(void*); @@ -193,7 +278,7 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength) else { returnData[i] = (void*)inData; - Log_Debug("Syscalls", "Arg %i: %i %p", i, + LOG("Syscalls", "%i DATA: %i %p", i, Request->Params[i].Length, returnData[i]); *(void**)&argListData[argListLen] = (void*)inData; argListLen += sizeof(void*); @@ -203,7 +288,7 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength) } } - retVal = caSyscalls[Request->CallID](formatString, argListData, argSizes); + retVal = caSyscalls[Request->CallID](&ret_errno, formatString, argListData, argSizes); } // Allocate the return @@ -221,22 +306,27 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength) *(Uint64*)inData = retVal; inData += sizeof(Uint64); - Log_Debug("Syscalls", "Return 0x%llx", retVal); + LOG("Syscalls", "Return 0x%llx", retVal); + retValueCount = 1; for( i = 0; i < Request->NParams; i ++ ) { if( Request->Params[i].Type != ARG_TYPE_DATA ) continue; if( !(Request->Params[i].Flags & ARG_FLAG_RETURN) ) continue; - ret->Params[1 + i].Type = Request->Params[i].Type; - ret->Params[1 + i].Flags = 0; - ret->Params[1 + i].Length = Request->Params[i].Length; + ret->Params[retValueCount].Type = Request->Params[i].Type; + ret->Params[retValueCount].Flags = 0; + ret->Params[retValueCount].Length = Request->Params[i].Length; + + LOG("Syscalls", "Ret %i: Type %i, Len %i", + i, Request->Params[i].Type, Request->Params[i].Length); memcpy(inData, returnData[i], Request->Params[i].Length); inData += Request->Params[i].Length; if( Request->Params[i].Flags & ARG_FLAG_ZEROED ) free( returnData[i] ); // Free temp buffer from above + retValueCount ++; } *ReturnLength = sizeof(tRequestHeader) diff --git a/AcessNative/acesskernel_src/threads.c b/AcessNative/acesskernel_src/threads.c index 5a0ce131..9d125178 100644 --- a/AcessNative/acesskernel_src/threads.c +++ b/AcessNative/acesskernel_src/threads.c @@ -5,13 +5,23 @@ * threads.c * - Thread and process handling */ -#define _SIGNAL_H_ +#define _SIGNAL_H_ // Stop the acess signal.h being used +#define _HEAP_H_ // Stop heap.h being imported (collides with stdlib heap) +#define _VFS_EXT_H // Stop vfs_ext.h being imported (collides with fd_set) #undef CLONE_VM // Such a hack #include +#undef NULL // Remove acess definition +#include +#include +#include #include #include #include #include "/usr/include/signal.h" +#include + +// === IMPORTS === +void VFS_CloneHandleList(int PID); // === STRUCTURES === #if 0 @@ -24,6 +34,7 @@ typedef struct sState typedef struct sThread { + struct sThread *GlobalNext; struct sThread *Next; int KernelTID; @@ -36,27 +47,55 @@ typedef struct sThread char *ThreadName; int State; // 0: Dead, 1: Active, 2: Paused, 3: Asleep + int ExitStatus; #if 0 tState CurState; #endif + // Threads waiting for this thread to exit. + // Quit logic: + // - Wait for `WaitingThreads` to be non-null (maybe?) + // - Wake first in the queue, wait for it to be removed + // - Repeat + // - Free thread and quit kernel thread + struct sThread *WaitingThreads; + struct sThread *WaitingThreadsEnd; + // Config? Uint Config[NUM_CFG_ENTRIES]; } tThread; +// === PROTOTYPES === + int Threads_Wake(tThread *Thread); + // === GLOBALS === -tThread gThread_Zero = { +tThread gThreadZero = { State: 1, ThreadName: "ThreadZero" }; -tThread *gpThreads = &gThread_Zero; -__thread tThread *gpCurrentThread = &gThread_Zero; +tThread *gpThreads = &gThreadZero; +__thread tThread *gpCurrentThread = &gThreadZero; + int giThreads_NextThreadID = 1; // === CODE === +void Threads_Dump(void) +{ + tThread *thread; + for( thread = gpThreads; thread; thread = thread->GlobalNext ) + { + Log_Log("Threads", "TID %i (%s), PID %i", + thread->TID, thread->ThreadName, thread->PID); + Log_Log("Threads", "User: %i, Group: %i", + thread->UID, thread->GID); + Log_Log("Threads", "Kernel Thread ID: %i", + thread->KernelTID); + } +} + tThread *Threads_GetThread(int TID) { tThread *thread; - for( thread = gpThreads; thread; thread = thread->Next ) + for( thread = gpThreads; thread; thread = thread->GlobalNext ) { if( thread->TID == TID ) return thread; @@ -64,12 +103,55 @@ tThread *Threads_GetThread(int TID) return NULL; } +/** + * \brief Clone a thread control block (with a different TID) + */ +tThread *Threads_CloneTCB(tThread *TemplateThread) +{ + tThread *ret = malloc(sizeof(tThread)); + + memcpy(ret, TemplateThread, sizeof(tThread)); + + ret->TID = giThreads_NextThreadID ++; + + ret->ThreadName = strdup(TemplateThread->ThreadName); + + ret->WaitingThreads = NULL; + ret->WaitingThreadsEnd = NULL; + + // Add to the end of the queue + // TODO: Handle concurrency issues + ret->GlobalNext = gpThreads; + gpThreads = ret; + + return ret; +} + tUID Threads_GetUID() { return gpCurrentThread->UID; } tGID Threads_GetGID() { return gpCurrentThread->GID; } tTID Threads_GetTID() { return gpCurrentThread->TID; } -tPID Threads_GetPID() { - return SDL_ThreadID(); - //return gpCurrentThread->PID; +tPID Threads_GetPID() { return gpCurrentThread->PID; } + +int Threads_SetUID(int *Errno, tUID NewUID) +{ + if(Threads_GetUID() != 0) { + if(Errno) *Errno = -EACCES; + return -1; + } + + gpCurrentThread->UID = NewUID; + return 0; +} + +int Threads_SetGID(int *Errno, tGID NewGID) +{ + if(Threads_GetUID() != 0) { + if(Errno) *Errno = -EACCES; + return -1; + } + + gpCurrentThread->GID = NewGID; + return 0; } Uint *Threads_GetCfgPtr(int Index) @@ -81,8 +163,62 @@ Uint *Threads_GetCfgPtr(int Index) return &gpCurrentThread->Config[Index]; } +int Threads_WaitTID(int TID, int *Status) +{ + // Any Child + if(TID == -1) { + Log_Error("Threads", "TODO: Threads_WaitTID(TID=-1) - Any Child"); + return -1; + } + + // Any peer/child thread + if(TID == 0) { + Log_Error("Threads", "TODO: Threads_WaitTID(TID=0) - Any Child/Sibling"); + return -1; + } + + // TGID = abs(TID) + if(TID < -1) { + Log_Error("Threads", "TODO: Threads_WaitTID(TID<0) - TGID"); + return -1; + } + + // Specific Thread + if(TID > 0) { + + tThread *thread = Threads_GetThread(TID); + tThread *us = gpCurrentThread; + if(!thread) return -1; + + us->Next = NULL; + us->State = 3; + if(thread->WaitingThreadsEnd) + { + thread->WaitingThreadsEnd->Next = us; + thread->WaitingThreadsEnd = us; + } + else + { + thread->WaitingThreads = us; + thread->WaitingThreadsEnd = us; + } + + while(thread->State != 0) + pause(); + + if(Status) *Status = thread->ExitStatus; + thread->WaitingThreads = thread->WaitingThreads->Next; + us->Next = NULL; + + return TID; + } + + return 0; +} + void Threads_Sleep(void) { + // TODO: Add to a sleeping queue pause(); } @@ -91,22 +227,70 @@ void Threads_Yield(void) // yield(); } +void Threads_Exit(int TID, int Status) +{ + tThread *toWake; + +// VFS_Handles_Cleanup(); + + #if 1 + // Wait for the thread to be waited upon + while( gpCurrentThread->WaitingThreads == NULL ) + SDL_Delay(10); + #endif + + while( (toWake = gpCurrentThread->WaitingThreads) ) + { + Threads_Wake(toWake); + + while(gpCurrentThread->WaitingThreads == toWake) + SDL_Delay(10); + } +} + +int Threads_Wake(tThread *Thread) +{ + kill( Thread->KernelTID, SIGUSR1 ); + return 0; +} + int Threads_WakeTID(tTID TID) { tThread *thread; thread = Threads_GetThread(TID); if( !thread ) return -1; - kill( thread->KernelTID, SIGUSR1 ); - return 0; + return Threads_Wake(thread); +} + +int Threads_CreateRootProcess(void) +{ + tThread *thread = Threads_CloneTCB(&gThreadZero); + thread->PID = thread->TID; + + // Handle list is created on first open + + return thread->PID; +} + +int Threads_Fork(void) +{ + tThread *thread = Threads_CloneTCB(gpCurrentThread); + thread->PID = thread->TID; + // Duplicate the VFS handles (and nodes) from vfs_handle.c + + VFS_CloneHandleList(thread->PID); + + return thread->PID; } -void Mutex_Acquire(tMutex *Mutex) +int Mutex_Acquire(tMutex *Mutex) { if(!Mutex->Protector.IsValid) { pthread_mutex_init( &Mutex->Protector.Mutex, NULL ); Mutex->Protector.IsValid = 1; } pthread_mutex_lock( &Mutex->Protector.Mutex ); + return 0; } void Mutex_Release(tMutex *Mutex) @@ -114,6 +298,27 @@ void Mutex_Release(tMutex *Mutex) pthread_mutex_unlock( &Mutex->Protector.Mutex ); } +void Semaphore_Init(tSemaphore *Sem, int InitValue, int MaxValue, const char *Module, const char *Name) +{ + memset(Sem, 0, sizeof(tSemaphore)); + // HACK: Use `Sem->Protector` as space for the semaphore pointer + *(void**)(&Sem->Protector) = SDL_CreateSemaphore(InitValue); +} + +int Semaphore_Wait(tSemaphore *Sem, int MaxToTake) +{ + SDL_SemWait( *(void**)(&Sem->Protector) ); + return 1; +} + +int Semaphore_Signal(tSemaphore *Sem, int AmmountToAdd) +{ + int i; + for( i = 0; i < AmmountToAdd; i ++ ) + SDL_SemPost( *(void**)(&Sem->Protector) ); + return AmmountToAdd; +} + #if 0 void Threads_Sleep() { diff --git a/AcessNative/acesskernel_src/ui_sdl.c b/AcessNative/acesskernel_src/ui_sdl.c index 546021a6..3f3cb139 100644 --- a/AcessNative/acesskernel_src/ui_sdl.c +++ b/AcessNative/acesskernel_src/ui_sdl.c @@ -39,6 +39,9 @@ int UI_Initialise(int MaxWidth, int MaxHeight) // Start main thread gInputThread = SDL_CreateThread(UI_MainThread, NULL); + while(gScreen == NULL) + SDL_Delay(10); + return 0; } @@ -152,15 +155,21 @@ void UI_BlitBitmap(int DstX, int DstY, int SrcW, int SrcH, Uint32 *Bitmap) SDL_Surface *tmp; SDL_Rect dstRect; +// printf("UI_BlitBitmap: Blit to (%i,%i) from %p (%ix%i 32bpp bitmap)\n", +// DstX, DstY, Bitmap, SrcW, SrcH); + tmp = SDL_CreateRGBSurfaceFrom(Bitmap, SrcW, SrcH, 32, SrcW*4, 0xFF0000, 0x00FF00, 0x0000FF, 0xFF000000); SDL_SetAlpha(tmp, 0, SDL_ALPHA_OPAQUE); dstRect.x = DstX; dstRect.y = DstY; + dstRect.w = -1; dstRect.h = -1; SDL_BlitSurface(tmp, NULL, gScreen, &dstRect); + //SDL_BlitSurface(tmp, NULL, gScreen, NULL); SDL_FreeSurface(tmp); +// SDL_Flip(gScreen); } void UI_BlitFramebuffer(int DstX, int DstY, int SrcX, int SrcY, int W, int H) @@ -182,10 +191,12 @@ void UI_FillBitmap(int X, int Y, int W, int H, Uint32 Value) dstRect.x = X; dstRect.y = Y; dstRect.w = W; dstRect.h = H; +// printf("UI_FillBitmap: gScreen = %p\n", gScreen); SDL_FillRect(gScreen, &dstRect, Value); } void UI_Redraw(void) { - // No-Op, we're not using double buffering + // TODO: Keep track of changed rectangle + SDL_UpdateRect(gScreen, 0, 0, giUI_Width, giUI_Height); } diff --git a/AcessNative/acesskernel_src/vfs_handle.c b/AcessNative/acesskernel_src/vfs_handle.c index 5a94e6d3..91caeffe 100644 --- a/AcessNative/acesskernel_src/vfs_handle.c +++ b/AcessNative/acesskernel_src/vfs_handle.c @@ -2,11 +2,11 @@ * Acess2 VFS * - AllocHandle, GetHandle */ -#define DEBUG 0 +#define DEBUG 1 #include -#include "vfs.h" -#include "vfs_int.h" -#include "vfs_ext.h" +#include +#include +#include // === CONSTANTS === #define MAX_KERNEL_FILES 128 @@ -32,6 +32,59 @@ tUserHandles *gpUserHandles = NULL; tVFS_Handle gaKernelHandles[MAX_KERNEL_FILES]; // === CODE === +tUserHandles *VFS_int_GetUserHandles(int PID, int bCreate) +{ + tUserHandles *ent, *prev = NULL; + for( ent = gpUserHandles; ent; prev = ent, ent = ent->Next ) { + if( ent->PID == PID ) { + Log_Warning("VFS", "Process %i already has a handle list", PID); + return ent; + } + if( ent->PID > PID ) break; + } + + if(!bCreate) + return NULL; + + ent = calloc( 1, sizeof(tUserHandles) ); + ent->PID = PID; + if( prev ) { + ent->Next = prev->Next; + prev->Next = ent; + } + else { + ent->Next = gpUserHandles; + gpUserHandles = ent; + } + Log_Notice("VFS", "Created handle list for process %i", PID); + return ent; +} + +/** + * \brief Clone the handle list of the current process into another + */ +void VFS_CloneHandleList(int PID) +{ + tUserHandles *ent; + tUserHandles *cur; + int i; + + cur = VFS_int_GetUserHandles(Threads_GetPID(), 0); + if(!cur) return ; // Don't need to do anything if the current list is empty + + ent = VFS_int_GetUserHandles(PID, 1); + + memcpy(ent->Handles, cur->Handles, CFGINT(CFG_VFS_MAXFILES)*sizeof(tVFS_Handle)); + + for( i = 0; i < CFGINT(CFG_VFS_MAXFILES); i ++ ) + { + if(!cur->Handles[i].Node) continue; + + if(ent->Handles[i].Node->Reference) + ent->Handles[i].Node->Reference(ent->Handles[i].Node); + } +} + /** * \fn tVFS_Handle *VFS_GetHandle(int FD) * \brief Gets a pointer to the handle information structure @@ -42,32 +95,42 @@ tVFS_Handle *VFS_GetHandle(int FD) //Log_Debug("VFS", "VFS_GetHandle: (FD=0x%x)", FD); - if(FD < 0) return NULL; + if(FD < 0) { + LOG("FD (%i) < 0, RETURN NULL", FD); + return NULL; + } if(FD & VFS_KERNEL_FLAG) { FD &= (VFS_KERNEL_FLAG - 1); - if(FD >= MAX_KERNEL_FILES) return NULL; + if(FD >= MAX_KERNEL_FILES) { + LOG("FD (%i) > MAX_KERNEL_FILES (%i), RETURN NULL", FD, MAX_KERNEL_FILES); + return NULL; + } h = &gaKernelHandles[ FD ]; } - else { + else + { tUserHandles *ent; - int pid = Server_GetClientID(); - for( ent = gpUserHandles; ent; ent = ent->Next ) { - if( ent->PID == pid ) break; - if( ent->PID > pid ) { - Log_Error("VFS", "PID %i does not have a handle list", pid); - return NULL; - } + int pid = Threads_GetPID(); + + ent = VFS_int_GetUserHandles(pid, 0); + if(!ent) { + Log_Error("VFS", "Client %i does not have a handle list (>)", pid); + return NULL; } - if( !ent ) { - Log_Error("VFS", "PID %i does not have a handle list", pid); + + if(FD >= CFGINT(CFG_VFS_MAXFILES)) { + LOG("FD (%i) > Limit (%i), RETURN NULL", FD, CFGINT(CFG_VFS_MAXFILES)); return NULL; } - if(FD >= CFGINT(CFG_VFS_MAXFILES)) return NULL; h = &ent->Handles[ FD ]; + LOG("FD (%i) -> %p (Mode:0x%x,Node:%p)", FD, h, h->Mode, h->Node); } - if(h->Node == NULL) return NULL; + if(h->Node == NULL) { + LOG("FD (%i) Unused", FD); + return NULL; + } //Log_Debug("VFS", "VFS_GetHandle: RETURN %p", h); return h; } @@ -79,24 +142,9 @@ int VFS_AllocHandle(int bIsUser, tVFS_Node *Node, int Mode) // Check for a user open if(bIsUser) { - tUserHandles *ent, *prev = NULL; - int pid = Server_GetClientID(); - for( ent = gpUserHandles; ent; prev = ent, ent = ent->Next ) { - if( ent->PID == pid ) break; - if( ent->PID > pid ) break; - } - if( !ent || ent->PID > pid ) { - ent = calloc( 1, sizeof(tUserHandles) ); - ent->PID = pid; - if( prev ) { - ent->Next = prev->Next; - prev->Next = ent; - } - else { - ent->Next = gpUserHandles; - gpUserHandles = ent; - } - } + tUserHandles *ent; + // Find the PID's handle list + ent = VFS_int_GetUserHandles(Threads_GetPID(), 1); // Get a handle for(i=0;i #include #include @@ -90,6 +91,8 @@ Uint64 Video_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) // Sanity Check if( Offset > (Uint64)(heightInChars*widthInChars) ) { + Log_Notice("Video", "Offset (%i) > %i*%i (%i)", Offset, + heightInChars, widthInChars, heightInChars*widthInChars); LEAVE('i', 0); return 0; } @@ -106,21 +109,36 @@ Uint64 Video_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) Log_Notice("Video", "Clipping write size to %i characters", (int)Length); } +// Log_Debug("Video", "(%i,%i) %i chars", x, y, (int)Length); + // Print characters for( i = 0; i < (int)Length; i++ ) { - VT_Font_Render( - chars->Ch, - //dest + x*giVT_CharWidth, pitch, - tmpBuf, giVT_CharWidth, - VT_Colour12to24(chars->BGCol), - VT_Colour12to24(chars->FGCol) - ); - UI_BlitBitmap( - x*giVT_CharWidth, y*giVT_CharHeight, - giVT_CharWidth, giVT_CharHeight, - tmpBuf - ); + if( chars->Ch ) + { +// Log_Debug("Video", "Render Char 0x%x in 0x%03x:%03x", +// chars->Ch, chars->FGCol, chars->BGCol); + memset(tmpBuf, 0xFF, giVT_CharWidth*giVT_CharHeight*4); + VT_Font_Render( + chars->Ch, + tmpBuf, 32, giVT_CharWidth*4, + VT_Colour12to24(chars->BGCol), + VT_Colour12to24(chars->FGCol) + ); + UI_BlitBitmap( + x*giVT_CharWidth, y*giVT_CharHeight, + giVT_CharWidth, giVT_CharHeight, + tmpBuf + ); + } + else + { + UI_FillBitmap( + x*giVT_CharWidth, y*giVT_CharHeight, + giVT_CharWidth, giVT_CharHeight, + VT_Colour12to24(chars->BGCol) + ); + } chars ++; x ++; @@ -146,7 +164,6 @@ Uint64 Video_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) } LOG("buffer = %p", Buffer); - LOG("Updating Framebuffer (%p to %p)", destBuf, destBuf + (Uint)Length); startX = Offset % giUI_Width; startY = Offset / giUI_Width; @@ -211,7 +228,7 @@ Uint64 Video_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) return Length; } -const char * const csaVIDEO_IOCTLS[] = {DRV_IOCTLNAMES, DRV_VIDEO_IOCTLNAMES, NULL}; +const char * csaVIDEO_IOCTLS[] = {DRV_IOCTLNAMES, DRV_VIDEO_IOCTLNAMES, NULL}; /** * \brief Handle messages to the device */ diff --git a/AcessNative/ld-acess_src/Makefile b/AcessNative/ld-acess_src/Makefile index 4fb6ae28..f7543fd0 100644 --- a/AcessNative/ld-acess_src/Makefile +++ b/AcessNative/ld-acess_src/Makefile @@ -19,6 +19,9 @@ endif CFLAGS += -Wall -Werror -g -m32 +DEPFILES = $(filter %.o.$(PLATFORM),$(OBJ)) +DEPFILES := $(DEPFILES:%.o.$(PLATFORM)=%.d.$(PLATFORM)) + .PHONY: all clean all: $(BIN) @@ -31,9 +34,12 @@ $(BIN): link.ld.$(PLATFORM) $(OBJ) $(CC) -g -o $@ $(OBJ) -m32 -Wl,-T,link.ld.$(PLATFORM) %.o.$(PLATFORM): %.c - $(CC) -c $< -o $@ $(CFLAGS) $(CPPFLAGS) + @echo [CC] -o $@ + @$(CC) -c $< -o $@ $(CFLAGS) $(CPPFLAGS) + @$(CC) -M $(CPPFLAGS) -MT $@ -o $*.d.$(PLATFORM) $< # Modify the default makefile to put the executable at 1MB instead link.ld.lin: - $(LD) --verbose | awk '{ if( substr($$0,0,5) == "====="){ bPrint = !bPrint; } else { if(bPrint){ print $$0;} } }' | sed 's/\b0x0[08][0-9]*\b/0x00100000/g' > $@ + @echo Making Linker Script ($@) + @$(LD) --verbose | awk '{ if( substr($$0,0,5) == "====="){ bPrint = !bPrint; } else { if(bPrint){ print $$0;} } }' | sed 's/\b0x0[08][0-9]*\b/0x00100000/g' > $@ diff --git a/AcessNative/ld-acess_src/binary.c b/AcessNative/ld-acess_src/binary.c index 0ce9fac9..d3dee99a 100644 --- a/AcessNative/ld-acess_src/binary.c +++ b/AcessNative/ld-acess_src/binary.c @@ -6,7 +6,7 @@ #include #include -#define LIBRARY_PATH "../Usermode/Output/i386/Libs" +#define LIBRARY_PATH "$$$$../Usermode/Output/i386/Libs" // === TYPES === typedef struct sBinary { @@ -18,7 +18,7 @@ typedef struct sBinary { } tBinary; // === IMPORTS === -extern void *Elf_Load(FILE *FP); +extern void *Elf_Load(int fd); extern uintptr_t Elf_Relocate(void *Base); extern int Elf_GetSymbol(void *Base, char *Name, uintptr_t *ret); extern int ciNumBuiltinSymbols; @@ -43,7 +43,7 @@ char *Binary_LocateLibrary(const char *Name) { char *envPath = getenv("ACESS_LIBRARY_PATH"); int nameLen = strlen(Name); - FILE *fp; + int fd; if( strcmp(Name, "libld-acess.so") == 0 ) { return strdup("libld-acess.so"); @@ -59,9 +59,9 @@ char *Binary_LocateLibrary(const char *Name) strcat(tmp, "/"); strcat(tmp, Name); - fp = fopen(tmp, "r"); - if(fp) { - fclose(fp); + fd = acess_open(tmp, 4); // OPENFLAG_EXEC + if(fd != -1) { + acess_close(fd); return strdup(tmp); } } @@ -74,16 +74,20 @@ char *Binary_LocateLibrary(const char *Name) strcat(tmp, "/"); strcat(tmp, Name); + #if DEBUG printf("Binary_LocateLibrary: tmp = '%s'\n", tmp); + #endif - fp = fopen(tmp, "r"); - if(fp) { - fclose(fp); + fd = acess_open(tmp, 4); // OPENFLAG_EXEC + if(fd != -1) { + acess_close(fd); return strdup(tmp); } } + #if DEBUG fprintf(stderr, "Unable to locate library '%s'\n", Name); + #endif return NULL; } @@ -96,7 +100,9 @@ void *Binary_LoadLibrary(const char *Name) // Find File path = Binary_LocateLibrary(Name); + #if DEBUG printf("Binary_LoadLibrary: path = '%s'\n", path); + #endif if( !path ) { return NULL; } @@ -104,10 +110,14 @@ void *Binary_LoadLibrary(const char *Name) ret = Binary_Load(path, (uintptr_t*)&entry); free(path); + #if DEBUG printf("Binary_LoadLibrary: ret = %p, entry = %p\n", ret, entry); + #endif if( entry ) { char *argv[] = {NULL}; + #if DEBUG printf("Calling '%s' entry point %p\n", Name, entry); + #endif entry(0, argv, NULL); } @@ -116,8 +126,8 @@ void *Binary_LoadLibrary(const char *Name) void *Binary_Load(const char *Filename, uintptr_t *EntryPoint) { - FILE *fp; - uint32_t dword; + int fd; + uint32_t dword = 0xFA17FA17; void *ret; uintptr_t entry = 0; tBinFmt *fmt; @@ -138,36 +148,43 @@ void *Binary_Load(const char *Filename, uintptr_t *EntryPoint) } } - fp = fopen(Filename, "r"); - if( !fp ) { + fd = acess_open(Filename, 2|1); // Execute and Read + if( fd == -1 ) { // TODO: Handle libary directories perror("Opening binary"); return NULL; } - fread(&dword, 1, 4, fp); - fseek(fp, 0, SEEK_SET); + acess_read(fd, 4, &dword); + acess_seek(fd, 0, ACESS_SEEK_SET); if( memcmp(&dword, "\x7F""ELF", 4) == 0 ) { fmt = &gElf_FormatDef; } else { - fclose(fp); + fprintf(stderr, "Unknown executable format (0x%08x)\n", dword); + acess_close(fd); return NULL; } - printf("fmt->Load(%p)...\n", fp); - ret = fmt->Load(fp); - printf("fmt->Load(%p): %p\n", fp, ret); + #if DEBUG + printf("fmt->Load(%i)...\n", fd); + #endif + ret = fmt->Load(fd); + acess_close(fd); + #if DEBUG + printf("fmt->Load(%p): %p\n", fd, ret); + #endif if( !ret ) { - fclose(fp); return NULL; } Binary_AddToList(Filename, ret, fmt); entry = fmt->Relocate(ret); + #if DEBUG printf("fmt->Relocate(%p): %p\n", ret, (void*)entry); + #endif if( !entry ) { // TODO: Clean up return NULL; @@ -176,8 +193,6 @@ void *Binary_Load(const char *Filename, uintptr_t *EntryPoint) if( EntryPoint ) *EntryPoint = entry; - fclose(fp); - Binary_SetReadyToUse(ret); return ret; diff --git a/AcessNative/ld-acess_src/common.h b/AcessNative/ld-acess_src/common.h index 4667acba..b544a459 100644 --- a/AcessNative/ld-acess_src/common.h +++ b/AcessNative/ld-acess_src/common.h @@ -18,6 +18,15 @@ extern uintptr_t FindFreeRange(size_t ByteCount, int MaxBits); extern void Warning(const char *Format, ...); extern void Notice(const char *Format, ...); +#define ACESS_SEEK_CUR 0 +#define ACESS_SEEK_SET 1 +#define ACESS_SEEK_END -1 + +extern int acess_open(const char *Path, int Flags); +extern void acess_close(int FD); +extern size_t acess_read(int FD, size_t Bytes, void *Dest); +extern int acess_seek(int FD, int64_t Offset, int Dir); + typedef struct { char *Name; void *Value; @@ -26,7 +35,7 @@ typedef struct { typedef struct sBinFmt { struct sBinFmt *Next; char *Name; - void *(*Load)(FILE *fp); + void *(*Load)(int fd); uintptr_t (*Relocate)(void *base); int (*GetSymbol)(void*,char*,uintptr_t*); } tBinFmt; diff --git a/AcessNative/ld-acess_src/elf.c b/AcessNative/ld-acess_src/elf.c index a79b591f..b99f1901 100644 --- a/AcessNative/ld-acess_src/elf.c +++ b/AcessNative/ld-acess_src/elf.c @@ -29,14 +29,14 @@ #endif // === PROTOTYPES === -void *Elf_Load(FILE *FP); +void *Elf_Load(int FD); uintptr_t Elf_Relocate(void *Base); int Elf_GetSymbol(void *Base, char *Name, uintptr_t *ret); int Elf_Int_DoRelocate(uint32_t r_info, uint32_t *ptr, uint32_t addend, Elf32_Sym *symtab, void *Base); uint32_t Elf_Int_HashString(char *str); // === CODE === -void *Elf_Load(FILE *FP) +void *Elf_Load(int FD) { Elf32_Ehdr hdr; Elf32_Phdr *phtab; @@ -46,10 +46,10 @@ void *Elf_Load(FILE *FP) uint32_t addr; uint32_t baseDiff = 0; - ENTER("pFP", FP); + ENTER("iFD", FD); // Read ELF Header - fread(&hdr, sizeof(hdr), 1, FP); + acess_read(FD, sizeof(hdr), &hdr); // Check the file type if(hdr.ident[0] != 0x7F || hdr.ident[1] != 'E' || hdr.ident[2] != 'L' || hdr.ident[3] != 'F') { @@ -74,8 +74,8 @@ void *Elf_Load(FILE *FP) return NULL; } LOG("hdr.phoff = 0x%08x\n", hdr.phoff); - fseek(FP, hdr.phoff, SEEK_SET); - fread(phtab, sizeof(Elf32_Phdr), hdr.phentcount, FP); + acess_seek(FD, hdr.phoff, ACESS_SEEK_SET); + acess_read(FD, sizeof(Elf32_Phdr) * hdr.phentcount, phtab); // Count Pages iPageCount = 0; @@ -143,8 +143,8 @@ void *Elf_Load(FILE *FP) char *tmp; //if(ret->Interpreter) continue; tmp = malloc(phtab[i].FileSize); - fseek(FP, phtab[i].Offset, SEEK_SET); - fread(tmp, phtab[i].FileSize, 1, FP); + acess_seek(FD, phtab[i].Offset, ACESS_SEEK_SET); + acess_read(FD, phtab[i].FileSize, tmp); //ret->Interpreter = Binary_RegInterp(tmp); LOG("Interpreter '%s'\n", tmp); free(tmp); @@ -165,8 +165,8 @@ void *Elf_Load(FILE *FP) return NULL; } - fseek(FP, phtab[i].Offset, SEEK_SET); - fread( PTRMK(void, addr), phtab[i].FileSize, 1, FP ); + acess_seek(FD, phtab[i].Offset, ACESS_SEEK_SET); + acess_read(FD, phtab[i].FileSize, PTRMK(void, addr) ); memset( PTRMK(char, addr) + phtab[i].FileSize, 0, phtab[i].MemSize - phtab[i].FileSize ); } diff --git a/AcessNative/ld-acess_src/main.c b/AcessNative/ld-acess_src/main.c index b2a8660e..852b3981 100644 --- a/AcessNative/ld-acess_src/main.c +++ b/AcessNative/ld-acess_src/main.c @@ -4,6 +4,7 @@ #include #include #include +#include // === CODE === int main(int argc, char *argv[], char **envp) @@ -11,12 +12,32 @@ int main(int argc, char *argv[], char **envp) int i; int appArgc; char **appArgv; - char *appPath; + char *appPath = NULL; int (*appMain)(int, char *[], char **); void *base; + int syscall_handle = -1; + for( i = 1; i < argc; i ++ ) { + if(strcmp(argv[i], "--key") == 0) { + syscall_handle = atoi(argv[++i]); + continue ; + } + + if(strcmp(argv[i], "--binary") == 0) { + appPath = argv[++i]; + continue ; + } + + if(strcmp(argv[i], "--open") == 0) { + if( acess_open(argv[++i], 6) == -1 ) { // Read/Write + fprintf(stderr, "Unable to open '%s'\n", argv[i]); + exit(1); + } + continue ; + } + if( argv[i][0] != '-' ) break; } @@ -25,7 +46,8 @@ int main(int argc, char *argv[], char **envp) return 1; } - appPath = argv[i]; + if( !appPath ) + appPath = argv[i]; appArgc = argc - i; appArgv = &argv[i]; @@ -47,7 +69,6 @@ int main(int argc, char *argv[], char **envp) "push %2;\n\t" "jmp *%3;\n\t" : : "r" (envp), "r" (appArgv), "r" (appArgc), "r" (appMain) ); - //return appMain(appArgc, appArgv, envp); return -1; } diff --git a/AcessNative/ld-acess_src/request.c b/AcessNative/ld-acess_src/request.c index c5e89efc..75565f15 100644 --- a/AcessNative/ld-acess_src/request.c +++ b/AcessNative/ld-acess_src/request.c @@ -89,6 +89,7 @@ int _InitSyscalls() #endif exit(0); } + giSyscall_ClientID = gSocket; // A bit of a hack really :( #endif #if 0 @@ -130,7 +131,7 @@ int _InitSyscalls() return 0; } -int SendRequest(tRequestHeader *Request, int RequestSize) +int SendRequest(tRequestHeader *Request, int RequestSize, int ResponseSize) { if( gSocket == INVALID_SOCKET ) { @@ -153,38 +154,38 @@ int SendRequest(tRequestHeader *Request, int RequestSize) { int i; char *data = (char*)&Request->Params[Request->NParams]; - printf("Request #%i\n", Request->CallID); + printf("Request #%i (%s) -", Request->CallID, casSYSCALL_NAMES[Request->CallID]); for( i = 0; i < Request->NParams; i ++ ) { - printf("%i: ", i); switch(Request->Params[i].Type) { case ARG_TYPE_INT32: - printf("INT32 %x", *(uint32_t*)data); + printf(" 0x%08x", *(uint32_t*)data); data += sizeof(uint32_t); break; case ARG_TYPE_INT64: - printf("INT64 %llx", *(uint64_t*)data); + printf(" 0x%016llx", *(uint64_t*)data); data += sizeof(uint64_t); break; case ARG_TYPE_STRING: - printf("STRING '%s'", (char*)data); + printf(" '%s'", (char*)data); data += Request->Params[i].Length; break; case ARG_TYPE_DATA: - printf("DATA %i %p", Request->Params[i].Length, (char*)data); - data += Request->Params[i].Length; + printf(" %p:0x%x", (char*)data, Request->Params[i].Length); + if( !(Request->Params[i].Flags & ARG_FLAG_ZEROED) ) + data += Request->Params[i].Length; break; } - printf("\n"); } + printf("\n"); } // Send it off SendData(Request, RequestSize); // Wait for a response (no timeout) - return ReadData(Request, RequestSize, 0); + return ReadData(Request, ResponseSize, 0); } void SendData(void *Data, int Length) diff --git a/AcessNative/ld-acess_src/request.h b/AcessNative/ld-acess_src/request.h index b33a80f9..f31a6333 100644 --- a/AcessNative/ld-acess_src/request.h +++ b/AcessNative/ld-acess_src/request.h @@ -10,6 +10,6 @@ #include "../syscalls.h" -extern int SendRequest(tRequestHeader *Request, int RequestSize); +extern int SendRequest(tRequestHeader *Request, int RequestSize, int ResponseSize); #endif diff --git a/AcessNative/ld-acess_src/syscalls.c b/AcessNative/ld-acess_src/syscalls.c index 02a59b90..2a63622a 100644 --- a/AcessNative/ld-acess_src/syscalls.c +++ b/AcessNative/ld-acess_src/syscalls.c @@ -1,5 +1,6 @@ /* */ +#define DONT_INCLUDE_SYSCALL_NAMES 1 #include "../../Usermode/include/acess/sys.h" #include "common.h" #include @@ -7,12 +8,22 @@ #include #include #include +#include #include "request.h" #include "../syscalls.h" +#define DEBUG(x...) printf(x) + +#define NATIVE_FILE_MASK 0x40000000 +#define MAX_FPS 16 + // === Types === // === IMPORTS === +extern int giSyscall_ClientID; // Needed for execve + +// === GLOBALS === +FILE *gaSyscall_LocalFPs[MAX_FPS]; // === CODE === const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const char *ArgTypes, va_list *Args) @@ -53,7 +64,6 @@ const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const } val32 = va_arg(*Args, uint32_t); - printf("val32 = 0x%x\n", val32); Dest->Type = ARG_TYPE_INT32; Dest->Length = sizeof(uint32_t); @@ -71,7 +81,6 @@ const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const } val64 = va_arg(*Args, uint64_t); - printf("val64 = 0x%llx\n", val64); Dest->Type = ARG_TYPE_INT64; Dest->Length = sizeof(uint64_t); @@ -88,7 +97,6 @@ const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const } str = va_arg(*Args, char*); - printf("str = %p '%s'\n", str, str); Dest->Type = ARG_TYPE_STRING; Dest->Length = strlen(str) + 1; @@ -104,8 +112,6 @@ const char *ReadEntry(tRequestValue *Dest, void *DataDest, void **PtrDest, const len = va_arg(*Args, int); str = va_arg(*Args, char*); - printf("len = %i, str = %p\n", len, str); - // Save the pointer for later if( PtrDest ) *PtrDest = str; @@ -159,6 +165,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; @@ -219,7 +230,7 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...) va_end(args); // Send syscall request - if( SendRequest(req, dataLength) < 0 ) { + if( SendRequest(req, dataLength, retLength) < 0 ) { fprintf(stderr, "syscalls.c: SendRequest failed (SyscallID = %i)\n", SyscallID); exit(127); } @@ -227,7 +238,7 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...) // Parse return value dataPtr = &req->Params[req->NParams]; retValue = 0; - if( req->NParams > 1 ) + if( req->NParams >= 1 ) { switch(req->Params[0].Type) { @@ -243,94 +254,241 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...) } // Write changes to buffers - va_start(args, ArgTypes); + retCount = 0; for( i = 1; 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 + memcpy( retPtrs[retCount++], dataPtr, req->Params[i].Length ); dataPtr += req->Params[i].Length; } - va_end(args); free( req ); + free( retPtrs ); - return 0; + printf("Return %llx\n", retValue); + + return retValue; } // --- VFS Calls -int open(const char *Path, int Flags) { +int acess_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)\n", Path, Flags); return _Syscall(SYS_OPEN, ">s >i", Path, Flags); } -void close(int FD) { +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)\n", FD); _Syscall(SYS_CLOSE, ">i", FD); } -int reopen(int FD, const char *Path, int Flags) { +int acess_reopen(int FD, const char *Path, int Flags) { + DEBUG("reopen(0x%x, \"%s\", 0x%x)\n", FD, Path, Flags); return _Syscall(SYS_REOPEN, ">i >s >i", FD, Path, Flags); } -size_t read(int FD, size_t Bytes, void *Dest) { - return _Syscall(SYS_READ, "i >i i >i i >i >d", FD, Bytes, Bytes, Src); } -int seek(int FD, int64_t Ofs, int Dir) { +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)\n", FD, Ofs, Dir); return _Syscall(SYS_SEEK, ">i >I >i", FD, Ofs, Dir); } -uint64_t tell(int FD) { +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 ioctl(int fd, int id, void *data) { +int acess_ioctl(int fd, int id, void *data) { // NOTE: 1024 byte size is a hack return _Syscall(SYS_IOCTL, ">i >i ?d", fd, id, 1024, data); } -int finfo(int fd, t_sysFInfo *info, int maxacls) { +int acess_finfo(int fd, t_sysFInfo *info, int maxacls) { return _Syscall(SYS_FINFO, ">i i", fd, sizeof(t_sysFInfo)+maxacls*sizeof(t_sysACL), info, maxacls); } -int readdir(int fd, char *dest) { +int acess_readdir(int fd, char *dest) { return _Syscall(SYS_READDIR, ">i i >s >i", fd, name, flags); } -int _SysGetACL(int fd, t_sysACL *dest) { +int acess__SysGetACL(int fd, t_sysACL *dest) { return _Syscall(SYS_GETACL, "i s >s >s >s", Device, Directory, Type, Options); } // --- Error Handler -int _SysSetFaultHandler(int (*Handler)(int)) { +int acess__SysSetFaultHandler(int (*Handler)(int)) { return 0; } // --- Memory Management --- -uint64_t _SysAllocate(uint vaddr) +uint64_t acess__SysAllocate(uint vaddr) { if( AllocateMemory(vaddr, 0x1000) == -1 ) // Allocate a page return 0; + return vaddr; // Just ignore the need for paddrs :) } +// --- Process Management --- +int acess_clone(int flags, void *stack) +{ + extern int fork(void); + if(flags & CLONE_VM) { + int ret, newID, kernel_tid=0; + printf("fork()\n"); + + newID = _Syscall(SYS_FORK, "i i", ID); +} + +int acess_setgid(int ID) +{ + return _Syscall(SYS_SETGID, ">i", ID); +} + +// --- Logging +void acess__SysDebug(const char *Format, ...) +{ + va_list args; + + va_start(args, Format); + + printf("[_SysDebug] "); + vprintf(Format, args); + printf("\n"); + + va_end(args); +} + +void acess__exit(int Status) +{ + _Syscall(SYS_EXIT, ">i", Status); + exit(Status); +} + // === Symbol List === -#define DEFSYM(name) {#name, name} +#define DEFSYM(name) {#name, acess_##name} const tSym caBuiltinSymbols[] = { - {"_exit", exit}, + DEFSYM(_exit), DEFSYM(open), DEFSYM(close), @@ -346,9 +504,17 @@ const tSym caBuiltinSymbols[] = { DEFSYM(_SysGetACL), DEFSYM(_SysMount), - DEFSYM(_SysAllocate), + DEFSYM(clone), + DEFSYM(execve), + DEFSYM(sleep), + + DEFSYM(waittid), + DEFSYM(setuid), + DEFSYM(setgid), - {"_SysSetFaultHandler", _SysSetFaultHandler} + DEFSYM(_SysAllocate), + DEFSYM(_SysDebug), + DEFSYM(_SysSetFaultHandler) }; const int ciNumBuiltinSymbols = sizeof(caBuiltinSymbols)/sizeof(caBuiltinSymbols[0]); diff --git a/AcessNative/syscalls.h b/AcessNative/syscalls.h index b4d211c7..158a6ccb 100644 --- a/AcessNative/syscalls.h +++ b/AcessNative/syscalls.h @@ -17,7 +17,7 @@ typedef struct sRequestValue { /// \see eArgumentTypes uint16_t Type; - uint8_t Flags; + uint16_t Flags; uint16_t Length; } tRequestValue; @@ -31,6 +31,9 @@ typedef struct sRequestHeader { enum eSyscalls { SYS_NULL, + + SYS_EXIT, + SYS_OPEN, SYS_CLOSE, SYS_READ, @@ -44,9 +47,43 @@ enum eSyscalls { SYS_GETACL, SYS_MOUNT, SYS_REOPEN, + + SYS_WAITTID, + SYS_SETUID, + SYS_SETGID, + + // IPC + SYS_SLEEP, + SYS_FORK, + N_SYSCALLS }; +#ifndef DONT_INCLUDE_SYSCALL_NAMES +static const char * casSYSCALL_NAMES[] = { + "SYS_NULL", + + "SYS_EXIT", + + "SYS_OPEN", + "SYS_CLOSE", + "SYS_READ", + "SYS_WRITE", + "SYS_SEEK", + "SYS_TELL", + "SYS_IOCTL", + "SYS_FINFO", + "SYS_READDIR", + "SYS_OPENCHILD", + "SYS_GETACL", + "SYS_MOUNT", + "SYS_REOPEN", + + // IPC + "SYS_SLEEP" +}; +#endif + enum eArgumentTypes { ARG_TYPE_VOID, ARG_TYPE_INT32,