AcessNative - Work on the ELF Loader
authorJohn Hodge <[email protected]>
Thu, 30 Dec 2010 10:12:55 +0000 (21:12 +1100)
committerJohn Hodge <[email protected]>
Thu, 30 Dec 2010 10:12:55 +0000 (21:12 +1100)
- Still not working, but does load now
- Updated gitignore to ignore vim swap files

.gitignore
AcessNative/ld-acess.so_src/Makefile
AcessNative/ld-acess.so_src/binary.c
AcessNative/ld-acess.so_src/common.h
AcessNative/ld-acess.so_src/elf.c
AcessNative/ld-acess.so_src/elf.h
AcessNative/ld-acess.so_src/main.c
AcessNative/ld-acess.so_src/memory.c [new file with mode: 0644]
AcessNative/ld-acess.so_src/request.c
AcessNative/ld-acess.so_src/syscalls.c

index 0f64f8b..2491a49 100644 (file)
@@ -26,3 +26,4 @@ SrcDoc/
 ApiDoc/
 Usermode/Output/
 gitstats/
+.*.swp
index ba3a946..08e12c8 100644 (file)
@@ -5,7 +5,7 @@ ifeq ($(PLATFORM),)
        PLATFORM := lin
 endif
 
-OBJ := main.o syscalls.o request.o
+OBJ := main.o syscalls.o request.o binary.o memory.o
 OBJ += elf.o
 OBJ := $(addsuffix .$(PLATFORM),$(OBJ))
 
@@ -16,7 +16,7 @@ ifeq ($(PLATFORM),lin)
        BIN := ../ld-acess
 endif
 
-CFLAGS += -Wall -Werror
+CFLAGS += -Wall -Werror -g
 
 .PHONY: all clean
 
@@ -26,7 +26,7 @@ clean:
        $(RM) $(BIN) $(OBJ)
 
 $(BIN): $(OBJ)
-       $(CC) -shared -o $@ $<
+       $(CC) -g -o $@ $(OBJ)
 
 %.o.$(PLATFORM): %.c
        $(CC) -c $< -o $@ $(CFLAGS) $(CPPFLAGS)
index 8378c6c..7f97edd 100644 (file)
@@ -1,9 +1,221 @@
 /*
  * AcessNative
  */
+#include "common.h"
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#define LIBRARY_PATH   "../Usermode/Output/i386/Libs"
+
+// === TYPES ===
+typedef struct sBinary {
+       struct sBinary  *Next;
+       void    *Base;
+        int    Ready;
+       tBinFmt *Format;
+       char    Path[];
+}      tBinary;
+
+// === IMPORTS ===
+extern void    *Elf_Load(FILE *FP);
+extern uintptr_t       Elf_Relocate(void *Base);
+extern int     Elf_GetSymbol(void *Base, char *Name, uintptr_t *ret);
+extern int     ciNumBuiltinSymbols;
+extern tSym    caBuiltinSymbols[];
+
+// === PROTOTYPES ===
+void   Binary_AddToList(const char *Filename, void *Base, tBinFmt *Format);
+
+// === GLOBALS ===
+tBinFmt        gElf_FormatDef = {
+//     .Mask = 0xFFFFFFFF,
+//     .Magic = "\x7F""ELF",
+       .Name = "ELF32",
+       .Load = Elf_Load,
+       .Relocate = Elf_Relocate,
+       .GetSymbol = Elf_GetSymbol
+       };
+tBinary        *gLoadedBinaries;
 
 // === CODE ===
