From 381005a446e3f8c7c56bf4764b2e697dee203840 Mon Sep 17 00:00:00 2001
From: John Hodge <tpg@mutabah.net>
Date: Thu, 30 Dec 2010 21:12:55 +1100
Subject: [PATCH] AcessNative - Work on the ELF Loader

- Still not working, but does load now
- Updated gitignore to ignore vim swap files
---
 .gitignore                             |   1 +
 AcessNative/ld-acess.so_src/Makefile   |   6 +-
 AcessNative/ld-acess.so_src/binary.c   | 214 ++++++++++++++++++++++++-
 AcessNative/ld-acess.so_src/common.h   |  28 +++-
 AcessNative/ld-acess.so_src/elf.c      | 214 ++++++++++++++-----------
 AcessNative/ld-acess.so_src/elf.h      |   2 +-
 AcessNative/ld-acess.so_src/main.c     |  62 +++++++
 AcessNative/ld-acess.so_src/memory.c   |  69 ++++++++
 AcessNative/ld-acess.so_src/request.c  |   3 +-
 AcessNative/ld-acess.so_src/syscalls.c |  16 ++
 10 files changed, 513 insertions(+), 102 deletions(-)
 create mode 100644 AcessNative/ld-acess.so_src/memory.c

diff --git a/.gitignore b/.gitignore
index 0f64f8bd..2491a497 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,3 +26,4 @@ SrcDoc/
 ApiDoc/
 Usermode/Output/
 gitstats/
+.*.swp
diff --git a/AcessNative/ld-acess.so_src/Makefile b/AcessNative/ld-acess.so_src/Makefile
index ba3a9460..08e12c8a 100644
--- a/AcessNative/ld-acess.so_src/Makefile
+++ b/AcessNative/ld-acess.so_src/Makefile
@@ -5,7 +5,7 @@ ifeq ($(PLATFORM),)
 	PLATFORM := lin
 endif
 
-OBJ := main.o syscalls.o request.o
+OBJ := main.o syscalls.o request.o binary.o memory.o
 OBJ += elf.o
 OBJ := $(addsuffix .$(PLATFORM),$(OBJ))
 
@@ -16,7 +16,7 @@ ifeq ($(PLATFORM),lin)
 	BIN := ../ld-acess
 endif
 
-CFLAGS += -Wall -Werror
+CFLAGS += -Wall -Werror -g
 
 .PHONY: all clean
 
@@ -26,7 +26,7 @@ clean:
 	$(RM) $(BIN) $(OBJ)
 
 $(BIN): $(OBJ)
-	$(CC) -shared -o $@ $<
+	$(CC) -g -o $@ $(OBJ)
 
 %.o.$(PLATFORM): %.c
 	$(CC) -c $< -o $@ $(CFLAGS) $(CPPFLAGS)
diff --git a/AcessNative/ld-acess.so_src/binary.c b/AcessNative/ld-acess.so_src/binary.c
index 8378c6c7..7f97edda 100644
--- a/AcessNative/ld-acess.so_src/binary.c
+++ b/AcessNative/ld-acess.so_src/binary.c
@@ -1,9 +1,221 @@
 /*
  * AcessNative
  */
+#include "common.h"
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#define LIBRARY_PATH	"../Usermode/Output/i386/Libs"
+
+// === TYPES ===
+typedef struct sBinary {
+	struct sBinary	*Next;
+	void	*Base;
+	 int	Ready;
+	tBinFmt	*Format;
+	char	Path[];
+}	tBinary;
+
+// === IMPORTS ===
+extern void	*Elf_Load(FILE *FP);
+extern uintptr_t	Elf_Relocate(void *Base);
+extern int	Elf_GetSymbol(void *Base, char *Name, uintptr_t *ret);
+extern int	ciNumBuiltinSymbols;
+extern tSym	caBuiltinSymbols[];
+
+// === PROTOTYPES ===
+void	Binary_AddToList(const char *Filename, void *Base, tBinFmt *Format);
+
+// === GLOBALS ===
+tBinFmt	gElf_FormatDef = {
+//	.Mask = 0xFFFFFFFF,
+//	.Magic = "\x7F""ELF",
+	.Name = "ELF32",
+	.Load = Elf_Load,
+	.Relocate = Elf_Relocate,
+	.GetSymbol = Elf_GetSymbol
+	};
+tBinary	*gLoadedBinaries;
 
 // === CODE ===
