Renamed ld-acess.so_src directory to ld-acess_src
authorJohn Hodge <[email protected]>
Tue, 18 Jan 2011 23:48:16 +0000 (07:48 +0800)
committerJohn Hodge <[email protected]>
Tue, 18 Jan 2011 23:48:16 +0000 (07:48 +0800)
20 files changed:
AcessNative/ld-acess.so_src/Makefile [deleted file]
AcessNative/ld-acess.so_src/binary.c [deleted file]
AcessNative/ld-acess.so_src/common.h [deleted file]
AcessNative/ld-acess.so_src/elf.c [deleted file]
AcessNative/ld-acess.so_src/elf.h [deleted file]
AcessNative/ld-acess.so_src/main.c [deleted file]
AcessNative/ld-acess.so_src/memory.c [deleted file]
AcessNative/ld-acess.so_src/request.c [deleted file]
AcessNative/ld-acess.so_src/request.h [deleted file]
AcessNative/ld-acess.so_src/syscalls.c [deleted file]
AcessNative/ld-acess_src/Makefile [new file with mode: 0644]
AcessNative/ld-acess_src/binary.c [new file with mode: 0644]
AcessNative/ld-acess_src/common.h [new file with mode: 0644]
AcessNative/ld-acess_src/elf.c [new file with mode: 0644]
AcessNative/ld-acess_src/elf.h [new file with mode: 0644]
AcessNative/ld-acess_src/main.c [new file with mode: 0644]
AcessNative/ld-acess_src/memory.c [new file with mode: 0644]
AcessNative/ld-acess_src/request.c [new file with mode: 0644]
AcessNative/ld-acess_src/request.h [new file with mode: 0644]
AcessNative/ld-acess_src/syscalls.c [new file with mode: 0644]