-int Binary_GetSymbol(const char *SymbolName, intptr_t *Value)
+char *Binary_LocateLibrary(const char *Name)
+{
+       char    *envPath = getenv("ACESS_LIBRARY_PATH");
+        int    nameLen = strlen(Name);
+       FILE    *fp;
+       
+       // Try the environment ACESS_LIBRARY_PATH
+       if( envPath && envPath[0] != '\0' )
+       {
+                int    len = strlen(envPath)+1+nameLen+1;
+               char    tmp[len];
+
+               strcpy(tmp, envPath);
+               strcat(tmp, "/");
+               strcat(tmp, Name);
+               
+               fp = fopen(tmp, "r");
+               if(fp) {
+                       fclose(fp);
+                       return strdup(tmp);
+               }
+       }               
+
+       {
+                int    len = strlen(LIBRARY_PATH)+1+nameLen+1;
+               char    tmp[len];
+
+               strcpy(tmp, LIBRARY_PATH);
+               strcat(tmp, "/");
+               strcat(tmp, Name);
+               
+               printf("Binary_LocateLibrary: tmp = '%s'\n", tmp);
+
+               fp = fopen(tmp, "r");
+               if(fp) {
+                       fclose(fp);
+                       return strdup(tmp);
+               }
+       }               
+
+       fprintf(stderr, "Unable to locate library '%s'\n", Name);
+
+       return NULL;
+}
+
+void *Binary_LoadLibrary(const char *Name)
+{
+       char    *path;
+       void    *ret;
+        int    (*entry)(int,char*[],char**) = NULL;
+
+       // Find File
+       path = Binary_LocateLibrary(Name);
+       printf("Binary_LoadLibrary: path = '%s'\n", path);
+       if( !path ) {
+               return NULL;
+       }
+
+       ret = Binary_Load(path, (uintptr_t*)&entry);
+       free(path);
+       
+       printf("Binary_LoadLibrary: ret = %p, entry = %p\n", ret, entry);
+       if( entry ) {
+               char    *argv[] = {NULL};
+               entry(0, argv, NULL);
+       }
+
+       return ret;
+}
+
+void *Binary_Load(const char *Filename, uintptr_t *EntryPoint)
 {
+       FILE    *fp;
+       uint32_t        dword;
+       void    *ret;
+       uintptr_t       entry = 0;
+       tBinFmt *fmt;
+
+       {
+               tBinary *bin;
+               for(bin = gLoadedBinaries; bin; bin = bin->Next)
+               {
+                       if( strcmp(Filename, bin->Path) == 0 ) {
+                               return bin->Base;
+                       }
+               }
+       }
+
+       fp = fopen(Filename, "r");
+       if( !fp ) {
+               // TODO: Handle libary directories
+               perror("Opening binary");
+               return NULL;
+       }
+
+       fread(&dword, 1, 4, fp);
+       fseek(fp, 0, SEEK_SET);
+       printf("dword = %08x\n", dword);
+       
+       if( memcmp(&dword, "\x7F""ELF", 4) == 0 ) {
+               fmt = &gElf_FormatDef;
+       }
+       else {
+               fclose(fp);
+               return NULL;
+       }
+
+       ret = fmt->Load(fp);
+       printf("fmt->Load(%p): %p\n", fp, ret);
+       if( !ret ) {
+               fclose(fp);
+               return NULL;
+       }
+       
+       Binary_AddToList(Filename, ret, fmt);
+
+       entry = fmt->Relocate(ret);
+       printf("fmt->Relocate(%p): %p\n", ret, (void*)entry);
+       if( !entry ) {
+               // TODO: Clean up
+               return NULL;
+       }
+       
+       if( EntryPoint )
+               *EntryPoint = entry;
+
+       fclose(fp);
+
+       Binary_SetReadyToUse(ret);
+
+       return ret;
+}
+
+void Binary_AddToList(const char *Filename, void *Base, tBinFmt *Format)
+{
+       tBinary *bin = malloc(sizeof(tBinary) + strlen(Filename) + 1);
+       bin->Base = Base;
+       bin->Format = Format;
+       strcpy(bin->Path, Filename);
+       bin->Ready = 0;
+       
+       bin->Next = gLoadedBinaries;
+       gLoadedBinaries = bin;
+}
+
+void Binary_SetReadyToUse(void *Base)
+{
+       tBinary *bin;
+       for(bin = gLoadedBinaries; bin; bin = bin->Next)
+       {
+               if( bin->Base != Base ) continue ;
+               bin->Ready = 1;
+       }
+}
+
+int Binary_GetSymbol(const char *SymbolName, uintptr_t *Value)
+{
+        int    i;
+       tBinary *bin;
+       
+       // TODO: Search list of loaded binaries
+       for(bin = gLoadedBinaries; bin; bin = bin->Next)
+       {
+               if( !bin->Ready )       continue;
+               printf("Binary_GetSymbol: bin = %p{%p, %s}\n", bin, bin->Base, bin->Path);
+               if( bin->Format->GetSymbol(bin->Base, (char*)SymbolName, Value) )
+                       return 1;
+       }
+
+       // Search builtins
+       for( i = 0; i < ciNumBuiltinSymbols; i ++ )
+       {
+               if( strcmp(caBuiltinSymbols[i].Name, SymbolName) == 0 ) {
+                       *Value = (uintptr_t)caBuiltinSymbols[i].Value;
+                       return 1;
+               }
+       }
+
        return 0;
 }
