From 4726431cb7e0bada749b32f9e51dedadf882d50b Mon Sep 17 00:00:00 2001 From: John Hodge Date: Tue, 18 Jan 2011 20:47:12 +0800 Subject: [PATCH] Big changes to AcessNative - ld-acess can now execute an application > the syscall interface is not yet completed, so nothing happens - Getting ld-acess working required some changes to the Usermode build system, specifically making ld-acess.so actually a shared library. > It was being linked statically, causing the AcessNative versions of syscalls to not be used (and causing segfaults on "int 0xAC") --- AcessNative/ld-acess.so_src/Makefile | 12 +- AcessNative/ld-acess.so_src/binary.c | 37 ++- AcessNative/ld-acess.so_src/elf.c | 21 +- AcessNative/ld-acess.so_src/main.c | 9 +- AcessNative/ld-acess.so_src/request.c | 78 +++++- AcessNative/ld-acess.so_src/request.h | 26 ++ AcessNative/ld-acess.so_src/syscalls.c | 254 +++++++++++++++++++- AcessNative/syscalls.h | 29 ++- Usermode/Applications/Makefile.cfg | 2 +- Usermode/Libraries/Makefile.tpl | 6 +- Usermode/Libraries/acess.ld_src/acess.ld.h | 2 +- Usermode/Libraries/ld-acess.so_src/Makefile | 7 +- 12 files changed, 435 insertions(+), 48 deletions(-) create mode 100644 AcessNative/ld-acess.so_src/request.h diff --git a/AcessNative/ld-acess.so_src/Makefile b/AcessNative/ld-acess.so_src/Makefile index 08e12c8a..4fb6ae28 100644 --- a/AcessNative/ld-acess.so_src/Makefile +++ b/AcessNative/ld-acess.so_src/Makefile @@ -14,9 +14,10 @@ ifeq ($(PLATFORM),win) endif ifeq ($(PLATFORM),lin) BIN := ../ld-acess + LD += -m elf_i386 endif -CFLAGS += -Wall -Werror -g +CFLAGS += -Wall -Werror -g -m32 .PHONY: all clean @@ -25,9 +26,14 @@ all: $(BIN) clean: $(RM) $(BIN) $(OBJ) -$(BIN): $(OBJ) - $(CC) -g -o $@ $(OBJ) +$(BIN): link.ld.$(PLATFORM) $(OBJ) +# $(LD) -g -o $@ $(OBJ) -T link.ld.$(PLATFORM) + $(CC) -g -o $@ $(OBJ) -m32 -Wl,-T,link.ld.$(PLATFORM) %.o.$(PLATFORM): %.c $(CC) -c $< -o $@ $(CFLAGS) $(CPPFLAGS) +# Modify the default makefile to put the executable at 1MB instead +link.ld.lin: + $(LD) --verbose | awk '{ if( substr($$0,0,5) == "====="){ bPrint = !bPrint; } else { if(bPrint){ print $$0;} } }' | sed 's/\b0x0[08][0-9]*\b/0x00100000/g' > $@ + diff --git a/AcessNative/ld-acess.so_src/binary.c b/AcessNative/ld-acess.so_src/binary.c index 7f97edda..b8f6e71b 100644 --- a/AcessNative/ld-acess.so_src/binary.c +++ b/AcessNative/ld-acess.so_src/binary.c @@ -45,6 +45,10 @@ char *Binary_LocateLibrary(const char *Name) int nameLen = strlen(Name); FILE *fp; + if( strcmp(Name, "libld-acess.so") == 0 ) { + return strdup("libld-acess.so"); + } + // Try the environment ACESS_LIBRARY_PATH if( envPath && envPath[0] != '\0' ) { @@ -103,6 +107,7 @@ void *Binary_LoadLibrary(const char *Name) printf("Binary_LoadLibrary: ret = %p, entry = %p\n", ret, entry); if( entry ) { char *argv[] = {NULL}; + printf("Calling '%s' entry point %p\n", Name, entry); entry(0, argv, NULL); } @@ -117,6 +122,12 @@ void *Binary_Load(const char *Filename, uintptr_t *EntryPoint) uintptr_t entry = 0; tBinFmt *fmt; + // Ignore loading ld-acess + if( strcmp(Filename, "libld-acess.so") == 0 ) { + *EntryPoint = 0; + return (void*)-1; + } + { tBinary *bin; for(bin = gLoadedBinaries; bin; bin = bin->Next) @@ -145,7 +156,8 @@ void *Binary_Load(const char *Filename, uintptr_t *EntryPoint) fclose(fp); return NULL; } - + + printf("fmt->Load(%p)...\n", fp); ret = fmt->Load(fp); printf("fmt->Load(%p): %p\n", fp, ret); if( !ret ) { @@ -199,16 +211,12 @@ int Binary_GetSymbol(const char *SymbolName, uintptr_t *Value) int i; tBinary *bin; - // TODO: Search list of loaded binaries - for(bin = gLoadedBinaries; bin; bin = bin->Next) - { - if( !bin->Ready ) continue; - printf("Binary_GetSymbol: bin = %p{%p, %s}\n", bin, bin->Base, bin->Path); - if( bin->Format->GetSymbol(bin->Base, (char*)SymbolName, Value) ) - return 1; - } + printf("Binary_GetSymbol: (SymbolName='%s', Value=%p)\n", + SymbolName, Value); // Search builtins + // - Placed first to override smartarses that define their own versions + // of system calls for( i = 0; i < ciNumBuiltinSymbols; i ++ ) { if( strcmp(caBuiltinSymbols[i].Name, SymbolName) == 0 ) { @@ -216,6 +224,17 @@ int Binary_GetSymbol(const char *SymbolName, uintptr_t *Value) return 1; } } + + // TODO: Search list of loaded binaries + for(bin = gLoadedBinaries; bin; bin = bin->Next) + { + if( !bin->Ready ) continue; + printf(" Binary_GetSymbol: bin = %p{%p, %s}\n", bin, bin->Base, bin->Path); + if( bin->Format->GetSymbol(bin->Base, (char*)SymbolName, Value) ) + return 1; + } + printf("Binary_GetSymbol: RETURN 0, not found\n"); + return 0; } diff --git a/AcessNative/ld-acess.so_src/elf.c b/AcessNative/ld-acess.so_src/elf.c index 11bd2df7..3ab5a504 100644 --- a/AcessNative/ld-acess.so_src/elf.c +++ b/AcessNative/ld-acess.so_src/elf.c @@ -16,16 +16,16 @@ #define PTRMK(_type,_val) MKPTR(_type,_val) #define PTR(_val) ((void*)(uintptr_t)(_val)) -#if 0 +#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(...) +# define ENTER(...) +# define LOG(...) +# define LOGS(...) +# define LEAVE(...) #endif // === PROTOTYPES === @@ -274,9 +274,16 @@ uintptr_t Elf_Relocate(void *Base) // Alter Symbols to true base for(i = 0; i < iSymCount; i ++) { - dynsymtab[i].value += iBaseDiff; dynsymtab[i].nameOfs += (uintptr_t)dynstrtab; - LOG("Sym '%s' = 0x%x (relocated)\n", MKPTR(char,dynsymtab[i].name), dynsymtab[i].value); + 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) === diff --git a/AcessNative/ld-acess.so_src/main.c b/AcessNative/ld-acess.so_src/main.c index d9bad138..e310a84a 100644 --- a/AcessNative/ld-acess.so_src/main.c +++ b/AcessNative/ld-acess.so_src/main.c @@ -37,7 +37,14 @@ int main(int argc, char *argv[], char **envp) printf("base = %p\n", base); if( !base ) return 127; - return appMain(appArgc, appArgv, envp); + __asm__ __volatile__ ( + "push %0;\n\t" + "push %1;\n\t" + "push %2;\n\t" + "jmp *%3;\n\t" + : : "r" (envp), "r" (appArgv), "r" (appArgc), "r" (appMain) ); + //return appMain(appArgc, appArgv, envp); + return -1; } void Warning(const char *Format, ...) diff --git a/AcessNative/ld-acess.so_src/request.c b/AcessNative/ld-acess.so_src/request.c index 79db625d..f9526b3a 100644 --- a/AcessNative/ld-acess.so_src/request.c +++ b/AcessNative/ld-acess.so_src/request.c @@ -11,17 +11,22 @@ # include # include #endif +#include "request.h" +#include "../syscalls.h" #define SERVER_PORT 0xACE // === GLOBALS === #ifdef __WIN32__ WSADATA gWinsock; -SOCKET gSocket; +SOCKET gSocket = INVALID_SOCKET; #else - int gSocket; # define INVALID_SOCKET -1 + int gSocket = INVALID_SOCKET; #endif +// Client ID to pass to server +// TODO: Implement such that each thread gets a different one +static int siSyscall_ClientID = 0; // === CODE === int _InitSyscalls() @@ -75,9 +80,72 @@ int _InitSyscalls() } return 0; } -#if 0 -int _Syscall(const char *ArgTypes, ...) + +int SendRequest(int RequestID, int NumOutput, tOutValue **Output, int NumInput, tInValue **Input) { + tRequestHeader *request; + tRequestValue *value; + char *data; + int requestLen; + int i; + + // See ../syscalls.h for details of request format + requestLen = sizeof(tRequestHeader) + (NumOutput + NumInput) * sizeof(tRequestValue); + + // Get total param length + for( i = 0; i < NumOutput; i ++ ) + requestLen += Output[i]->Length; + + // Allocate request + request = malloc( requestLen ); + value = request->Params; + data = (char*)&request->Params[ NumOutput + NumInput ]; + + // Set header + request->ClientID = siSyscall_ClientID; + request->CallID = RequestID; // Syscall + request->NParams = NumOutput; + request->NReturn = NumInput; + + // Set parameters + for( i = 0; i < NumOutput; i ++ ) + { + switch(Output[i]->Type) + { + case 'i': value->Type = ARG_TYPE_INT32; break; + case 'I': value->Type = ARG_TYPE_INT64; break; + case 'd': value->Type = ARG_TYPE_DATA; break; + default: + return -1; + } + value->Length = Output[i]->Length; + + memcpy(data, Output[i]->Data, Output[i]->Length); + + data += Output[i]->Length; + } + + // Set return values + for( i = 0; i < NumInput; i ++ ) + { + switch(Input[i]->Type) + { + case 'i': value->Type = ARG_TYPE_INT32; break; + case 'I': value->Type = ARG_TYPE_INT64; break; + case 'd': value->Type = ARG_TYPE_DATA; break; + default: + return -1; + } + value->Length = Input[i]->Length; + } + + // Send it off + send(gSocket, request, requestLen, 0); + + // Wait for a response + recv(gSocket, request, requestLen, 0); + + // Parse response out + return 0; } -#endif diff --git a/AcessNative/ld-acess.so_src/request.h b/AcessNative/ld-acess.so_src/request.h new file mode 100644 index 00000000..8c89e6f6 --- /dev/null +++ b/AcessNative/ld-acess.so_src/request.h @@ -0,0 +1,26 @@ +/* + * Acess2 - AcessNative + * ld-acess + * + * request.h - IPC Request common header + */ + +#ifndef _REQUEST_H_ +#define _REQUEST_H_ + +typedef struct { + char Type; + int Length; + char Data[]; +} tOutValue; + +typedef struct { + char Type; + int Length; + void *Data; +} tInValue; + +extern int SendRequest(int RequestID, int NumOutput, tOutValue **Output, + int NumInput, tInValue **Input); + +#endif diff --git a/AcessNative/ld-acess.so_src/syscalls.c b/AcessNative/ld-acess.so_src/syscalls.c index e26ae359..ec4af017 100644 --- a/AcessNative/ld-acess.so_src/syscalls.c +++ b/AcessNative/ld-acess.so_src/syscalls.c @@ -1,36 +1,225 @@ /* */ -//#include +#include "../../Usermode/include/acess/sys.h" #include "common.h" #include #include #include #include +#include +#include "request.h" + +// === Types === // === IMPORTS === // === CODE === +const char *ReadEntry(tOutValue **OutDest, tInValue **InDest, + int *Direction, const char *ArgTypes, va_list Args) +{ + uint64_t val64, *ptr64; + uint32_t val32, *ptr32; + int direction = 0; // 0: Invalid, 1: Out, 2: In, 3: Out + char *str; + int len; + + // Eat whitespace + while(*ArgTypes && *ArgTypes == ' ') ArgTypes ++; + if( *ArgTypes == '\0' ) return ArgTypes; + + // Get direction + switch(*ArgTypes) + { + case '>': direction = 1; break; + case '<': direction = 2; break; + case '?': direction = 3; break; + default: + return NULL; + } + ArgTypes ++; + + // Eat whitespace + while(*ArgTypes && *ArgTypes == ' ') ArgTypes ++; + if( *ArgTypes == '\0' ) return ArgTypes; + + // Internal helper macro + #define MAKE_OUT(_dest,_typeChar,_typeName,_value) do{if((_dest)){\ + *(_dest) = (tOutValue*)malloc(sizeof(tOutValue)+sizeof(_typeName));\ + (*(_dest))->Type=(_typeChar);(*(_dest))->Length=sizeof(_typeName);\ + *(_typeName*)((*(_dest))->Data) = (_value);\ + }}while(0) + #define MAKE_IN(_dest,_typeChar,_typeName,_value) do{if((_dest)){\ + *(_dest) = (tInValue*)malloc(sizeof(tInValue));\ + (*(_dest))->Type=(_typeChar);(*(_dest))->Length=sizeof(_typeName);\ + (*(_dest))->Data = (_value);\ + }}while(0) + + // Get type + switch(*ArgTypes) + { + case 'i': // 32-bit integer + // Input? + if( direction & 2 ) + { + ptr32 = va_arg(Args, uint32_t*); + MAKE_IN(InDest, 'i', uint32_t*, ptr32); + if( direction & 1 ) + MAKE_OUT(OutDest, 'i', uint32_t, *ptr32); + } + else + { + val32 = va_arg(Args, uint32_t); + MAKE_OUT(OutDest, 'i', uint32_t, val32); + } + break; + case 'I': // 64-bit integer + // Input? + if( direction & 2 ) + { + ptr64 = va_arg(Args, uint64_t*); + MAKE_IN(InDest, 'I', uint64_t*, ptr64); + if( direction & 1 ) + MAKE_OUT(OutDest, 'I', uint64_t, *ptr64); + } + else + { + val64 = va_arg(Args, uint64_t); + MAKE_OUT(OutDest, 'I', uint64_t, val64); + } + break; + case 's': + // Input string makes no sense! + if( direction & 2 ) { + fprintf(stderr, "ReadEntry: Incoming string is not defined\n"); + return NULL; + } + + str = va_arg(Args, char*); + if( OutDest ) + { + int len = strlen(str) + 1; + *OutDest = malloc( sizeof(tOutValue) + len ); + (*OutDest)->Type = 's'; + (*OutDest)->Length = len; + memcpy((*OutDest)->Data, str, len); + } + break; + + case 'd': + len = va_arg(Args, int); + str = va_arg(Args, char*); + + // Input ? + if( (direction & 2) && InDest ) + { + *InDest = (tInValue*)malloc( sizeof(tInValue) ); + (*InDest)->Type = 'd'; + (*InDest)->Length = len; + (*InDest)->Data = str; + } + + // Output ? + if( (direction & 1) && InDest ) + { + *OutDest = (tOutValue*)malloc( sizeof(tOutValue) + len ); + (*OutDest)->Type = 'd'; + (*OutDest)->Length = len; + memcpy((*OutDest)->Data, str, len); + } + break; + + default: + return NULL; + } + ArgTypes ++; + #undef MAKE_ASSIGN + + *Direction = direction; + + return ArgTypes; +} + /** * \param ArgTypes * * Whitespace is ignored - * >i: Input Integer + * >i: Input Integer (32-bits) * >I: Input Long Integer (64-bits) * >s: Input String * >d: Input Buffer (Preceded by valid size) * s >i", Path, Flags); } @@ -47,25 +236,66 @@ size_t write(int FD, size_t Bytes, void *Src) { return _Syscall(">i >i >d", FD, Bytes, Bytes, Src); } +int seek(int FD, int64_t Ofs, int Dir) { + return _Syscall(">i >I >i", FD, Ofs, Dir); +} + uint64_t tell(int FD) { uint64_t ret; _Syscall("i", &ret, FD); return ret; } -int seek(int FD, uint64_t Ofs, int Dir) { - return _Syscall(">i >I >i", FD, Ofs, Dir); +int ioctl(int fd, int id, void *data) { + // NOTE: 1024 byte size is a hack + return _Syscall(">i >i ?d", fd, id, 1024, data); +} +int finfo(int fd, t_sysFInfo *info, int maxacls) { + return _Syscall(">i i", fd, maxacls*sizeof(t_sysFInfo), info, maxacls); } +int readdir(int fd, char *dest) { + return _Syscall(">i i >s >i", fd, name, flags); +} + +int _SysGetACL(int fd, t_sysACL *dest) { + return _Syscall(">i s >s >s >s", Device, Directory, Type, Options); +} + + +// --- Error Handler +int _SysSetFaultHandler(int (*Handler)(int)) { + return 0; +} + + // === Symbol List === +#define DEFSYM(name) {#name, name} const tSym caBuiltinSymbols[] = { - {"open", open}, - {"close", close}, - {"read", read}, - {"write", write}, - {"tell", tell}, - {"seek", seek}, - {"_exit", exit} + {"_exit", exit}, + + DEFSYM(open), + DEFSYM(close), + DEFSYM(read), + DEFSYM(write), + DEFSYM(seek), + DEFSYM(tell), + DEFSYM(ioctl), + DEFSYM(finfo), + DEFSYM(readdir), + DEFSYM(_SysOpenChild), + DEFSYM(_SysGetACL), + DEFSYM(_SysMount), + + {"_SysSetFaultHandler", _SysSetFaultHandler} }; const int ciNumBuiltinSymbols = sizeof(caBuiltinSymbols)/sizeof(caBuiltinSymbols[0]); diff --git a/AcessNative/syscalls.h b/AcessNative/syscalls.h index 2784fd02..e298c94d 100644 --- a/AcessNative/syscalls.h +++ b/AcessNative/syscalls.h @@ -3,6 +3,30 @@ #ifndef _NATIVE_SYSCALLS_H_ #define _NATIVE_SYSCALLS_H_ +/* + * Request format + * + * tRequestHeader header + * tRequestValue params[header.NParams] + * tRequestValue retvals[header.NReturn] + * uint8_t paramData[SUM(params[].Lengh)]; + */ + +typedef struct sRequestValue { + /// \see eArgumentTypes + uint16_t Type; + uint16_t Length; +} tRequestValue; + +typedef struct sRequestHeader { + uint16_t ClientID; + uint16_t CallID; //!< \see eSyscalls + uint16_t NParams; + uint16_t NReturn; + + tRequestValue Params[]; +} tRequestHeader; + enum eSyscalls { SYS_NULL, SYS_OPEN @@ -12,12 +36,7 @@ enum eArgumentTypes { ARG_TYPE_VOID, ARG_TYPE_INT32, ARG_TYPE_INT64, - ARG_TYPE_STRING, ARG_TYPE_DATA }; -#define ARG_DIR_TOSRV 0x10 -#define ARG_DIR_TOCLI 0x20 -#define ARG_DIR_BOTH 0x30 - #endif diff --git a/Usermode/Applications/Makefile.cfg b/Usermode/Applications/Makefile.cfg index 6b946969..2e64b9d6 100644 --- a/Usermode/Applications/Makefile.cfg +++ b/Usermode/Applications/Makefile.cfg @@ -14,5 +14,5 @@ include $(dir $(lastword $(MAKEFILE_LIST)))../Makefile.cfg ASFLAGS = -felf CPPFLAGS = -I$(ACESSUSERDIR)/include/ CFLAGS = -fno-stack-protector $(CPPFLAGS) -LDFLAGS = -T $(OUTPUTDIR)Libs/acess.ld -rpath-link $(OUTPUTDIR)Libs -L $(OUTPUTDIR)Libs -I /Acess/Libs/ld-acess.so -lc +LDFLAGS = -T $(OUTPUTDIR)Libs/acess.ld -rpath-link $(OUTPUTDIR)Libs -L $(OUTPUTDIR)Libs -I /Acess/Libs/ld-acess.so -lld-acess -lc DIR = Bin diff --git a/Usermode/Libraries/Makefile.tpl b/Usermode/Libraries/Makefile.tpl index 5f736327..9712bf8a 100644 --- a/Usermode/Libraries/Makefile.tpl +++ b/Usermode/Libraries/Makefile.tpl @@ -6,14 +6,14 @@ DEPFILES := $(addsuffix .d,$(OBJ)) _BIN := $(OUTPUTDIR)Libs/$(BIN) -.PHONY: all clean install +.PHONY: all clean install postbuild -all: $(_BIN) +all: $(_BIN) postbuild clean: $(RM) $(_BIN) $(OBJ) $(_BIN).dsm $(DEPFILES) -install: $(_BIN) +install: all $(xCP) $(_BIN) $(DISTROOT)/Libs/ $(_BIN): $(OBJ) diff --git a/Usermode/Libraries/acess.ld_src/acess.ld.h b/Usermode/Libraries/acess.ld_src/acess.ld.h index c059c79d..e81c0a56 100644 --- a/Usermode/Libraries/acess.ld_src/acess.ld.h +++ b/Usermode/Libraries/acess.ld_src/acess.ld.h @@ -2,7 +2,7 @@ OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") OUTPUT_ARCH(i386) ENTRY(start) SEARCH_DIR(__LIBDIR) -INPUT(crt0.o ld-acess.so) +INPUT(crt0.o) SECTIONS { /* Read-only sections, merged into text segment: */ diff --git a/Usermode/Libraries/ld-acess.so_src/Makefile b/Usermode/Libraries/ld-acess.so_src/Makefile index 48bb38fa..3c02d3db 100644 --- a/Usermode/Libraries/ld-acess.so_src/Makefile +++ b/Usermode/Libraries/ld-acess.so_src/Makefile @@ -10,7 +10,12 @@ BIN = ld-acess.so CFLAGS = -Wall -fno-builtin -fno-leading-underscore -fno-stack-protector ASFLAGS = -felf -LDFLAGS = -T link.ld -Map map.txt -Bstatic +LDFLAGS = -T link.ld -Map map.txt -Bstatic -shared include ../Makefile.tpl +postbuild: $(OUTPUTDIR)Libs/libld-acess.so + +$(OUTPUTDIR)Libs/libld-acess.so: + ln -s $(_BIN) $(OUTPUTDIR)Libs/libld-acess.so + -- 2.20.1