/*
* AcessNative
*/
+#include "common.h"
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#define LIBRARY_PATH "../Usermode/Output/i386/Libs"
+
+// === TYPES ===
+typedef struct sBinary {
+ struct sBinary *Next;
+ void *Base;
+ int Ready;
+ tBinFmt *Format;
+ char Path[];
+} tBinary;
+
+// === IMPORTS ===
+extern void *Elf_Load(FILE *FP);
+extern uintptr_t Elf_Relocate(void *Base);
+extern int Elf_GetSymbol(void *Base, char *Name, uintptr_t *ret);
+extern int ciNumBuiltinSymbols;
+extern tSym caBuiltinSymbols[];
+
+// === PROTOTYPES ===
+void Binary_AddToList(const char *Filename, void *Base, tBinFmt *Format);
+
+// === GLOBALS ===
+tBinFmt gElf_FormatDef = {
+// .Mask = 0xFFFFFFFF,
+// .Magic = "\x7F""ELF",
+ .Name = "ELF32",
+ .Load = Elf_Load,
+ .Relocate = Elf_Relocate,
+ .GetSymbol = Elf_GetSymbol
+ };
+tBinary *gLoadedBinaries;
// === CODE ===
-int Binary_GetSymbol(const char *SymbolName, intptr_t *Value)
+char *Binary_LocateLibrary(const char *Name)
+{
+ char *envPath = getenv("ACESS_LIBRARY_PATH");
+ int nameLen = strlen(Name);
+ FILE *fp;
+
+ // Try the environment ACESS_LIBRARY_PATH
+ if( envPath && envPath[0] != '\0' )
+ {
+ int len = strlen(envPath)+1+nameLen+1;
+ char tmp[len];
+
+ strcpy(tmp, envPath);
+ strcat(tmp, "/");
+ strcat(tmp, Name);
+
+ fp = fopen(tmp, "r");
+ if(fp) {
+ fclose(fp);
+ return strdup(tmp);
+ }
+ }
+
+ {
+ int len = strlen(LIBRARY_PATH)+1+nameLen+1;
+ char tmp[len];
+
+ strcpy(tmp, LIBRARY_PATH);
+ strcat(tmp, "/");
+ strcat(tmp, Name);
+
+ printf("Binary_LocateLibrary: tmp = '%s'\n", tmp);
+
+ fp = fopen(tmp, "r");
+ if(fp) {
+ fclose(fp);
+ return strdup(tmp);
+ }
+ }
+
+ fprintf(stderr, "Unable to locate library '%s'\n", Name);
+
+ return NULL;
+}
+
+void *Binary_LoadLibrary(const char *Name)
+{
+ char *path;
+ void *ret;
+ int (*entry)(int,char*[],char**) = NULL;
+
+ // Find File
+ path = Binary_LocateLibrary(Name);
+ printf("Binary_LoadLibrary: path = '%s'\n", path);
+ if( !path ) {
+ return NULL;
+ }
+
+ ret = Binary_Load(path, (uintptr_t*)&entry);
+ free(path);
+
+ printf("Binary_LoadLibrary: ret = %p, entry = %p\n", ret, entry);
+ if( entry ) {
+ char *argv[] = {NULL};
+ entry(0, argv, NULL);
+ }
+
+ return ret;
+}
+
+void *Binary_Load(const char *Filename, uintptr_t *EntryPoint)
{
+ FILE *fp;
+ uint32_t dword;
+ void *ret;
+ uintptr_t entry = 0;
+ tBinFmt *fmt;
+
+ {
+ tBinary *bin;
+ for(bin = gLoadedBinaries; bin; bin = bin->Next)
+ {
+ if( strcmp(Filename, bin->Path) == 0 ) {
+ return bin->Base;
+ }
+ }
+ }
+
+ fp = fopen(Filename, "r");
+ if( !fp ) {
+ // TODO: Handle libary directories
+ perror("Opening binary");
+ return NULL;
+ }
+
+ fread(&dword, 1, 4, fp);
+ fseek(fp, 0, SEEK_SET);
+ printf("dword = %08x\n", dword);
+
+ if( memcmp(&dword, "\x7F""ELF", 4) == 0 ) {
+ fmt = &gElf_FormatDef;
+ }
+ else {
+ fclose(fp);
+ return NULL;
+ }
+
+ ret = fmt->Load(fp);
+ printf("fmt->Load(%p): %p\n", fp, ret);
+ if( !ret ) {
+ fclose(fp);
+ return NULL;
+ }
+
+ Binary_AddToList(Filename, ret, fmt);
+
+ entry = fmt->Relocate(ret);
+ printf("fmt->Relocate(%p): %p\n", ret, (void*)entry);
+ if( !entry ) {
+ // TODO: Clean up
+ return NULL;
+ }
+
+ if( EntryPoint )
+ *EntryPoint = entry;
+
+ fclose(fp);
+
+ Binary_SetReadyToUse(ret);
+
+ return ret;
+}
+
+void Binary_AddToList(const char *Filename, void *Base, tBinFmt *Format)
+{
+ tBinary *bin = malloc(sizeof(tBinary) + strlen(Filename) + 1);
+ bin->Base = Base;
+ bin->Format = Format;
+ strcpy(bin->Path, Filename);
+ bin->Ready = 0;
+
+ bin->Next = gLoadedBinaries;
+ gLoadedBinaries = bin;
+}
+
+void Binary_SetReadyToUse(void *Base)
+{
+ tBinary *bin;
+ for(bin = gLoadedBinaries; bin; bin = bin->Next)
+ {
+ if( bin->Base != Base ) continue ;
+ bin->Ready = 1;
+ }
+}
+
+int Binary_GetSymbol(const char *SymbolName, uintptr_t *Value)
+{
+ int i;
+ tBinary *bin;
+
+ // TODO: Search list of loaded binaries
+ for(bin = gLoadedBinaries; bin; bin = bin->Next)
+ {
+ if( !bin->Ready ) continue;
+ printf("Binary_GetSymbol: bin = %p{%p, %s}\n", bin, bin->Base, bin->Path);
+ if( bin->Format->GetSymbol(bin->Base, (char*)SymbolName, Value) )
+ return 1;
+ }
+
+ // Search builtins
+ for( i = 0; i < ciNumBuiltinSymbols; i ++ )
+ {
+ if( strcmp(caBuiltinSymbols[i].Name, SymbolName) == 0 ) {
+ *Value = (uintptr_t)caBuiltinSymbols[i].Value;
+ return 1;
+ }
+ }
+
return 0;
}