From 4726431cb7e0bada749b32f9e51dedadf882d50b Mon Sep 17 00:00:00 2001
From: John Hodge <tpg@mutabah.net>
Date: Tue, 18 Jan 2011 20:47:12 +0800
Subject: [PATCH] Big changes to AcessNative

- ld-acess can now execute an application
 > the syscall interface is not yet completed, so nothing happens
- Getting ld-acess working required some changes to the Usermode build
  system, specifically making ld-acess.so actually a shared library.
 > It was being linked statically, causing the AcessNative versions of
   syscalls to not be used (and causing segfaults on "int 0xAC")
---
 AcessNative/ld-acess.so_src/Makefile        |  12 +-
 AcessNative/ld-acess.so_src/binary.c        |  37 ++-
 AcessNative/ld-acess.so_src/elf.c           |  21 +-
 AcessNative/ld-acess.so_src/main.c          |   9 +-
 AcessNative/ld-acess.so_src/request.c       |  78 +++++-
 AcessNative/ld-acess.so_src/request.h       |  26 ++
 AcessNative/ld-acess.so_src/syscalls.c      | 254 +++++++++++++++++++-
 AcessNative/syscalls.h                      |  29 ++-
 Usermode/Applications/Makefile.cfg          |   2 +-
 Usermode/Libraries/Makefile.tpl             |   6 +-
 Usermode/Libraries/acess.ld_src/acess.ld.h  |   2 +-
 Usermode/Libraries/ld-acess.so_src/Makefile |   7 +-
 12 files changed, 435 insertions(+), 48 deletions(-)
 create mode 100644 AcessNative/ld-acess.so_src/request.h

diff --git a/AcessNative/ld-acess.so_src/Makefile b/AcessNative/ld-acess.so_src/Makefile
index 08e12c8a..4fb6ae28 100644
--- a/AcessNative/ld-acess.so_src/Makefile
+++ b/AcessNative/ld-acess.so_src/Makefile
@@ -14,9 +14,10 @@ ifeq ($(PLATFORM),win)
 endif
 ifeq ($(PLATFORM),lin)
 	BIN := ../ld-acess
+	LD += -m elf_i386
 endif
 
-CFLAGS += -Wall -Werror -g
+CFLAGS += -Wall -Werror -g -m32
 
 .PHONY: all clean
 
@@ -25,9 +26,14 @@ all: $(BIN)
 clean:
 	$(RM) $(BIN) $(OBJ)
 
-$(BIN): $(OBJ)
-	$(CC) -g -o $@ $(OBJ)
+$(BIN): link.ld.$(PLATFORM) $(OBJ)
+#	$(LD) -g -o $@ $(OBJ) -T link.ld.$(PLATFORM)
+	$(CC) -g -o $@ $(OBJ) -m32 -Wl,-T,link.ld.$(PLATFORM)
 
 %.o.$(PLATFORM): %.c
 	$(CC) -c $< -o $@ $(CFLAGS) $(CPPFLAGS)
 
+# 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' > $@
+
diff --git a/AcessNative/ld-acess.so_src/binary.c b/AcessNative/ld-acess.so_src/binary.c
index 7f97edda..b8f6e71b 100644
--- a/AcessNative/ld-acess.so_src/binary.c
+++ b/AcessNative/ld-acess.so_src/binary.c
@@ -45,6 +45,10 @@ char *Binary_LocateLibrary(const char *Name)
 	 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' )
 	{
@@ -103,6 +107,7 @@ void *Binary_LoadLibrary(const char *Name)
 	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);
 	}
 
@@ -117,6 +122,12 @@ void *Binary_Load(const char *Filename, uintptr_t *EntryPoint)
 	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)
@@ -145,7 +156,8 @@ void *Binary_Load(const char *Filename, uintptr_t *EntryPoint)
 		fclose(fp);
 		return NULL;
 	}
-
+	
+	printf("fmt->Load(%p)...\n", fp);
 	ret = fmt->Load(fp);
 	printf("fmt->Load(%p): %p\n", fp, ret);
 	if( !ret ) {
@@ -199,16 +211,12 @@ int Binary_GetSymbol(const char *SymbolName, uintptr_t *Value)
 	 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 ) {
@@ -216,6 +224,17 @@ int Binary_GetSymbol(const char *SymbolName, uintptr_t *Value)
 			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;
 }
diff --git a/AcessNative/ld-acess.so_src/elf.c b/AcessNative/ld-acess.so_src/elf.c
index 11bd2df7..3ab5a504 100644
--- a/AcessNative/ld-acess.so_src/elf.c
+++ b/AcessNative/ld-acess.so_src/elf.c
@@ -16,16 +16,16 @@
 #define PTRMK(_type,_val)	MKPTR(_type,_val)
 #define PTR(_val)	((void*)(uintptr_t)(_val))
 
