# AcessNative Server\r
# Makefile\r
\r
+-include ../../Makefile.Version.cfg\r
+-include Makefile.BuildNum\r
+ifeq ($(BUILD_NUM),)\r
+BUILD_NUM = 1\r
+endif\r
+\r
ifeq ($(PLATFORM),)\r
PLATFORM := lin\r
endif\r
\r
N_OBJ := main.o\r
\r
+BUILDINFO_OBJ := obj-$(PLATFORM)/buildinfo.o\r
+BUILDINFO_SRC := $(BUILDINFO_OBJ:%.o=%.c)\r
+\r
OBJ := helpers.o threads.o server.o syscalls.o\r
OBJ += video.o keyboard.o mouse.o nativefs.o vfs_handle.o ui_sdl.o\r
OBJ := $(addprefix obj-$(PLATFORM)/,$(OBJ))\r
N_OBJ := $(addprefix obj-$(PLATFORM)/,$(N_OBJ))\r
-K_OBJ := $(addprefix $(KERNEL_SRC)obj-$(PLATFORM)/,$(KERNEL_OBJ))\r
+K_OBJ := $(addprefix $(KERNEL_SRC)obj-native-$(PLATFORM)/,$(KERNEL_OBJ))\r
\r
DEPFILES = $(filter %.o,$(OBJ) $(N_OBJ) $(K_OBJ))\r
DEPFILES := $(DEPFILES:%=%.dep)\r
\r
CPPFLAGS += -I include/ -I $(KERNEL_SRC)include/\r
CFLAGS += -Wall -g\r
-LDFLAGS += -lSDL -lSDLmain -g\r
+LDFLAGS += -lSDL -lSDLmain -g -Wl,--defsym,__buildnum=$(BUILD_NUM)\r
\r
ifeq ($(PLATFORM),win)\r
BIN := ../AcessKernel.exe\r
clean:\r
$(RM) $(BIN) $(OBJ) $(N_OBJ) $(K_OBJ) $(DEPFILES)\r
\r
-$(BIN): $(OBJ) $(N_OBJ) $(K_OBJ)\r
+$(BIN): $(OBJ) $(N_OBJ) $(K_OBJ) $(BUILDINFO_OBJ)\r
@echo [LINK] -o $@\r
- @$(CC) $(LDFLAGS) -o $@ $(N_OBJ) $(K_OBJ) $(OBJ)\r
+ @$(CC) -o $@ $(N_OBJ) $(K_OBJ) $(OBJ) $(BUILDINFO_OBJ) $(LDFLAGS)\r
+ @echo BUILD_NUM = $$(( $(BUILD_NUM) + 1 )) > Makefile.BuildNum\r
\r
$(OBJ): obj-$(PLATFORM)/%.o: %.c\r
@mkdir -p $(dir $@)\r
@$(CC) -c $< -o $@ $(CFLAGS) $(CPPFLAGS)\r
\r
-$(K_OBJ): $(KERNEL_SRC)obj-$(PLATFORM)/%.o: $(KERNEL_SRC)%.c\r
+$(K_OBJ): $(KERNEL_SRC)obj-native-$(PLATFORM)/%.o: $(KERNEL_SRC)%.c\r
@mkdir -p $(dir $@)\r
@echo [CC] -o $@\r
@$(CC) -c $< -o $@ $(CFLAGS) $(CPPFLAGS)\r
@$(CC) -c $< -o $@ $(CFLAGS)\r
\r
+$(BUILDINFO_SRC): $(filter-out $(BUILDINFO_OBJ), $(OBJ)) Makefile\r
+ @echo "" > $@\r
+ @echo "const char gsKernelVersion[] = \"$(ACESS_VERSION)\";" >> $@\r
+ @echo "const char gsGitHash[] = \""`git log -n 1 | head -n 1 | awk '{print $$2}'`"\";" >> $@\r
+ @echo "const int giBuildNumber = $(BUILD_NUM);" >> $@\r
+$(BUILDINFO_OBJ): $(BUILDINFO_SRC)\r
+ @echo [CC] -o $@\r
+ @$(CC) -o $@ -c $< $(CFLAGS) $(CPPFLAGS)\r
+\r
-include $(DEPFILES)\r
--- /dev/null
+BUILD_NUM = 16
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
+#include <stdint.h>
// === 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";
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
// - Blocks
SyscallServer();
+ UI_MainLoop();
+
return 0;
}
// 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;
+}
+
// === 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, ...);
tClient *Server_GetClient(int ClientID);
int Server_WorkerThread(void *ClientPtr);
int SyscallServer(void);
+ int Server_ListenThread(void *Unused);
// === GLOBALS ===
#ifdef __WIN32__
int gSocket = INVALID_SOCKET;
#endif
tClient gaServer_Clients[MAX_CLIENTS];
+SDL_Thread *gpServer_ListenThread;
// === CODE ===
int Server_GetClientID(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( ;; )
{
SDL_CondSignal(client->WaitFlag);
#endif
}
-
return -1;
}
// === 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);
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;
}
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))
{
case SDL_QUIT:
AcessNative_Exit();
- return 0;
+ return ;
case SDL_KEYDOWN:
acess_sym = UI_GetAcessKeyFromSDL(event.key.keysym.sym,
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)
// === 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[];
// .Magic = "\x7F""ELF",
.Name = "ELF32",
.Load = Elf_Load,
- .Relocate = Elf_Relocate,
- .GetSymbol = Elf_GetSymbol
+ .Relocate = ElfRelocate,
+ .GetSymbol = ElfGetSymbol
};
tBinary *gLoadedBinaries;
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
+#include <string.h>
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;
+++ /dev/null
-/*\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 MKPTR(_type,_val) ((_type*)(uintptr_t)(_val))\r
-#define PTRMK(_type,_val) MKPTR(_type,_val)\r
-#define PTR(_val) ((void*)(uintptr_t)(_val))\r
-\r
-#if DEBUG\r
-# define ENTER(...)\r
-# define LOG(s, ...) printf("%s: " s, __func__, __VA_ARGS__)\r
-# define LOGS(s) printf("%s: " s, __func__)\r
-# define LEAVE(...)\r
-#else\r
-# define ENTER(...)\r
-# define LOG(...)\r
-# define LOGS(...)\r
-# define LEAVE(...)\r
-#endif\r
-\r
-// === PROTOTYPES ===\r
-void *Elf_Load(int FD);\r
-uintptr_t Elf_Relocate(void *Base);\r
- int Elf_GetSymbol(void *Base, char *Name, uintptr_t *ret);\r
- int Elf_Int_DoRelocate(uint32_t r_info, uint32_t *ptr, uint32_t addend, Elf32_Sym *symtab, void *Base);\r
-uint32_t Elf_Int_HashString(char *str);\r
-\r
-// === CODE ===\r
-void *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;\r
- uint32_t addr;\r
- uint32_t baseDiff = 0;\r
- \r
- ENTER("iFD", FD);\r
- \r
- // Read ELF Header\r
- acess_read(FD, sizeof(hdr), &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 NULL;\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 NULL;\r
- }\r
- \r
- // Read Program Header Table\r
- phtab = malloc( sizeof(Elf32_Phdr) * hdr.phentcount );\r
- if( !phtab ) {\r
- LEAVE('n');\r
- return NULL;\r
- }\r
- LOG("hdr.phoff = 0x%08x\n", hdr.phoff);\r
- acess_seek(FD, hdr.phoff, ACESS_SEEK_SET);\r
- acess_read(FD, sizeof(Elf32_Phdr) * hdr.phentcount, phtab);\r
- \r
- // Count Pages\r
- iPageCount = 0;\r
- LOG("hdr.phentcount = %i\n", hdr.phentcount);\r
- for( i = 0; i < hdr.phentcount; i++ )\r
- {\r
- // Ignore Non-LOAD types\r
- if(phtab[i].Type != PT_LOAD)\r
- continue;\r
- iPageCount += ((phtab[i].VAddr&0xFFF) + phtab[i].MemSize + 0xFFF) >> 12;\r
- LOG("phtab[%i] = {VAddr:0x%x, MemSize:0x%x}\n", i, phtab[i].VAddr, phtab[i].MemSize);\r
- }\r
- \r
- LOG("iPageCount = %i\n", 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
- max = 0;\r
- base = 0xFFFFFFFF;\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 + phtab[i].MemSize > max )\r
- max = phtab[i].VAddr + phtab[i].MemSize;\r
- }\r
-\r
- LOG("base = %08x, max = %08x\n", base, max);\r
-\r
- if( base == 0 ) {\r
- // Find a nice space (31 address bits allowed)\r
- base = FindFreeRange( max, 31 );\r
- LOG("new base = %08x\n", base);\r
- if( base == 0 ) return NULL;\r
- baseDiff = base;\r
- }\r
- \r
- // Load Pages\r
- j = 0;\r
- for( i = 0; i < hdr.phentcount; i++ )\r
- {\r
- //LOG("phtab[%i].Type = 0x%x", i, phtab[i].Type);\r
- LOG("phtab[%i] = {\n", i);\r
- LOG(" .Type = 0x%08x\n", phtab[i].Type);\r
- LOG(" .Offset = 0x%08x\n", phtab[i].Offset);\r
- LOG(" .VAddr = 0x%08x\n", phtab[i].VAddr);\r
- LOG(" .PAddr = 0x%08x\n", phtab[i].PAddr);\r
- LOG(" .FileSize = 0x%08x\n", phtab[i].FileSize);\r
- LOG(" .MemSize = 0x%08x\n", phtab[i].MemSize);\r
- LOG(" .Flags = 0x%08x\n", phtab[i].Flags);\r
- LOG(" .Align = 0x%08x\n", phtab[i].Align);\r
- LOGS(" }\n");\r
- // Get Interpreter Name\r
- if( phtab[i].Type == PT_INTERP )\r
- {\r
- char *tmp;\r
- //if(ret->Interpreter) continue;\r
- tmp = malloc(phtab[i].FileSize);\r
- acess_seek(FD, phtab[i].Offset, ACESS_SEEK_SET);\r
- acess_read(FD, phtab[i].FileSize, tmp);\r
- //ret->Interpreter = Binary_RegInterp(tmp);\r
- LOG("Interpreter '%s'\n", tmp);\r
- free(tmp);\r
- continue;\r
- }\r
- // Ignore non-LOAD types\r
- if(phtab[i].Type != PT_LOAD) continue;\r
- \r
- LOG("phtab[%i] = {VAddr:0x%x,Offset:0x%x,FileSize:0x%x}\n",\r
- i, phtab[i].VAddr+baseDiff, phtab[i].Offset, phtab[i].FileSize);\r
- \r
- addr = phtab[i].VAddr + baseDiff;\r
-\r
- if( AllocateMemory( addr, phtab[i].MemSize ) ) {\r
- fprintf(stderr, "Elf_Load: Unable to map memory at %x (0x%x bytes)\n",\r
- addr, phtab[i].MemSize);\r
- free( phtab );\r
- return NULL;\r
- }\r
- \r
- acess_seek(FD, phtab[i].Offset, ACESS_SEEK_SET);\r
- acess_read(FD, phtab[i].FileSize, PTRMK(void, addr) );\r
- memset( PTRMK(char, addr) + phtab[i].FileSize, 0, phtab[i].MemSize - phtab[i].FileSize );\r
- }\r
- \r
- // Clean Up\r
- free(phtab);\r
- // Return\r
- LEAVE('p', base);\r
- return PTRMK(void, base);\r
-}\r
-\r
-// --- ELF RELOCATION ---\r
-/**\r
- * \brief Relocates a loaded ELF Executable\r
- */\r
-uintptr_t Elf_Relocate(void *Base)\r
-{\r
- Elf32_Ehdr *hdr = Base;\r
- Elf32_Phdr *phtab;\r
- int i, j; // Counters\r
- char *libPath;\r
- uint32_t iRealBase = -1;\r
- uintptr_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
- LOG("Base = %p\n", 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 = MKPTR(void, 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
- LOG("dynamicTab = %p\n", dynamicTab);\r
- // Adjust "Real" Base\r
- iBaseDiff = (uintptr_t)Base - iRealBase;\r
- LOG("iBaseDiff = %p\n", (void*)iBaseDiff);\r
- // Adjust Dynamic Table\r
- dynamicTab = PTR( (uintptr_t)dynamicTab + iBaseDiff);\r
- LOG("dynamicTab = %p\n", dynamicTab);\r
-\r
- hdr->entrypoint += iBaseDiff;\r
- \r
- hdr->misc.SymTable = 0;\r
- hdr->misc.HashTable = 0;\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 = PTRMK(void, dynamicTab[j].d_val);\r
- hdr->misc.SymTable = dynamicTab[j].d_val; // Saved in unused bytes of ident\r
- break;\r
- \r
- // --- String Table ---\r
- case DT_STRTAB:\r
- dynamicTab[j].d_val += iBaseDiff;\r
- dynstrtab = PTRMK(void, dynamicTab[j].d_val);\r
- break;\r
- \r
- // --- Hash Table --\r
- case DT_HASH:\r
- dynamicTab[j].d_val += iBaseDiff;\r
- iSymCount = (PTRMK(uint32_t, dynamicTab[j].d_val))[1];\r
- hdr->misc.HashTable = dynamicTab[j].d_val; // Saved in unused bytes of ident\r
- break;\r
- }\r
- }\r
- \r
- LOG("hdr->misc.SymTable = %x, hdr->misc.HashTable = %x",\r
- hdr->misc.SymTable, hdr->misc.HashTable);\r
-\r
-\r
- // Alter Symbols to true base\r
- for(i = 0; i < iSymCount; i ++)\r
- {\r
- dynsymtab[i].nameOfs += (uintptr_t)dynstrtab;\r
- if( dynsymtab[i].shndx == SHN_UNDEF )\r
- {\r
- LOG("Sym '%s' = UNDEF\n", MKPTR(char,dynsymtab[i].name));\r
- }\r
- else\r
- {\r
- dynsymtab[i].value += iBaseDiff;\r
- LOG("Sym '%s' = 0x%x (relocated)\n", MKPTR(char,dynsymtab[i].name), dynsymtab[i].value);\r
- }\r
- }\r
- \r
- // === Add to loaded list (can be imported now) ===\r
- Binary_SetReadyToUse( 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
- Binary_LoadLibrary(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, 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, 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)\n", plt, pltSz, j);\r
- for(i = 0; i < j; i++)\r
- {\r
- ptr = (void*)(iBaseDiff + pltRel[i].r_offset);\r
- if( !Elf_Int_DoRelocate(pltRel[i].r_info, ptr, *ptr, dynsymtab, 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)\n", plt, pltSz, j);\r
- for(i=0;i<j;i++)\r
- {\r
- ptr = (void*)(iBaseDiff + pltRela[i].r_offset);\r
- if( !Elf_Int_DoRelocate(pltRela[i].r_info, ptr, pltRela[i].r_addend, dynsymtab, 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, void *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, void *base)\r
-{\r
- uintptr_t val;\r
- int type = ELF32_R_TYPE(r_info);\r
- int sym = ELF32_R_SYM(r_info);\r
- char *sSymName = PTRMK(char, symtab[sym].name);\r
- \r
- //LogF("Elf_Int_DoRelocate: (r_info=0x%x, ptr=0x%x, addend=0x%x, .., base=0x%x)\n",\r
- // r_info, ptr, addend, base);\r
- \r
- switch( type )\r
- {\r
- // Standard 32 Bit Relocation (S+A)\r
- case R_386_32:\r
- if( !Elf_GetSymbol( base, sSymName, &val ) && !Binary_GetSymbol( sSymName, &val ) ) {\r
- Warning("Unable to find symbol '%s'", sSymName);\r
- return 0;\r
- }\r
- LOG("%08x R_386_32 *%p += %p('%s')\n", r_info, ptr, (void*)val, sSymName);\r
- *ptr = val + addend;\r
- break;\r
- \r
- // 32 Bit Relocation wrt. Offset (S+A-P)\r
- case R_386_PC32:\r
- if( !Elf_GetSymbol( base, sSymName, &val ) && !Binary_GetSymbol( sSymName, &val ) ) {\r
- Warning("Unable to find symbol '%s'", sSymName);\r
- return 0;\r
- }\r
- LOG("%08x R_386_PC32 *%p = 0x%x + %p('%s') - %p\n", r_info, ptr, *ptr, (void*)val, sSymName, ptr );\r
- // TODO: Check if it needs the true value of ptr or the compiled value\r
- // NOTE: Testing using true value\r
- *ptr = val + addend - (uintptr_t)ptr;\r
- break;\r
-\r
- // Absolute Value of a symbol (S)\r
- case R_386_GLOB_DAT:\r
- if( !Elf_GetSymbol( base, sSymName, &val ) && !Binary_GetSymbol( sSymName, &val ) ) {\r
- Warning("Unable to find symbol '%s'", sSymName);\r
- return 0; \r
- }\r
- LOG("%08x R_386_GLOB_DAT *%p = 0x%x(%s)\n", r_info, ptr, (unsigned int)val, sSymName);\r
- *ptr = val;\r
- break;\r
- \r
- // Absolute Value of a symbol (S)\r
- case R_386_JMP_SLOT:\r
- if( !Elf_GetSymbol( base, sSymName, &val ) && !Binary_GetSymbol( sSymName, &val ) ) {\r
- Warning("Unable to find symbol '%s'", sSymName);\r
- return 0;\r
- }\r
- LOG("%08x R_386_JMP_SLOT *%p = 0x%x (%s)\n", r_info, ptr, (unsigned int)val, sSymName);\r
- *ptr = val;\r
- break;\r
-\r
- // Base Address (B+A)\r
- case R_386_RELATIVE:\r
- LOG("%08x R_386_RELATIVE *%p = %p + 0x%x\n", r_info, ptr, base, addend);\r
- *ptr = (uintptr_t)base + addend;\r
- break;\r
- \r
- default:\r
- LOG("Rel %p: 0x%x,%i\n", ptr, sym, type);\r
- break;\r
- }\r
- return 1;\r
-}\r
-\r
-/**\r
- * \fn int Elf_GetSymbol(void *Base, char *name, uintptr_t *ret)\r
- * \brief Get a symbol from the loaded binary\r
- */\r
-int Elf_GetSymbol(void *Base, char *Name, uintptr_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 = PTR(hdr->misc.HashTable);\r
- symtab = PTR(hdr->misc.SymTable);\r
- \r
-// LOG("Base = %p : pBuckets = %p, symtab = %p\n", Base, pBuckets, symtab);\r
- \r
- if(!pBuckets || !symtab)\r
- return 0;\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(MKPTR(char,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(MKPTR(char,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
--- /dev/null
+../../Usermode/Libraries/ld-acess.so_src/elf.c
\ No newline at end of file
+++ /dev/null
-/**\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
- uint32_t 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
--- /dev/null
+../../Usermode/Libraries/ld-acess.so_src/elf32.h
\ No newline at end of file
--- /dev/null
+../../Usermode/Libraries/ld-acess.so_src/elf64.h
\ No newline at end of file
--- /dev/null
+/*\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 "elf32.h"\r
+\r
+#define DEBUG_WARN 1\r
+\r
+#define MKPTR(_type,_val) ((_type*)(uintptr_t)(_val))\r
+#define PTRMK(_type,_val) MKPTR(_type,_val)\r
+#define PTR(_val) ((void*)(uintptr_t)(_val))\r
+\r
+#if DEBUG\r
+# define ENTER(...)\r
+# define LOG(s, ...) printf("%s: " s, __func__, __VA_ARGS__)\r
+# define LOGS(s) printf("%s: " s, __func__)\r
+# define LEAVE(...)\r
+#else\r
+# define ENTER(...)\r
+# define LOG(...)\r
+# define LOGS(...)\r
+# define LEAVE(...)\r
+#endif\r
+\r
+// === PROTOTYPES ===\r
+void *Elf_Load(int FD);\r
+void *Elf32Load(int FD, Elf32_Ehdr *hdr);\r
+\r
+// === CODE ===\r
+void *Elf_Load(int FD)\r
+{\r
+ Elf32_Ehdr hdr;\r
+ \r
+ // Read ELF Header\r
+ acess_read(FD, sizeof(hdr), &hdr);\r
+ \r
+ // Check the file type\r
+ if(hdr.e_ident[0] != 0x7F || hdr.e_ident[1] != 'E' || hdr.e_ident[2] != 'L' || hdr.e_ident[3] != 'F') {\r
+ Warning("Non-ELF File was passed to the ELF loader\n");\r
+ return NULL;\r
+ }\r
+\r
+ switch(hdr.e_ident[4])\r
+ {\r
+ case ELFCLASS32:\r
+ return Elf32Load(FD, &hdr);\r
+ default:\r
+ return NULL;\r
+ }\r
+}\r
+void *Elf32Load(int FD, Elf32_Ehdr *hdr)\r
+{\r
+ Elf32_Phdr *phtab;\r
+ int i;\r
+ int iPageCount;\r
+ uint32_t max, base;\r
+ uint32_t addr;\r
+ uint32_t baseDiff = 0;\r
+ \r
+ ENTER("iFD", FD);\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 NULL;\r
+ }\r
+ \r
+ // Read Program Header Table\r
+ phtab = malloc( sizeof(Elf32_Phdr) * hdr->phentcount );\r
+ if( !phtab ) {\r
+ LEAVE('n');\r
+ return NULL;\r
+ }\r
+ LOG("hdr.phoff = 0x%08x\n", hdr->phoff);\r
+ acess_seek(FD, hdr->phoff, ACESS_SEEK_SET);\r
+ acess_read(FD, sizeof(Elf32_Phdr) * hdr->phentcount, phtab);\r
+ \r
+ // Count Pages\r
+ iPageCount = 0;\r
+ LOG("hdr.phentcount = %i\n", hdr->phentcount);\r
+ for( i = 0; i < hdr->phentcount; i++ )\r
+ {\r
+ // Ignore Non-LOAD types\r
+ if(phtab[i].Type != PT_LOAD)\r
+ continue;\r
+ iPageCount += ((phtab[i].VAddr&0xFFF) + phtab[i].MemSize + 0xFFF) >> 12;\r
+ LOG("phtab[%i] = {VAddr:0x%x, MemSize:0x%x}\n", i, phtab[i].VAddr, phtab[i].MemSize);\r
+ }\r
+ \r
+ LOG("iPageCount = %i\n", 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
+ max = 0;\r
+ base = 0xFFFFFFFF;\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 + phtab[i].MemSize > max )\r
+ max = phtab[i].VAddr + phtab[i].MemSize;\r
+ }\r
+\r
+ LOG("base = %08x, max = %08x\n", base, max);\r
+\r
+ if( base == 0 ) {\r
+ // Find a nice space (31 address bits allowed)\r
+ base = FindFreeRange( max, 31 );\r
+ LOG("new base = %08x\n", base);\r
+ if( base == 0 ) return NULL;\r
+ baseDiff = base;\r
+ }\r
+ \r
+ // Load Pages\r
+ for( i = 0; i < hdr->phentcount; i++ )\r
+ {\r
+ //LOG("phtab[%i].Type = 0x%x", i, phtab[i].Type);\r
+ LOG("phtab[%i] = {\n", i);\r
+ LOG(" .Type = 0x%08x\n", phtab[i].Type);\r
+ LOG(" .Offset = 0x%08x\n", phtab[i].Offset);\r
+ LOG(" .VAddr = 0x%08x\n", phtab[i].VAddr);\r
+ LOG(" .PAddr = 0x%08x\n", phtab[i].PAddr);\r
+ LOG(" .FileSize = 0x%08x\n", phtab[i].FileSize);\r
+ LOG(" .MemSize = 0x%08x\n", phtab[i].MemSize);\r
+ LOG(" .Flags = 0x%08x\n", phtab[i].Flags);\r
+ LOG(" .Align = 0x%08x\n", phtab[i].Align);\r
+ LOGS(" }\n");\r
+ // Get Interpreter Name\r
+ if( phtab[i].Type == PT_INTERP )\r
+ {\r
+ char *tmp;\r
+ //if(ret->Interpreter) continue;\r
+ tmp = malloc(phtab[i].FileSize);\r
+ acess_seek(FD, phtab[i].Offset, ACESS_SEEK_SET);\r
+ acess_read(FD, phtab[i].FileSize, tmp);\r
+ //ret->Interpreter = Binary_RegInterp(tmp);\r
+ LOG("Interpreter '%s'\n", tmp);\r
+ free(tmp);\r
+ continue;\r
+ }\r
+ // Ignore non-LOAD types\r
+ if(phtab[i].Type != PT_LOAD) continue;\r
+ \r
+ LOG("phtab[%i] = {VAddr:0x%x,Offset:0x%x,FileSize:0x%x}\n",\r
+ i, phtab[i].VAddr+baseDiff, phtab[i].Offset, phtab[i].FileSize);\r
+ \r
+ addr = phtab[i].VAddr + baseDiff;\r
+\r
+ if( AllocateMemory( addr, phtab[i].MemSize ) ) {\r
+ fprintf(stderr, "Elf_Load: Unable to map memory at %x (0x%x bytes)\n",\r
+ addr, phtab[i].MemSize);\r
+ free( phtab );\r
+ return NULL;\r
+ }\r
+ \r
+ acess_seek(FD, phtab[i].Offset, ACESS_SEEK_SET);\r
+ acess_read(FD, phtab[i].FileSize, PTRMK(void, addr) );\r
+ memset( PTRMK(char, addr) + phtab[i].FileSize, 0, phtab[i].MemSize - phtab[i].FileSize );\r
+ }\r
+ \r
+ // Clean Up\r
+ free(phtab);\r
+ // Return\r
+ LEAVE('p', base);\r
+ return PTRMK(void, base);\r
+}\r
--- /dev/null
+/*
+ * AcessNative
+ *
+ * exports.c
+ * - Exported functions
+ */
+#define DONT_INCLUDE_SYSCALL_NAMES 1
+#include "../../Usermode/include/acess/sys.h"
+#include "../syscalls.h"
+#include "exports.h"
+#include <stdarg.h>
+
+#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 <d", FD, Bytes, Bytes, Dest);
+}
+
+size_t acess_write(int FD, size_t Bytes, const void *Src) {
+ if(FD & NATIVE_FILE_MASK)
+ return native_write(FD & (NATIVE_FILE_MASK-1), Bytes, Src);
+ DEBUG("write(0x%x, 0x%x, %p\"%.*s\")", FD, Bytes, Src, Bytes, (char*)Src);
+ return _Syscall(SYS_WRITE, ">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 <d >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 <d", fd, 256, dest);
+}
+
+int acess_select(int nfds, fd_set *read, fd_set *write, fd_set *error, time_t *timeout)
+{
+ DEBUG("select(%i, %p, %p, %p, %p)", nfds, read, write, error, timeout);
+ return _Syscall(SYS_SELECT, ">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 >i <d", fd, sizeof(t_sysACL), dest);
+}
+
+int acess__SysMount(const char *Device, const char *Directory, const char *Type, const char *Options) {
+ return _Syscall(SYS_MOUNT, ">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, "<d", sizeof(int), &kernel_tid);
+ ret = fork();
+ if(ret < 0) return ret;
+
+ if(ret == 0)
+ {
+ giSyscall_ClientID = newID;
+ return 0;
+ }
+
+ // Return the acess TID instead
+ return kernel_tid;
+ }
+ else
+ {
+ fprintf(stderr, "ERROR: Threads currently unsupported\n");
+ exit(-1);
+ }
+}
+
+int acess_execve(char *path, char **argv, char **envp)
+{
+ int i, argc;
+
+ DEBUG("acess_execve: (path='%s', argv=%p, envp=%p)", path, argv, envp);
+
+ // Get argument count
+ for( argc = 0; argv[argc]; argc ++ ) ;
+ DEBUG(" acess_execve: argc = %i", argc);
+
+ char *new_argv[5+argc+1];
+ char key[11];
+ sprintf(key, "%i", giSyscall_ClientID);
+ new_argv[0] = "ld-acess"; // TODO: Get path to ld-acess executable
+ new_argv[1] = "--key"; // Set socket/client ID for Request.c
+ new_argv[2] = key;
+ new_argv[3] = "--binary"; // Set the binary path (instead of using argv[0])
+ new_argv[4] = path;
+ for( i = 0; i < argc; i ++ ) new_argv[5+i] = argv[i];
+ new_argv[5+i] = NULL;
+
+ #if 1
+ argc += 5;
+ for( i = 0; i < argc; i ++ )
+ printf("\"%s\" ", new_argv[i]);
+ printf("\n");
+ #endif
+
+ // Call actual execve
+ return execve("./ld-acess", new_argv, envp);
+}
+
+void acess_sleep(void)
+{
+ _Syscall(SYS_SLEEP, "");
+}
+
+int acess_waittid(int TID, int *ExitStatus)
+{
+ return _Syscall(SYS_WAITTID, ">i <d", TID, sizeof(int), &ExitStatus);
+}
+
+int acess_setuid(int ID)
+{
+ return _Syscall(SYS_SETUID, ">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, "<d <d",
+ SourceTID ? sizeof(int) : 0, SourceTID,
+ Data ? 4096 : 0, Data
+ );
+}
+
+// --- Logging
+void acess__SysDebug(const char *Format, ...)
+{
+ va_list args;
+
+ va_start(args, Format);
+
+ printf("[_SysDebug %i]", giSyscall_ClientID);
+ vprintf(Format, args);
+ printf("\n");
+
+ va_end(args);
+}
+
+void acess__exit(int Status)
+{
+ DEBUG("_exit(%i)", Status);
+ _Syscall(SYS_EXIT, ">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]);
+
--- /dev/null
+/*
+ * 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
+
/*
*/
#define DONT_INCLUDE_SYSCALL_NAMES 1
-#include "../../Usermode/include/acess/sys.h"
#include "common.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#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];
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 <d", FD, Bytes, Bytes, Dest);
-}
-
-size_t acess_write(int FD, size_t Bytes, void *Src) {
- if(FD & NATIVE_FILE_MASK)
- return fwrite( Src, Bytes, 1, gaSyscall_LocalFPs[FD & (NATIVE_FILE_MASK-1)] );
- DEBUG("write(0x%x, 0x%x, %p\"%.*s\")", FD, Bytes, Src, Bytes, (char*)Src);
- return _Syscall(SYS_WRITE, ">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 <d >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 <d", fd, 256, dest);
-}
-
-int acess_select(int nfds, fd_set *read, fd_set *write, fd_set *error, time_t *timeout)
-{
- DEBUG("select(%i, %p, %p, %p, %p)", nfds, read, write, error, timeout);
- return _Syscall(SYS_SELECT, ">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 >i <d", fd, sizeof(t_sysACL), dest);
-}
-
-int acess__SysMount(const char *Device, const char *Directory, const char *Type, const char *Options) {
- return _Syscall(SYS_MOUNT, ">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, "<d", sizeof(int), &kernel_tid);
- ret = fork();
- if(ret < 0) return ret;
-
- if(ret == 0)
- {
- giSyscall_ClientID = newID;
- return 0;
- }
-
- // Return the acess TID instead
- return kernel_tid;
- }
- else
- {
- fprintf(stderr, "ERROR: Threads currently unsupported\n");
- exit(-1);
- }
-}
-
-int acess_execve(char *path, char **argv, char **envp)
-{
- int i, argc;
-
- DEBUG("acess_execve: (path='%s', argv=%p, envp=%p)", path, argv, envp);
-
- // Get argument count
- for( argc = 0; argv[argc]; argc ++ ) ;
- DEBUG(" acess_execve: argc = %i", argc);
-
- char *new_argv[5+argc+1];
- char key[11];
- sprintf(key, "%i", giSyscall_ClientID);
- new_argv[0] = "ld-acess"; // TODO: Get path to ld-acess executable
- new_argv[1] = "--key"; // Set socket/client ID for Request.c
- new_argv[2] = key;
- new_argv[3] = "--binary"; // Set the binary path (instead of using argv[0])
- new_argv[4] = path;
- for( i = 0; i < argc; i ++ ) new_argv[5+i] = argv[i];
- new_argv[5+i] = NULL;
-
- #if 1
- argc += 5;
- for( i = 0; i < argc; i ++ )
- printf("\"%s\" ", new_argv[i]);
- printf("\n");
- #endif
-
- // Call actual execve
- return execve("./ld-acess", new_argv, envp);
-}
-void acess_sleep(void)
+int native_open(const char *Path, int Flags)
{
- _Syscall(SYS_SLEEP, "");
+ 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;
}
-int acess_waittid(int TID, int *ExitStatus)
+void native_close(int FD)
{
- return _Syscall(SYS_WAITTID, ">i <d", TID, sizeof(int), &ExitStatus);
+ fclose( gaSyscall_LocalFPs[FD] );
+ gaSyscall_LocalFPs[FD] = NULL;
}
-int acess_setuid(int ID)
+size_t native_read(int FD, size_t Bytes, void *Dest)
{
- return _Syscall(SYS_SETUID, ">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, "<d <d",
- SourceTID ? sizeof(int) : 0, SourceTID,
- Data ? 4096 : 0, Data
- );
-}
-
-// --- Logging
-void acess__SysDebug(const char *Format, ...)
-{
- va_list args;
-
- va_start(args, Format);
-
- printf("[_SysDebug %i]", giSyscall_ClientID);
- vprintf(Format, args);
- printf("\n");
-
- va_end(args);
+ if(Dir == 0)
+ return fseek( gaSyscall_LocalFPs[FD], Ofs, SEEK_CUR );
+ else if(Dir > 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]);
-