-int Binary_GetSymbol(const char *SymbolName, intptr_t *Value)
+char *Binary_LocateLibrary(const char *Name)
+{
+	char	*envPath = getenv("ACESS_LIBRARY_PATH");
+	 int	nameLen = strlen(Name);
+	FILE	*fp;
+	
+	// Try the environment ACESS_LIBRARY_PATH
+	if( envPath && envPath[0] != '\0' )
+	{
+		 int	len = strlen(envPath)+1+nameLen+1;
+		char	tmp[len];
+
+		strcpy(tmp, envPath);
+		strcat(tmp, "/");
+		strcat(tmp, Name);
+		
+		fp = fopen(tmp, "r");
+		if(fp) {
+			fclose(fp);
+			return strdup(tmp);
+		}
+	}		
+
+	{
+		 int	len = strlen(LIBRARY_PATH)+1+nameLen+1;
+		char	tmp[len];
+
+		strcpy(tmp, LIBRARY_PATH);
+		strcat(tmp, "/");
+		strcat(tmp, Name);
+		
+		printf("Binary_LocateLibrary: tmp = '%s'\n", tmp);
+
+		fp = fopen(tmp, "r");
+		if(fp) {
+			fclose(fp);
+			return strdup(tmp);
+		}
+	}		
+
+	fprintf(stderr, "Unable to locate library '%s'\n", Name);
+
+	return NULL;
+}
+
+void *Binary_LoadLibrary(const char *Name)
+{
+	char	*path;
+	void	*ret;
+	 int	(*entry)(int,char*[],char**) = NULL;
+
+	// Find File
+	path = Binary_LocateLibrary(Name);
+	printf("Binary_LoadLibrary: path = '%s'\n", path);
+	if( !path ) {
+		return NULL;
+	}
+
+	ret = Binary_Load(path, (uintptr_t*)&entry);
+	free(path);
+	
+	printf("Binary_LoadLibrary: ret = %p, entry = %p\n", ret, entry);
+	if( entry ) {
+		char	*argv[] = {NULL};
+		entry(0, argv, NULL);
+	}
+
+	return ret;
+}
+
+void *Binary_Load(const char *Filename, uintptr_t *EntryPoint)
 {
+	FILE	*fp;
+	uint32_t	dword;
+	void	*ret;
+	uintptr_t	entry = 0;
+	tBinFmt	*fmt;
+
+	{
+		tBinary	*bin;
+		for(bin = gLoadedBinaries; bin; bin = bin->Next)
+		{
+			if( strcmp(Filename, bin->Path) == 0 ) {
+				return bin->Base;
+			}
+		}
+	}
+
+	fp = fopen(Filename, "r");
+	if( !fp ) {
+		// TODO: Handle libary directories
+		perror("Opening binary");
+		return NULL;
+	}
+
+	fread(&dword, 1, 4, fp);
+	fseek(fp, 0, SEEK_SET);
+	printf("dword = %08x\n", dword);
+	
+	if( memcmp(&dword, "\x7F""ELF", 4) == 0 ) {
+		fmt = &gElf_FormatDef;
+	}
+	else {
+		fclose(fp);
+		return NULL;
+	}
+
+	ret = fmt->Load(fp);
+	printf("fmt->Load(%p): %p\n", fp, ret);
+	if( !ret ) {
+		fclose(fp);
+		return NULL;
+	}
+	
+	Binary_AddToList(Filename, ret, fmt);
+
+	entry = fmt->Relocate(ret);
+	printf("fmt->Relocate(%p): %p\n", ret, (void*)entry);
+	if( !entry ) {
+		// TODO: Clean up
+		return NULL;
+	}
+	
+	if( EntryPoint )
+		*EntryPoint = entry;
+
+	fclose(fp);
+
+	Binary_SetReadyToUse(ret);
+
+	return ret;
+}
+
+void Binary_AddToList(const char *Filename, void *Base, tBinFmt *Format)
+{
+	tBinary	*bin = malloc(sizeof(tBinary) + strlen(Filename) + 1);
+	bin->Base = Base;
+	bin->Format = Format;
+	strcpy(bin->Path, Filename);
+	bin->Ready = 0;
+	
+	bin->Next = gLoadedBinaries;
+	gLoadedBinaries = bin;
+}
+
+void Binary_SetReadyToUse(void *Base)
+{
+	tBinary	*bin;
+	for(bin = gLoadedBinaries; bin; bin = bin->Next)
+	{
+		if( bin->Base != Base )	continue ;
+		bin->Ready = 1;
+	}
+}
+
+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;
+	}
+
+	// Search builtins
+	for( i = 0; i < ciNumBuiltinSymbols; i ++ )
+	{
+		if( strcmp(caBuiltinSymbols[i].Name, SymbolName) == 0 ) {
+			*Value = (uintptr_t)caBuiltinSymbols[i].Value;
+			return 1;
+		}
+	}
+
 	return 0;
 }
diff --git a/AcessNative/ld-acess.so_src/common.h b/AcessNative/ld-acess.so_src/common.h
index 276938f4..4667acba 100644
--- a/AcessNative/ld-acess.so_src/common.h
+++ b/AcessNative/ld-acess.so_src/common.h
@@ -3,15 +3,33 @@
 #ifndef _COMMON_H_
 #define _COMMON_H_
 
+#include <stdlib.h>
+#include <stdio.h>
 #include <stdint.h>
 
-extern int	Binary_GetSymbol(const char *SymbolName, intptr_t *Value);
-extern int	Binary_LoadLibrary(const char *Path);
+extern int	Binary_GetSymbol(const char *SymbolName, uintptr_t *Value);
+extern void	*Binary_LoadLibrary(const char *Path);
+extern void	*Binary_Load(const char *Path, uintptr_t *EntryPoint);
+extern void	Binary_SetReadyToUse(void *Base);
 
-extern int	AllocateMemory(intptr_t VirtAddr, size_t ByteCount);
+extern int	AllocateMemory(uintptr_t VirtAddr, size_t ByteCount);
+extern uintptr_t	FindFreeRange(size_t ByteCount, int MaxBits);
 