-#if 0
+#if DEBUG
 # define ENTER(...)
 # define LOG(s, ...)	printf("%s: " s, __func__, __VA_ARGS__)
 # define LOGS(s)	printf("%s: " s, __func__)
 # define LEAVE(...)
 #else
-#define ENTER(...)
-#define LOG(...)
-#define LOGS(...)
-#define LEAVE(...)
+# define ENTER(...)
+# define LOG(...)
+# define LOGS(...)
+# define LEAVE(...)
 #endif
 
 // === PROTOTYPES ===
@@ -274,9 +274,16 @@ uintptr_t Elf_Relocate(void *Base)
 	// Alter Symbols to true base
 	for(i = 0; i < iSymCount; i ++)
 	{
-		dynsymtab[i].value += iBaseDiff;
 		dynsymtab[i].nameOfs += (uintptr_t)dynstrtab;
-		LOG("Sym '%s' = 0x%x (relocated)\n", MKPTR(char,dynsymtab[i].name), dynsymtab[i].value);
+		if( dynsymtab[i].shndx == SHN_UNDEF )
+		{
+			LOG("Sym '%s' = UNDEF\n", MKPTR(char,dynsymtab[i].name));
+		}
+		else
+		{
+			dynsymtab[i].value += iBaseDiff;
+			LOG("Sym '%s' = 0x%x (relocated)\n", MKPTR(char,dynsymtab[i].name), dynsymtab[i].value);
+		}
 	}
 	
 	// === Add to loaded list (can be imported now) ===
diff --git a/AcessNative/ld-acess.so_src/main.c b/AcessNative/ld-acess.so_src/main.c
index d9bad138..e310a84a 100644
--- a/AcessNative/ld-acess.so_src/main.c
+++ b/AcessNative/ld-acess.so_src/main.c
@@ -37,7 +37,14 @@ int main(int argc, char *argv[], char **envp)
 	printf("base = %p\n", base);
 	if( !base )	return 127;
 	
-	return appMain(appArgc, appArgv, envp);
+	__asm__ __volatile__ (
+		"push %0;\n\t"
+		"push %1;\n\t"
+		"push %2;\n\t"
+		"jmp *%3;\n\t"
+		: : "r" (envp), "r" (appArgv), "r" (appArgc), "r" (appMain) );
+	//return appMain(appArgc, appArgv, envp);
+	return -1;
 }
 
 void Warning(const char *Format, ...)
diff --git a/AcessNative/ld-acess.so_src/request.c b/AcessNative/ld-acess.so_src/request.c
index 79db625d..f9526b3a 100644
--- a/AcessNative/ld-acess.so_src/request.c
+++ b/AcessNative/ld-acess.so_src/request.c
@@ -11,17 +11,22 @@
 # 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()
@@ -75,9 +80,72 @@ 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
diff --git a/AcessNative/ld-acess.so_src/request.h b/AcessNative/ld-acess.so_src/request.h
new file mode 100644
index 00000000..8c89e6f6
--- /dev/null
+++ b/AcessNative/ld-acess.so_src/request.h
@@ -0,0 +1,26 @@
+/*
+ * Acess2 - AcessNative
+ * ld-acess
+ *
+ * request.h - IPC Request common header
+ */
+
+#ifndef _REQUEST_H_
+#define _REQUEST_H_
+
+typedef struct {
+	char	Type;
+	 int	Length;
+	char	Data[];
+}	tOutValue;
+
+typedef struct {
+	char	Type;
+	 int	Length;
+	void	*Data;
+}	tInValue;
+
+extern int SendRequest(int RequestID, int NumOutput, tOutValue **Output,
+	int NumInput, tInValue **Input);
+
+#endif
diff --git a/AcessNative/ld-acess.so_src/syscalls.c b/AcessNative/ld-acess.so_src/syscalls.c
index e26ae359..ec4af017 100644
--- a/AcessNative/ld-acess.so_src/syscalls.c
+++ b/AcessNative/ld-acess.so_src/syscalls.c
@@ -1,36 +1,225 @@
 /*
  */
-//#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);
 }
@@ -47,25 +236,66 @@ size_t write(int FD, size_t Bytes, void *Src) {
 	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]);
diff --git a/AcessNative/syscalls.h b/AcessNative/syscalls.h
index 2784fd02..e298c94d 100644
--- a/AcessNative/syscalls.h
+++ b/AcessNative/syscalls.h
@@ -3,6 +3,30 @@
 #ifndef _NATIVE_SYSCALLS_H_
 #define _NATIVE_SYSCALLS_H_
 
