From b8b25ae01e13c655608fb6705574e5218b1a519f Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 23 Oct 2011 11:54:42 +0800 Subject: [PATCH] AcessNative - Cleanup and slight fixes. - Shared elf relocation with Usermode ld-acess - Reduced ammount of code that mixes Acess and native headers - Shifted server syscall handling into a thread so SDL doesn't do event handling / initialisation in a thread. --- AcessNative/acesskernel_src/Makefile | 29 +- AcessNative/acesskernel_src/Makefile.BuildNum | 1 + AcessNative/acesskernel_src/main.c | 29 +- AcessNative/acesskernel_src/server.c | 11 +- AcessNative/acesskernel_src/ui_sdl.c | 45 +- AcessNative/ld-acess_src/Makefile | 4 +- AcessNative/ld-acess_src/binary.c | 8 +- AcessNative/ld-acess_src/common.h | 29 +- AcessNative/ld-acess_src/elf.c | 546 +----------------- AcessNative/ld-acess_src/elf.h | 217 ------- AcessNative/ld-acess_src/elf32.h | 1 + AcessNative/ld-acess_src/elf64.h | 1 + AcessNative/ld-acess_src/elf_load.c | 184 ++++++ AcessNative/ld-acess_src/exports.c | 299 ++++++++++ AcessNative/ld-acess_src/exports.h | 34 ++ AcessNative/ld-acess_src/syscalls.c | 291 +--------- 16 files changed, 650 insertions(+), 1079 deletions(-) create mode 100644 AcessNative/acesskernel_src/Makefile.BuildNum mode change 100644 => 120000 AcessNative/ld-acess_src/elf.c delete mode 100644 AcessNative/ld-acess_src/elf.h create mode 120000 AcessNative/ld-acess_src/elf32.h create mode 120000 AcessNative/ld-acess_src/elf64.h create mode 100644 AcessNative/ld-acess_src/elf_load.c create mode 100644 AcessNative/ld-acess_src/exports.c create mode 100644 AcessNative/ld-acess_src/exports.h diff --git a/AcessNative/acesskernel_src/Makefile b/AcessNative/acesskernel_src/Makefile index 91bee8b3..ec64b5fe 100644 --- a/AcessNative/acesskernel_src/Makefile +++ b/AcessNative/acesskernel_src/Makefile @@ -1,6 +1,12 @@ # AcessNative Server # Makefile +-include ../../Makefile.Version.cfg +-include Makefile.BuildNum +ifeq ($(BUILD_NUM),) +BUILD_NUM = 1 +endif + ifeq ($(PLATFORM),) PLATFORM := lin endif @@ -15,18 +21,21 @@ KERNEL_OBJ += drv/vterm.o drv/fifo.o drv/proc.o N_OBJ := main.o +BUILDINFO_OBJ := obj-$(PLATFORM)/buildinfo.o +BUILDINFO_SRC := $(BUILDINFO_OBJ:%.o=%.c) + OBJ := helpers.o threads.o server.o syscalls.o OBJ += video.o keyboard.o mouse.o nativefs.o vfs_handle.o ui_sdl.o OBJ := $(addprefix obj-$(PLATFORM)/,$(OBJ)) N_OBJ := $(addprefix obj-$(PLATFORM)/,$(N_OBJ)) -K_OBJ := $(addprefix $(KERNEL_SRC)obj-$(PLATFORM)/,$(KERNEL_OBJ)) +K_OBJ := $(addprefix $(KERNEL_SRC)obj-native-$(PLATFORM)/,$(KERNEL_OBJ)) DEPFILES = $(filter %.o,$(OBJ) $(N_OBJ) $(K_OBJ)) DEPFILES := $(DEPFILES:%=%.dep) CPPFLAGS += -I include/ -I $(KERNEL_SRC)include/ CFLAGS += -Wall -g -LDFLAGS += -lSDL -lSDLmain -g +LDFLAGS += -lSDL -lSDLmain -g -Wl,--defsym,__buildnum=$(BUILD_NUM) ifeq ($(PLATFORM),win) BIN := ../AcessKernel.exe @@ -43,9 +52,10 @@ all: $(BIN) clean: $(RM) $(BIN) $(OBJ) $(N_OBJ) $(K_OBJ) $(DEPFILES) -$(BIN): $(OBJ) $(N_OBJ) $(K_OBJ) +$(BIN): $(OBJ) $(N_OBJ) $(K_OBJ) $(BUILDINFO_OBJ) @echo [LINK] -o $@ - @$(CC) $(LDFLAGS) -o $@ $(N_OBJ) $(K_OBJ) $(OBJ) + @$(CC) -o $@ $(N_OBJ) $(K_OBJ) $(OBJ) $(BUILDINFO_OBJ) $(LDFLAGS) + @echo BUILD_NUM = $$(( $(BUILD_NUM) + 1 )) > Makefile.BuildNum $(OBJ): obj-$(PLATFORM)/%.o: %.c @mkdir -p $(dir $@) @@ -53,7 +63,7 @@ $(OBJ): obj-$(PLATFORM)/%.o: %.c @$(CC) -c $< -o $@ $(CFLAGS) $(CPPFLAGS) @$(CC) -M $(CPPFLAGS) -MT $@ -o $@.dep $< -$(K_OBJ): $(KERNEL_SRC)obj-$(PLATFORM)/%.o: $(KERNEL_SRC)%.c +$(K_OBJ): $(KERNEL_SRC)obj-native-$(PLATFORM)/%.o: $(KERNEL_SRC)%.c @mkdir -p $(dir $@) @echo [CC] -o $@ @$(CC) -c $< -o $@ $(CFLAGS) $(CPPFLAGS) @@ -66,4 +76,13 @@ $(N_OBJ): obj-$(PLATFORM)/%.o: %.c @$(CC) -c $< -o $@ $(CFLAGS) @$(CC) -M -MT $@ -o $@.dep $< +$(BUILDINFO_SRC): $(filter-out $(BUILDINFO_OBJ), $(OBJ)) Makefile + @echo "" > $@ + @echo "const char gsKernelVersion[] = \"$(ACESS_VERSION)\";" >> $@ + @echo "const char gsGitHash[] = \""`git log -n 1 | head -n 1 | awk '{print $$2}'`"\";" >> $@ + @echo "const int giBuildNumber = $(BUILD_NUM);" >> $@ +$(BUILDINFO_OBJ): $(BUILDINFO_SRC) + @echo [CC] -o $@ + @$(CC) -o $@ -c $< $(CFLAGS) $(CPPFLAGS) + -include $(DEPFILES) diff --git a/AcessNative/acesskernel_src/Makefile.BuildNum b/AcessNative/acesskernel_src/Makefile.BuildNum new file mode 100644 index 00000000..72d5c7bf --- /dev/null +++ b/AcessNative/acesskernel_src/Makefile.BuildNum @@ -0,0 +1 @@ +BUILD_NUM = 16 diff --git a/AcessNative/acesskernel_src/main.c b/AcessNative/acesskernel_src/main.c index 3f724130..9f0daa45 100644 --- a/AcessNative/acesskernel_src/main.c +++ b/AcessNative/acesskernel_src/main.c @@ -7,15 +7,22 @@ #include #include #include +#include // === IMPORTS === extern int UI_Initialise(int Width, int Height); +extern void UI_MainLoop(void); extern int VFS_Init(void); extern int Video_Install(char **Arguments); extern int NativeKeyboard_Install(char **Arguments); +extern int NativeFS_Install(char **Arguments); +extern void Debug_SetKTerminal(char *Path); extern int VT_Install(char **Arguments); extern int VFS_Mount(const char *Device, const char *MountPoint, const char *Filesystem, const char *Options); extern int SyscallServer(void); +extern const char gsKernelVersion[]; +extern const char gsGitHash[]; +extern int giBuildNumber; // === GLOBALS === const char *gsAcessDir = "../Usermode/Output/i386"; @@ -24,13 +31,15 @@ const char *gsAcessDir = "../Usermode/Output/i386"; int main(int argc, char *argv[]) { // Parse command line settings + printf("Acess2 Native v%s\n", gsKernelVersion); + printf(" Build %i, Git Hash %s\n", giBuildNumber, gsGitHash); - // - Ignore SIGUSR1 (used to wake threads) - signal(SIGUSR1, SIG_IGN); - // Start UI subsystem UI_Initialise(800, 480); + // - Ignore SIGUSR1 (used to wake threads) + signal(SIGUSR1, SIG_IGN); + // Initialise VFS VFS_Init(); // - Start IO Drivers @@ -55,6 +64,8 @@ int main(int argc, char *argv[]) // - Blocks SyscallServer(); + UI_MainLoop(); + return 0; } @@ -63,3 +74,15 @@ void AcessNative_Exit(void) // TODO: Close client applications too exit(0); } + +uint64_t DivMod64U(uint64_t Num, uint64_t Den, uint64_t *Rem) +{ + if(Rem) *Rem = Num % Den; + return Num / Den; +} + +int Module_EnsureLoaded(const char *Name) +{ + return 0; +} + diff --git a/AcessNative/acesskernel_src/server.c b/AcessNative/acesskernel_src/server.c index 264f4122..80d7c256 100644 --- a/AcessNative/acesskernel_src/server.c +++ b/AcessNative/acesskernel_src/server.c @@ -38,6 +38,7 @@ typedef struct { // === IMPORTS === extern tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength); extern int Threads_CreateRootProcess(void); +extern void Threads_SetThread(int TID); // HACK: Should have these in a header extern void Log_Debug(const char *Subsys, const char *Message, ...); extern void Log_Notice(const char *Subsys, const char *Message, ...); @@ -46,6 +47,7 @@ extern void Log_Notice(const char *Subsys, const char *Message, ...); tClient *Server_GetClient(int ClientID); int Server_WorkerThread(void *ClientPtr); int SyscallServer(void); + int Server_ListenThread(void *Unused); // === GLOBALS === #ifdef __WIN32__ @@ -56,6 +58,7 @@ SOCKET gSocket = INVALID_SOCKET; int gSocket = INVALID_SOCKET; #endif tClient gaServer_Clients[MAX_CLIENTS]; +SDL_Thread *gpServer_ListenThread; // === CODE === int Server_GetClientID(void) @@ -229,7 +232,12 @@ int SyscallServer(void) #endif Log_Notice("AcessSrv", "Listening on 0.0.0.0:%i", SERVER_PORT); - + gpServer_ListenThread = SDL_CreateThread( Server_ListenThread, NULL ); + return 0; +} + +int Server_ListenThread(void *Unused) +{ // Wait for something to do :) for( ;; ) { @@ -294,6 +302,5 @@ int SyscallServer(void) SDL_CondSignal(client->WaitFlag); #endif } - return -1; } diff --git a/AcessNative/acesskernel_src/ui_sdl.c b/AcessNative/acesskernel_src/ui_sdl.c index 11033d98..6917c6c1 100644 --- a/AcessNative/acesskernel_src/ui_sdl.c +++ b/AcessNative/acesskernel_src/ui_sdl.c @@ -14,7 +14,6 @@ extern void AcessNative_Exit(void); // === PROTOTYPES === int UI_Initialise(int MaxWidth, int MaxHeight); - int UI_MainThread(void *Unused); void UI_BlitBitmap(int DstX, int DstY, int SrcW, int SrcH, Uint32 *Bitmap); void UI_BlitFramebuffer(int DstX, int DstY, int SrcX, int SrcY, int W, int H); void UI_FillBitmap(int X, int Y, int W, int H, Uint32 Value); @@ -36,12 +35,25 @@ int UI_Initialise(int MaxWidth, int MaxHeight) giUI_Width = MaxWidth; giUI_Height = MaxHeight; - // Start main thread - gInputThread = SDL_CreateThread(UI_MainThread, NULL); + // Set up video + SDL_Init(SDL_INIT_VIDEO); + printf("UI attempting %ix%i %ibpp\n", giUI_Width, giUI_Height, 32); + gScreen = SDL_SetVideoMode(giUI_Width, giUI_Height, 32, 0); + if( !gScreen ) { + fprintf(stderr, "Couldn't set %ix%i video mode: %s\n", giUI_Width, giUI_Height, SDL_GetError()); + SDL_Quit(); + exit(2); + } + SDL_WM_SetCaption("Acess2", "Acess2"); - while(gScreen == NULL) - SDL_Delay(10); + giUI_Width = gScreen->w; + giUI_Height = gScreen->h; + giUI_Pitch = gScreen->pitch; + + printf("UI window %ix%i %i bytes per line\n", giUI_Width, giUI_Height, giUI_Pitch); + SDL_EnableUNICODE(1); + return 0; } @@ -100,28 +112,11 @@ Uint32 UI_GetAcessKeyFromSDL(SDLKey Sym, Uint16 Unicode) return ret; } -int UI_MainThread(void *Unused) +void UI_MainLoop(void) { SDL_Event event; Uint32 acess_sym; - - SDL_Init(SDL_INIT_VIDEO); - - // Set up video - gScreen = SDL_SetVideoMode(giUI_Width, giUI_Height, 32, 0); - if( !gScreen ) { - fprintf(stderr, "Couldn't set %ix%i video mode: %s\n", giUI_Width, giUI_Height, SDL_GetError()); - SDL_Quit(); - exit(2); - } - SDL_WM_SetCaption("Acess2", "Acess2"); - - giUI_Width = gScreen->w; - giUI_Height = gScreen->h; - giUI_Pitch = gScreen->pitch; - - SDL_EnableUNICODE(1); - + for( ;; ) { while(SDL_PollEvent(&event)) @@ -130,7 +125,7 @@ int UI_MainThread(void *Unused) { case SDL_QUIT: AcessNative_Exit(); - return 0; + return ; case SDL_KEYDOWN: acess_sym = UI_GetAcessKeyFromSDL(event.key.keysym.sym, diff --git a/AcessNative/ld-acess_src/Makefile b/AcessNative/ld-acess_src/Makefile index 5a604a3c..bbce43df 100644 --- a/AcessNative/ld-acess_src/Makefile +++ b/AcessNative/ld-acess_src/Makefile @@ -5,8 +5,8 @@ ifeq ($(PLATFORM),) PLATFORM := lin endif -OBJ := main.o syscalls.o request.o binary.o memory.o -OBJ += elf.o +OBJ := main.o syscalls.o request.o binary.o memory.o exports.o +OBJ += elf.o elf_load.o OBJ := $(addprefix obj-$(PLATFORM)/,$(OBJ)) ifeq ($(PLATFORM),win) diff --git a/AcessNative/ld-acess_src/binary.c b/AcessNative/ld-acess_src/binary.c index 3ae8d7f1..746fbb8b 100644 --- a/AcessNative/ld-acess_src/binary.c +++ b/AcessNative/ld-acess_src/binary.c @@ -19,8 +19,8 @@ typedef struct sBinary { // === IMPORTS === extern void *Elf_Load(int fd); -extern uintptr_t Elf_Relocate(void *Base); -extern int Elf_GetSymbol(void *Base, char *Name, uintptr_t *ret); +extern uintptr_t ElfRelocate(void *Base); +extern int ElfGetSymbol(void *Base, char *Name, uintptr_t *ret); extern int ciNumBuiltinSymbols; extern tSym caBuiltinSymbols[]; @@ -33,8 +33,8 @@ tBinFmt gElf_FormatDef = { // .Magic = "\x7F""ELF", .Name = "ELF32", .Load = Elf_Load, - .Relocate = Elf_Relocate, - .GetSymbol = Elf_GetSymbol + .Relocate = ElfRelocate, + .GetSymbol = ElfGetSymbol }; tBinary *gLoadedBinaries; diff --git a/AcessNative/ld-acess_src/common.h b/AcessNative/ld-acess_src/common.h index 05c288b2..59be119f 100644 --- a/AcessNative/ld-acess_src/common.h +++ b/AcessNative/ld-acess_src/common.h @@ -6,32 +6,43 @@ #include #include #include +#include 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); +// HACKS - So this can share the usermode elf.c +static inline void *GetSymbol(const char*sym, size_t*sz) +{ + uintptr_t rv; + if( Binary_GetSymbol(sym, &rv) ) + return NULL; + return (void*)rv; +} +static inline void *LoadLibrary(const char *Name, const char *SearchPath, char **envp) +{ + return Binary_LoadLibrary(Name); +} +static inline void AddLoaded(const char *Path, void *Base) +{ + Binary_SetReadyToUse(Base); +} + extern int AllocateMemory(uintptr_t VirtAddr, size_t ByteCount); extern uintptr_t FindFreeRange(size_t ByteCount, int MaxBits); extern void Warning(const char *Format, ...); extern void Notice(const char *Format, ...); extern void Debug(const char *Format, ...); +#define SysDebug Debug #define ACESS_SEEK_CUR 0 #define ACESS_SEEK_SET 1 #define ACESS_SEEK_END -1 -extern int acess_open(const char *Path, int Flags); -extern void acess_close(int FD); -extern size_t acess_read(int FD, size_t Bytes, void *Dest); -extern int acess_seek(int FD, int64_t Offset, int Dir); - -typedef struct { - char *Name; - void *Value; -} tSym; +#include "exports.h" typedef struct sBinFmt { struct sBinFmt *Next; diff --git a/AcessNative/ld-acess_src/elf.c b/AcessNative/ld-acess_src/elf.c deleted file mode 100644 index daea0443..00000000 --- a/AcessNative/ld-acess_src/elf.c +++ /dev/null @@ -1,545 +0,0 @@ -/* - * Acess v0.1 - * ELF Executable Loader Code - */ -#define DEBUG 0 -#include -#include -#include -#include -#include "common.h" -#include "elf.h" - -#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 DEBUG -# 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 === -void *Elf_Load(int FD); -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 === -void *Elf_Load(int FD) -{ - Elf32_Ehdr hdr; - Elf32_Phdr *phtab; - int i, j; - int iPageCount; - uint32_t max, base; - uint32_t addr; - uint32_t baseDiff = 0; - - ENTER("iFD", FD); - - // Read ELF Header - acess_read(FD, sizeof(hdr), &hdr); - - // 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 NULL; - } - - // Check for a program header - if(hdr.phoff == 0) { - #if DEBUG_WARN - Warning("ELF File does not contain a program header\n"); - #endif - LEAVE('n'); - return NULL; - } - - // Read Program Header Table - phtab = malloc( sizeof(Elf32_Phdr) * hdr.phentcount ); - if( !phtab ) { - LEAVE('n'); - return NULL; - } - LOG("hdr.phoff = 0x%08x\n", hdr.phoff); - acess_seek(FD, hdr.phoff, ACESS_SEEK_SET); - acess_read(FD, sizeof(Elf32_Phdr) * hdr.phentcount, phtab); - - // Count Pages - iPageCount = 0; - 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}\n", i, phtab[i].VAddr, phtab[i].MemSize); - } - - LOG("iPageCount = %i\n", iPageCount); - - // Allocate Information Structure - //ret = malloc( sizeof(tBinary) + sizeof(tBinaryPage)*iPageCount ); - // Fill Info Struct - //ret->Entry = hdr.entrypoint; - //ret->Base = -1; // Set Base to maximum value - //ret->NumPages = iPageCount; - //ret->Interpreter = NULL; - - // Prescan for base and size - max = 0; - base = 0xFFFFFFFF; - for( i = 0; i < hdr.phentcount; i ++) - { - if( phtab[i].Type != PT_LOAD ) - continue; - if( phtab[i].VAddr < base ) - base = phtab[i].VAddr; - if( phtab[i].VAddr + phtab[i].MemSize > max ) - max = phtab[i].VAddr + phtab[i].MemSize; - } - - 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] = {\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); - acess_seek(FD, phtab[i].Offset, ACESS_SEEK_SET); - acess_read(FD, phtab[i].FileSize, tmp); - //ret->Interpreter = Binary_RegInterp(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}\n", - i, phtab[i].VAddr+baseDiff, phtab[i].Offset, phtab[i].FileSize); - - addr = phtab[i].VAddr + baseDiff; - - if( AllocateMemory( addr, phtab[i].MemSize ) ) { - fprintf(stderr, "Elf_Load: Unable to map memory at %x (0x%x bytes)\n", - addr, phtab[i].MemSize); - free( phtab ); - return NULL; - } - - acess_seek(FD, phtab[i].Offset, ACESS_SEEK_SET); - acess_read(FD, phtab[i].FileSize, PTRMK(void, addr) ); - memset( PTRMK(char, addr) + phtab[i].FileSize, 0, phtab[i].MemSize - phtab[i].FileSize ); - } - - // Clean Up - free(phtab); - // Return - LEAVE('p', base); - return PTRMK(void, base); -} - -// --- ELF RELOCATION --- -/** - * \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; - uintptr_t iBaseDiff; - int iSegmentCount; - int iSymCount = 0; - Elf32_Rel *rel = NULL; - Elf32_Rela *rela = NULL; - uint32_t *pltgot = NULL; - void *plt = NULL; - uint32_t *ptr; - int relSz=0, relEntSz=8; - int relaSz=0, relaEntSz=8; - int pltSz=0, pltType=0; - Elf32_Dyn *dynamicTab = NULL; // Dynamic Table Pointer - char *dynstrtab = NULL; // .dynamic String Table - Elf32_Sym *dynsymtab = NULL; - int bFailed = 0; - - ENTER("pBase", Base); - LOG("Base = %p\n", Base); - - // Parse Program Header to get Dynamic Table - phtab = Base + hdr->phoff; - iSegmentCount = hdr->phentcount; - for(i = 0; i < iSegmentCount; i ++ ) - { - // Determine linked base address - if(phtab[i].Type == PT_LOAD && iRealBase > phtab[i].VAddr) - iRealBase = phtab[i].VAddr; - - // Find Dynamic Section - if(phtab[i].Type == PT_DYNAMIC) { - if(dynamicTab) { - Warning("Elf_Relocate - Multiple PT_DYNAMIC segments\n"); - continue; - } - dynamicTab = MKPTR(void, phtab[i].VAddr); - j = i; // Save Dynamic Table ID - break; - } - } - - // Check if a PT_DYNAMIC segement was found - if(!dynamicTab) { - Warning("Elf_Relocate: No PT_DYNAMIC segment in image, returning\n"); - LEAVE('x', hdr->entrypoint); - return hdr->entrypoint; - } - - // Page Align real base - iRealBase &= ~0xFFF; - - LOG("dynamicTab = %p\n", dynamicTab); - // Adjust "Real" Base - iBaseDiff = (uintptr_t)Base - iRealBase; - LOG("iBaseDiff = %p\n", (void*)iBaseDiff); - // Adjust Dynamic Table - dynamicTab = PTR( (uintptr_t)dynamicTab + iBaseDiff); - LOG("dynamicTab = %p\n", dynamicTab); - - hdr->entrypoint += iBaseDiff; - - hdr->misc.SymTable = 0; - hdr->misc.HashTable = 0; - - // === Get Symbol table and String Table === - for( j = 0; dynamicTab[j].d_tag != DT_NULL; j++) - { - switch(dynamicTab[j].d_tag) - { - // --- Symbol Table --- - case DT_SYMTAB: - dynamicTab[j].d_val += iBaseDiff; - 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 = PTRMK(void, dynamicTab[j].d_val); - break; - - // --- Hash Table -- - case DT_HASH: - dynamicTab[j].d_val += iBaseDiff; - iSymCount = (PTRMK(uint32_t, dynamicTab[j].d_val))[1]; - hdr->misc.HashTable = dynamicTab[j].d_val; // Saved in unused bytes of ident - break; - } - } - - LOG("hdr->misc.SymTable = %x, hdr->misc.HashTable = %x", - hdr->misc.SymTable, hdr->misc.HashTable); - - - // Alter Symbols to true base - for(i = 0; i < iSymCount; i ++) - { - dynsymtab[i].nameOfs += (uintptr_t)dynstrtab; - if( dynsymtab[i].shndx == SHN_UNDEF ) - { - LOG("Sym '%s' = UNDEF\n", MKPTR(char,dynsymtab[i].name)); - } - else - { - dynsymtab[i].value += iBaseDiff; - LOG("Sym '%s' = 0x%x (relocated)\n", MKPTR(char,dynsymtab[i].name), dynsymtab[i].value); - } - } - - // === Add to loaded list (can be imported now) === - Binary_SetReadyToUse( Base ); - - // === Parse Relocation Data === - for( j = 0; dynamicTab[j].d_tag != DT_NULL; j++) - { - switch(dynamicTab[j].d_tag) - { - // --- Shared Library Name --- - case DT_SONAME: - LOG(".so Name '%s'\n", dynstrtab + dynamicTab[j].d_val); - break; - // --- Needed Library --- - case DT_NEEDED: - libPath = dynstrtab + dynamicTab[j].d_val; - Binary_LoadLibrary(libPath); - break; - // --- PLT/GOT --- - case DT_PLTGOT: pltgot = (void*)(iBaseDiff+dynamicTab[j].d_val); break; - case DT_JMPREL: plt = (void*)(iBaseDiff+dynamicTab[j].d_val); break; - case DT_PLTREL: pltType = dynamicTab[j].d_val; break; - case DT_PLTRELSZ: pltSz = dynamicTab[j].d_val; break; - - // --- Relocation --- - case DT_REL: rel = (void*)(iBaseDiff + dynamicTab[j].d_val); break; - case DT_RELSZ: relSz = dynamicTab[j].d_val; break; - case DT_RELENT: relEntSz = dynamicTab[j].d_val; break; - - case DT_RELA: rela = (void*)(iBaseDiff + dynamicTab[j].d_val); break; - case DT_RELASZ: relaSz = dynamicTab[j].d_val; break; - case DT_RELAENT: relaEntSz = dynamicTab[j].d_val; break; - } - } - - // Parse Relocation Entries - if(rel && relSz) - { - j = relSz / relEntSz; - for( i = 0; i < j; i++ ) - { - ptr = (void*)(iBaseDiff + rel[i].r_offset); - if( !Elf_Int_DoRelocate(rel[i].r_info, ptr, *ptr, dynsymtab, Base) ) { - bFailed = 1; - } - } - } - // Parse Relocation Entries - if(rela && relaSz) - { - j = relaSz / relaEntSz; - 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, Base) ) { - bFailed = 1; - } - } - } - - // === Process PLT (Procedure Linkage Table) === - if(plt && pltSz) - { - if(pltType == DT_REL) - { - Elf32_Rel *pltRel = plt; - j = pltSz / sizeof(Elf32_Rel); - 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, Base) ) { - bFailed = 1; - } - } - } - else - { - Elf32_Rela *pltRela = plt; - j = pltSz / sizeof(Elf32_Rela); - LOG("PLT RelA - plt = %p, pltSz = %i (%i ents)\n", plt, pltSz, j); - for(i=0;ientrypoint); - return hdr->entrypoint; -} - -/** - * \fn void Elf_Int_DoRelocate(uint32_t r_info, uint32_t *ptr, uint32_t addend, Elf32_Sym *symtab, void *base) - * \brief Performs a relocation - * \param r_info Field from relocation entry - * \param ptr Pointer to location of relocation - * \param addend Value to add to symbol - * \param symtab Symbol Table - * \param base Base of loaded binary - */ -int Elf_Int_DoRelocate(uint32_t r_info, uint32_t *ptr, uint32_t addend, Elf32_Sym *symtab, void *base) -{ - uintptr_t val; - int type = ELF32_R_TYPE(r_info); - int sym = ELF32_R_SYM(r_info); - char *sSymName = PTRMK(char, symtab[sym].name); - - //LogF("Elf_Int_DoRelocate: (r_info=0x%x, ptr=0x%x, addend=0x%x, .., base=0x%x)\n", - // r_info, ptr, addend, base); - - switch( type ) - { - // Standard 32 Bit Relocation (S+A) - case R_386_32: - if( !Elf_GetSymbol( base, sSymName, &val ) && !Binary_GetSymbol( sSymName, &val ) ) { - Warning("Unable to find symbol '%s'", sSymName); - return 0; - } - LOG("%08x R_386_32 *%p += %p('%s')\n", r_info, ptr, (void*)val, sSymName); - *ptr = val + addend; - break; - - // 32 Bit Relocation wrt. Offset (S+A-P) - case R_386_PC32: - if( !Elf_GetSymbol( base, sSymName, &val ) && !Binary_GetSymbol( sSymName, &val ) ) { - Warning("Unable to find symbol '%s'", sSymName); - return 0; - } - LOG("%08x R_386_PC32 *%p = 0x%x + %p('%s') - %p\n", r_info, ptr, *ptr, (void*)val, sSymName, ptr ); - // TODO: Check if it needs the true value of ptr or the compiled value - // NOTE: Testing using true value - *ptr = val + addend - (uintptr_t)ptr; - break; - - // Absolute Value of a symbol (S) - case R_386_GLOB_DAT: - if( !Elf_GetSymbol( base, sSymName, &val ) && !Binary_GetSymbol( sSymName, &val ) ) { - Warning("Unable to find symbol '%s'", sSymName); - return 0; - } - LOG("%08x R_386_GLOB_DAT *%p = 0x%x(%s)\n", r_info, ptr, (unsigned int)val, sSymName); - *ptr = val; - break; - - // Absolute Value of a symbol (S) - case R_386_JMP_SLOT: - if( !Elf_GetSymbol( base, sSymName, &val ) && !Binary_GetSymbol( sSymName, &val ) ) { - Warning("Unable to find symbol '%s'", sSymName); - return 0; - } - LOG("%08x R_386_JMP_SLOT *%p = 0x%x (%s)\n", r_info, ptr, (unsigned int)val, sSymName); - *ptr = val; - break; - - // Base Address (B+A) - case R_386_RELATIVE: - LOG("%08x R_386_RELATIVE *%p = %p + 0x%x\n", r_info, ptr, base, addend); - *ptr = (uintptr_t)base + addend; - break; - - default: - LOG("Rel %p: 0x%x,%i\n", ptr, sym, type); - break; - } - return 1; -} - -/** - * \fn int Elf_GetSymbol(void *Base, char *name, uintptr_t *ret) - * \brief Get a symbol from the loaded binary - */ -int Elf_GetSymbol(void *Base, char *Name, uintptr_t *ret) -{ - Elf32_Ehdr *hdr = (void*)Base; - Elf32_Sym *symtab; - int nbuckets = 0; - int iSymCount = 0; - int i; - uint32_t *pBuckets; - uint32_t *pChains; - uint32_t iNameHash; - - if(!Base) return 0; - - pBuckets = PTR(hdr->misc.HashTable); - symtab = PTR(hdr->misc.SymTable); - -// LOG("Base = %p : pBuckets = %p, symtab = %p\n", Base, pBuckets, symtab); - - if(!pBuckets || !symtab) - return 0; - - nbuckets = pBuckets[0]; - iSymCount = pBuckets[1]; - pBuckets = &pBuckets[2]; - pChains = &pBuckets[ nbuckets ]; - - // Get hash - iNameHash = Elf_Int_HashString(Name); - iNameHash %= nbuckets; - - // Check Bucket - i = pBuckets[ iNameHash ]; - if(symtab[i].shndx != SHN_UNDEF && strcmp(MKPTR(char,symtab[i].name), Name) == 0) { - if(ret) *ret = symtab[ i ].value; - return 1; - } - - // Walk Chain - while(pChains[i] != STN_UNDEF) - { - i = pChains[i]; - if(symtab[i].shndx != SHN_UNDEF && strcmp(MKPTR(char,symtab[i].name), Name) == 0) { - if(ret) *ret = symtab[ i ].value; - return 1; - } - } - return 0; -} - -/** - * \fn uint32_t Elf_Int_HashString(char *str) - * \brief Hash a string in the ELF format - * \param str String to hash - * \return Hash value - */ -uint32_t Elf_Int_HashString(char *str) -{ - uint32_t h = 0, g; - while(*str) - { - h = (h << 4) + *str++; - if( (g = h & 0xf0000000) ) - h ^= g >> 24; - h &= ~g; - } - return h; -} diff --git a/AcessNative/ld-acess_src/elf.c b/AcessNative/ld-acess_src/elf.c new file mode 120000 index 00000000..f7aa1a5b --- /dev/null +++ b/AcessNative/ld-acess_src/elf.c @@ -0,0 +1 @@ +../../Usermode/Libraries/ld-acess.so_src/elf.c \ No newline at end of file diff --git a/AcessNative/ld-acess_src/elf.h b/AcessNative/ld-acess_src/elf.h deleted file mode 100644 index 77be918b..00000000 --- a/AcessNative/ld-acess_src/elf.h +++ /dev/null @@ -1,217 +0,0 @@ -/** - * \file elf.h - * \brief ELF Exeutable Loader - */ -#ifndef _BIN_ELF_H -#define _BIN_ELF_H - -#include - -/** - * \brief ELF File Header - */ -struct sElf32_Ehdr -{ - union { - char ident[16]; //!< Identifier Bytes - struct { - uint32_t Ident1; - uint32_t Ident2; - uint32_t HashTable; - uint32_t SymTable; - } misc; - }; - uint16_t filetype; //!< File Type - uint16_t machine; //!< Machine / Arch - uint32_t version; //!< Version (File?) - uint32_t entrypoint; //!< Entry Point - uint32_t phoff; //!< Program Header Offset - uint32_t shoff; //!< Section Header Offset - uint32_t flags; //!< Flags - uint16_t headersize; //!< Header Size - uint16_t phentsize; //!< Program Header Entry Size - uint16_t phentcount; //!< Program Header Entry Count - uint16_t shentsize; //!< Section Header Entry Size - uint16_t shentcount; //!< Section Header Entry Count - uint16_t shstrindex; //!< Section Header String Table Index -} __attribute__ ((packed)); - -/** - * \brief Executable Types - */ -enum eElf32_ExecTypes -{ - ET_NONE = 0, //!< NULL Type - ET_REL = 1, //!< Relocatable (Object) - ET_EXEC = 2, //!< Executable - ET_DYN = 3, //!< Dynamic Library - ET_CORE = 4, //!< Core? - ET_LOPROC = 0xFF00, //!< Low Impl Defined - ET_HIPROC = 0xFFFF //!< High Impl Defined -}; - -/** - \name Section IDs - \{ -*/ -#define SHN_UNDEF 0 //!< Undefined Section -#define SHN_LORESERVE 0xFF00 //!< Low Reserved -#define SHN_LOPROC 0xFF00 //!< Low Impl Defined -#define SHN_HIPROC 0xFF1F //!< High Impl Defined -#define SHN_ABS 0xFFF1 //!< Absolute Address (Base: 0, Size: -1) -#define SHN_COMMON 0xFFF2 //!< Common -#define SHN_HIRESERVE 0xFFFF //!< High Reserved -//! \} - -/** - \enum eElfSectionTypes - \brief ELF Section Types -*/ -enum eElfSectionTypes { - SHT_NULL, //0 - SHT_PROGBITS, //1 - SHT_SYMTAB, //2 - SHT_STRTAB, //3 - SHT_RELA, //4 - SHT_HASH, //5 - SHT_DYNAMIC, //6 - SHT_NOTE, //7 - SHT_NOBITS, //8 - SHT_REL, //9 - SHT_SHLIB, //A - SHT_DYNSYM, //B - SHT_LAST, //C - SHT_LOPROC = 0x70000000, - SHT_HIPROC = 0x7fffffff, - SHT_LOUSER = 0x80000000, - SHT_HIUSER = 0xffffffff -}; - -#define SHF_WRITE 0x1 -#define SHF_ALLOC 0x2 -#define SHF_EXECINSTR 0x4 -#define SHF_MASKPROC 0xf0000000 - -struct sElf32_Shent { - uint32_t name; - uint32_t type; - uint32_t flags; - uint32_t address; - uint32_t offset; - uint32_t size; - uint32_t link; - uint32_t info; - uint32_t addralign; - uint32_t entsize; -} __attribute__ ((packed)); //sizeof = 40 - -struct elf_sym_s { - union { - uint32_t nameOfs; - uint32_t name; - }; - uint32_t value; //Address - uint32_t size; - uint8_t info; - uint8_t other; - uint16_t shndx; -} __attribute__ ((packed)); -#define STN_UNDEF 0 // Undefined Symbol - -enum { - PT_NULL, //0 - PT_LOAD, //1 - PT_DYNAMIC, //2 - PT_INTERP, //3 - PT_NOTE, //4 - PT_SHLIB, //5 - PT_PHDR, //6 - PT_LOPROC = 0x70000000, - PT_HIPROC = 0x7fffffff -}; - -struct sElf32_Phdr { - uint32_t Type; - uint32_t Offset; - uint32_t VAddr; - uint32_t PAddr; - uint32_t FileSize; - uint32_t MemSize; - uint32_t Flags; - uint32_t Align; -} __attribute__ ((packed)); - -struct elf32_rel_s { - uint32_t r_offset; - uint32_t r_info; -} __attribute__ ((packed)); - -struct elf32_rela_s { - uint32_t r_offset; - uint32_t r_info; - int32_t r_addend; -} __attribute__ ((packed)); - -enum { - R_386_NONE = 0, // none - R_386_32, // S+A - R_386_PC32, // S+A-P - R_386_GOT32, // G+A-P - R_386_PLT32, // L+A-P - R_386_COPY, // none - R_386_GLOB_DAT, // S - R_386_JMP_SLOT, // S - R_386_RELATIVE, // B+A - R_386_GOTOFF, // S+A-GOT - R_386_GOTPC, // GOT+A-P - R_386_LAST // none -}; - -#define ELF32_R_SYM(i) ((i)>>8) // Takes an info value and returns a symbol index -#define ELF32_R_TYPE(i) ((i)&0xFF) // Takes an info value and returns a type -#define ELF32_R_INFO(s,t) (((s)<<8)+((t)&0xFF)) // Takes a type and symbol index and returns an info value - -struct elf32_dyn_s { - uint32_t d_tag; - uint32_t d_val; //Also d_ptr -} __attribute__ ((packed)); - -enum { - DT_NULL, //!< Marks End of list - DT_NEEDED, //!< Offset in strtab to needed library - DT_PLTRELSZ, //!< Size in bytes of PLT - DT_PLTGOT, //!< Address of PLT/GOT - DT_HASH, //!< Address of symbol hash table - DT_STRTAB, //!< String Table address - DT_SYMTAB, //!< Symbol Table address - DT_RELA, //!< Relocation table address - DT_RELASZ, //!< Size of relocation table - DT_RELAENT, //!< Size of entry in relocation table - DT_STRSZ, //!< Size of string table - DT_SYMENT, //!< Size of symbol table entry - DT_INIT, //!< Address of initialisation function - DT_FINI, //!< Address of termination function - DT_SONAME, //!< String table offset of so name - DT_RPATH, //!< String table offset of library path - DT_SYMBOLIC,//!< Reverse order of symbol searching for library, search libs first then executable - DT_REL, //!< Relocation Entries (Elf32_Rel instead of Elf32_Rela) - DT_RELSZ, //!< Size of above table (bytes) - DT_RELENT, //!< Size of entry in above table - DT_PLTREL, //!< Relocation entry of PLT - DT_DEBUG, //!< Debugging Entry - Unknown contents - DT_TEXTREL, //!< Indicates that modifcations to a non-writeable segment may occur - DT_JMPREL, //!< Address of PLT only relocation entries - DT_LOPROC = 0x70000000, //!< Low Definable - DT_HIPROC = 0x7FFFFFFF //!< High Definable -}; - -typedef struct sElf32_Ehdr Elf32_Ehdr; -typedef struct sElf32_Phdr Elf32_Phdr; -typedef struct sElf32_Shent Elf32_Shent; -typedef struct elf_sym_s elf_symtab; -typedef struct elf_sym_s Elf32_Sym; -typedef struct elf32_rel_s Elf32_Rel; -typedef struct elf32_rela_s Elf32_Rela; -typedef struct elf32_dyn_s Elf32_Dyn; - -#endif // defined(_EXE_ELF_H) diff --git a/AcessNative/ld-acess_src/elf32.h b/AcessNative/ld-acess_src/elf32.h new file mode 120000 index 00000000..a693e8d6 --- /dev/null +++ b/AcessNative/ld-acess_src/elf32.h @@ -0,0 +1 @@ +../../Usermode/Libraries/ld-acess.so_src/elf32.h \ No newline at end of file diff --git a/AcessNative/ld-acess_src/elf64.h b/AcessNative/ld-acess_src/elf64.h new file mode 120000 index 00000000..272e8de0 --- /dev/null +++ b/AcessNative/ld-acess_src/elf64.h @@ -0,0 +1 @@ +../../Usermode/Libraries/ld-acess.so_src/elf64.h \ No newline at end of file diff --git a/AcessNative/ld-acess_src/elf_load.c b/AcessNative/ld-acess_src/elf_load.c new file mode 100644 index 00000000..49298699 --- /dev/null +++ b/AcessNative/ld-acess_src/elf_load.c @@ -0,0 +1,184 @@ +/* + * Acess v0.1 + * ELF Executable Loader Code + */ +#define DEBUG 0 +#include +#include +#include +#include +#include "common.h" +#include "elf32.h" + +#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 DEBUG +# 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 === +void *Elf_Load(int FD); +void *Elf32Load(int FD, Elf32_Ehdr *hdr); + +// === CODE === +void *Elf_Load(int FD) +{ + Elf32_Ehdr hdr; + + // Read ELF Header + acess_read(FD, sizeof(hdr), &hdr); + + // Check the file type + if(hdr.e_ident[0] != 0x7F || hdr.e_ident[1] != 'E' || hdr.e_ident[2] != 'L' || hdr.e_ident[3] != 'F') { + Warning("Non-ELF File was passed to the ELF loader\n"); + return NULL; + } + + switch(hdr.e_ident[4]) + { + case ELFCLASS32: + return Elf32Load(FD, &hdr); + default: + return NULL; + } +} +void *Elf32Load(int FD, Elf32_Ehdr *hdr) +{ + Elf32_Phdr *phtab; + int i; + int iPageCount; + uint32_t max, base; + uint32_t addr; + uint32_t baseDiff = 0; + + ENTER("iFD", FD); + + // Check for a program header + if(hdr->phoff == 0) { + #if DEBUG_WARN + Warning("ELF File does not contain a program header\n"); + #endif + LEAVE('n'); + return NULL; + } + + // Read Program Header Table + phtab = malloc( sizeof(Elf32_Phdr) * hdr->phentcount ); + if( !phtab ) { + LEAVE('n'); + return NULL; + } + LOG("hdr.phoff = 0x%08x\n", hdr->phoff); + acess_seek(FD, hdr->phoff, ACESS_SEEK_SET); + acess_read(FD, sizeof(Elf32_Phdr) * hdr->phentcount, phtab); + + // Count Pages + iPageCount = 0; + 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}\n", i, phtab[i].VAddr, phtab[i].MemSize); + } + + LOG("iPageCount = %i\n", iPageCount); + + // Allocate Information Structure + //ret = malloc( sizeof(tBinary) + sizeof(tBinaryPage)*iPageCount ); + // Fill Info Struct + //ret->Entry = hdr.entrypoint; + //ret->Base = -1; // Set Base to maximum value + //ret->NumPages = iPageCount; + //ret->Interpreter = NULL; + + // Prescan for base and size + max = 0; + base = 0xFFFFFFFF; + for( i = 0; i < hdr->phentcount; i ++) + { + if( phtab[i].Type != PT_LOAD ) + continue; + if( phtab[i].VAddr < base ) + base = phtab[i].VAddr; + if( phtab[i].VAddr + phtab[i].MemSize > max ) + max = phtab[i].VAddr + phtab[i].MemSize; + } + + 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 + for( i = 0; i < hdr->phentcount; i++ ) + { + //LOG("phtab[%i].Type = 0x%x", i, phtab[i].Type); + 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); + acess_seek(FD, phtab[i].Offset, ACESS_SEEK_SET); + acess_read(FD, phtab[i].FileSize, tmp); + //ret->Interpreter = Binary_RegInterp(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}\n", + i, phtab[i].VAddr+baseDiff, phtab[i].Offset, phtab[i].FileSize); + + addr = phtab[i].VAddr + baseDiff; + + if( AllocateMemory( addr, phtab[i].MemSize ) ) { + fprintf(stderr, "Elf_Load: Unable to map memory at %x (0x%x bytes)\n", + addr, phtab[i].MemSize); + free( phtab ); + return NULL; + } + + acess_seek(FD, phtab[i].Offset, ACESS_SEEK_SET); + acess_read(FD, phtab[i].FileSize, PTRMK(void, addr) ); + memset( PTRMK(char, addr) + phtab[i].FileSize, 0, phtab[i].MemSize - phtab[i].FileSize ); + } + + // Clean Up + free(phtab); + // Return + LEAVE('p', base); + return PTRMK(void, base); +} diff --git a/AcessNative/ld-acess_src/exports.c b/AcessNative/ld-acess_src/exports.c new file mode 100644 index 00000000..af9cc900 --- /dev/null +++ b/AcessNative/ld-acess_src/exports.c @@ -0,0 +1,299 @@ +/* + * AcessNative + * + * exports.c + * - Exported functions + */ +#define DONT_INCLUDE_SYSCALL_NAMES 1 +#include "../../Usermode/include/acess/sys.h" +#include "../syscalls.h" +#include "exports.h" +#include + +#define DEBUG(v...) Debug(v) + +typedef struct sFILE FILE; + +extern FILE *stderr; +extern void exit(int) __attribute__ ((noreturn)); +extern int printf(const char *, ...); +extern int fprintf(FILE *,const char *, ...); +extern int sprintf(char *,const char *, ...); +extern int vprintf(const char *, va_list); +extern int strncmp(const char *, const char *, size_t); + +extern int giSyscall_ClientID; // Needed for execve +extern void Debug(const char *Format, ...); +extern int AllocateMemory(uintptr_t VirtAddr, size_t ByteCount); + +// === CONSTANTS === +#define NATIVE_FILE_MASK 0x40000000 + +// === CODE === +// --- VFS Calls +int acess_chdir(const char *Path) +{ + return _Syscall(SYS_CHDIR, ">s", Path); +} + +int acess_open(const char *Path, int Flags) +{ + if( strncmp(Path, "$$$$", 4) == 0 ) + { + return native_open(Path, Flags) | NATIVE_FILE_MASK; + } + DEBUG("open(\"%s\", 0x%x)", Path, Flags); + return _Syscall(SYS_OPEN, ">s >i", Path, Flags); +} + +void acess_close(int FD) { + if(FD & NATIVE_FILE_MASK) { + return native_close(FD & (NATIVE_FILE_MASK-1)); + } + DEBUG("close(%i)", FD); + _Syscall(SYS_CLOSE, ">i", FD); +} + +int acess_reopen(int FD, const char *Path, int Flags) { + DEBUG("reopen(0x%x, \"%s\", 0x%x)", FD, Path, Flags); + return _Syscall(SYS_REOPEN, ">i >s >i", FD, Path, Flags); +} + +size_t acess_read(int FD, size_t Bytes, void *Dest) { + if(FD & NATIVE_FILE_MASK) + return native_read(FD & (NATIVE_FILE_MASK-1), Bytes, Dest); + DEBUG("read(0x%x, 0x%x, *%p)", FD, Bytes, Dest); + return _Syscall(SYS_READ, ">i >i i >i >d", FD, Bytes, Bytes, Src); +} + +int acess_seek(int FD, int64_t Ofs, int Dir) { + if(FD & NATIVE_FILE_MASK) { + return native_seek(FD & (NATIVE_FILE_MASK-1), Ofs, Dir); + } + DEBUG("seek(0x%x, 0x%llx, %i)", FD, Ofs, Dir); + return _Syscall(SYS_SEEK, ">i >I >i", FD, Ofs, Dir); +} + +uint64_t acess_tell(int FD) { + if(FD & NATIVE_FILE_MASK) + return native_tell( FD & (NATIVE_FILE_MASK-1) ); + return _Syscall(SYS_TELL, ">i", FD); +} + +int acess_ioctl(int fd, int id, void *data) { + // NOTE: 1024 byte size is a hack + DEBUG("ioctl(%i, %i, %p)", fd, id, data); + return _Syscall(SYS_IOCTL, ">i >i ?d", fd, id, 1024, data); +} +int acess_finfo(int fd, t_sysFInfo *info, int maxacls) { + return _Syscall(SYS_FINFO, ">i i", + fd, + sizeof(t_sysFInfo)+maxacls*sizeof(t_sysACL), info, + maxacls); +} + +int acess_readdir(int fd, char *dest) { + DEBUG("readdir(%i, %p)", fd, dest); + return _Syscall(SYS_READDIR, ">i i ?d ?d ?d >d", nfds, + read ? (nfds+7)/8 : 0, read, + write ? (nfds+7)/8 : 0, write, + error ? (nfds+7)/8 : 0, error, + sizeof(*timeout), timeout + ); +} + +int acess__SysOpenChild(int fd, char *name, int flags) { + return _Syscall(SYS_OPENCHILD, ">i >s >i", fd, name, flags); +} + +int acess__SysGetACL(int fd, t_sysACL *dest) { + return _Syscall(SYS_GETACL, "i s >s >s >s", Device, Directory, Type, Options); +} + + +// --- Error Handler +int acess__SysSetFaultHandler(int (*Handler)(int)) { + printf("TODO: Set fault handler (asked to set to %p)\n", Handler); + return 0; +} + +// --- Memory Management --- +uint64_t acess__SysAllocate(uint vaddr) +{ + if( AllocateMemory(vaddr, 0x1000) == -1 ) // Allocate a page + return 0; + + return vaddr; // Just ignore the need for paddrs :) +} + +// --- Process Management --- +int acess_clone(int flags, void *stack) +{ + extern int fork(void); + if(flags & CLONE_VM) { + int ret, newID, kernel_tid=0; + printf("fork()"); + + newID = _Syscall(SYS_FORK, "i i", ID); +} + +int acess_setgid(int ID) +{ + return _Syscall(SYS_SETGID, ">i", ID); +} + +int acess_SysSendMessage(int DestTID, int Length, void *Data) +{ + return _Syscall(SYS_SENDMSG, ">i >d", DestTID, Length, Data); +} + +int acess_SysGetMessage(int *SourceTID, void *Data) +{ + return _Syscall(SYS_GETMSG, "i", Status); + exit(Status); +} + + +// === Symbol List === +#define DEFSYM(name) {#name, acess_##name} +const tSym caBuiltinSymbols[] = { + DEFSYM(_exit), + + DEFSYM(chdir), + DEFSYM(open), + DEFSYM(close), + DEFSYM(reopen), + DEFSYM(read), + DEFSYM(write), + DEFSYM(seek), + DEFSYM(tell), + DEFSYM(ioctl), + DEFSYM(finfo), + DEFSYM(readdir), + DEFSYM(select), + DEFSYM(_SysOpenChild), + DEFSYM(_SysGetACL), + DEFSYM(_SysMount), + + DEFSYM(clone), + DEFSYM(execve), + DEFSYM(sleep), + + DEFSYM(waittid), + DEFSYM(setuid), + DEFSYM(setgid), + + DEFSYM(SysSendMessage), + DEFSYM(SysGetMessage), + + DEFSYM(_SysAllocate), + DEFSYM(_SysDebug), + DEFSYM(_SysSetFaultHandler) +}; + +const int ciNumBuiltinSymbols = sizeof(caBuiltinSymbols)/sizeof(caBuiltinSymbols[0]); + diff --git a/AcessNative/ld-acess_src/exports.h b/AcessNative/ld-acess_src/exports.h new file mode 100644 index 00000000..7fd9bb57 --- /dev/null +++ b/AcessNative/ld-acess_src/exports.h @@ -0,0 +1,34 @@ +/* + * AcessNative Dymamic Linker + * - By John Hodge (thePowersGang) + * + * exports.h + * - Syscalls/Symbol definitions + */ +#ifndef _EXPORTS_H_ +#define _EXPORTS_H_ + +// Syscall request (used by acess_*) +extern uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...); + +extern int native_open(const char *Path, int Flags); +extern void native_close(int FD); +extern size_t native_read(int FD, size_t Bytes, void *Dest); +extern size_t native_write(int FD, size_t Bytes, const void *Src); +extern int native_seek(int FD, int64_t Offset, int Dir); +extern uint64_t native_tell(int FD); + +// Syscalls used by the linker +extern int acess_open(const char *Path, int Flags); +extern void acess_close(int FD); +extern size_t acess_read(int FD, size_t Bytes, void *Dest); +extern int acess_seek(int FD, int64_t Offset, int Dir); + +// Symbol type +typedef struct { + const char *Name; + void *Value; +} tSym; + +#endif + diff --git a/AcessNative/ld-acess_src/syscalls.c b/AcessNative/ld-acess_src/syscalls.c index 54609561..3c07ef25 100644 --- a/AcessNative/ld-acess_src/syscalls.c +++ b/AcessNative/ld-acess_src/syscalls.c @@ -1,7 +1,6 @@ /* */ #define DONT_INCLUDE_SYSCALL_NAMES 1 -#include "../../Usermode/include/acess/sys.h" #include "common.h" #include #include @@ -10,17 +9,14 @@ #include #include #include "request.h" -#include "../syscalls.h" #define DEBUG(str, x...) Debug(str, x) -#define NATIVE_FILE_MASK 0x40000000 #define MAX_FPS 16 // === Types === // === IMPORTS === -extern int giSyscall_ClientID; // Needed for execve // === GLOBALS === FILE *gaSyscall_LocalFPs[MAX_FPS]; @@ -276,284 +272,45 @@ uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...) return retValue; } -// --- VFS Calls -int acess_chdir(const char *Path) -{ - return _Syscall(SYS_CHDIR, ">s", Path); -} - -int acess_open(const char *Path, int Flags) -{ - if( strncmp(Path, "$$$$", 4) == 0 ) - { - int ret; - for(ret = 0; ret < MAX_FPS && gaSyscall_LocalFPs[ret]; ret ++ ) ; - if(ret == MAX_FPS) return -1; - // TODO: Handle directories - gaSyscall_LocalFPs[ret] = fopen(&Path[4], "r+"); - if(!gaSyscall_LocalFPs[ret]) return -1; - return ret|NATIVE_FILE_MASK; - } - DEBUG("open(\"%s\", 0x%x)", Path, Flags); - return _Syscall(SYS_OPEN, ">s >i", Path, Flags); -} - -void acess_close(int FD) { - if(FD & NATIVE_FILE_MASK) { - fclose( gaSyscall_LocalFPs[FD & (NATIVE_FILE_MASK-1)] ); - gaSyscall_LocalFPs[FD & (NATIVE_FILE_MASK-1)] = NULL; - return ; - } - DEBUG("close(%i)", FD); - _Syscall(SYS_CLOSE, ">i", FD); -} - -int acess_reopen(int FD, const char *Path, int Flags) { - DEBUG("reopen(0x%x, \"%s\", 0x%x)", FD, Path, Flags); - return _Syscall(SYS_REOPEN, ">i >s >i", FD, Path, Flags); -} - -size_t acess_read(int FD, size_t Bytes, void *Dest) { - if(FD & NATIVE_FILE_MASK) - return fread( Dest, Bytes, 1, gaSyscall_LocalFPs[FD & (NATIVE_FILE_MASK-1)] ); - DEBUG("read(0x%x, 0x%x, *%p)", FD, Bytes, Dest); - return _Syscall(SYS_READ, ">i >i i >i >d", FD, Bytes, Bytes, Src); -} - -int acess_seek(int FD, int64_t Ofs, int Dir) { - if(FD & NATIVE_FILE_MASK) { - switch(Dir) { - case ACESS_SEEK_SET: Dir = SEEK_SET; break; - default: - case ACESS_SEEK_CUR: Dir = SEEK_CUR; break; - case ACESS_SEEK_END: Dir = SEEK_END; break; - } - return fseek( gaSyscall_LocalFPs[FD & (NATIVE_FILE_MASK-1)], Ofs, Dir ); - } - DEBUG("seek(0x%x, 0x%llx, %i)", FD, Ofs, Dir); - return _Syscall(SYS_SEEK, ">i >I >i", FD, Ofs, Dir); -} - -uint64_t acess_tell(int FD) { - if(FD & NATIVE_FILE_MASK) - return ftell( gaSyscall_LocalFPs[FD & (NATIVE_FILE_MASK-1)] ); - return _Syscall(SYS_TELL, ">i", FD); -} - -int acess_ioctl(int fd, int id, void *data) { - // NOTE: 1024 byte size is a hack - DEBUG("ioctl(%i, %i, %p)", fd, id, data); - return _Syscall(SYS_IOCTL, ">i >i ?d", fd, id, 1024, data); -} -int acess_finfo(int fd, t_sysFInfo *info, int maxacls) { - return _Syscall(SYS_FINFO, ">i i", - fd, - sizeof(t_sysFInfo)+maxacls*sizeof(t_sysACL), info, - maxacls); -} - -int acess_readdir(int fd, char *dest) { - DEBUG("readdir(%i, %p)", fd, dest); - return _Syscall(SYS_READDIR, ">i i ?d ?d ?d >d", nfds, - read ? (nfds+7)/8 : 0, read, - write ? (nfds+7)/8 : 0, write, - error ? (nfds+7)/8 : 0, error, - sizeof(*timeout), timeout - ); -} - -int acess__SysOpenChild(int fd, char *name, int flags) { - return _Syscall(SYS_OPENCHILD, ">i >s >i", fd, name, flags); -} - -int acess__SysGetACL(int fd, t_sysACL *dest) { - return _Syscall(SYS_GETACL, "i s >s >s >s", Device, Directory, Type, Options); -} - - -// --- Error Handler -int acess__SysSetFaultHandler(int (*Handler)(int)) { - printf("TODO: Set fault handler (asked to set to %p)\n", Handler); - return 0; -} - -// --- Memory Management --- -uint64_t acess__SysAllocate(uint vaddr) -{ - if( AllocateMemory(vaddr, 0x1000) == -1 ) // Allocate a page - return 0; - - return vaddr; // Just ignore the need for paddrs :) -} - -// --- Process Management --- -int acess_clone(int flags, void *stack) -{ - extern int fork(void); - if(flags & CLONE_VM) { - int ret, newID, kernel_tid=0; - printf("fork()"); - - newID = _Syscall(SYS_FORK, "i i", ID); + return fread( Dest, Bytes, 1, gaSyscall_LocalFPs[FD] ); } -int acess_setgid(int ID) +size_t native_write(int FD, size_t Bytes, const void *Src) { - return _Syscall(SYS_SETGID, ">i", ID); + return fwrite( Src, Bytes, 1, gaSyscall_LocalFPs[FD] ); } -int acess_SysSendMessage(int DestTID, int Length, void *Data) +int native_seek(int FD, int64_t Ofs, int Dir) { - return _Syscall(SYS_SENDMSG, ">i >d", DestTID, Length, Data); -} - -int acess_SysGetMessage(int *SourceTID, void *Data) -{ - return _Syscall(SYS_GETMSG, " 0) + return fseek( gaSyscall_LocalFPs[FD], Ofs, SEEK_SET ); + else + return fseek( gaSyscall_LocalFPs[FD], Ofs, SEEK_END ); } -void acess__exit(int Status) +uint64_t native_tell(int FD) { - DEBUG("_exit(%i)", Status); - _Syscall(SYS_EXIT, ">i", Status); - exit(Status); + return ftell( gaSyscall_LocalFPs[FD] ); } - - -// === Symbol List === -#define DEFSYM(name) {#name, acess_##name} -const tSym caBuiltinSymbols[] = { - DEFSYM(_exit), - - DEFSYM(chdir), - DEFSYM(open), - DEFSYM(close), - DEFSYM(reopen), - DEFSYM(read), - DEFSYM(write), - DEFSYM(seek), - DEFSYM(tell), - DEFSYM(ioctl), - DEFSYM(finfo), - DEFSYM(readdir), - DEFSYM(select), - DEFSYM(_SysOpenChild), - DEFSYM(_SysGetACL), - DEFSYM(_SysMount), - - DEFSYM(clone), - DEFSYM(execve), - DEFSYM(sleep), - - DEFSYM(waittid), - DEFSYM(setuid), - DEFSYM(setgid), - - DEFSYM(SysSendMessage), - DEFSYM(SysGetMessage), - - DEFSYM(_SysAllocate), - DEFSYM(_SysDebug), - DEFSYM(_SysSetFaultHandler) -}; - -const int ciNumBuiltinSymbols = sizeof(caBuiltinSymbols)/sizeof(caBuiltinSymbols[0]); - -- 2.20.1