AcessNative - ld-acess - Woking on ELF loading
authorJohn Hodge <[email protected]>
Mon, 20 Dec 2010 01:54:45 +0000 (10:39 +0845)
committerJohn Hodge <[email protected]>
Mon, 20 Dec 2010 01:54:45 +0000 (10:39 +0845)
AcessNative/ld-acess.so_src/Makefile
AcessNative/ld-acess.so_src/binary.c [new file with mode: 0644]
AcessNative/ld-acess.so_src/common.h [new file with mode: 0644]
AcessNative/ld-acess.so_src/elf.c [new file with mode: 0644]
AcessNative/ld-acess.so_src/elf.h [new file with mode: 0644]
AcessNative/ld-acess.so_src/main.c [new file with mode: 0644]
AcessNative/ld-acess.so_src/request.c
AcessNative/ld-acess.so_src/syscalls.c

index 3531f71..ba3a946 100644 (file)
@@ -5,16 +5,18 @@ ifeq ($(PLATFORM),)
        PLATFORM := lin
 endif
 
-OBJ := syscalls.$(PLATFORM).o request.$(PLATFORM).o
+OBJ := main.o syscalls.o request.o
+OBJ += elf.o
+OBJ := $(addsuffix .$(PLATFORM),$(OBJ))
 
 ifeq ($(PLATFORM),win)
-       BIN := ../libacess.dll
+       BIN := ../ld-acess.exe
 endif
 ifeq ($(PLATFORM),lin)
-       BIN := ../libacess.so
-       CFLAGS += -fPIC
+       BIN := ../ld-acess
 endif
 
+CFLAGS += -Wall -Werror
 
 .PHONY: all clean
 
@@ -26,6 +28,6 @@ clean:
 $(BIN): $(OBJ)
        $(CC) -shared -o $@ $<
 
-%.$(PLATFORM).o: %.c
+%.o.$(PLATFORM): %.c
        $(CC) -c $< -o $@ $(CFLAGS) $(CPPFLAGS)
 