-extern int	Warning(const char *Format, ...);
-extern int	Notice(const char *Format, ...);
+extern void	Warning(const char *Format, ...);
+extern void	Notice(const char *Format, ...);
+
+typedef struct {
+	char	*Name;
+	void	*Value;
+}	tSym;
+
+typedef struct sBinFmt {
+	struct sBinFmt	*Next;
+	char	*Name;
+	void	*(*Load)(FILE *fp);
+	uintptr_t	(*Relocate)(void *base);
+	 int	(*GetSymbol)(void*,char*,uintptr_t*);
+}	tBinFmt;
 
 #endif
 
diff --git a/AcessNative/ld-acess.so_src/elf.c b/AcessNative/ld-acess.so_src/elf.c
index 35ac56b4..11bd2df7 100644
--- a/AcessNative/ld-acess.so_src/elf.c
+++ b/AcessNative/ld-acess.so_src/elf.c
@@ -12,19 +12,31 @@
 
 #define DEBUG_WARN	1
 
+#define MKPTR(_type,_val)	((_type*)(uintptr_t)(_val))
+#define PTRMK(_type,_val)	MKPTR(_type,_val)
+#define PTR(_val)	((void*)(uintptr_t)(_val))
+
+#if 0
+# 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(...)
+#endif
 
 // === PROTOTYPES ===
- int	Elf_Load(int fd);
- int	Elf_Relocate(void *Base);
- int	Elf_GetSymbol(void *Base, char *Name, intptr_t *ret);
- int	Elf_Int_DoRelocate(uint32_t r_info, uint32_t *ptr, uint32_t addend, Elf32_Sym *symtab, intptr_t base);
+void	*Elf_Load(FILE *FP);
+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 ===
-int Elf_Load(int FD)
+void *Elf_Load(FILE *FP)
 {
 	Elf32_Ehdr	hdr;
 	Elf32_Phdr	*phtab;
@@ -32,17 +44,18 @@ int Elf_Load(int FD)
 	 int	iPageCount;
 	uint32_t	max, base = -1;
 	uint32_t	addr;
+	uint32_t	baseDiff = 0;
 	
-	ENTER("xFD", FD);
+	ENTER("pFP", FP);
 	
 	// Read ELF Header
-	read(FD, &hdr, sizeof(hdr));
+	fread(&hdr, sizeof(hdr), 1, FP);
 	
 	// Check the file type
 	if(hdr.ident[0] != 0x7F || hdr.ident[1] != 'E' || hdr.ident[2] != 'L' || hdr.ident[3] != 'F') {
 		Warning("Non-ELF File was passed to the ELF loader\n");
 		LEAVE('n');
-		return 1;
+		return NULL;
 	}
 	
 	// Check for a program header
@@ -51,32 +64,32 @@ int Elf_Load(int FD)
 		Warning("ELF File does not contain a program header\n");
 		#endif
 		LEAVE('n');
-		return 1;
+		return NULL;
 	}
 	
 	// Read Program Header Table
 	phtab = malloc( sizeof(Elf32_Phdr) * hdr.phentcount );
 	if( !phtab ) {
 		LEAVE('n');
-		return 1;
+		return NULL;
 	}
-	LOG("hdr.phoff = 0x%08x", hdr.phoff);
-	lseek(FD, hdr.phoff, SEEK_SET);
-	read(FD, phtab, sizeof(Elf32_Phdr)*hdr.phentcount);
+	LOG("hdr.phoff = 0x%08x\n", hdr.phoff);
+	fseek(FP, hdr.phoff, SEEK_SET);
+	fread(phtab, sizeof(Elf32_Phdr), hdr.phentcount, FP);
 	
 	// Count Pages
 	iPageCount = 0;
-	LOG("hdr.phentcount = %i", hdr.phentcount);
+	LOG("hdr.phentcount = %i\n", hdr.phentcount);
 	for( i = 0; i < hdr.phentcount; i++ )
 	{
 		// Ignore Non-LOAD types
 		if(phtab[i].Type != PT_LOAD)
 			continue;
 		iPageCount += ((phtab[i].VAddr&0xFFF) + phtab[i].MemSize + 0xFFF) >> 12;
-		LOG("phtab[%i] = {VAddr:0x%x, MemSize:0x%x}", i, phtab[i].VAddr, phtab[i].MemSize);
+		LOG("phtab[%i] = {VAddr:0x%x, MemSize:0x%x}\n", i, phtab[i].VAddr, phtab[i].MemSize);
 	}
 	
-	LOG("iPageCount = %i", iPageCount);
+	LOG("iPageCount = %i\n", iPageCount);
 	
 	// Allocate Information Structure
 	//ret = malloc( sizeof(tBinary) + sizeof(tBinaryPage)*iPageCount );
@@ -97,71 +110,80 @@ int Elf_Load(int FD)
 			max = phtab[i].VAddr;
 	}
 