index 276938f..4667acb 100644 (file)
@@ -3,15 +3,33 @@
 #ifndef _COMMON_H_
 #define _COMMON_H_
 
+#include <stdlib.h>
+#include <stdio.h>
 #include <stdint.h>
 
-extern int     Binary_GetSymbol(const char *SymbolName, intptr_t *Value);
-extern int     Binary_LoadLibrary(const char *Path);
+extern int     Binary_GetSymbol(const char *SymbolName, uintptr_t *Value);
+extern void    *Binary_LoadLibrary(const char *Path);
+extern void    *Binary_Load(const char *Path, uintptr_t *EntryPoint);
+extern void    Binary_SetReadyToUse(void *Base);
 
-extern int     AllocateMemory(intptr_t VirtAddr, size_t ByteCount);
+extern int     AllocateMemory(uintptr_t VirtAddr, size_t ByteCount);
+extern uintptr_t       FindFreeRange(size_t ByteCount, int MaxBits);
 
-extern int     Warning(const char *Format, ...);
-extern int     Notice(const char *Format, ...);
+extern void    Warning(const char *Format, ...);
+extern void    Notice(const char *Format, ...);
+
+typedef struct {
+       char    *Name;
+       void    *Value;
+}      tSym;
+
+typedef struct sBinFmt {
+       struct sBinFmt  *Next;
+       char    *Name;
+       void    *(*Load)(FILE *fp);
+       uintptr_t       (*Relocate)(void *base);
+        int    (*GetSymbol)(void*,char*,uintptr_t*);
+}      tBinFmt;
 
 #endif
 
index 35ac56b..11bd2df 100644 (file)
 \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 0\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
- int   Elf_Load(int fd);\r
- int   Elf_Relocate(void *Base);\r
- int   Elf_GetSymbol(void *Base, char *Name, intptr_t *ret);\r
- int   Elf_Int_DoRelocate(uint32_t r_info, uint32_t *ptr, uint32_t addend, Elf32_Sym *symtab, intptr_t base);\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
-int Elf_Load(int FD)\r
+void *Elf_Load(FILE *FP)\r
 {\r
        Elf32_Ehdr      hdr;\r
        Elf32_Phdr      *phtab;\r
@@ -32,17 +44,18 @@ int Elf_Load(int FD)
         int    iPageCount;\r
        uint32_t        max, base = -1;\r
        uint32_t        addr;\r
+       uint32_t        baseDiff = 0;\r
        \r
-       ENTER("xFD", FD);\r
+       ENTER("pFP", FP);\r
        \r
        // Read ELF Header\r
-       read(FD, &hdr, sizeof(hdr));\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 1;\r
+               return NULL;\r
        }\r
        \r
        // Check for a program header\r
@@ -51,32 +64,32 @@ int Elf_Load(int FD)
                Warning("ELF File does not contain a program header\n");\r
                #endif\r
                LEAVE('n');\r
