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