-	LOG("base = %08x, max = %08x", base, max);
+	LOG("base = %08x, max = %08x\n", base, max);
+
+	if( base == 0 ) {
+		// Find a nice space (31 address bits allowed)
+		base = FindFreeRange( max, 31 );
+		LOG("new base = %08x\n", base);
+		if( base == 0 )	return NULL;
+		baseDiff = base;
+	}
 	
 	// Load Pages
 	j = 0;
 	for( i = 0; i < hdr.phentcount; i++ )
 	{
 		//LOG("phtab[%i].Type = 0x%x", i, phtab[i].Type);
-		LOG("phtab[%i] = {", i);
-		LOG(" .Type = 0x%08x", phtab[i].Type);
-		LOG(" .Offset = 0x%08x", phtab[i].Offset);
-		LOG(" .VAddr = 0x%08x", phtab[i].VAddr);
-		LOG(" .PAddr = 0x%08x", phtab[i].PAddr);
-		LOG(" .FileSize = 0x%08x", phtab[i].FileSize);
-		LOG(" .MemSize = 0x%08x", phtab[i].MemSize);
-		LOG(" .Flags = 0x%08x", phtab[i].Flags);
-		LOG(" .Align = 0x%08x", phtab[i].Align);
-		LOG(" }");
+		LOG("phtab[%i] = {\n", i);
+		LOG(" .Type = 0x%08x\n", phtab[i].Type);
+		LOG(" .Offset = 0x%08x\n", phtab[i].Offset);
+		LOG(" .VAddr = 0x%08x\n", phtab[i].VAddr);
+		LOG(" .PAddr = 0x%08x\n", phtab[i].PAddr);
+		LOG(" .FileSize = 0x%08x\n", phtab[i].FileSize);
+		LOG(" .MemSize = 0x%08x\n", phtab[i].MemSize);
+		LOG(" .Flags = 0x%08x\n", phtab[i].Flags);
+		LOG(" .Align = 0x%08x\n", phtab[i].Align);
+		LOGS(" }\n");
 		// Get Interpreter Name
 		if( phtab[i].Type == PT_INTERP )
 		{
 			char *tmp;
 			//if(ret->Interpreter)	continue;
 			tmp = malloc(phtab[i].FileSize);
-			lseek(FD, phtab[i].Offset, 1);
-			read(FD, tmp, phtab[i].FileSize);
+			fseek(FP, phtab[i].Offset, SEEK_SET);
+			fread(tmp, phtab[i].FileSize, 1, FP);
 			//ret->Interpreter = Binary_RegInterp(tmp);
-			LOG("Interpreter '%s'", tmp);
+			LOG("Interpreter '%s'\n", tmp);
 			free(tmp);
 			continue;
 		}
 		// Ignore non-LOAD types
 		if(phtab[i].Type != PT_LOAD)	continue;
 		
-		LOG("phtab[%i] = {VAddr:0x%x,Offset:0x%x,FileSize:0x%x}",
-			i, phtab[i].VAddr, phtab[i].Offset, phtab[i].FileSize);
+		LOG("phtab[%i] = {VAddr:0x%x,Offset:0x%x,FileSize:0x%x}\n",
+			i, phtab[i].VAddr+baseDiff, phtab[i].Offset, phtab[i].FileSize);
 		
-		addr = phtab[i].VAddr;
+		addr = phtab[i].VAddr + baseDiff;
 
-		AllocateMemory( addr, phtab[i].MemSize );
+		if( AllocateMemory( addr, phtab[i].MemSize ) ) {
+			return NULL;
+		}
 		
-		lseek(FD, phtab[i].Offset, SEEK_SET);
-		read(FD, (void*)(intptr_t)addr, phtab[i].FileSize);
-		memset( (char*)(intptr_t)addr + phtab[i].FileSize, 0, phtab[i].MemSize - phtab[i].FileSize);
+		fseek(FP, phtab[i].Offset, SEEK_SET);
+		fread( PTRMK(void, addr), phtab[i].FileSize, 1, FP );
+		memset( PTRMK(char, addr) + phtab[i].FileSize, 0, phtab[i].MemSize - phtab[i].FileSize );
 	}
 	
 	// Clean Up
 	free(phtab);
 	// Return
-	LEAVE('i', 0);
-	return 0;
+	LEAVE('p', base);
+	return PTRMK(void, base);
 }
 
 // --- ELF RELOCATION ---
 /**
- \fn int Elf_Relocate(void *Base)
- \brief Relocates a loaded ELF Executable
-*/
-int Elf_Relocate(void *Base)
+ * \brief Relocates a loaded ELF Executable
+ */
+uintptr_t Elf_Relocate(void *Base)
 {
 	Elf32_Ehdr	*hdr = Base;
 	Elf32_Phdr	*phtab;
 	 int	i, j;	// Counters
 	char	*libPath;
 	uint32_t	iRealBase = -1;
-	intptr_t	iBaseDiff;
+	uintptr_t	iBaseDiff;
 	 int	iSegmentCount;
 	 int	iSymCount = 0;
 	Elf32_Rel	*rel = NULL;
@@ -178,6 +200,7 @@ int Elf_Relocate(void *Base)
 	 int	bFailed = 0;
 	
 	ENTER("pBase", Base);
+	LOG("Base = %p\n", Base);
 	
 	// Parse Program Header to get Dynamic Table
 	phtab = Base + hdr->phoff;
@@ -194,7 +217,7 @@ int Elf_Relocate(void *Base)
 				Warning("Elf_Relocate - Multiple PT_DYNAMIC segments\n");
 				continue;
 			}
-			dynamicTab = (void *) (intptr_t) phtab[i].VAddr;
+			dynamicTab = MKPTR(void, phtab[i].VAddr);
 			j = i;	// Save Dynamic Table ID
 			break;
 		}
@@ -210,10 +233,15 @@ int Elf_Relocate(void *Base)
 	// Page Align real base
 	iRealBase &= ~0xFFF;
 	