-               return 1;\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 1;\r
+               return NULL;\r
        }\r
-       LOG("hdr.phoff = 0x%08x", hdr.phoff);\r
-       lseek(FD, hdr.phoff, SEEK_SET);\r
-       read(FD, phtab, sizeof(Elf32_Phdr)*hdr.phentcount);\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", hdr.phentcount);\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}", i, phtab[i].VAddr, phtab[i].MemSize);\r
+               LOG("phtab[%i] = {VAddr:0x%x, MemSize:0x%x}\n", i, phtab[i].VAddr, phtab[i].MemSize);\r
        }\r
        \r
-       LOG("iPageCount = %i", iPageCount);\r
+       LOG("iPageCount = %i\n", iPageCount);\r
        \r
        // Allocate Information Structure\r
        //ret = malloc( sizeof(tBinary) + sizeof(tBinaryPage)*iPageCount );\r
@@ -97,71 +110,80 @@ int Elf_Load(int FD)
                        max = phtab[i].VAddr;\r
        }\r
 \r
-       LOG("base = %08x, max = %08x", base, max);\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] = {", i);\r
-               LOG(" .Type = 0x%08x", phtab[i].Type);\r
-               LOG(" .Offset = 0x%08x", phtab[i].Offset);\r
-               LOG(" .VAddr = 0x%08x", phtab[i].VAddr);\r
-               LOG(" .PAddr = 0x%08x", phtab[i].PAddr);\r
-               LOG(" .FileSize = 0x%08x", phtab[i].FileSize);\r
-               LOG(" .MemSize = 0x%08x", phtab[i].MemSize);\r
-               LOG(" .Flags = 0x%08x", phtab[i].Flags);\r
-               LOG(" .Align = 0x%08x", phtab[i].Align);\r
-               LOG(" }");\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
-                       lseek(FD, phtab[i].Offset, 1);\r
-                       read(FD, tmp, 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'", 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}",\r
-                       i, phtab[i].VAddr, phtab[i].Offset, phtab[i].FileSize);\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;\r
+               addr = phtab[i].VAddr + baseDiff;\r
 \r
-               AllocateMemory( addr, phtab[i].MemSize );\r
+               if( AllocateMemory( addr, phtab[i].MemSize ) ) {\r
+                       return NULL;\r
+               }\r
                \r
-               lseek(FD, phtab[i].Offset, SEEK_SET);\r
-               read(FD, (void*)(intptr_t)addr, phtab[i].FileSize);\r
-               memset( (char*)(intptr_t)addr + phtab[i].FileSize, 0, phtab[i].MemSize - phtab[i].FileSize);\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('i', 0);\r
-       return 0;\r
+       LEAVE('p', base);\r
+       return PTRMK(void, base);\r
 }\r
 \r
 // --- ELF RELOCATION ---\r
 /**\r
- \fn int Elf_Relocate(void *Base)\r
- \brief Relocates a loaded ELF Executable\r
-*/\r
-int Elf_Relocate(void *Base)\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
-       intptr_t        iBaseDiff;\r
+       uintptr_t       iBaseDiff;\r
         int    iSegmentCount;\r
         int    iSymCount = 0;\r
        Elf32_Rel       *rel = NULL;\r
@@ -178,6 +200,7 @@ int Elf_Relocate(void *Base)
         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
@@ -194,7 +217,7 @@ int Elf_Relocate(void *Base)
                                Warning("Elf_Relocate - Multiple PT_DYNAMIC segments\n");\r
                                continue;\r
                        }\r
-                       dynamicTab = (void *) (intptr_t) phtab[i].VAddr;\r
+                       dynamicTab = MKPTR(void, phtab[i].VAddr);\r
                        j = i;  // Save Dynamic Table ID\r
                        break;\r
                }\r