diff --git a/AcessNative/ld-acess.so_src/Makefile b/AcessNative/ld-acess.so_src/Makefile
deleted file mode 100644 (file)
index 4fb6ae2..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-#
-
-ifeq ($(PLATFORM),)
-       PLATFORM := lin
-endif
-
-OBJ := main.o syscalls.o request.o binary.o memory.o
-OBJ += elf.o
-OBJ := $(addsuffix .$(PLATFORM),$(OBJ))
-
-ifeq ($(PLATFORM),win)
-       BIN := ../ld-acess.exe
-endif
-ifeq ($(PLATFORM),lin)
-       BIN := ../ld-acess
-       LD += -m elf_i386
-endif
-
-CFLAGS += -Wall -Werror -g -m32
-
-.PHONY: all clean
-
-all: $(BIN)
-
-clean:
-       $(RM) $(BIN) $(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
deleted file mode 100644 (file)
index b8f6e71..0000000
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * 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 ===
-char *Binary_LocateLibrary(const char *Name)
-{
-       char    *envPath = getenv("ACESS_LIBRARY_PATH");
-        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' )
-       {
-                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};
-               printf("Calling '%s' entry point %p\n", Name, entry);
-               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;
-
-       // 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)
-               {
-                       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;
-       }
-       
-       printf("fmt->Load(%p)...\n", fp);
-       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;
-       
-       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 ) {
-                       *Value = (uintptr_t)caBuiltinSymbols[i].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/common.h b/AcessNative/ld-acess.so_src/common.h
deleted file mode 100644 (file)
index 4667acb..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- */
-#ifndef _COMMON_H_
-#define _COMMON_H_
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
-
-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(uintptr_t VirtAddr, size_t ByteCount);
-extern uintptr_t       FindFreeRange(size_t ByteCount, int MaxBits);
-
-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
deleted file mode 100644 (file)
index 3ab5a50..0000000
+++ /dev/null
@@ -1,529 +0,0 @@
-/*\r
- * Acess v0.1\r
- * ELF Executable Loader Code\r
- */\r
-#define DEBUG  0\r
-#include <stdlib.h>\r
-#include <stdio.h>\r
-#include <string.h>\r
-#include <unistd.h>\r
-#include "common.h"\r
-#include "elf.h"\r
-\r
-#define DEBUG_WARN     1\r
-\r
-#define MKPTR(_type,_val)      ((_type*)(uintptr_t)(_val))\r
-#define PTRMK(_type,_val)      MKPTR(_type,_val)\r
-#define PTR(_val)      ((void*)(uintptr_t)(_val))\r
-\r
-#if DEBUG\r
-# define ENTER(...)\r
-# define LOG(s, ...)   printf("%s: " s, __func__, __VA_ARGS__)\r
-# define LOGS(s)       printf("%s: " s, __func__)\r
-# define LEAVE(...)\r
-#else\r
-# define ENTER(...)\r
-# define LOG(...)\r
-# define LOGS(...)\r
-# define LEAVE(...)\r
-#endif\r
-\r
-// === PROTOTYPES ===\r
-void   *Elf_Load(FILE *FP);\r
-uintptr_t      Elf_Relocate(void *Base);\r
- int   Elf_GetSymbol(void *Base, char *Name, uintptr_t *ret);\r
- int   Elf_Int_DoRelocate(uint32_t r_info, uint32_t *ptr, uint32_t addend, Elf32_Sym *symtab, void *Base);\r
-uint32_t       Elf_Int_HashString(char *str);\r
-\r
-// === CODE ===\r
-void *Elf_Load(FILE *FP)\r
-{\r
-       Elf32_Ehdr      hdr;\r
-       Elf32_Phdr      *phtab;\r
-        int    i, j;\r
-        int    iPageCount;\r
-       uint32_t        max, base = -1;\r
-       uint32_t        addr;\r
-       uint32_t        baseDiff = 0;\r
-       \r
-       ENTER("pFP", FP);\r
-       \r
-       // Read ELF Header\r
-       fread(&hdr, sizeof(hdr), 1, FP);\r
-       \r
-       // Check the file type\r
-       if(hdr.ident[0] != 0x7F || hdr.ident[1] != 'E' || hdr.ident[2] != 'L' || hdr.ident[3] != 'F') {\r
-               Warning("Non-ELF File was passed to the ELF loader\n");\r
-               LEAVE('n');\r
-               return NULL;\r
-       }\r
-       \r
-       // Check for a program header\r
-       if(hdr.phoff == 0) {\r
-               #if DEBUG_WARN\r
-               Warning("ELF File does not contain a program header\n");\r
-               #endif\r
-               LEAVE('n');\r
-               return NULL;\r
-       }\r
-       \r
-       // Read Program Header Table\r
-       phtab = malloc( sizeof(Elf32_Phdr) * hdr.phentcount );\r
-       if( !phtab ) {\r
-               LEAVE('n');\r
-               return NULL;\r
-       }\r
-       LOG("hdr.phoff = 0x%08x\n", hdr.phoff);\r
-       fseek(FP, hdr.phoff, SEEK_SET);\r
-       fread(phtab, sizeof(Elf32_Phdr), hdr.phentcount, FP);\r
-       \r
-       // Count Pages\r
-       iPageCount = 0;\r
-       LOG("hdr.phentcount = %i\n", hdr.phentcount);\r
-       for( i = 0; i < hdr.phentcount; i++ )\r
-       {\r
-               // Ignore Non-LOAD types\r
-               if(phtab[i].Type != PT_LOAD)\r
-                       continue;\r
-               iPageCount += ((phtab[i].VAddr&0xFFF) + phtab[i].MemSize + 0xFFF) >> 12;\r
-               LOG("phtab[%i] = {VAddr:0x%x, MemSize:0x%x}\n", i, phtab[i].VAddr, phtab[i].MemSize);\r
-       }\r
-       \r
-       LOG("iPageCount = %i\n", iPageCount);\r
-       \r
-       // Allocate Information Structure\r
-       //ret = malloc( sizeof(tBinary) + sizeof(tBinaryPage)*iPageCount );\r
-       // Fill Info Struct\r
-       //ret->Entry = hdr.entrypoint;\r
-       //ret->Base = -1;               // Set Base to maximum value\r
-       //ret->NumPages = iPageCount;\r
-       //ret->Interpreter = NULL;\r
-\r
-       // Prescan for base and size\r
-       for( i = 0; i < hdr.phentcount; i ++)\r
-       {\r
-               if( phtab[i].Type != PT_LOAD )\r
-                       continue;\r
-               if( phtab[i].VAddr < base )\r
-                       base = phtab[i].VAddr;\r
-               if( phtab[i].VAddr > max )\r
-                       max = phtab[i].VAddr;\r
-       }\r
-\r
-       LOG("base = %08x, max = %08x\n", base, max);\r
-\r
-       if( base == 0 ) {\r
-               // Find a nice space (31 address bits allowed)\r
-               base = FindFreeRange( max, 31 );\r
-               LOG("new base = %08x\n", base);\r
-               if( base == 0 ) return NULL;\r
-               baseDiff = base;\r
-       }\r
-       \r
-       // Load Pages\r
-       j = 0;\r
-       for( i = 0; i < hdr.phentcount; i++ )\r
-       {\r
-               //LOG("phtab[%i].Type = 0x%x", i, phtab[i].Type);\r
-               LOG("phtab[%i] = {\n", i);\r
-               LOG(" .Type = 0x%08x\n", phtab[i].Type);\r
-               LOG(" .Offset = 0x%08x\n", phtab[i].Offset);\r
-               LOG(" .VAddr = 0x%08x\n", phtab[i].VAddr);\r
-               LOG(" .PAddr = 0x%08x\n", phtab[i].PAddr);\r
-               LOG(" .FileSize = 0x%08x\n", phtab[i].FileSize);\r
-               LOG(" .MemSize = 0x%08x\n", phtab[i].MemSize);\r
-               LOG(" .Flags = 0x%08x\n", phtab[i].Flags);\r
-               LOG(" .Align = 0x%08x\n", phtab[i].Align);\r
-               LOGS(" }\n");\r
-               // Get Interpreter Name\r
-               if( phtab[i].Type == PT_INTERP )\r
-               {\r
-                       char *tmp;\r
-                       //if(ret->Interpreter)  continue;\r
-                       tmp = malloc(phtab[i].FileSize);\r
-                       fseek(FP, phtab[i].Offset, SEEK_SET);\r
-                       fread(tmp, phtab[i].FileSize, 1, FP);\r
-                       //ret->Interpreter = Binary_RegInterp(tmp);\r
-                       LOG("Interpreter '%s'\n", tmp);\r
-                       free(tmp);\r
-                       continue;\r
-               }\r
-               // Ignore non-LOAD types\r
-               if(phtab[i].Type != PT_LOAD)    continue;\r
-               \r
-               LOG("phtab[%i] = {VAddr:0x%x,Offset:0x%x,FileSize:0x%x}\n",\r
-                       i, phtab[i].VAddr+baseDiff, phtab[i].Offset, phtab[i].FileSize);\r
-               \r
-               addr = phtab[i].VAddr + baseDiff;\r
-\r
-               if( AllocateMemory( addr, phtab[i].MemSize ) ) {\r
-                       return NULL;\r
-               }\r
-               \r
-               fseek(FP, phtab[i].Offset, SEEK_SET);\r
-               fread( PTRMK(void, addr), phtab[i].FileSize, 1, FP );\r
-               memset( PTRMK(char, addr) + phtab[i].FileSize, 0, phtab[i].MemSize - phtab[i].FileSize );\r
-       }\r
-       \r
-       // Clean Up\r
-       free(phtab);\r
-       // Return\r
-       LEAVE('p', base);\r
-       return PTRMK(void, base);\r
-}\r
-\r
-// --- ELF RELOCATION ---\r
-/**\r
- * \brief Relocates a loaded ELF Executable\r
- */\r
-uintptr_t Elf_Relocate(void *Base)\r
-{\r
-       Elf32_Ehdr      *hdr = Base;\r
-       Elf32_Phdr      *phtab;\r
-        int    i, j;   // Counters\r
-       char    *libPath;\r
-       uint32_t        iRealBase = -1;\r
-       uintptr_t       iBaseDiff;\r
-        int    iSegmentCount;\r
-        int    iSymCount = 0;\r
-       Elf32_Rel       *rel = NULL;\r
-       Elf32_Rela      *rela = NULL;\r
-       uint32_t        *pltgot = NULL;\r
-       void    *plt = NULL;\r
-       uint32_t        *ptr;\r
-        int    relSz=0, relEntSz=8;\r
-        int    relaSz=0, relaEntSz=8;\r
-        int    pltSz=0, pltType=0;\r
-       Elf32_Dyn       *dynamicTab = NULL;     // Dynamic Table Pointer\r
-       char    *dynstrtab = NULL;      // .dynamic String Table\r
-       Elf32_Sym       *dynsymtab = NULL;\r
-        int    bFailed = 0;\r
-       \r
-       ENTER("pBase", Base);\r
-       LOG("Base = %p\n", Base);\r
-       \r
-       // Parse Program Header to get Dynamic Table\r
-       phtab = Base + hdr->phoff;\r
-       iSegmentCount = hdr->phentcount;\r
-       for(i = 0; i < iSegmentCount; i ++ )\r
-       {\r
-               // Determine linked base address\r
-               if(phtab[i].Type == PT_LOAD && iRealBase > phtab[i].VAddr)\r
-                       iRealBase = phtab[i].VAddr;\r
-               \r
-               // Find Dynamic Section\r
-               if(phtab[i].Type == PT_DYNAMIC) {\r
-                       if(dynamicTab) {\r
-                               Warning("Elf_Relocate - Multiple PT_DYNAMIC segments\n");\r
-                               continue;\r
-                       }\r
-                       dynamicTab = MKPTR(void, phtab[i].VAddr);\r
-                       j = i;  // Save Dynamic Table ID\r
-                       break;\r
-               }\r
-       }\r
-       \r
-       // Check if a PT_DYNAMIC segement was found\r
-       if(!dynamicTab) {\r
-               Warning("Elf_Relocate: No PT_DYNAMIC segment in image, returning\n");\r
-               LEAVE('x', hdr->entrypoint);\r
-               return hdr->entrypoint;\r
-       }\r
-       \r
-       // Page Align real base\r
-       iRealBase &= ~0xFFF;\r
-       \r
-       LOG("dynamicTab = %p\n", dynamicTab);\r
-       // Adjust "Real" Base\r
-       iBaseDiff = (uintptr_t)Base - iRealBase;\r
-       LOG("iBaseDiff = %p\n", (void*)iBaseDiff);\r
-       // Adjust Dynamic Table\r
-       dynamicTab = PTR( (uintptr_t)dynamicTab + iBaseDiff);\r
-       LOG("dynamicTab = %p\n", dynamicTab);\r
-\r
-       hdr->entrypoint += iBaseDiff;\r
-       \r
-       // === Get Symbol table and String Table ===\r
-       for( j = 0; dynamicTab[j].d_tag != DT_NULL; j++)\r
-       {\r
-               switch(dynamicTab[j].d_tag)\r
-               {\r
-               // --- Symbol Table ---\r
-               case DT_SYMTAB:\r
-                       dynamicTab[j].d_val += iBaseDiff;\r
-                       dynsymtab = PTRMK(void, dynamicTab[j].d_val);\r
-                       hdr->misc.SymTable = dynamicTab[j].d_val;       // Saved in unused bytes of ident\r
-                       break;\r
-               \r
-               // --- String Table ---\r
-               case DT_STRTAB:\r
-                       dynamicTab[j].d_val += iBaseDiff;\r
-                       dynstrtab = PTRMK(void, dynamicTab[j].d_val);\r
-                       break;\r
-               \r
-               // --- Hash Table --\r
-               case DT_HASH:\r
-                       dynamicTab[j].d_val += iBaseDiff;\r
-                       iSymCount = (PTRMK(uint32_t, dynamicTab[j].d_val))[1];\r
-                       hdr->misc.HashTable = dynamicTab[j].d_val;      // Saved in unused bytes of ident\r
-                       break;\r
-               }\r
-       }\r
-\r
-\r
-       // Alter Symbols to true base\r
-       for(i = 0; i < iSymCount; i ++)\r
-       {\r
-               dynsymtab[i].nameOfs += (uintptr_t)dynstrtab;\r
-               if( dynsymtab[i].shndx == SHN_UNDEF )\r
-               {\r
-                       LOG("Sym '%s' = UNDEF\n", MKPTR(char,dynsymtab[i].name));\r
-               }\r
-               else\r
-               {\r
-                       dynsymtab[i].value += iBaseDiff;\r
-                       LOG("Sym '%s' = 0x%x (relocated)\n", MKPTR(char,dynsymtab[i].name), dynsymtab[i].value);\r
-               }\r
-       }\r
-       \r
-       // === Add to loaded list (can be imported now) ===\r
-       Binary_SetReadyToUse( Base );\r
-\r
-       // === Parse Relocation Data ===\r
-       for( j = 0; dynamicTab[j].d_tag != DT_NULL; j++)\r
-       {\r
-               switch(dynamicTab[j].d_tag)\r
-               {\r
-               // --- Shared Library Name ---\r
-               case DT_SONAME:\r
-                       LOG(".so Name '%s'\n", dynstrtab + dynamicTab[j].d_val);\r
-                       break;\r
-               // --- Needed Library ---\r
-               case DT_NEEDED:\r
-                       libPath = dynstrtab + dynamicTab[j].d_val;\r
-                       Binary_LoadLibrary(libPath);\r
-                       break;\r
-               // --- PLT/GOT ---\r
-               case DT_PLTGOT: pltgot = (void*)(iBaseDiff+dynamicTab[j].d_val);        break;\r
-               case DT_JMPREL: plt = (void*)(iBaseDiff+dynamicTab[j].d_val);   break;\r
-               case DT_PLTREL: pltType = dynamicTab[j].d_val;  break;\r
-               case DT_PLTRELSZ:       pltSz = dynamicTab[j].d_val;    break;\r
-               \r
-               // --- Relocation ---\r
-               case DT_REL:    rel = (void*)(iBaseDiff + dynamicTab[j].d_val); break;\r
-               case DT_RELSZ:  relSz = dynamicTab[j].d_val;    break;\r
-               case DT_RELENT: relEntSz = dynamicTab[j].d_val; break;\r
-               \r
-               case DT_RELA:   rela = (void*)(iBaseDiff + dynamicTab[j].d_val);        break;\r
-               case DT_RELASZ: relaSz = dynamicTab[j].d_val;   break;\r
-               case DT_RELAENT:        relaEntSz = dynamicTab[j].d_val;        break;\r
-               }\r
-       }\r
-       \r
-       // Parse Relocation Entries\r
-       if(rel && relSz)\r
-       {\r
-               j = relSz / relEntSz;\r
-               for( i = 0; i < j; i++ )\r
-               {\r
-                       ptr = (void*)(iBaseDiff + rel[i].r_offset);\r
-                       if( !Elf_Int_DoRelocate(rel[i].r_info, ptr, *ptr, dynsymtab, Base) ) {\r
-                               bFailed = 1;\r
-                       }\r
-               }\r
-       }\r
-       // Parse Relocation Entries\r
-       if(rela && relaSz)\r
-       {\r
-               j = relaSz / relaEntSz;\r
-               for( i = 0; i < j; i++ )\r
-               {\r
-                       ptr = (void*)(iBaseDiff + rela[i].r_offset);\r
-                       if( !Elf_Int_DoRelocate(rel[i].r_info, ptr, rela[i].r_addend, dynsymtab, Base) ) {\r
-                               bFailed = 1;\r
-                       }\r
-               }\r
-       }\r
-       \r
-       // === Process PLT (Procedure Linkage Table) ===\r
-       if(plt && pltSz)\r
-       {\r
-               if(pltType == DT_REL)\r
-               {\r
-                       Elf32_Rel       *pltRel = plt;\r
-                       j = pltSz / sizeof(Elf32_Rel);\r
-                       LOG("PLT Rel - plt = %p, pltSz = %i (%i ents)\n", plt, pltSz, j);\r
-                       for(i = 0; i < j; i++)\r
-                       {\r
-                               ptr = (void*)(iBaseDiff + pltRel[i].r_offset);\r
-                               if( !Elf_Int_DoRelocate(pltRel[i].r_info, ptr, *ptr, dynsymtab, Base) ) {\r
-                                       bFailed = 1;\r
-                               }\r
-                       }\r
-               }\r
-               else\r
-               {\r
-                       Elf32_Rela      *pltRela = plt;\r
-                       j = pltSz / sizeof(Elf32_Rela);\r
-                       LOG("PLT RelA - plt = %p, pltSz = %i (%i ents)\n", plt, pltSz, j);\r
-                       for(i=0;i<j;i++)\r
-                       {\r
-                               ptr = (void*)(iBaseDiff + pltRela[i].r_offset);\r
-                               if( !Elf_Int_DoRelocate(pltRela[i].r_info, ptr, pltRela[i].r_addend, dynsymtab, Base) ) {\r
-                                       bFailed = 1;\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-       \r
-       if(bFailed) {\r
-               LEAVE('i', 0);\r
-               return 0;\r
-       }\r
-       \r
-       LEAVE('x', hdr->entrypoint);\r
-       return hdr->entrypoint;\r
-}\r
-\r
-/**\r
- * \fn void Elf_Int_DoRelocate(uint32_t r_info, uint32_t *ptr, uint32_t addend, Elf32_Sym *symtab, void *base)\r
- * \brief Performs a relocation\r
- * \param r_info       Field from relocation entry\r
- * \param ptr  Pointer to location of relocation\r
- * \param addend       Value to add to symbol\r
- * \param symtab       Symbol Table\r
- * \param base Base of loaded binary\r
- */\r
-int Elf_Int_DoRelocate(uint32_t r_info, uint32_t *ptr, uint32_t addend, Elf32_Sym *symtab, void *base)\r
-{\r
-       uintptr_t       val;\r
-        int    type = ELF32_R_TYPE(r_info);\r
-        int    sym = ELF32_R_SYM(r_info);\r
-       char    *sSymName = PTRMK(char, symtab[sym].name);\r
-       \r
-       //LogF("Elf_Int_DoRelocate: (r_info=0x%x, ptr=0x%x, addend=0x%x, .., base=0x%x)\n",\r
-       //      r_info, ptr, addend, base);\r
-       \r
-       switch( type )\r
-       {\r
-       // Standard 32 Bit Relocation (S+A)\r
-       case R_386_32:\r
-               if( !Elf_GetSymbol( base, sSymName, &val ) && !Binary_GetSymbol( sSymName, &val ) ) {\r
-                       Warning("Unable to find symbol '%s'", sSymName);\r
-                       return 0;\r
-               }\r
-               LOG("%08x R_386_32 *%p += %p('%s')\n", r_info, ptr, (void*)val, sSymName);\r
-               *ptr = val + addend;\r
-               break;\r
-               \r
-       // 32 Bit Relocation wrt. Offset (S+A-P)\r
-       case R_386_PC32:\r
-               if( !Elf_GetSymbol( base, sSymName, &val ) && !Binary_GetSymbol( sSymName, &val ) ) {\r
-                       Warning("Unable to find symbol '%s'", sSymName);\r
-                       return 0;\r
-               }\r
-               LOG("%08x R_386_PC32 *%p = 0x%x + %p('%s') - %p\n", r_info, ptr, *ptr, (void*)val, sSymName, ptr );\r
-               // TODO: Check if it needs the true value of ptr or the compiled value\r
-               // NOTE: Testing using true value\r
-               *ptr = val + addend - (uintptr_t)ptr;\r
-               break;\r
-\r
-       // Absolute Value of a symbol (S)\r
-       case R_386_GLOB_DAT:\r
-               if( !Elf_GetSymbol( base, sSymName, &val ) && !Binary_GetSymbol( sSymName, &val ) ) {\r
-                       Warning("Unable to find symbol '%s'", sSymName);\r
-                       return 0; \r
-               }\r
-               LOG("%08x R_386_GLOB_DAT *%p = 0x%x(%s)\n", r_info, ptr, (unsigned int)val, sSymName);\r
-               *ptr = val;\r
-               break;\r
-       \r
-       // Absolute Value of a symbol (S)\r
-       case R_386_JMP_SLOT:\r
-               if( !Elf_GetSymbol( base, sSymName, &val ) && !Binary_GetSymbol( sSymName, &val ) ) {\r
-                       Warning("Unable to find symbol '%s'", sSymName);\r
-                       return 0;\r
-               }\r
-               LOG("%08x R_386_JMP_SLOT *%p = 0x%x (%s)\n", r_info, ptr, (unsigned int)val, sSymName);\r
-               *ptr = val;\r
-               break;\r
-\r
-       // Base Address (B+A)\r
-       case R_386_RELATIVE:\r
-               LOG("%08x R_386_RELATIVE *%p = %p + 0x%x\n", r_info, ptr, base, addend);\r
-               *ptr = (uintptr_t)base + addend;\r
-               break;\r
-               \r
-       default:\r
-               LOG("Rel %p: 0x%x,%i\n", ptr, sym, type);\r
-               break;\r
-       }\r
-       return 1;\r
-}\r
-\r
-/**\r
- * \fn int Elf_GetSymbol(void *Base, char *name, uintptr_t *ret)\r
- * \brief Get a symbol from the loaded binary\r
- */\r
-int Elf_GetSymbol(void *Base, char *Name, uintptr_t *ret)\r
-{\r
-       Elf32_Ehdr      *hdr = (void*)Base;\r
-       Elf32_Sym       *symtab;\r
-        int    nbuckets = 0;\r
-        int    iSymCount = 0;\r
-        int    i;\r
-       uint32_t        *pBuckets;\r
-       uint32_t        *pChains;\r
-       uint32_t        iNameHash;\r
-\r
-       if(!Base)       return 0;\r
-\r
-       pBuckets = PTR(hdr->misc.HashTable);\r
-       symtab = PTR(hdr->misc.SymTable);\r
-       \r
-       nbuckets = pBuckets[0];\r
-       iSymCount = pBuckets[1];\r
-       pBuckets = &pBuckets[2];\r
-       pChains = &pBuckets[ nbuckets ];\r
-       \r
-       // Get hash\r
-       iNameHash = Elf_Int_HashString(Name);\r
-       iNameHash %= nbuckets;\r
-\r
-       // Check Bucket\r
-       i = pBuckets[ iNameHash ];\r
-       if(symtab[i].shndx != SHN_UNDEF && strcmp(MKPTR(char,symtab[i].name), Name) == 0) {\r
-               if(ret) *ret = symtab[ i ].value;\r
-               return 1;\r
-       }\r
-       \r
-       // Walk Chain\r
-       while(pChains[i] != STN_UNDEF)\r
-       {\r
-               i = pChains[i];\r
-               if(symtab[i].shndx != SHN_UNDEF && strcmp(MKPTR(char,symtab[i].name), Name) == 0) {\r
-                       if(ret) *ret = symtab[ i ].value;\r
-                       return 1;\r
-               }\r
-       }\r
-       return 0;\r
-}\r
-\r
-/**\r
- * \fn uint32_t Elf_Int_HashString(char *str)\r
- * \brief Hash a string in the ELF format\r
- * \param str  String to hash\r
- * \return Hash value\r
- */\r
-uint32_t Elf_Int_HashString(char *str)\r
-{\r
-       uint32_t        h = 0, g;\r
-       while(*str)\r
-       {\r
-               h = (h << 4) + *str++;\r
-               if( (g = h & 0xf0000000) )\r
-                       h ^= g >> 24;\r
-               h &= ~g;\r
-       }\r
-       return h;\r
-}\r
diff --git a/AcessNative/ld-acess.so_src/elf.h b/AcessNative/ld-acess.so_src/elf.h
deleted file mode 100644 (file)
index 77be918..0000000
+++ /dev/null
@@ -1,217 +0,0 @@
-/**\r
- * \file elf.h\r
- * \brief ELF Exeutable Loader\r
- */\r
-#ifndef _BIN_ELF_H\r
-#define _BIN_ELF_H\r
-\r
-#include <stdint.h>\r
-\r
-/**\r
- * \brief ELF File Header\r
- */\r
-struct sElf32_Ehdr\r
-{\r
-       union {\r
-               char    ident[16];      //!< Identifier Bytes\r
-               struct {\r
-                       uint32_t        Ident1;\r
-                       uint32_t        Ident2;\r
-                       uint32_t        HashTable;\r
-                       uint32_t        SymTable;\r
-               } misc;\r
-       };\r
-       uint16_t        filetype;       //!< File Type\r
-       uint16_t        machine;        //!< Machine / Arch\r
-       uint32_t        version;        //!< Version (File?)\r
-       uint32_t        entrypoint;     //!< Entry Point\r
-       uint32_t        phoff;  //!< Program Header Offset\r
-       uint32_t        shoff;  //!< Section Header Offset\r
-       uint32_t        flags;  //!< Flags\r
-       uint16_t        headersize;     //!< Header Size\r
-       uint16_t        phentsize;      //!< Program Header Entry Size\r
-       uint16_t        phentcount;     //!< Program Header Entry Count\r
-       uint16_t        shentsize;      //!< Section Header Entry Size\r
-       uint16_t        shentcount;     //!< Section Header Entry Count\r
-       uint16_t        shstrindex;     //!< Section Header String Table Index\r
-} __attribute__ ((packed));\r
-\r
-/**\r
- * \brief Executable Types\r
- */\r
-enum eElf32_ExecTypes\r
-{\r
-       ET_NONE = 0,    //!< NULL Type\r
-       ET_REL  = 1,    //!< Relocatable (Object)\r
-       ET_EXEC = 2,    //!< Executable\r
-       ET_DYN  = 3,    //!< Dynamic Library\r
-       ET_CORE = 4,    //!< Core?\r
-       ET_LOPROC = 0xFF00,     //!< Low Impl Defined\r
-       ET_HIPROC = 0xFFFF      //!< High Impl Defined\r
-};\r
-\r
-/**\r
- \name Section IDs\r
- \{\r
-*/\r
-#define SHN_UNDEF              0       //!< Undefined Section\r
-#define SHN_LORESERVE  0xFF00  //!< Low Reserved\r
-#define SHN_LOPROC             0xFF00  //!< Low Impl Defined\r
-#define SHN_HIPROC             0xFF1F  //!< High Impl Defined\r
-#define SHN_ABS                        0xFFF1  //!< Absolute Address (Base: 0, Size: -1)\r
-#define SHN_COMMON             0xFFF2  //!< Common\r
-#define SHN_HIRESERVE  0xFFFF  //!< High Reserved\r
-//! \}\r
-\r
-/**\r
- \enum eElfSectionTypes\r
- \brief ELF Section Types\r
-*/\r
-enum eElfSectionTypes {\r
-       SHT_NULL,       //0\r
-       SHT_PROGBITS,   //1\r
-       SHT_SYMTAB,     //2\r
-       SHT_STRTAB,     //3\r
-       SHT_RELA,       //4\r
-       SHT_HASH,       //5\r
-       SHT_DYNAMIC,    //6\r
-       SHT_NOTE,       //7\r
-       SHT_NOBITS,     //8\r
-       SHT_REL,        //9\r
-       SHT_SHLIB,      //A\r
-       SHT_DYNSYM,     //B\r
-       SHT_LAST,       //C\r
-       SHT_LOPROC = 0x70000000,\r
-       SHT_HIPROC = 0x7fffffff,\r
-       SHT_LOUSER = 0x80000000,\r
-       SHT_HIUSER = 0xffffffff\r
-};\r
-\r
-#define SHF_WRITE      0x1\r
-#define SHF_ALLOC      0x2\r
-#define SHF_EXECINSTR  0x4\r
-#define SHF_MASKPROC   0xf0000000\r
-\r
-struct sElf32_Shent {\r
-       uint32_t        name;\r
-       uint32_t        type;\r
-       uint32_t        flags;\r
-       uint32_t        address;\r
-       uint32_t        offset;\r
-       uint32_t        size;\r
-       uint32_t        link;\r
-       uint32_t        info;\r
-       uint32_t        addralign;\r
-       uint32_t        entsize;\r
-} __attribute__ ((packed));    //sizeof = 40\r
-\r
-struct elf_sym_s {\r
-       union {\r
-               uint32_t        nameOfs;\r
-               uint32_t        name;\r
-       };\r
-       uint32_t        value;  //Address\r
-       uint32_t        size;\r
-       uint8_t info;\r
-       uint8_t other;\r
-       uint16_t        shndx;\r
-} __attribute__ ((packed));\r
-#define        STN_UNDEF       0       // Undefined Symbol\r
-\r
-enum {\r
-       PT_NULL,        //0\r
-       PT_LOAD,        //1\r
-       PT_DYNAMIC,     //2\r
-       PT_INTERP,      //3\r
-       PT_NOTE,        //4\r
-       PT_SHLIB,       //5\r
-       PT_PHDR,        //6\r
-       PT_LOPROC = 0x70000000,\r
-       PT_HIPROC = 0x7fffffff\r
-};\r
-\r
-struct sElf32_Phdr {\r
-       uint32_t        Type;\r
-       uint32_t        Offset;\r
-       uint32_t        VAddr;\r
-       uint32_t        PAddr;\r
-       uint32_t        FileSize;\r
-       uint32_t        MemSize;\r
-       uint32_t        Flags;\r
-       uint32_t        Align;\r
-} __attribute__ ((packed));\r
-\r
-struct elf32_rel_s {\r
-       uint32_t        r_offset;\r
-       uint32_t        r_info;\r
-} __attribute__ ((packed));\r
-\r
-struct elf32_rela_s {\r
-       uint32_t        r_offset;\r
-       uint32_t        r_info;\r
-       int32_t r_addend;\r
-} __attribute__ ((packed));\r
-\r
-enum {\r
-       R_386_NONE = 0, // none\r
-       R_386_32,       // S+A\r
-       R_386_PC32,     // S+A-P\r
-       R_386_GOT32,    // G+A-P\r
-       R_386_PLT32,    // L+A-P\r
-       R_386_COPY,     // none\r
-       R_386_GLOB_DAT, // S\r
-       R_386_JMP_SLOT, // S\r
-       R_386_RELATIVE, // B+A\r
-       R_386_GOTOFF,   // S+A-GOT\r
-       R_386_GOTPC,    // GOT+A-P\r
-       R_386_LAST      // none\r
-};\r
-\r
-#define        ELF32_R_SYM(i)  ((i)>>8)        // Takes an info value and returns a symbol index\r
-#define        ELF32_R_TYPE(i) ((i)&0xFF)      // Takes an info value and returns a type\r
-#define        ELF32_R_INFO(s,t)       (((s)<<8)+((t)&0xFF))   // Takes a type and symbol index and returns an info value\r
-\r
-struct elf32_dyn_s {\r
-       uint32_t        d_tag;\r
-       uint32_t        d_val;  //Also d_ptr\r
-} __attribute__ ((packed));\r
-\r
-enum {\r
-       DT_NULL,        //!< Marks End of list\r
-       DT_NEEDED,      //!< Offset in strtab to needed library\r
-       DT_PLTRELSZ,    //!< Size in bytes of PLT\r
-       DT_PLTGOT,      //!< Address of PLT/GOT\r
-       DT_HASH,        //!< Address of symbol hash table\r
-       DT_STRTAB,      //!< String Table address\r
-       DT_SYMTAB,      //!< Symbol Table address\r
-       DT_RELA,        //!< Relocation table address\r
-       DT_RELASZ,      //!< Size of relocation table\r
-       DT_RELAENT,     //!< Size of entry in relocation table\r
-       DT_STRSZ,       //!< Size of string table\r
-       DT_SYMENT,      //!< Size of symbol table entry\r
-       DT_INIT,        //!< Address of initialisation function\r
-       DT_FINI,        //!< Address of termination function\r
-       DT_SONAME,      //!< String table offset of so name\r
-       DT_RPATH,       //!< String table offset of library path\r
-       DT_SYMBOLIC,//!< Reverse order of symbol searching for library, search libs first then executable\r
-       DT_REL,         //!< Relocation Entries (Elf32_Rel instead of Elf32_Rela)\r
-       DT_RELSZ,       //!< Size of above table (bytes)\r
-       DT_RELENT,      //!< Size of entry in above table\r
-       DT_PLTREL,      //!< Relocation entry of PLT\r
-       DT_DEBUG,       //!< Debugging Entry - Unknown contents\r
-       DT_TEXTREL,     //!< Indicates that modifcations to a non-writeable segment may occur\r
-       DT_JMPREL,      //!< Address of PLT only relocation entries\r
-       DT_LOPROC = 0x70000000, //!< Low Definable\r
-       DT_HIPROC = 0x7FFFFFFF  //!< High Definable\r
-};\r
-\r
-typedef struct sElf32_Ehdr     Elf32_Ehdr;\r
-typedef struct sElf32_Phdr     Elf32_Phdr;\r
-typedef struct sElf32_Shent    Elf32_Shent;\r
-typedef struct elf_sym_s       elf_symtab;\r
-typedef struct elf_sym_s       Elf32_Sym;\r
-typedef struct elf32_rel_s     Elf32_Rel;\r
-typedef struct elf32_rela_s    Elf32_Rela;\r
-typedef struct elf32_dyn_s     Elf32_Dyn;\r
-\r
-#endif // defined(_EXE_ELF_H)\r
diff --git a/AcessNative/ld-acess.so_src/main.c b/AcessNative/ld-acess.so_src/main.c
deleted file mode 100644 (file)
index e310a84..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- */
-#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;
-       
-       __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, ...)
-{
-       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
deleted file mode 100644 (file)
index 627f902..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- */
-#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
deleted file mode 100644 (file)
index f9526b3..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- */
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#ifdef __WIN32__
-# include <windows.h>
-# include <winsock.h>
-#else
-# include <unistd.h>
-# 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 = INVALID_SOCKET;
-#else
-# 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()
-{
-       struct sockaddr_in      server;
-       struct sockaddr_in      client;
-       
-       #ifdef __WIN32__
-       /* Open windows connection */
-       if (WSAStartup(0x0101, &gWinsock) != 0)
-       {
-               fprintf(stderr, "Could not open Windows connection.\n");
-               exit(0);
-       }
-       #endif
-       
-       // Open UDP Connection
-       gSocket = socket(AF_INET, SOCK_DGRAM, 0);
-       if (gSocket == INVALID_SOCKET)
-       {
-               fprintf(stderr, "Could not create socket.\n");
-               #if __WIN32__
-               WSACleanup();
-               #endif
-               exit(0);
-       }
-       
-       // Set server address
-       memset((void *)&server, '\0', sizeof(struct sockaddr_in));
-       server.sin_family = AF_INET;
-       server.sin_port = htons(SERVER_PORT);
-       server.sin_addr.s_addr = htonl(0x7F00001);
-       
-       // Set client address
-       memset((void *)&client, '\0', sizeof(struct sockaddr_in));
-       client.sin_family = AF_INET;
-       client.sin_port = htons(0);
-       client.sin_addr.s_addr = htonl(0x7F00001);
-       
-       // Bind
-       if( bind(gSocket, (struct sockaddr *)&client, sizeof(struct sockaddr_in)) == -1 )
-       {
-               fprintf(stderr, "Cannot bind address to socket.\n");
-               #if __WIN32__
-               closesocket(gSocket);
-               WSACleanup();
-               #else
-               close(gSocket);
-               #endif
-               exit(0);
-       }
-       return 0;
-}
-
-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;
-}
diff --git a/AcessNative/ld-acess.so_src/request.h b/AcessNative/ld-acess.so_src/request.h
deleted file mode 100644 (file)
index 8c89e6f..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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
deleted file mode 100644 (file)
index ec4af01..0000000
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- */
-#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 (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, ...)
-{
-       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);
-}
-
-void close(int FD) {
-       _Syscall(">i", FD);
-}
-
-size_t read(int FD, size_t Bytes, void *Dest) {
-       return _Syscall(">i >i <d", FD, Bytes, Bytes, Dest);
-}
-
-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 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[] = {
-       {"_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/ld-acess_src/Makefile b/AcessNative/ld-acess_src/Makefile
new file mode 100644 (file)
index 0000000..4fb6ae2
--- /dev/null
@@ -0,0 +1,39 @@
+#
+#
+
+ifeq ($(PLATFORM),)
+       PLATFORM := lin
+endif
+
+OBJ := main.o syscalls.o request.o binary.o memory.o
+OBJ += elf.o
+OBJ := $(addsuffix .$(PLATFORM),$(OBJ))
+
+ifeq ($(PLATFORM),win)
+       BIN := ../ld-acess.exe
+endif
+ifeq ($(PLATFORM),lin)
+       BIN := ../ld-acess
+       LD += -m elf_i386
+endif
+
+CFLAGS += -Wall -Werror -g -m32
+
+.PHONY: all clean
+
+all: $(BIN)
+
+clean:
+       $(RM) $(BIN) $(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_src/binary.c b/AcessNative/ld-acess_src/binary.c
new file mode 100644 (file)
index 0000000..b8f6e71
--- /dev/null
@@ -0,0 +1,240 @@
+/*
+ * 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 ===
+char *Binary_LocateLibrary(const char *Name)
+{
+       char    *envPath = getenv("ACESS_LIBRARY_PATH");
+        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' )
+       {
+                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};
+               printf("Calling '%s' entry point %p\n", Name, entry);
+               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;
+
+       // 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)
+               {
+                       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;
+       }
+       
+       printf("fmt->Load(%p)...\n", fp);
+       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;
+       
+       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 ) {
+                       *Value = (uintptr_t)caBuiltinSymbols[i].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_src/common.h b/AcessNative/ld-acess_src/common.h
new file mode 100644 (file)
index 0000000..4667acb
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ */
+#ifndef _COMMON_H_
+#define _COMMON_H_
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+
+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(uintptr_t VirtAddr, size_t ByteCount);
+extern uintptr_t       FindFreeRange(size_t ByteCount, int MaxBits);
+
+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_src/elf.c b/AcessNative/ld-acess_src/elf.c
new file mode 100644 (file)
index 0000000..3ab5a50
--- /dev/null
@@ -0,0 +1,529 @@
+/*\r
+ * Acess v0.1\r
+ * ELF Executable Loader Code\r
+ */\r
+#define DEBUG  0\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <unistd.h>\r
+#include "common.h"\r
+#include "elf.h"\r
+\r
+#define DEBUG_WARN     1\r
+\r
+#define MKPTR(_type,_val)      ((_type*)(uintptr_t)(_val))\r
+#define PTRMK(_type,_val)      MKPTR(_type,_val)\r
+#define PTR(_val)      ((void*)(uintptr_t)(_val))\r
+\r
+#if DEBUG\r
+# define ENTER(...)\r
+# define LOG(s, ...)   printf("%s: " s, __func__, __VA_ARGS__)\r
+# define LOGS(s)       printf("%s: " s, __func__)\r
+# define LEAVE(...)\r
+#else\r
+# define ENTER(...)\r
+# define LOG(...)\r
+# define LOGS(...)\r
+# define LEAVE(...)\r
+#endif\r
+\r
+// === PROTOTYPES ===\r
+void   *Elf_Load(FILE *FP);\r
+uintptr_t      Elf_Relocate(void *Base);\r
+ int   Elf_GetSymbol(void *Base, char *Name, uintptr_t *ret);\r
+ int   Elf_Int_DoRelocate(uint32_t r_info, uint32_t *ptr, uint32_t addend, Elf32_Sym *symtab, void *Base);\r
+uint32_t       Elf_Int_HashString(char *str);\r
+\r
+// === CODE ===\r
+void *Elf_Load(FILE *FP)\r
+{\r
+       Elf32_Ehdr      hdr;\r
+       Elf32_Phdr      *phtab;\r
+        int    i, j;\r
+        int    iPageCount;\r
+       uint32_t        max, base = -1;\r
+       uint32_t        addr;\r
+       uint32_t        baseDiff = 0;\r
+       \r
+       ENTER("pFP", FP);\r
+       \r
+       // Read ELF Header\r
+       fread(&hdr, sizeof(hdr), 1, FP);\r
+       \r
+       // Check the file type\r
+       if(hdr.ident[0] != 0x7F || hdr.ident[1] != 'E' || hdr.ident[2] != 'L' || hdr.ident[3] != 'F') {\r
+               Warning("Non-ELF File was passed to the ELF loader\n");\r
+               LEAVE('n');\r
+               return NULL;\r
+       }\r
+       \r
+       // Check for a program header\r
+       if(hdr.phoff == 0) {\r
+               #if DEBUG_WARN\r
+               Warning("ELF File does not contain a program header\n");\r
+               #endif\r
+               LEAVE('n');\r
+               return NULL;\r
+       }\r
+       \r
+       // Read Program Header Table\r
+       phtab = malloc( sizeof(Elf32_Phdr) * hdr.phentcount );\r
+       if( !phtab ) {\r
+               LEAVE('n');\r
+               return NULL;\r
+       }\r
+       LOG("hdr.phoff = 0x%08x\n", hdr.phoff);\r
+       fseek(FP, hdr.phoff, SEEK_SET);\r
+       fread(phtab, sizeof(Elf32_Phdr), hdr.phentcount, FP);\r
+       \r
+       // Count Pages\r
+       iPageCount = 0;\r
+       LOG("hdr.phentcount = %i\n", hdr.phentcount);\r
+       for( i = 0; i < hdr.phentcount; i++ )\r
+       {\r
+               // Ignore Non-LOAD types\r
+               if(phtab[i].Type != PT_LOAD)\r
+                       continue;\r
+               iPageCount += ((phtab[i].VAddr&0xFFF) + phtab[i].MemSize + 0xFFF) >> 12;\r
+               LOG("phtab[%i] = {VAddr:0x%x, MemSize:0x%x}\n", i, phtab[i].VAddr, phtab[i].MemSize);\r
+       }\r
+       \r
+       LOG("iPageCount = %i\n", iPageCount);\r
+       \r
+       // Allocate Information Structure\r
+       //ret = malloc( sizeof(tBinary) + sizeof(tBinaryPage)*iPageCount );\r
+       // Fill Info Struct\r
+       //ret->Entry = hdr.entrypoint;\r
+       //ret->Base = -1;               // Set Base to maximum value\r
+       //ret->NumPages = iPageCount;\r
+       //ret->Interpreter = NULL;\r
+\r
+       // Prescan for base and size\r
+       for( i = 0; i < hdr.phentcount; i ++)\r
+       {\r
+               if( phtab[i].Type != PT_LOAD )\r
+                       continue;\r
+               if( phtab[i].VAddr < base )\r
+                       base = phtab[i].VAddr;\r
+               if( phtab[i].VAddr > max )\r
+                       max = phtab[i].VAddr;\r
+       }\r
+\r
+       LOG("base = %08x, max = %08x\n", base, max);\r
+\r
+       if( base == 0 ) {\r
+               // Find a nice space (31 address bits allowed)\r
+               base = FindFreeRange( max, 31 );\r
+               LOG("new base = %08x\n", base);\r
+               if( base == 0 ) return NULL;\r
+               baseDiff = base;\r
+       }\r
+       \r
+       // Load Pages\r
+       j = 0;\r
+       for( i = 0; i < hdr.phentcount; i++ )\r
+       {\r
+               //LOG("phtab[%i].Type = 0x%x", i, phtab[i].Type);\r
+               LOG("phtab[%i] = {\n", i);\r
+               LOG(" .Type = 0x%08x\n", phtab[i].Type);\r
+               LOG(" .Offset = 0x%08x\n", phtab[i].Offset);\r
+               LOG(" .VAddr = 0x%08x\n", phtab[i].VAddr);\r
+               LOG(" .PAddr = 0x%08x\n", phtab[i].PAddr);\r
+               LOG(" .FileSize = 0x%08x\n", phtab[i].FileSize);\r
+               LOG(" .MemSize = 0x%08x\n", phtab[i].MemSize);\r
+               LOG(" .Flags = 0x%08x\n", phtab[i].Flags);\r
+               LOG(" .Align = 0x%08x\n", phtab[i].Align);\r
+               LOGS(" }\n");\r
+               // Get Interpreter Name\r
+               if( phtab[i].Type == PT_INTERP )\r
+               {\r
+                       char *tmp;\r
+                       //if(ret->Interpreter)  continue;\r
+                       tmp = malloc(phtab[i].FileSize);\r
+                       fseek(FP, phtab[i].Offset, SEEK_SET);\r
+                       fread(tmp, phtab[i].FileSize, 1, FP);\r
+                       //ret->Interpreter = Binary_RegInterp(tmp);\r
+                       LOG("Interpreter '%s'\n", tmp);\r
+                       free(tmp);\r
+                       continue;\r
+               }\r
+               // Ignore non-LOAD types\r
+               if(phtab[i].Type != PT_LOAD)    continue;\r
+               \r
+               LOG("phtab[%i] = {VAddr:0x%x,Offset:0x%x,FileSize:0x%x}\n",\r
+                       i, phtab[i].VAddr+baseDiff, phtab[i].Offset, phtab[i].FileSize);\r
+               \r
+               addr = phtab[i].VAddr + baseDiff;\r
+\r
+               if( AllocateMemory( addr, phtab[i].MemSize ) ) {\r
+                       return NULL;\r
+               }\r
+               \r
+               fseek(FP, phtab[i].Offset, SEEK_SET);\r
+               fread( PTRMK(void, addr), phtab[i].FileSize, 1, FP );\r
+               memset( PTRMK(char, addr) + phtab[i].FileSize, 0, phtab[i].MemSize - phtab[i].FileSize );\r
+       }\r
+       \r
+       // Clean Up\r
+       free(phtab);\r
+       // Return\r
+       LEAVE('p', base);\r
+       return PTRMK(void, base);\r
+}\r
+\r
+// --- ELF RELOCATION ---\r
+/**\r
+ * \brief Relocates a loaded ELF Executable\r
+ */\r
+uintptr_t Elf_Relocate(void *Base)\r
+{\r
+       Elf32_Ehdr      *hdr = Base;\r
+       Elf32_Phdr      *phtab;\r
+        int    i, j;   // Counters\r
+       char    *libPath;\r
+       uint32_t        iRealBase = -1;\r
+       uintptr_t       iBaseDiff;\r
+        int    iSegmentCount;\r
+        int    iSymCount = 0;\r
+       Elf32_Rel       *rel = NULL;\r
+       Elf32_Rela      *rela = NULL;\r
+       uint32_t        *pltgot = NULL;\r
+       void    *plt = NULL;\r
+       uint32_t        *ptr;\r
+        int    relSz=0, relEntSz=8;\r
+        int    relaSz=0, relaEntSz=8;\r
+        int    pltSz=0, pltType=0;\r
+       Elf32_Dyn       *dynamicTab = NULL;     // Dynamic Table Pointer\r
+       char    *dynstrtab = NULL;      // .dynamic String Table\r
+       Elf32_Sym       *dynsymtab = NULL;\r
+        int    bFailed = 0;\r
+       \r
+       ENTER("pBase", Base);\r
+       LOG("Base = %p\n", Base);\r
+       \r
+       // Parse Program Header to get Dynamic Table\r
+       phtab = Base + hdr->phoff;\r
+       iSegmentCount = hdr->phentcount;\r
+       for(i = 0; i < iSegmentCount; i ++ )\r
+       {\r
+               // Determine linked base address\r
+               if(phtab[i].Type == PT_LOAD && iRealBase > phtab[i].VAddr)\r
+                       iRealBase = phtab[i].VAddr;\r
+               \r
+               // Find Dynamic Section\r
+               if(phtab[i].Type == PT_DYNAMIC) {\r
+                       if(dynamicTab) {\r
+                               Warning("Elf_Relocate - Multiple PT_DYNAMIC segments\n");\r
+                               continue;\r
+                       }\r
+                       dynamicTab = MKPTR(void, phtab[i].VAddr);\r
+                       j = i;  // Save Dynamic Table ID\r
+                       break;\r
+               }\r
+       }\r
+       \r
+       // Check if a PT_DYNAMIC segement was found\r
+       if(!dynamicTab) {\r
+               Warning("Elf_Relocate: No PT_DYNAMIC segment in image, returning\n");\r
+               LEAVE('x', hdr->entrypoint);\r
+               return hdr->entrypoint;\r
+       }\r
+       \r
+       // Page Align real base\r
+       iRealBase &= ~0xFFF;\r
+       \r
+       LOG("dynamicTab = %p\n", dynamicTab);\r
+       // Adjust "Real" Base\r
+       iBaseDiff = (uintptr_t)Base - iRealBase;\r
+       LOG("iBaseDiff = %p\n", (void*)iBaseDiff);\r
+       // Adjust Dynamic Table\r
+       dynamicTab = PTR( (uintptr_t)dynamicTab + iBaseDiff);\r
+       LOG("dynamicTab = %p\n", dynamicTab);\r
+\r
+       hdr->entrypoint += iBaseDiff;\r
+       \r
+       // === Get Symbol table and String Table ===\r
+       for( j = 0; dynamicTab[j].d_tag != DT_NULL; j++)\r
+       {\r
+               switch(dynamicTab[j].d_tag)\r
+               {\r
+               // --- Symbol Table ---\r
+               case DT_SYMTAB:\r
+                       dynamicTab[j].d_val += iBaseDiff;\r
+                       dynsymtab = PTRMK(void, dynamicTab[j].d_val);\r
+                       hdr->misc.SymTable = dynamicTab[j].d_val;       // Saved in unused bytes of ident\r
+                       break;\r
+               \r
+               // --- String Table ---\r
+               case DT_STRTAB:\r
+                       dynamicTab[j].d_val += iBaseDiff;\r
+                       dynstrtab = PTRMK(void, dynamicTab[j].d_val);\r
+                       break;\r
+               \r
+               // --- Hash Table --\r
+               case DT_HASH:\r
+                       dynamicTab[j].d_val += iBaseDiff;\r
+                       iSymCount = (PTRMK(uint32_t, dynamicTab[j].d_val))[1];\r
+                       hdr->misc.HashTable = dynamicTab[j].d_val;      // Saved in unused bytes of ident\r
+                       break;\r
+               }\r
+       }\r
+\r
+\r
+       // Alter Symbols to true base\r
+       for(i = 0; i < iSymCount; i ++)\r
+       {\r
+               dynsymtab[i].nameOfs += (uintptr_t)dynstrtab;\r
+               if( dynsymtab[i].shndx == SHN_UNDEF )\r
+               {\r
+                       LOG("Sym '%s' = UNDEF\n", MKPTR(char,dynsymtab[i].name));\r
+               }\r
+               else\r
+               {\r
+                       dynsymtab[i].value += iBaseDiff;\r
+                       LOG("Sym '%s' = 0x%x (relocated)\n", MKPTR(char,dynsymtab[i].name), dynsymtab[i].value);\r
+               }\r
+       }\r
+       \r
+       // === Add to loaded list (can be imported now) ===\r
+       Binary_SetReadyToUse( Base );\r
+\r
+       // === Parse Relocation Data ===\r
+       for( j = 0; dynamicTab[j].d_tag != DT_NULL; j++)\r
+       {\r
+               switch(dynamicTab[j].d_tag)\r
+               {\r
+               // --- Shared Library Name ---\r
+               case DT_SONAME:\r
+                       LOG(".so Name '%s'\n", dynstrtab + dynamicTab[j].d_val);\r
+                       break;\r
+               // --- Needed Library ---\r
+               case DT_NEEDED:\r
+                       libPath = dynstrtab + dynamicTab[j].d_val;\r
+                       Binary_LoadLibrary(libPath);\r
+                       break;\r
+               // --- PLT/GOT ---\r
+               case DT_PLTGOT: pltgot = (void*)(iBaseDiff+dynamicTab[j].d_val);        break;\r
+               case DT_JMPREL: plt = (void*)(iBaseDiff+dynamicTab[j].d_val);   break;\r
+               case DT_PLTREL: pltType = dynamicTab[j].d_val;  break;\r
+               case DT_PLTRELSZ:       pltSz = dynamicTab[j].d_val;    break;\r
+               \r
+               // --- Relocation ---\r
+               case DT_REL:    rel = (void*)(iBaseDiff + dynamicTab[j].d_val); break;\r
+               case DT_RELSZ:  relSz = dynamicTab[j].d_val;    break;\r
+               case DT_RELENT: relEntSz = dynamicTab[j].d_val; break;\r
+               \r
+               case DT_RELA:   rela = (void*)(iBaseDiff + dynamicTab[j].d_val);        break;\r
+               case DT_RELASZ: relaSz = dynamicTab[j].d_val;   break;\r
+               case DT_RELAENT:        relaEntSz = dynamicTab[j].d_val;        break;\r
+               }\r
+       }\r
+       \r
+       // Parse Relocation Entries\r
+       if(rel && relSz)\r
+       {\r
+               j = relSz / relEntSz;\r
+               for( i = 0; i < j; i++ )\r
+               {\r
+                       ptr = (void*)(iBaseDiff + rel[i].r_offset);\r
+                       if( !Elf_Int_DoRelocate(rel[i].r_info, ptr, *ptr, dynsymtab, Base) ) {\r
+                               bFailed = 1;\r
+                       }\r
+               }\r
+       }\r
+       // Parse Relocation Entries\r
+       if(rela && relaSz)\r
+       {\r
+               j = relaSz / relaEntSz;\r
+               for( i = 0; i < j; i++ )\r
+               {\r
+                       ptr = (void*)(iBaseDiff + rela[i].r_offset);\r
+                       if( !Elf_Int_DoRelocate(rel[i].r_info, ptr, rela[i].r_addend, dynsymtab, Base) ) {\r
+                               bFailed = 1;\r
+                       }\r
+               }\r
+       }\r
+       \r
+       // === Process PLT (Procedure Linkage Table) ===\r
+       if(plt && pltSz)\r
+       {\r
+               if(pltType == DT_REL)\r
+               {\r
+                       Elf32_Rel       *pltRel = plt;\r
+                       j = pltSz / sizeof(Elf32_Rel);\r
+                       LOG("PLT Rel - plt = %p, pltSz = %i (%i ents)\n", plt, pltSz, j);\r
+                       for(i = 0; i < j; i++)\r
+                       {\r
+                               ptr = (void*)(iBaseDiff + pltRel[i].r_offset);\r
+                               if( !Elf_Int_DoRelocate(pltRel[i].r_info, ptr, *ptr, dynsymtab, Base) ) {\r
+                                       bFailed = 1;\r
+                               }\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       Elf32_Rela      *pltRela = plt;\r
+                       j = pltSz / sizeof(Elf32_Rela);\r
+                       LOG("PLT RelA - plt = %p, pltSz = %i (%i ents)\n", plt, pltSz, j);\r
+                       for(i=0;i<j;i++)\r
+                       {\r
+                               ptr = (void*)(iBaseDiff + pltRela[i].r_offset);\r
+                               if( !Elf_Int_DoRelocate(pltRela[i].r_info, ptr, pltRela[i].r_addend, dynsymtab, Base) ) {\r
+                                       bFailed = 1;\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+       \r
+       if(bFailed) {\r
+               LEAVE('i', 0);\r
+               return 0;\r
+       }\r
+       \r
+       LEAVE('x', hdr->entrypoint);\r
+       return hdr->entrypoint;\r
+}\r
+\r
+/**\r
+ * \fn void Elf_Int_DoRelocate(uint32_t r_info, uint32_t *ptr, uint32_t addend, Elf32_Sym *symtab, void *base)\r
+ * \brief Performs a relocation\r
+ * \param r_info       Field from relocation entry\r
+ * \param ptr  Pointer to location of relocation\r
+ * \param addend       Value to add to symbol\r
+ * \param symtab       Symbol Table\r
+ * \param base Base of loaded binary\r
+ */\r
+int Elf_Int_DoRelocate(uint32_t r_info, uint32_t *ptr, uint32_t addend, Elf32_Sym *symtab, void *base)\r
+{\r
+       uintptr_t       val;\r
+        int    type = ELF32_R_TYPE(r_info);\r
+        int    sym = ELF32_R_SYM(r_info);\r
+       char    *sSymName = PTRMK(char, symtab[sym].name);\r
+       \r
+       //LogF("Elf_Int_DoRelocate: (r_info=0x%x, ptr=0x%x, addend=0x%x, .., base=0x%x)\n",\r
+       //      r_info, ptr, addend, base);\r
+       \r
+       switch( type )\r
+       {\r
+       // Standard 32 Bit Relocation (S+A)\r
+       case R_386_32:\r
+               if( !Elf_GetSymbol( base, sSymName, &val ) && !Binary_GetSymbol( sSymName, &val ) ) {\r
+                       Warning("Unable to find symbol '%s'", sSymName);\r
+                       return 0;\r
+               }\r
+               LOG("%08x R_386_32 *%p += %p('%s')\n", r_info, ptr, (void*)val, sSymName);\r
+               *ptr = val + addend;\r
+               break;\r
+               \r
+       // 32 Bit Relocation wrt. Offset (S+A-P)\r
+       case R_386_PC32:\r
+               if( !Elf_GetSymbol( base, sSymName, &val ) && !Binary_GetSymbol( sSymName, &val ) ) {\r
+                       Warning("Unable to find symbol '%s'", sSymName);\r
+                       return 0;\r
+               }\r
+               LOG("%08x R_386_PC32 *%p = 0x%x + %p('%s') - %p\n", r_info, ptr, *ptr, (void*)val, sSymName, ptr );\r
+               // TODO: Check if it needs the true value of ptr or the compiled value\r
+               // NOTE: Testing using true value\r
+               *ptr = val + addend - (uintptr_t)ptr;\r
+               break;\r
+\r
+       // Absolute Value of a symbol (S)\r
+       case R_386_GLOB_DAT:\r
+               if( !Elf_GetSymbol( base, sSymName, &val ) && !Binary_GetSymbol( sSymName, &val ) ) {\r
+                       Warning("Unable to find symbol '%s'", sSymName);\r
+                       return 0; \r
+               }\r
+               LOG("%08x R_386_GLOB_DAT *%p = 0x%x(%s)\n", r_info, ptr, (unsigned int)val, sSymName);\r
+               *ptr = val;\r
+               break;\r
+       \r
+       // Absolute Value of a symbol (S)\r
+       case R_386_JMP_SLOT:\r
+               if( !Elf_GetSymbol( base, sSymName, &val ) && !Binary_GetSymbol( sSymName, &val ) ) {\r
+                       Warning("Unable to find symbol '%s'", sSymName);\r
+                       return 0;\r
+               }\r
+               LOG("%08x R_386_JMP_SLOT *%p = 0x%x (%s)\n", r_info, ptr, (unsigned int)val, sSymName);\r
+               *ptr = val;\r
+               break;\r
+\r
+       // Base Address (B+A)\r
+       case R_386_RELATIVE:\r
+               LOG("%08x R_386_RELATIVE *%p = %p + 0x%x\n", r_info, ptr, base, addend);\r
+               *ptr = (uintptr_t)base + addend;\r
+               break;\r
+               \r
+       default:\r
+               LOG("Rel %p: 0x%x,%i\n", ptr, sym, type);\r
+               break;\r
+       }\r
+       return 1;\r
+}\r
+\r
+/**\r
+ * \fn int Elf_GetSymbol(void *Base, char *name, uintptr_t *ret)\r
+ * \brief Get a symbol from the loaded binary\r
+ */\r
+int Elf_GetSymbol(void *Base, char *Name, uintptr_t *ret)\r
+{\r
+       Elf32_Ehdr      *hdr = (void*)Base;\r
+       Elf32_Sym       *symtab;\r
+        int    nbuckets = 0;\r
+        int    iSymCount = 0;\r
+        int    i;\r
+       uint32_t        *pBuckets;\r
+       uint32_t        *pChains;\r
+       uint32_t        iNameHash;\r
+\r
+       if(!Base)       return 0;\r
+\r
+       pBuckets = PTR(hdr->misc.HashTable);\r
+       symtab = PTR(hdr->misc.SymTable);\r
+       \r
+       nbuckets = pBuckets[0];\r
+       iSymCount = pBuckets[1];\r
+       pBuckets = &pBuckets[2];\r
+       pChains = &pBuckets[ nbuckets ];\r
+       \r
+       // Get hash\r
+       iNameHash = Elf_Int_HashString(Name);\r
+       iNameHash %= nbuckets;\r
+\r
+       // Check Bucket\r
+       i = pBuckets[ iNameHash ];\r
+       if(symtab[i].shndx != SHN_UNDEF && strcmp(MKPTR(char,symtab[i].name), Name) == 0) {\r
+               if(ret) *ret = symtab[ i ].value;\r
+               return 1;\r
+       }\r
+       \r
+       // Walk Chain\r
+       while(pChains[i] != STN_UNDEF)\r
+       {\r
+               i = pChains[i];\r
+               if(symtab[i].shndx != SHN_UNDEF && strcmp(MKPTR(char,symtab[i].name), Name) == 0) {\r
+                       if(ret) *ret = symtab[ i ].value;\r
+                       return 1;\r
+               }\r
+       }\r
+       return 0;\r
+}\r
+\r
+/**\r
+ * \fn uint32_t Elf_Int_HashString(char *str)\r
+ * \brief Hash a string in the ELF format\r
+ * \param str  String to hash\r
+ * \return Hash value\r
+ */\r
+uint32_t Elf_Int_HashString(char *str)\r
+{\r
+       uint32_t        h = 0, g;\r
+       while(*str)\r
+       {\r
+               h = (h << 4) + *str++;\r
+               if( (g = h & 0xf0000000) )\r
+                       h ^= g >> 24;\r
+               h &= ~g;\r
+       }\r
+       return h;\r
+}\r
diff --git a/AcessNative/ld-acess_src/elf.h b/AcessNative/ld-acess_src/elf.h
new file mode 100644 (file)
index 0000000..77be918
--- /dev/null
@@ -0,0 +1,217 @@
+/**\r
+ * \file elf.h\r
+ * \brief ELF Exeutable Loader\r
+ */\r
+#ifndef _BIN_ELF_H\r
+#define _BIN_ELF_H\r
+\r
+#include <stdint.h>\r
+\r
+/**\r
+ * \brief ELF File Header\r
+ */\r
+struct sElf32_Ehdr\r
+{\r
+       union {\r
+               char    ident[16];      //!< Identifier Bytes\r
+               struct {\r
+                       uint32_t        Ident1;\r
+                       uint32_t        Ident2;\r
+                       uint32_t        HashTable;\r
+                       uint32_t        SymTable;\r
+               } misc;\r
+       };\r
+       uint16_t        filetype;       //!< File Type\r
+       uint16_t        machine;        //!< Machine / Arch\r
+       uint32_t        version;        //!< Version (File?)\r
+       uint32_t        entrypoint;     //!< Entry Point\r
+       uint32_t        phoff;  //!< Program Header Offset\r
+       uint32_t        shoff;  //!< Section Header Offset\r
+       uint32_t        flags;  //!< Flags\r
+       uint16_t        headersize;     //!< Header Size\r
+       uint16_t        phentsize;      //!< Program Header Entry Size\r
+       uint16_t        phentcount;     //!< Program Header Entry Count\r
+       uint16_t        shentsize;      //!< Section Header Entry Size\r
+       uint16_t        shentcount;     //!< Section Header Entry Count\r
+       uint16_t        shstrindex;     //!< Section Header String Table Index\r
+} __attribute__ ((packed));\r
+\r
+/**\r
+ * \brief Executable Types\r
+ */\r
+enum eElf32_ExecTypes\r
+{\r
+       ET_NONE = 0,    //!< NULL Type\r
+       ET_REL  = 1,    //!< Relocatable (Object)\r
+       ET_EXEC = 2,    //!< Executable\r
+       ET_DYN  = 3,    //!< Dynamic Library\r
+       ET_CORE = 4,    //!< Core?\r
+       ET_LOPROC = 0xFF00,     //!< Low Impl Defined\r
+       ET_HIPROC = 0xFFFF      //!< High Impl Defined\r
+};\r
+\r
+/**\r
+ \name Section IDs\r
+ \{\r
+*/\r
+#define SHN_UNDEF              0       //!< Undefined Section\r
+#define SHN_LORESERVE  0xFF00  //!< Low Reserved\r
+#define SHN_LOPROC             0xFF00  //!< Low Impl Defined\r
+#define SHN_HIPROC             0xFF1F  //!< High Impl Defined\r
+#define SHN_ABS                        0xFFF1  //!< Absolute Address (Base: 0, Size: -1)\r
+#define SHN_COMMON             0xFFF2  //!< Common\r
+#define SHN_HIRESERVE  0xFFFF  //!< High Reserved\r
+//! \}\r
+\r
+/**\r
+ \enum eElfSectionTypes\r
+ \brief ELF Section Types\r
+*/\r
+enum eElfSectionTypes {\r
+       SHT_NULL,       //0\r
+       SHT_PROGBITS,   //1\r
+       SHT_SYMTAB,     //2\r
+       SHT_STRTAB,     //3\r
+       SHT_RELA,       //4\r
+       SHT_HASH,       //5\r
+       SHT_DYNAMIC,    //6\r
+       SHT_NOTE,       //7\r
+       SHT_NOBITS,     //8\r
+       SHT_REL,        //9\r
+       SHT_SHLIB,      //A\r
+       SHT_DYNSYM,     //B\r
+       SHT_LAST,       //C\r
+       SHT_LOPROC = 0x70000000,\r
+       SHT_HIPROC = 0x7fffffff,\r
+       SHT_LOUSER = 0x80000000,\r
+       SHT_HIUSER = 0xffffffff\r
+};\r
+\r
+#define SHF_WRITE      0x1\r
+#define SHF_ALLOC      0x2\r
+#define SHF_EXECINSTR  0x4\r
+#define SHF_MASKPROC   0xf0000000\r
+\r
+struct sElf32_Shent {\r
+       uint32_t        name;\r
+       uint32_t        type;\r
+       uint32_t        flags;\r
+       uint32_t        address;\r
+       uint32_t        offset;\r
+       uint32_t        size;\r
+       uint32_t        link;\r
+       uint32_t        info;\r
+       uint32_t        addralign;\r
+       uint32_t        entsize;\r
+} __attribute__ ((packed));    //sizeof = 40\r
+\r
+struct elf_sym_s {\r
+       union {\r
+               uint32_t        nameOfs;\r
+               uint32_t        name;\r
+       };\r
+       uint32_t        value;  //Address\r
+       uint32_t        size;\r
+       uint8_t info;\r
+       uint8_t other;\r
+       uint16_t        shndx;\r
+} __attribute__ ((packed));\r
+#define        STN_UNDEF       0       // Undefined Symbol\r
+\r
+enum {\r
+       PT_NULL,        //0\r
+       PT_LOAD,        //1\r
+       PT_DYNAMIC,     //2\r
+       PT_INTERP,      //3\r
+       PT_NOTE,        //4\r
+       PT_SHLIB,       //5\r
+       PT_PHDR,        //6\r
+       PT_LOPROC = 0x70000000,\r
+       PT_HIPROC = 0x7fffffff\r
+};\r
+\r
+struct sElf32_Phdr {\r
+       uint32_t        Type;\r
+       uint32_t        Offset;\r
+       uint32_t        VAddr;\r
+       uint32_t        PAddr;\r
+       uint32_t        FileSize;\r
+       uint32_t        MemSize;\r
+       uint32_t        Flags;\r
+       uint32_t        Align;\r
+} __attribute__ ((packed));\r
+\r
+struct elf32_rel_s {\r
+       uint32_t        r_offset;\r
+       uint32_t        r_info;\r
+} __attribute__ ((packed));\r
+\r
+struct elf32_rela_s {\r
+       uint32_t        r_offset;\r
+       uint32_t        r_info;\r
+       int32_t r_addend;\r
+} __attribute__ ((packed));\r
+\r
+enum {\r
+       R_386_NONE = 0, // none\r
+       R_386_32,       // S+A\r
+       R_386_PC32,     // S+A-P\r
+       R_386_GOT32,    // G+A-P\r
+       R_386_PLT32,    // L+A-P\r
+       R_386_COPY,     // none\r
+       R_386_GLOB_DAT, // S\r
+       R_386_JMP_SLOT, // S\r
+       R_386_RELATIVE, // B+A\r
+       R_386_GOTOFF,   // S+A-GOT\r
+       R_386_GOTPC,    // GOT+A-P\r
+       R_386_LAST      // none\r
+};\r
+\r
+#define        ELF32_R_SYM(i)  ((i)>>8)        // Takes an info value and returns a symbol index\r
+#define        ELF32_R_TYPE(i) ((i)&0xFF)      // Takes an info value and returns a type\r
+#define        ELF32_R_INFO(s,t)       (((s)<<8)+((t)&0xFF))   // Takes a type and symbol index and returns an info value\r
+\r
+struct elf32_dyn_s {\r
+       uint32_t        d_tag;\r
+       uint32_t        d_val;  //Also d_ptr\r
+} __attribute__ ((packed));\r
+\r
+enum {\r
+       DT_NULL,        //!< Marks End of list\r
+       DT_NEEDED,      //!< Offset in strtab to needed library\r
+       DT_PLTRELSZ,    //!< Size in bytes of PLT\r
+       DT_PLTGOT,      //!< Address of PLT/GOT\r
+       DT_HASH,        //!< Address of symbol hash table\r
+       DT_STRTAB,      //!< String Table address\r
+       DT_SYMTAB,      //!< Symbol Table address\r
+       DT_RELA,        //!< Relocation table address\r
+       DT_RELASZ,      //!< Size of relocation table\r
+       DT_RELAENT,     //!< Size of entry in relocation table\r
+       DT_STRSZ,       //!< Size of string table\r
+       DT_SYMENT,      //!< Size of symbol table entry\r
+       DT_INIT,        //!< Address of initialisation function\r
+       DT_FINI,        //!< Address of termination function\r
+       DT_SONAME,      //!< String table offset of so name\r
+       DT_RPATH,       //!< String table offset of library path\r
+       DT_SYMBOLIC,//!< Reverse order of symbol searching for library, search libs first then executable\r
+       DT_REL,         //!< Relocation Entries (Elf32_Rel instead of Elf32_Rela)\r
+       DT_RELSZ,       //!< Size of above table (bytes)\r
+       DT_RELENT,      //!< Size of entry in above table\r
+       DT_PLTREL,      //!< Relocation entry of PLT\r
+       DT_DEBUG,       //!< Debugging Entry - Unknown contents\r
+       DT_TEXTREL,     //!< Indicates that modifcations to a non-writeable segment may occur\r
+       DT_JMPREL,      //!< Address of PLT only relocation entries\r
+       DT_LOPROC = 0x70000000, //!< Low Definable\r
+       DT_HIPROC = 0x7FFFFFFF  //!< High Definable\r
+};\r
+\r
+typedef struct sElf32_Ehdr     Elf32_Ehdr;\r
+typedef struct sElf32_Phdr     Elf32_Phdr;\r
+typedef struct sElf32_Shent    Elf32_Shent;\r
+typedef struct elf_sym_s       elf_symtab;\r
+typedef struct elf_sym_s       Elf32_Sym;\r
+typedef struct elf32_rel_s     Elf32_Rel;\r
+typedef struct elf32_rela_s    Elf32_Rela;\r
+typedef struct elf32_dyn_s     Elf32_Dyn;\r
+\r
+#endif // defined(_EXE_ELF_H)\r
diff --git a/AcessNative/ld-acess_src/main.c b/AcessNative/ld-acess_src/main.c
new file mode 100644 (file)
index 0000000..e310a84
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ */
+#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;
+       
+       __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, ...)
+{
+       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_src/memory.c b/AcessNative/ld-acess_src/memory.c
new file mode 100644 (file)
index 0000000..627f902
--- /dev/null
@@ -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_src/request.c b/AcessNative/ld-acess_src/request.c
new file mode 100644 (file)
index 0000000..f9526b3
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ */
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#ifdef __WIN32__
+# include <windows.h>
+# include <winsock.h>
+#else
+# include <unistd.h>
+# 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 = INVALID_SOCKET;
+#else
+# 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()
+{
+       struct sockaddr_in      server;
+       struct sockaddr_in      client;
+       
+       #ifdef __WIN32__
+       /* Open windows connection */
+       if (WSAStartup(0x0101, &gWinsock) != 0)
+       {
+               fprintf(stderr, "Could not open Windows connection.\n");
+               exit(0);
+       }
+       #endif
+       
+       // Open UDP Connection
+       gSocket = socket(AF_INET, SOCK_DGRAM, 0);
+       if (gSocket == INVALID_SOCKET)
+       {
+               fprintf(stderr, "Could not create socket.\n");
+               #if __WIN32__
+               WSACleanup();
+               #endif
+               exit(0);
+       }
+       
+       // Set server address
+       memset((void *)&server, '\0', sizeof(struct sockaddr_in));
+       server.sin_family = AF_INET;
+       server.sin_port = htons(SERVER_PORT);
+       server.sin_addr.s_addr = htonl(0x7F00001);
+       
+       // Set client address
+       memset((void *)&client, '\0', sizeof(struct sockaddr_in));
+       client.sin_family = AF_INET;
+       client.sin_port = htons(0);
+       client.sin_addr.s_addr = htonl(0x7F00001);
+       
+       // Bind
+       if( bind(gSocket, (struct sockaddr *)&client, sizeof(struct sockaddr_in)) == -1 )
+       {
+               fprintf(stderr, "Cannot bind address to socket.\n");
+               #if __WIN32__
+               closesocket(gSocket);
+               WSACleanup();
+               #else
+               close(gSocket);
+               #endif
+               exit(0);
+       }
+       return 0;
+}
+
+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;
+}
diff --git a/AcessNative/ld-acess_src/request.h b/AcessNative/ld-acess_src/request.h
new file mode 100644 (file)
index 0000000..8c89e6f
--- /dev/null
@@ -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_src/syscalls.c b/AcessNative/ld-acess_src/syscalls.c
new file mode 100644 (file)
index 0000000..ec4af01
--- /dev/null
@@ -0,0 +1,302 @@
+/*
+ */
+#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 (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, ...)
+{
+       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);
+}
+
+void close(int FD) {
+       _Syscall(">i", FD);
+}
+
+size_t read(int FD, size_t Bytes, void *Dest) {
+       return _Syscall(">i >i <d", FD, Bytes, Bytes, Dest);
+}
+
+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 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[] = {
+       {"_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]);
+

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