+	LOG("dynamicTab = %p\n", dynamicTab);
 	// Adjust "Real" Base
-	iBaseDiff = (intptr_t)Base - iRealBase;
+	iBaseDiff = (uintptr_t)Base - iRealBase;
+	LOG("iBaseDiff = %p\n", (void*)iBaseDiff);
 	// Adjust Dynamic Table
-	dynamicTab = (void *) ((intptr_t)dynamicTab + iBaseDiff);
+	dynamicTab = PTR( (uintptr_t)dynamicTab + iBaseDiff);
+	LOG("dynamicTab = %p\n", dynamicTab);
+
+	hdr->entrypoint += iBaseDiff;
 	
 	// === Get Symbol table and String Table ===
 	for( j = 0; dynamicTab[j].d_tag != DT_NULL; j++)
@@ -223,20 +251,20 @@ int Elf_Relocate(void *Base)
 		// --- Symbol Table ---
 		case DT_SYMTAB:
 			dynamicTab[j].d_val += iBaseDiff;
-			dynsymtab = (void*) (intptr_t) dynamicTab[j].d_val;
+			dynsymtab = PTRMK(void, dynamicTab[j].d_val);
 			hdr->misc.SymTable = dynamicTab[j].d_val;	// Saved in unused bytes of ident
 			break;
 		
 		// --- String Table ---
 		case DT_STRTAB:
 			dynamicTab[j].d_val += iBaseDiff;
-			dynstrtab = (void*) (intptr_t) dynamicTab[j].d_val;
+			dynstrtab = PTRMK(void, dynamicTab[j].d_val);
 			break;
 		
 		// --- Hash Table --
 		case DT_HASH:
 			dynamicTab[j].d_val += iBaseDiff;
-			iSymCount = ((uint32_t*)((intptr_t)dynamicTab[j].d_val))[1];
+			iSymCount = (PTRMK(uint32_t, dynamicTab[j].d_val))[1];
 			hdr->misc.HashTable = dynamicTab[j].d_val;	// Saved in unused bytes of ident
 			break;
 		}
@@ -247,12 +275,12 @@ int Elf_Relocate(void *Base)
 	for(i = 0; i < iSymCount; i ++)
 	{
 		dynsymtab[i].value += iBaseDiff;
-		dynsymtab[i].nameOfs += (intptr_t)dynstrtab;
-		//LOG("Sym '%s' = 0x%x (relocated)\n", dynsymtab[i].name, dynsymtab[i].value);
+		dynsymtab[i].nameOfs += (uintptr_t)dynstrtab;
+		LOG("Sym '%s' = 0x%x (relocated)\n", MKPTR(char,dynsymtab[i].name), dynsymtab[i].value);
 	}
 	
 	// === Add to loaded list (can be imported now) ===
-	//Binary_AddLoaded( (intptr_t)Base );
+	Binary_SetReadyToUse( Base );
 
 	// === Parse Relocation Data ===
 	for( j = 0; dynamicTab[j].d_tag != DT_NULL; j++)