@@ -210,10 +233,15 @@ int Elf_Relocate(void *Base)
        // Page Align real base\r
        iRealBase &= ~0xFFF;\r
        \r
+       LOG("dynamicTab = %p\n", dynamicTab);\r
        // Adjust "Real" Base\r
-       iBaseDiff = (intptr_t)Base - iRealBase;\r
+       iBaseDiff = (uintptr_t)Base - iRealBase;\r
+       LOG("iBaseDiff = %p\n", (void*)iBaseDiff);\r
        // Adjust Dynamic Table\r
-       dynamicTab = (void *) ((intptr_t)dynamicTab + iBaseDiff);\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
@@ -223,20 +251,20 @@ int Elf_Relocate(void *Base)
                // --- Symbol Table ---\r
                case DT_SYMTAB:\r
                        dynamicTab[j].d_val += iBaseDiff;\r
-                       dynsymtab = (void*) (intptr_t) dynamicTab[j].d_val;\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 = (void*) (intptr_t) dynamicTab[j].d_val;\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 = ((uint32_t*)((intptr_t)dynamicTab[j].d_val))[1];\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
@@ -247,12 +275,12 @@ int Elf_Relocate(void *Base)
        for(i = 0; i < iSymCount; i ++)\r
        {\r
                dynsymtab[i].value += iBaseDiff;\r
-               dynsymtab[i].nameOfs += (intptr_t)dynstrtab;\r
-               //LOG("Sym '%s' = 0x%x (relocated)\n", dynsymtab[i].name, dynsymtab[i].value);\r
+               dynsymtab[i].nameOfs += (uintptr_t)dynstrtab;\r
+               LOG("Sym '%s' = 0x%x (relocated)\n", MKPTR(char,dynsymtab[i].name), dynsymtab[i].value);\r
        }\r
        \r
        // === Add to loaded list (can be imported now) ===\r
-       //Binary_AddLoaded( (intptr_t)Base );\r
+       Binary_SetReadyToUse( Base );\r
 \r
        // === Parse Relocation Data ===\r
        for( j = 0; dynamicTab[j].d_tag != DT_NULL; j++)\r
@@ -261,12 +289,12 @@ int Elf_Relocate(void *Base)
                {\r
                // --- Shared Library Name ---\r
                case DT_SONAME:\r
-                       LOG(".so Name '%s'\n", dynstrtab+dynamicTab[j].d_val);\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
-                       Notice("%p - Required Library '%s' - TODO load DT_NEEDED\n", Base, libPath);\r
+                       Binary_LoadLibrary(libPath);\r
                        break;\r
                // --- PLT/GOT ---\r
                case DT_PLTGOT: pltgot = (void*)(iBaseDiff+dynamicTab[j].d_val);        break;\r
@@ -292,7 +320,7 @@ int Elf_Relocate(void *Base)
                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, (intptr_t)Base) ) {\r
+                       if( !Elf_Int_DoRelocate(rel[i].r_info, ptr, *ptr, dynsymtab, Base) ) {\r
                                bFailed = 1;\r
                        }\r
                }\r
@@ -304,7 +332,7 @@ int Elf_Relocate(void *Base)
                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, (intptr_t)Base) ) {\r
+                       if( !Elf_Int_DoRelocate(rel[i].r_info, ptr, rela[i].r_addend, dynsymtab, Base) ) {\r
                                bFailed = 1;\r
                        }\r
                }\r
@@ -317,11 +345,11 @@ int Elf_Relocate(void *Base)
                {\r
                        Elf32_Rel       *pltRel = plt;\r
                        j = pltSz / sizeof(Elf32_Rel);\r
-                       LOG("PLT Rel - plt = %p, pltSz = %i (%i ents)", plt, pltSz, j);\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, (intptr_t)Base) ) {\r
+                               if( !Elf_Int_DoRelocate(pltRel[i].r_info, ptr, *ptr, dynsymtab, Base) ) {\r
                                        bFailed = 1;\r
                                }\r
                        }\r