diff --git a/AcessNative/ld-acess.so_src/binary.c b/AcessNative/ld-acess.so_src/binary.c
new file mode 100644 (file)
index 0000000..8378c6c
--- /dev/null
@@ -0,0 +1,9 @@
+/*
+ * AcessNative
+ */
+
+// === CODE ===
+int Binary_GetSymbol(const char *SymbolName, intptr_t *Value)
+{
+       return 0;
+}
diff --git a/AcessNative/ld-acess.so_src/common.h b/AcessNative/ld-acess.so_src/common.h
new file mode 100644 (file)
index 0000000..276938f
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ */
+#ifndef _COMMON_H_
+#define _COMMON_H_
+
+#include <stdint.h>
+
+extern int     Binary_GetSymbol(const char *SymbolName, intptr_t *Value);
+extern int     Binary_LoadLibrary(const char *Path);
+
+extern int     AllocateMemory(intptr_t VirtAddr, size_t ByteCount);
+
+extern int     Warning(const char *Format, ...);
+extern int     Notice(const char *Format, ...);
+
+#endif
+
diff --git a/AcessNative/ld-acess.so_src/elf.c b/AcessNative/ld-acess.so_src/elf.c
new file mode 100644 (file)
index 0000000..35ac56b
--- /dev/null
@@ -0,0 +1,490 @@
+/*\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 ENTER(...)\r
+#define LOG(...)\r
+#define LEAVE(...)\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
+uint32_t       Elf_Int_HashString(char *str);\r
+\r
+// === CODE ===\r
+int Elf_Load(int FD)\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
+       \r
+       ENTER("xFD", FD);\r
+       \r
+       // Read ELF Header\r
+       read(FD, &hdr, sizeof(hdr));\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
+       }\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 1;\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
+       }\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
+       \r
+       // Count Pages\r
+       iPageCount = 0;\r
+       LOG("hdr.phentcount = %i", 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
+       }\r
+       \r
+       LOG("iPageCount = %i", 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", base, max);\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
+               // 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
+                       //ret->Interpreter = Binary_RegInterp(tmp);\r
+                       LOG("Interpreter '%s'", 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
+               \r
+               addr = phtab[i].VAddr;\r
+\r
+               AllocateMemory( addr, phtab[i].MemSize );\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
+       }\r
+       \r
+       // Clean Up\r
+       free(phtab);\r
+       // Return\r
+       LEAVE('i', 0);\r
+       return 0;\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
+{\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
+        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
+       \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 = (void *) (intptr_t) 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
+       // Adjust "Real" Base\r
+       iBaseDiff = (intptr_t)Base - iRealBase;\r
+       // Adjust Dynamic Table\r
+       dynamicTab = (void *) ((intptr_t)dynamicTab + 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 = (void*) (intptr_t) 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
+                       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
+                       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].value += iBaseDiff;\r
+               dynsymtab[i].nameOfs += (intptr_t)dynstrtab;\r
+               //LOG("Sym '%s' = 0x%x (relocated)\n", dynsymtab[i].name, dynsymtab[i].value);\r
+       }\r
+       \r
+       // === Add to loaded list (can be imported now) ===\r
+       //Binary_AddLoaded( (intptr_t)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
+                       Notice("%p - Required Library '%s' - TODO load DT_NEEDED\n", Base, 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, (intptr_t)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, (intptr_t)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)", 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
+                                       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)", 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
+                                       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, uint32_t 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, intptr_t base)\r
+{\r
+       intptr_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
+       \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((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
+               *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
+               // 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
+               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
+               *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
+               *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
+               break;\r
+               \r
+       default:\r
+               LOG("Rel 0x%x: 0x%x,%i", 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
+ * \brief Get a symbol from the loaded binary\r
+ */\r
+int Elf_GetSymbol(void *Base, char *Name, intptr_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 = (void *)(intptr_t) hdr->misc.HashTable;\r
+       symtab = (void *)(intptr_t) 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(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(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
new file mode 100644 (file)
index 0000000..2527e99
--- /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
+               char    *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
new file mode 100644 (file)
index 0000000..e69de29
index 5a64119..e806ca0 100644 (file)
@@ -1,8 +1,16 @@
 /*
  */
-#include <windows.h>
+#include <stdlib.h>
+#include <string.h>
 #include <stdio.h>
-#include <winsock.h>
+#ifdef __WIN32__
+# include <windows.h>
+# include <winsock.h>
+#else
+# include <unistd.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
+#endif
 
 #define        SERVER_PORT     0xACE
 
@@ -10,6 +18,9 @@
 #ifdef __WIN32__
 WSADATA        gWinsock;
 SOCKET gSocket;
+#else
+ int   gSocket;
+# define INVALID_SOCKET -1
 #endif
 
 // === CODE ===
@@ -32,7 +43,9 @@ int _InitSyscalls()
        if (gSocket == INVALID_SOCKET)
        {
                fprintf(stderr, "Could not create socket.\n");
+               #if __WIN32__
                WSACleanup();
+               #endif
                exit(0);
        }
        
@@ -40,28 +53,27 @@ int _InitSyscalls()
        memset((void *)&server, '\0', sizeof(struct sockaddr_in));
        server.sin_family = AF_INET;
        server.sin_port = htons(SERVER_PORT);
-       server.sin_addr.S_un.S_un_b.s_b1 = (unsigned char)127;
-       server.sin_addr.S_un.S_un_b.s_b2 = (unsigned char)0;
-       server.sin_addr.S_un.S_un_b.s_b3 = (unsigned char)0;
-       server.sin_addr.S_un.S_un_b.s_b4 = (unsigned char)1;
+       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_un.S_un_b.s_b1 = (unsigned char)127;
-       client.sin_addr.S_un.S_un_b.s_b2 = (unsigned char)0;
-       client.sin_addr.S_un.S_un_b.s_b3 = (unsigned char)0;
-       client.sin_addr.S_un.S_un_b.s_b4 = (unsigned char)1;
+       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 _Syscall(const char *ArgTypes, ...)
index 35fa6ae..416cab6 100644 (file)
@@ -4,6 +4,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
+#include <stdarg.h>
 
 // === IMPORTS ===
 /**
  */
 int _Syscall(const char *ArgTypes, ...)
 {
-        int    outBufSize = 0;
+       // int  outBufSize = 0;
        va_list args;
        
        va_start(args, ArgTypes);
        va_end(args);
-       
+       return 0;
 }
 
 int open(const char *Path, int Flags) {

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