@@ -261,12 +289,12 @@ int Elf_Relocate(void *Base)
 		{
 		// --- Shared Library Name ---
 		case DT_SONAME:
-			LOG(".so Name '%s'\n", dynstrtab+dynamicTab[j].d_val);
+			LOG(".so Name '%s'\n", dynstrtab + dynamicTab[j].d_val);
 			break;
 		// --- Needed Library ---
 		case DT_NEEDED:
 			libPath = dynstrtab + dynamicTab[j].d_val;
-			Notice("%p - Required Library '%s' - TODO load DT_NEEDED\n", Base, libPath);
+			Binary_LoadLibrary(libPath);
 			break;
 		// --- PLT/GOT ---
 		case DT_PLTGOT:	pltgot = (void*)(iBaseDiff+dynamicTab[j].d_val);	break;
@@ -292,7 +320,7 @@ int Elf_Relocate(void *Base)
 		for( i = 0; i < j; i++ )
 		{
 			ptr = (void*)(iBaseDiff + rel[i].r_offset);
-			if( !Elf_Int_DoRelocate(rel[i].r_info, ptr, *ptr, dynsymtab, (intptr_t)Base) ) {
+			if( !Elf_Int_DoRelocate(rel[i].r_info, ptr, *ptr, dynsymtab, Base) ) {
 				bFailed = 1;
 			}
 		}
@@ -304,7 +332,7 @@ int Elf_Relocate(void *Base)
 		for( i = 0; i < j; i++ )
 		{
 			ptr = (void*)(iBaseDiff + rela[i].r_offset);
-			if( !Elf_Int_DoRelocate(rel[i].r_info, ptr, rela[i].r_addend, dynsymtab, (intptr_t)Base) ) {
+			if( !Elf_Int_DoRelocate(rel[i].r_info, ptr, rela[i].r_addend, dynsymtab, Base) ) {
 				bFailed = 1;
 			}
 		}
@@ -317,11 +345,11 @@ int Elf_Relocate(void *Base)
 		{
 			Elf32_Rel	*pltRel = plt;
 			j = pltSz / sizeof(Elf32_Rel);
-			LOG("PLT Rel - plt = %p, pltSz = %i (%i ents)", plt, pltSz, j);
+			LOG("PLT Rel - plt = %p, pltSz = %i (%i ents)\n", plt, pltSz, j);
 			for(i = 0; i < j; i++)
 			{
 				ptr = (void*)(iBaseDiff + pltRel[i].r_offset);
-				if( !Elf_Int_DoRelocate(pltRel[i].r_info, ptr, *ptr, dynsymtab, (intptr_t)Base) ) {
+				if( !Elf_Int_DoRelocate(pltRel[i].r_info, ptr, *ptr, dynsymtab, Base) ) {
 					bFailed = 1;
 				}
 			}
@@ -330,11 +358,11 @@ int Elf_Relocate(void *Base)
 		{
 			Elf32_Rela	*pltRela = plt;
 			j = pltSz / sizeof(Elf32_Rela);
-			LOG("PLT RelA - plt = %p, pltSz = %i (%i ents)", plt, pltSz, j);
+			LOG("PLT RelA - plt = %p, pltSz = %i (%i ents)\n", plt, pltSz, j);
 			for(i=0;i<j;i++)
 			{
 				ptr = (void*)(iBaseDiff + pltRela[i].r_offset);
-				if( !Elf_Int_DoRelocate(pltRela[i].r_info, ptr, pltRela[i].r_addend, dynsymtab, (intptr_t)Base) ) {
+				if( !Elf_Int_DoRelocate(pltRela[i].r_info, ptr, pltRela[i].r_addend, dynsymtab, Base) ) {
 					bFailed = 1;
 				}
 			}
@@ -351,7 +379,7 @@ int Elf_Relocate(void *Base)
 }
 
 /**
- * \fn void Elf_Int_DoRelocate(uint32_t r_info, uint32_t *ptr, uint32_t addend, Elf32_Sym *symtab, uint32_t base)
+ * \fn void Elf_Int_DoRelocate(uint32_t r_info, uint32_t *ptr, uint32_t addend, Elf32_Sym *symtab, void *base)
  * \brief Performs a relocation
  * \param r_info	Field from relocation entry
  * \param ptr	Pointer to location of relocation
@@ -359,12 +387,12 @@ int Elf_Relocate(void *Base)
  * \param symtab	Symbol Table
  * \param base	Base of loaded binary
  */
-int Elf_Int_DoRelocate(uint32_t r_info, uint32_t *ptr, uint32_t addend, Elf32_Sym *symtab, intptr_t base)
+int Elf_Int_DoRelocate(uint32_t r_info, uint32_t *ptr, uint32_t addend, Elf32_Sym *symtab, void *base)
 {
-	intptr_t	val;
+	uintptr_t	val;
 	 int	type = ELF32_R_TYPE(r_info);
 	 int	sym = ELF32_R_SYM(r_info);
-	char	*sSymName = symtab[sym].name;
+	char	*sSymName = PTRMK(char, symtab[sym].name);
 	
 	//LogF("Elf_Int_DoRelocate: (r_info=0x%x, ptr=0x%x, addend=0x%x, .., base=0x%x)\n",
 	//	r_info, ptr, addend, base);
@@ -373,60 +401,64 @@ int Elf_Int_DoRelocate(uint32_t r_info, uint32_t *ptr, uint32_t addend, Elf32_Sy
 	{
 	// Standard 32 Bit Relocation (S+A)
 	case R_386_32:
-		if( !Elf_GetSymbol((void*)base, sSymName, &val) )	// Search this binary first
-			if( !Binary_GetSymbol( sSymName, &val ) )
-				return 0;
-		LOG("%08x R_386_32 *0x%x += 0x%x('%s')", r_info, ptr, val, sSymName);
+		if( !Elf_GetSymbol( base, sSymName, &val ) && !Binary_GetSymbol( sSymName, &val ) ) {
+			Warning("Unable to find symbol '%s'", sSymName);
+			return 0;
+		}
+		LOG("%08x R_386_32 *%p += %p('%s')\n", r_info, ptr, (void*)val, sSymName);
 		*ptr = val + addend;
 		break;
 		
 	// 32 Bit Relocation wrt. Offset (S+A-P)
 	case R_386_PC32:
-		if( !Elf_GetSymbol( (void*)base, sSymName, &val ) )
-			if( !Binary_GetSymbol( sSymName, &val ) )
-				return 0;
-		LOG("%08x R_386_PC32 *0x%x = 0x%x + 0x%x('%s') - %p", r_info, ptr, *ptr, val, sSymName, ptr );
+		if( !Elf_GetSymbol( base, sSymName, &val ) && !Binary_GetSymbol( sSymName, &val ) ) {
+			Warning("Unable to find symbol '%s'", sSymName);
+			return 0;
+		}
+		LOG("%08x R_386_PC32 *%p = 0x%x + %p('%s') - %p\n", r_info, ptr, *ptr, (void*)val, sSymName, ptr );
 		// TODO: Check if it needs the true value of ptr or the compiled value
 		// NOTE: Testing using true value
-		*ptr = val + addend - (intptr_t)ptr;
+		*ptr = val + addend - (uintptr_t)ptr;
 		break;
 
 	// Absolute Value of a symbol (S)
 	case R_386_GLOB_DAT:
-		if( !Elf_GetSymbol( (void*)base, sSymName, &val ) )
-			if( !Binary_GetSymbol( sSymName, &val ) )
-				return 0;
-		LOG("%08x R_386_GLOB_DAT *0x%x = 0x%x (%s)", r_info, ptr, val, sSymName);
+		if( !Elf_GetSymbol( base, sSymName, &val ) && !Binary_GetSymbol( sSymName, &val ) ) {
+			Warning("Unable to find symbol '%s'", sSymName);
+			return 0; 
+		}
+		LOG("%08x R_386_GLOB_DAT *%p = 0x%x(%s)\n", r_info, ptr, (unsigned int)val, sSymName);
 		*ptr = val;
 		break;
 	
 	// Absolute Value of a symbol (S)
 	case R_386_JMP_SLOT:
-		if( !Elf_GetSymbol( (void*)base, sSymName, &val ) )
-			if( !Binary_GetSymbol( sSymName, &val ) )
-				return 0;
-		LOG("%08x R_386_JMP_SLOT %p = 0x%x (%s)", r_info, ptr, val, sSymName);
+		if( !Elf_GetSymbol( base, sSymName, &val ) && !Binary_GetSymbol( sSymName, &val ) ) {
+			Warning("Unable to find symbol '%s'", sSymName);
+			return 0;
+		}
+		LOG("%08x R_386_JMP_SLOT *%p = 0x%x (%s)\n", r_info, ptr, (unsigned int)val, sSymName);
 		*ptr = val;
 		break;
 
 	// Base Address (B+A)
 	case R_386_RELATIVE:
-		LOG("%08x R_386_RELATIVE %p = 0x%x + 0x%x", r_info, ptr, base, addend);
-		*ptr = base + addend;
+		LOG("%08x R_386_RELATIVE *%p = %p + 0x%x\n", r_info, ptr, base, addend);
+		*ptr = (uintptr_t)base + addend;
 		break;
 		
 	default:
-		LOG("Rel 0x%x: 0x%x,%i", ptr, sym, type);
+		LOG("Rel %p: 0x%x,%i\n", ptr, sym, type);
 		break;
 	}
 	return 1;
 }
 
 /**
- * \fn int Elf_GetSymbol(void *Base, char *name, intptr_t *ret)
+ * \fn int Elf_GetSymbol(void *Base, char *name, uintptr_t *ret)
  * \brief Get a symbol from the loaded binary
  */
-int Elf_GetSymbol(void *Base, char *Name, intptr_t *ret)
+int Elf_GetSymbol(void *Base, char *Name, uintptr_t *ret)
 {
 	Elf32_Ehdr	*hdr = (void*)Base;
 	Elf32_Sym	*symtab;
@@ -439,8 +471,8 @@ int Elf_GetSymbol(void *Base, char *Name, intptr_t *ret)
 
 	if(!Base)	return 0;
 
-	pBuckets = (void *)(intptr_t) hdr->misc.HashTable;
-	symtab = (void *)(intptr_t) hdr->misc.SymTable;
+	pBuckets = PTR(hdr->misc.HashTable);
+	symtab = PTR(hdr->misc.SymTable);
 	
 	nbuckets = pBuckets[0];
 	iSymCount = pBuckets[1];
@@ -453,7 +485,7 @@ int Elf_GetSymbol(void *Base, char *Name, intptr_t *ret)
 
 	// Check Bucket
 	i = pBuckets[ iNameHash ];
-	if(symtab[i].shndx != SHN_UNDEF && strcmp(symtab[i].name, Name) == 0) {
+	if(symtab[i].shndx != SHN_UNDEF && strcmp(MKPTR(char,symtab[i].name), Name) == 0) {
 		if(ret)	*ret = symtab[ i ].value;
 		return 1;
 	}
@@ -462,7 +494,7 @@ int Elf_GetSymbol(void *Base, char *Name, intptr_t *ret)
 	while(pChains[i] != STN_UNDEF)
 	{
 		i = pChains[i];
-		if(symtab[i].shndx != SHN_UNDEF && strcmp(symtab[ i ].name, Name) == 0) {
+		if(symtab[i].shndx != SHN_UNDEF && strcmp(MKPTR(char,symtab[i].name), Name) == 0) {
 			if(ret)	*ret = symtab[ i ].value;
 			return 1;
 		}
diff --git a/AcessNative/ld-acess.so_src/elf.h b/AcessNative/ld-acess.so_src/elf.h
index 2527e99a..77be918b 100644
--- a/AcessNative/ld-acess.so_src/elf.h
+++ b/AcessNative/ld-acess.so_src/elf.h
@@ -108,7 +108,7 @@ struct sElf32_Shent {
 struct elf_sym_s {
 	union {
 		uint32_t	nameOfs;
-		char	*name;
+		uint32_t	name;
 	};
 	uint32_t	value;	//Address
 	uint32_t	size;
diff --git a/AcessNative/ld-acess.so_src/main.c b/AcessNative/ld-acess.so_src/main.c
index e69de29b..d9bad138 100644
--- a/AcessNative/ld-acess.so_src/main.c
+++ b/AcessNative/ld-acess.so_src/main.c
@@ -0,0 +1,62 @@
+/*
+ */
+#include "common.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+// === CODE ===
+int main(int argc, char *argv[], char **envp)
+{
+	 int	i;
+	 int	appArgc;
+	char	**appArgv;
+	char	*appPath;
+	 int	(*appMain)(int, char *[], char **);
+	void	*base;
+	
+	for( i = 1; i < argc; i ++ )
+	{
+		if( argv[i][0] != '-' )	break;
+	}
+
+	if( i >= argc ) {
+		fprintf(stderr, "Usage: ld-acess <executable> [arguments ...]\n");
+		return 1;
+	}
+	
+	appPath = argv[i];
+
+	appArgc = argc - i;
+	appArgv = &argv[i];
+
+	printf("Exectutable Path: '%s'\n", appPath);
+	printf("Executable argc = %i\n", appArgc);
+
+	base = Binary_Load(appPath, (uintptr_t*)&appMain);
+	printf("base = %p\n", base);
+	if( !base )	return 127;
+	
+	return appMain(appArgc, appArgv, envp);
+}
+
+void Warning(const char *Format, ...)
+{
+	va_list	args;
+	printf("Warning: ");
+	va_start(args, Format);
+	vprintf(Format, args);
+	va_end(args);
+	printf("\n");
+}
+
+void Notice(const char *Format, ...)
+{
+	va_list	args;
+	printf("Notice: ");
+	va_start(args, Format);
+	vprintf(Format, args);
+	va_end(args);
+	printf("\n");
+}
+
diff --git a/AcessNative/ld-acess.so_src/memory.c b/AcessNative/ld-acess.so_src/memory.c
new file mode 100644
index 00000000..627f9024
--- /dev/null
+++ b/AcessNative/ld-acess.so_src/memory.c
@@ -0,0 +1,69 @@
+/*
+ */
+#include "common.h"
+#include <stdio.h>
+#include <stdlib.h>
+#if __WIN32__
+# include <windows.h>
+#else
+# include <sys/mman.h>
+# include <errno.h>
+#endif
+
+// === PROTOTYPES ===
+ int	AllocateMemory(uintptr_t VirtAddr, size_t ByteCount);
+uintptr_t	FindFreeRange(size_t ByteCount, int MaxBits);
+
+// === CODE ===
+int AllocateMemory(uintptr_t VirtAddr, size_t ByteCount)
+{
+	uintptr_t	base = (VirtAddr >> 12) << 12;
+	size_t	size = (VirtAddr & 0xFFF) + ByteCount;
+	void	*tmp;
+	#if __WIN32__
+	tmp = VirtualAlloc(base, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
+	if( tmp == NULL ) {
+		printf("ERROR: Unable to allocate memory (%i)\n", GetLastError());
+		return -1;
+	}
+	#else
+	tmp = mmap((void*)base, size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
+	if( tmp == MAP_FAILED ) {
+		return -1;
+	}
+	#endif
+	return 0;
+}
+
+uintptr_t FindFreeRange(size_t ByteCount, int MaxBits)
+{
+	#if __WIN32__
+	# error "Windows FindFreeRange() unimplemented"
+	#else
+	uintptr_t	base, ofs, size;
+	uintptr_t	end = -1;
+	const int	PAGE_SIZE = 0x1000;
+	
+	size = (ByteCount + PAGE_SIZE - 1) / PAGE_SIZE;
+	size *= PAGE_SIZE;
+
+	end <<= (sizeof(intptr_t)*8-MaxBits);
+	end >>= (sizeof(intptr_t)*8-MaxBits);
+	printf("end = %p\n", (void*)end);
+	
+//	for( base = 0; base < end - size; base -= PAGE_SIZE )
+	for( base = end - size + 1; base > 0; base -= PAGE_SIZE )
+	{
+		for( ofs = 0; ofs < size; ofs += PAGE_SIZE ) {
+			if( msync( (void*)(base+ofs), 1, 0) == 0 )
+				break;
+			if( errno != ENOMEM )
+				perror("FindFreeRange, msync");
+		}
+		if( ofs >= size ) {
+			return base;
+		}
+	}
+	return 0;
+	#endif
+}
diff --git a/AcessNative/ld-acess.so_src/request.c b/AcessNative/ld-acess.so_src/request.c
index e806ca0d..79db625d 100644
--- a/AcessNative/ld-acess.so_src/request.c
+++ b/AcessNative/ld-acess.so_src/request.c
@@ -75,8 +75,9 @@ int _InitSyscalls()
 	}
 	return 0;
 }
-
+#if 0
 int _Syscall(const char *ArgTypes, ...)
 {
 	return 0;
 }
+#endif
diff --git a/AcessNative/ld-acess.so_src/syscalls.c b/AcessNative/ld-acess.so_src/syscalls.c
index 416cab61..e26ae359 100644
--- a/AcessNative/ld-acess.so_src/syscalls.c
+++ b/AcessNative/ld-acess.so_src/syscalls.c
@@ -1,12 +1,15 @@
 /*
  */
 //#include <acess/sys.h>
+#include "common.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
 #include <stdarg.h>
 
 // === IMPORTS ===
+
+// === CODE ===
 /**
  * \param ArgTypes
  *
@@ -54,3 +57,16 @@ int seek(int FD, uint64_t Ofs, int Dir) {
 	return _Syscall(">i >I >i", FD, Ofs, Dir);
 }
 
+// === Symbol List ===
+const tSym	caBuiltinSymbols[] = {
+	{"open", open},
+	{"close", close},
+	{"read", read},
+	{"write", write},
+	{"tell", tell},
+	{"seek", seek},
+	{"_exit", exit}
+};
+
+const int	ciNumBuiltinSymbols = sizeof(caBuiltinSymbols)/sizeof(caBuiltinSymbols[0]);
+
-- 
GitLab