@@ -330,11 +358,11 @@ int Elf_Relocate(void *Base)
                {\r
                        Elf32_Rela      *pltRela = plt;\r
                        j = pltSz / sizeof(Elf32_Rela);\r
-                       LOG("PLT RelA - plt = %p, pltSz = %i (%i ents)", plt, pltSz, j);\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, (intptr_t)Base) ) {\r
+                               if( !Elf_Int_DoRelocate(pltRela[i].r_info, ptr, pltRela[i].r_addend, dynsymtab, Base) ) {\r
                                        bFailed = 1;\r
                                }\r
                        }\r
@@ -351,7 +379,7 @@ int Elf_Relocate(void *Base)
 }\r
 \r
 /**\r
- * \fn void Elf_Int_DoRelocate(uint32_t r_info, uint32_t *ptr, uint32_t addend, Elf32_Sym *symtab, uint32_t base)\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
@@ -359,12 +387,12 @@ int Elf_Relocate(void *Base)
  * \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, intptr_t base)\r
+int Elf_Int_DoRelocate(uint32_t r_info, uint32_t *ptr, uint32_t addend, Elf32_Sym *symtab, void *base)\r
 {\r
-       intptr_t        val;\r
+       uintptr_t       val;\r
         int    type = ELF32_R_TYPE(r_info);\r
         int    sym = ELF32_R_SYM(r_info);\r
-       char    *sSymName = symtab[sym].name;\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
@@ -373,60 +401,64 @@ int Elf_Int_DoRelocate(uint32_t r_info, uint32_t *ptr, uint32_t addend, Elf32_Sy
        {\r
        // Standard 32 Bit Relocation (S+A)\r
        case R_386_32:\r
-               if( !Elf_GetSymbol((void*)base, sSymName, &val) )       // Search this binary first\r
-                       if( !Binary_GetSymbol( sSymName, &val ) )\r
-                               return 0;\r
-               LOG("%08x R_386_32 *0x%x += 0x%x('%s')", r_info, ptr, val, sSymName);\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( (void*)base, sSymName, &val ) )\r
-                       if( !Binary_GetSymbol( sSymName, &val ) )\r
-                               return 0;\r
-               LOG("%08x R_386_PC32 *0x%x = 0x%x + 0x%x('%s') - %p", r_info, ptr, *ptr, val, sSymName, ptr );\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 - (intptr_t)ptr;\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( (void*)base, sSymName, &val ) )\r
-                       if( !Binary_GetSymbol( sSymName, &val ) )\r
-                               return 0;\r
-               LOG("%08x R_386_GLOB_DAT *0x%x = 0x%x (%s)", r_info, ptr, val, sSymName);\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( (void*)base, sSymName, &val ) )\r
-                       if( !Binary_GetSymbol( sSymName, &val ) )\r
-                               return 0;\r
-               LOG("%08x R_386_JMP_SLOT %p = 0x%x (%s)", r_info, ptr, val, sSymName);\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 = 0x%x + 0x%x", r_info, ptr, base, addend);\r
-               *ptr = base + addend;\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 0x%x: 0x%x,%i", ptr, sym, type);\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, intptr_t *ret)\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, intptr_t *ret)\r
+int Elf_GetSymbol(void *Base, char *Name, uintptr_t *ret)\r
 {\r
        Elf32_Ehdr      *hdr = (void*)Base;\r
        Elf32_Sym       *symtab;\r
@@ -439,8 +471,8 @@ int Elf_GetSymbol(void *Base, char *Name, intptr_t *ret)
 \r
        if(!Base)       return 0;\r
 \r
-       pBuckets = (void *)(intptr_t) hdr->misc.HashTable;\r
-       symtab = (void *)(intptr_t) hdr->misc.SymTable;\r
+       pBuckets = PTR(hdr->misc.HashTable);\r
+       symtab = PTR(hdr->misc.SymTable);\r
        \r
        nbuckets = pBuckets[0];\r
        iSymCount = pBuckets[1];\r
@@ -453,7 +485,7 @@ int Elf_GetSymbol(void *Base, char *Name, intptr_t *ret)
 \r
        // Check Bucket\r
        i = pBuckets[ iNameHash ];\r
-       if(symtab[i].shndx != SHN_UNDEF && strcmp(symtab[i].name, Name) == 0) {\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
@@ -462,7 +494,7 @@ int Elf_GetSymbol(void *Base, char *Name, intptr_t *ret)
        while(pChains[i] != STN_UNDEF)\r
        {\r
                i = pChains[i];\r
-               if(symtab[i].shndx != SHN_UNDEF && strcmp(symtab[ i ].name, Name) == 0) {\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
index 2527e99..77be918 100644 (file)
@@ -108,7 +108,7 @@ struct sElf32_Shent {
 struct elf_sym_s {\r
        union {\r
                uint32_t        nameOfs;\r
-               char    *name;\r
+               uint32_t        name;\r
        };\r
        uint32_t        value;  //Address\r
        uint32_t        size;\r
index e69de29..d9bad13 100644 (file)
@@ -0,0 +1,62 @@
+/*
+ */
+#include "common.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+// === CODE ===
+int main(int argc, char *argv[], char **envp)
+{
+        int    i;
+        int    appArgc;
+       char    **appArgv;
+       char    *appPath;
+        int    (*appMain)(int, char *[], char **);
+       void    *base;
+       
+       for( i = 1; i < argc; i ++ )
+       {
+               if( argv[i][0] != '-' ) break;
+       }
+
+       if( i >= argc ) {
+               fprintf(stderr, "Usage: ld-acess <executable> [arguments ...]\n");
+               return 1;
+       }
+       
+       appPath = argv[i];
+
+       appArgc = argc - i;
+       appArgv = &argv[i];
+
+       printf("Exectutable Path: '%s'\n", appPath);
+       printf("Executable argc = %i\n", appArgc);
+
+       base = Binary_Load(appPath, (uintptr_t*)&appMain);
+       printf("base = %p\n", base);
+       if( !base )     return 127;
+       
+       return appMain(appArgc, appArgv, envp);
+}
+
+void Warning(const char *Format, ...)
+{
+       va_list args;
+       printf("Warning: ");
+       va_start(args, Format);
+       vprintf(Format, args);
+       va_end(args);
+       printf("\n");
+}
+
+void Notice(const char *Format, ...)
+{
+       va_list args;
+       printf("Notice: ");
+       va_start(args, Format);
+       vprintf(Format, args);
+       va_end(args);
+       printf("\n");
+}
+
diff --git a/AcessNative/ld-acess.so_src/memory.c b/AcessNative/ld-acess.so_src/memory.c
new file mode 100644 (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
+}
index e806ca0..79db625 100644 (file)
@@ -75,8 +75,9 @@ int _InitSyscalls()
        }
        return 0;
 }
-
+#if 0
 int _Syscall(const char *ArgTypes, ...)
 {
        return 0;
 }
+#endif
index 416cab6..e26ae35 100644 (file)
@@ -1,12 +1,15 @@
 /*
  */
 //#include <acess/sys.h>
+#include "common.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
 #include <stdarg.h>
 
 // === IMPORTS ===
+
+// === CODE ===
 /**
  * \param ArgTypes
  *
@@ -54,3 +57,16 @@ int seek(int FD, uint64_t Ofs, int Dir) {
        return _Syscall(">i >I >i", FD, Ofs, Dir);
 }
 
+// === Symbol List ===
+const tSym     caBuiltinSymbols[] = {
+       {"open", open},
+       {"close", close},
+       {"read", read},
+       {"write", write},
+       {"tell", tell},
+       {"seek", seek},
+       {"_exit", exit}
+};
+
+const int      ciNumBuiltinSymbols = sizeof(caBuiltinSymbols)/sizeof(caBuiltinSymbols[0]);
+

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