int nameLen = strlen(Name);
FILE *fp;
+ if( strcmp(Name, "libld-acess.so") == 0 ) {
+ return strdup("libld-acess.so");
+ }
+
// Try the environment ACESS_LIBRARY_PATH
if( envPath && envPath[0] != '\0' )
{
printf("Binary_LoadLibrary: ret = %p, entry = %p\n", ret, entry);
if( entry ) {
char *argv[] = {NULL};
+ printf("Calling '%s' entry point %p\n", Name, entry);
entry(0, argv, NULL);
}
uintptr_t entry = 0;
tBinFmt *fmt;
+ // Ignore loading ld-acess
+ if( strcmp(Filename, "libld-acess.so") == 0 ) {
+ *EntryPoint = 0;
+ return (void*)-1;
+ }
+
{
tBinary *bin;
for(bin = gLoadedBinaries; bin; bin = bin->Next)
fclose(fp);
return NULL;
}
-
+
+ printf("fmt->Load(%p)...\n", fp);
ret = fmt->Load(fp);
printf("fmt->Load(%p): %p\n", fp, ret);
if( !ret ) {
int i;
tBinary *bin;
- // TODO: Search list of loaded binaries
- for(bin = gLoadedBinaries; bin; bin = bin->Next)
- {
- if( !bin->Ready ) continue;
- printf("Binary_GetSymbol: bin = %p{%p, %s}\n", bin, bin->Base, bin->Path);
- if( bin->Format->GetSymbol(bin->Base, (char*)SymbolName, Value) )
- return 1;
- }
+ printf("Binary_GetSymbol: (SymbolName='%s', Value=%p)\n",
+ SymbolName, Value);
// Search builtins
+ // - Placed first to override smartarses that define their own versions
+ // of system calls
for( i = 0; i < ciNumBuiltinSymbols; i ++ )
{
if( strcmp(caBuiltinSymbols[i].Name, SymbolName) == 0 ) {
return 1;
}
}
+
+ // TODO: Search list of loaded binaries
+ for(bin = gLoadedBinaries; bin; bin = bin->Next)
+ {
+ if( !bin->Ready ) continue;
+ printf(" Binary_GetSymbol: bin = %p{%p, %s}\n", bin, bin->Base, bin->Path);
+ if( bin->Format->GetSymbol(bin->Base, (char*)SymbolName, Value) )
+ return 1;
+ }
+ printf("Binary_GetSymbol: RETURN 0, not found\n");
+
return 0;
}
# include <sys/socket.h>
# include <netinet/in.h>
#endif
+#include "request.h"
+#include "../syscalls.h"
#define SERVER_PORT 0xACE
// === GLOBALS ===
#ifdef __WIN32__
WSADATA gWinsock;
-SOCKET gSocket;
+SOCKET gSocket = INVALID_SOCKET;
#else
- int gSocket;
# define INVALID_SOCKET -1
+ int gSocket = INVALID_SOCKET;
#endif
+// Client ID to pass to server
+// TODO: Implement such that each thread gets a different one
+static int siSyscall_ClientID = 0;
// === CODE ===
int _InitSyscalls()
}
return 0;
}
-#if 0
-int _Syscall(const char *ArgTypes, ...)
+
+int SendRequest(int RequestID, int NumOutput, tOutValue **Output, int NumInput, tInValue **Input)
{
+ tRequestHeader *request;
+ tRequestValue *value;
+ char *data;
+ int requestLen;
+ int i;
+
+ // See ../syscalls.h for details of request format
+ requestLen = sizeof(tRequestHeader) + (NumOutput + NumInput) * sizeof(tRequestValue);
+
+ // Get total param length
+ for( i = 0; i < NumOutput; i ++ )
+ requestLen += Output[i]->Length;
+
+ // Allocate request
+ request = malloc( requestLen );
+ value = request->Params;
+ data = (char*)&request->Params[ NumOutput + NumInput ];
+
+ // Set header
+ request->ClientID = siSyscall_ClientID;
+ request->CallID = RequestID; // Syscall
+ request->NParams = NumOutput;
+ request->NReturn = NumInput;
+
+ // Set parameters
+ for( i = 0; i < NumOutput; i ++ )
+ {
+ switch(Output[i]->Type)
+ {
+ case 'i': value->Type = ARG_TYPE_INT32; break;
+ case 'I': value->Type = ARG_TYPE_INT64; break;
+ case 'd': value->Type = ARG_TYPE_DATA; break;
+ default:
+ return -1;
+ }
+ value->Length = Output[i]->Length;
+
+ memcpy(data, Output[i]->Data, Output[i]->Length);
+
+ data += Output[i]->Length;
+ }
+
+ // Set return values
+ for( i = 0; i < NumInput; i ++ )
+ {
+ switch(Input[i]->Type)
+ {
+ case 'i': value->Type = ARG_TYPE_INT32; break;
+ case 'I': value->Type = ARG_TYPE_INT64; break;
+ case 'd': value->Type = ARG_TYPE_DATA; break;
+ default:
+ return -1;
+ }
+ value->Length = Input[i]->Length;
+ }
+
+ // Send it off
+ send(gSocket, request, requestLen, 0);
+
+ // Wait for a response
+ recv(gSocket, request, requestLen, 0);
+
+ // Parse response out
+
return 0;
}
-#endif
/*
*/
-//#include <acess/sys.h>
+#include "../../Usermode/include/acess/sys.h"
#include "common.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
+#include <string.h>
+#include "request.h"
+
+// === Types ===
// === IMPORTS ===
// === CODE ===
+const char *ReadEntry(tOutValue **OutDest, tInValue **InDest,
+ int *Direction, const char *ArgTypes, va_list Args)
+{
+ uint64_t val64, *ptr64;
+ uint32_t val32, *ptr32;
+ 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;
+
+ // Get direction
+ switch(*ArgTypes)
+ {
+ case '>': direction = 1; break;
+ case '<': direction = 2; break;
+ case '?': direction = 3; break;
+ default:
+ return NULL;
+ }
+ ArgTypes ++;
+
+ // Eat whitespace
+ while(*ArgTypes && *ArgTypes == ' ') ArgTypes ++;
+ if( *ArgTypes == '\0' ) return ArgTypes;
+
+ // Internal helper macro
+ #define MAKE_OUT(_dest,_typeChar,_typeName,_value) do{if((_dest)){\
+ *(_dest) = (tOutValue*)malloc(sizeof(tOutValue)+sizeof(_typeName));\
+ (*(_dest))->Type=(_typeChar);(*(_dest))->Length=sizeof(_typeName);\
+ *(_typeName*)((*(_dest))->Data) = (_value);\
+ }}while(0)
+ #define MAKE_IN(_dest,_typeChar,_typeName,_value) do{if((_dest)){\
+ *(_dest) = (tInValue*)malloc(sizeof(tInValue));\
+ (*(_dest))->Type=(_typeChar);(*(_dest))->Length=sizeof(_typeName);\
+ (*(_dest))->Data = (_value);\
+ }}while(0)
+
+ // Get type
+ switch(*ArgTypes)
+ {
+ case 'i': // 32-bit integer
+ // Input?
+ if( direction & 2 )
+ {
+ ptr32 = va_arg(Args, uint32_t*);
+ MAKE_IN(InDest, 'i', uint32_t*, ptr32);
+ if( direction & 1 )
+ MAKE_OUT(OutDest, 'i', uint32_t, *ptr32);
+ }
+ else
+ {
+ val32 = va_arg(Args, uint32_t);
+ MAKE_OUT(OutDest, 'i', uint32_t, val32);
+ }
+ break;
+ case 'I': // 64-bit integer
+ // Input?
+ if( direction & 2 )
+ {
+ ptr64 = va_arg(Args, uint64_t*);
+ MAKE_IN(InDest, 'I', uint64_t*, ptr64);
+ if( direction & 1 )
+ MAKE_OUT(OutDest, 'I', uint64_t, *ptr64);
+ }
+ else
+ {
+ val64 = va_arg(Args, uint64_t);
+ MAKE_OUT(OutDest, 'I', uint64_t, val64);
+ }
+ break;
+ case 's':
+ // Input string makes no sense!
+ if( direction & 2 ) {
+ fprintf(stderr, "ReadEntry: Incoming string is not defined\n");
+ return NULL;
+ }
+
+ str = va_arg(Args, char*);
+ if( OutDest )
+ {
+ int len = strlen(str) + 1;
+ *OutDest = malloc( sizeof(tOutValue) + len );
+ (*OutDest)->Type = 's';
+ (*OutDest)->Length = len;
+ memcpy((*OutDest)->Data, str, len);
+ }
+ break;
+
+ case 'd':
+ len = va_arg(Args, int);
+ str = va_arg(Args, char*);
+
+ // Input ?
+ if( (direction & 2) && InDest )
+ {
+ *InDest = (tInValue*)malloc( sizeof(tInValue) );
+ (*InDest)->Type = 'd';
+ (*InDest)->Length = len;
+ (*InDest)->Data = str;
+ }
+
+ // Output ?
+ if( (direction & 1) && InDest )
+ {
+ *OutDest = (tOutValue*)malloc( sizeof(tOutValue) + len );
+ (*OutDest)->Type = 'd';
+ (*OutDest)->Length = len;
+ memcpy((*OutDest)->Data, str, len);
+ }
+ break;
+
+ default:
+ return NULL;
+ }
+ ArgTypes ++;
+ #undef MAKE_ASSIGN
+
+ *Direction = direction;
+
+ return ArgTypes;
+}
+
/**
* \param ArgTypes
*
* Whitespace is ignored
- * >i: Input Integer
+ * >i: Input Integer (32-bits)
* >I: Input Long Integer (64-bits)
* >s: Input String
* >d: Input Buffer (Preceded by valid size)
* <I: Output long integer
* <d: Output Buffer (Preceded by valid size)
+ * ?d: Bi-directional buffer (Preceded by valid size), buffer contents
+ * are returned
*/
int _Syscall(const char *ArgTypes, ...)
{
- // int outBufSize = 0;
va_list args;
+ int outCount = 0;
+ int inCount = 0;
+ const char *str;
+
+ tOutValue **output;
+ tInValue **input;
+ // Get data size
va_start(args, ArgTypes);
+ str = ArgTypes;
+ while(*str)
+ {
+ int dir;
+
+ str = ReadEntry(NULL, NULL, &dir, str, args);
+ if( !str ) break;
+
+ // Out!
+ if( dir & 1 ) outCount ++;
+
+ // and.. In!
+ if( dir & 2 ) inCount ++;
+ }
va_end(args);
+
+ // Allocate buffers
+ output = malloc( outCount*sizeof(tOutValue*) );
+ input = malloc( inCount*sizeof(tInValue*) );
+
+ // - re-zero so they can be used as indicies
+ outCount = 0;
+ inCount = 0;
+
+ // Fill `output` and `input`
+ va_start(args, ArgTypes);
+ str = ArgTypes;
+ while(*str)
+ {
+ tOutValue *outParam;
+ tInValue *inParam;
+ int dir;
+
+ str = ReadEntry(&outParam, &inParam, &dir, str, args);
+ if( !str ) break;
+
+ if( dir & 1 )
+ output[outCount++] = outParam;
+ if( dir & 2 )
+ input[inCount++] = inParam;
+ }
+ va_end(args);
+
+ // Send syscall request
+
+
+ // Clean up
+ while(outCount--) free(output[outCount]);
+ free(output);
+ while(inCount--) free(input[inCount]);
+ free(input);
+
return 0;
}
+// --- VFS Calls
int open(const char *Path, int Flags) {
return _Syscall(">s >i", Path, Flags);
}
return _Syscall(">i >i >d", FD, Bytes, Bytes, Src);
}
+int seek(int FD, int64_t Ofs, int Dir) {
+ return _Syscall(">i >I >i", FD, Ofs, Dir);
+}
+
uint64_t tell(int FD) {
uint64_t ret;
_Syscall("<I >i", &ret, FD);
return ret;
}
-int seek(int FD, uint64_t Ofs, int Dir) {
- return _Syscall(">i >I >i", FD, Ofs, Dir);
+int ioctl(int fd, int id, void *data) {
+ // NOTE: 1024 byte size is a hack
+ return _Syscall(">i >i ?d", fd, id, 1024, data);
+}
+int finfo(int fd, t_sysFInfo *info, int maxacls) {
+ return _Syscall(">i <d >i", fd, maxacls*sizeof(t_sysFInfo), info, maxacls);
}
+int readdir(int fd, char *dest) {
+ return _Syscall(">i <s", fd, dest);
+}
+
+int _SysOpenChild(int fd, char *name, int flags) {
+ return _Syscall(">i >s >i", fd, name, flags);
+}
+
+int _SysGetACL(int fd, t_sysACL *dest) {
+ return _Syscall(">i <d", fd, sizeof(t_sysACL), dest);
+}
+
+int _SysMount(const char *Device, const char *Directory, const char *Type, const char *Options) {
+ return _Syscall(">s >s >s >s", Device, Directory, Type, Options);
+}
+
+
+// --- Error Handler
+int _SysSetFaultHandler(int (*Handler)(int)) {
+ return 0;
+}
+
+
// === Symbol List ===
+#define DEFSYM(name) {#name, name}
const tSym caBuiltinSymbols[] = {
- {"open", open},
- {"close", close},
- {"read", read},
- {"write", write},
- {"tell", tell},
- {"seek", seek},
- {"_exit", exit}
+ {"_exit", exit},
+
+ DEFSYM(open),
+ DEFSYM(close),
+ DEFSYM(read),
+ DEFSYM(write),
+ DEFSYM(seek),
+ DEFSYM(tell),
+ DEFSYM(ioctl),
+ DEFSYM(finfo),
+ DEFSYM(readdir),
+ DEFSYM(_SysOpenChild),
+ DEFSYM(_SysGetACL),
+ DEFSYM(_SysMount),
+
+ {"_SysSetFaultHandler", _SysSetFaultHandler}
};
const int ciNumBuiltinSymbols = sizeof(caBuiltinSymbols)/sizeof(caBuiltinSymbols[0]);