+/*
+ * Request format
+ * 
+ * tRequestHeader	header
+ * tRequestValue	params[header.NParams]
+ * tRequestValue	retvals[header.NReturn]
+ * uint8_t	paramData[SUM(params[].Lengh)];
+ */
+
+typedef struct sRequestValue {
+	/// \see eArgumentTypes
+	uint16_t	Type;
+	uint16_t	Length;
+}	tRequestValue;
+
+typedef struct sRequestHeader {
+	uint16_t	ClientID;
+	uint16_t	CallID;	//!< \see eSyscalls
+	uint16_t	NParams;
+	uint16_t	NReturn;
+	
+	tRequestValue	Params[];
+}	tRequestHeader;
+
 enum eSyscalls {
 	SYS_NULL,
 	SYS_OPEN
@@ -12,12 +36,7 @@ enum eArgumentTypes {
 	ARG_TYPE_VOID,
 	ARG_TYPE_INT32,
 	ARG_TYPE_INT64,
-	ARG_TYPE_STRING,
 	ARG_TYPE_DATA
 };
 
-#define ARG_DIR_TOSRV	0x10
-#define	ARG_DIR_TOCLI	0x20
-#define ARG_DIR_BOTH	0x30
-
 #endif
diff --git a/Usermode/Applications/Makefile.cfg b/Usermode/Applications/Makefile.cfg
index 6b946969..2e64b9d6 100644
--- a/Usermode/Applications/Makefile.cfg
+++ b/Usermode/Applications/Makefile.cfg
@@ -14,5 +14,5 @@ include $(dir $(lastword $(MAKEFILE_LIST)))../Makefile.cfg
 ASFLAGS = -felf
 CPPFLAGS = -I$(ACESSUSERDIR)/include/
 CFLAGS   = -fno-stack-protector $(CPPFLAGS)
-LDFLAGS  = -T $(OUTPUTDIR)Libs/acess.ld -rpath-link $(OUTPUTDIR)Libs -L $(OUTPUTDIR)Libs -I /Acess/Libs/ld-acess.so -lc
+LDFLAGS  = -T $(OUTPUTDIR)Libs/acess.ld -rpath-link $(OUTPUTDIR)Libs -L $(OUTPUTDIR)Libs -I /Acess/Libs/ld-acess.so -lld-acess -lc
 DIR = Bin
diff --git a/Usermode/Libraries/Makefile.tpl b/Usermode/Libraries/Makefile.tpl
index 5f736327..9712bf8a 100644
--- a/Usermode/Libraries/Makefile.tpl
+++ b/Usermode/Libraries/Makefile.tpl
@@ -6,14 +6,14 @@ DEPFILES := $(addsuffix .d,$(OBJ))
 
 _BIN := $(OUTPUTDIR)Libs/$(BIN)
 
-.PHONY: all clean install
+.PHONY: all clean install postbuild
 
-all: $(_BIN)
+all: $(_BIN) postbuild
 
 clean:
 	$(RM) $(_BIN) $(OBJ) $(_BIN).dsm $(DEPFILES)
 
-install: $(_BIN)
+install: all
 	$(xCP) $(_BIN) $(DISTROOT)/Libs/
 
 $(_BIN): $(OBJ)
diff --git a/Usermode/Libraries/acess.ld_src/acess.ld.h b/Usermode/Libraries/acess.ld_src/acess.ld.h
index c059c79d..e81c0a56 100644
--- a/Usermode/Libraries/acess.ld_src/acess.ld.h
+++ b/Usermode/Libraries/acess.ld_src/acess.ld.h
@@ -2,7 +2,7 @@ OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
 OUTPUT_ARCH(i386)
 ENTRY(start)
 SEARCH_DIR(__LIBDIR)
-INPUT(crt0.o ld-acess.so)
+INPUT(crt0.o)
 SECTIONS
 {
   /* Read-only sections, merged into text segment: */
diff --git a/Usermode/Libraries/ld-acess.so_src/Makefile b/Usermode/Libraries/ld-acess.so_src/Makefile
index 48bb38fa..3c02d3db 100644
--- a/Usermode/Libraries/ld-acess.so_src/Makefile
+++ b/Usermode/Libraries/ld-acess.so_src/Makefile
@@ -10,7 +10,12 @@ BIN = ld-acess.so
 
 CFLAGS   = -Wall -fno-builtin -fno-leading-underscore -fno-stack-protector
 ASFLAGS  = -felf
-LDFLAGS  = -T link.ld -Map map.txt -Bstatic
+LDFLAGS  = -T link.ld -Map map.txt -Bstatic -shared
 
 include ../Makefile.tpl
 
+postbuild: $(OUTPUTDIR)Libs/libld-acess.so
+
+$(OUTPUTDIR)Libs/libld-acess.so:
+	ln -s $(_BIN) $(OUTPUTDIR)Libs/libld-acess.so
+
-- 
GitLab