From 49fee999ebaa079cbd48a98edd2323f7b0bbb03c Mon Sep 17 00:00:00 2001 From: John Hodge Date: Wed, 4 Jul 2012 21:32:31 +0800 Subject: [PATCH] AcessNative - Fixing crashes --- AcessNative/Makefile | 4 + AcessNative/RunTest | 2 +- AcessNative/acesskernel_src/Makefile | 2 +- AcessNative/acesskernel_src/include/arch.h | 3 + .../acesskernel_src/include/threads_int.h | 78 +++++++++++++++++++ AcessNative/acesskernel_src/server.c | 10 ++- AcessNative/acesskernel_src/syscalls.c | 27 +++++-- AcessNative/acesskernel_src/threads.c | 72 ++++++----------- AcessNative/acesskernel_src/time.c | 40 ++++++++++ AcessNative/ld-acess_src/binary.c | 3 +- AcessNative/ld-acess_src/elf_load.c | 6 +- AcessNative/ld-acess_src/exports.c | 12 +-- AcessNative/ld-acess_src/main.c | 5 ++ 13 files changed, 196 insertions(+), 68 deletions(-) create mode 100644 AcessNative/Makefile create mode 100644 AcessNative/acesskernel_src/include/threads_int.h create mode 100644 AcessNative/acesskernel_src/time.c diff --git a/AcessNative/Makefile b/AcessNative/Makefile new file mode 100644 index 00000000..c9cd4816 --- /dev/null +++ b/AcessNative/Makefile @@ -0,0 +1,4 @@ + +all: + @$(MAKE) -C acesskernel_src + @$(MAKE) -C ld-acess_src diff --git a/AcessNative/RunTest b/AcessNative/RunTest index 9137ff94..3a2a3a21 100755 --- a/AcessNative/RunTest +++ b/AcessNative/RunTest @@ -1,5 +1,5 @@ #!/bin/sh trap '' 2 -./AcessKernel --rootapp /Acess/SBin/login +$1 ./AcessKernel --rootapp /Acess/SBin/login trap 2 killall ld-acess diff --git a/AcessNative/acesskernel_src/Makefile b/AcessNative/acesskernel_src/Makefile index 4cc939ec..0d63d5f5 100644 --- a/AcessNative/acesskernel_src/Makefile +++ b/AcessNative/acesskernel_src/Makefile @@ -25,7 +25,7 @@ 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 := helpers.o threads.o server.o syscalls.o time.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)) diff --git a/AcessNative/acesskernel_src/include/arch.h b/AcessNative/acesskernel_src/include/arch.h index f5135306..b63d1bb2 100644 --- a/AcessNative/acesskernel_src/include/arch.h +++ b/AcessNative/acesskernel_src/include/arch.h @@ -40,5 +40,8 @@ struct sShortSpinlock //#define NUM_CFG_ENTRIES 10 +extern void Debug_PutCharDebug(char ch); +extern void Debug_PutStringDebug(const char *str); + #endif diff --git a/AcessNative/acesskernel_src/include/threads_int.h b/AcessNative/acesskernel_src/include/threads_int.h new file mode 100644 index 00000000..f070a50e --- /dev/null +++ b/AcessNative/acesskernel_src/include/threads_int.h @@ -0,0 +1,78 @@ +#ifndef _THREADS_INT_H_ +#define _THREADS_INT_H_ + +/** + * \brief IPC Message + */ +typedef struct sMessage +{ + struct sMessage *Next; //!< Next message in thread's inbox + tTID Source; //!< Source thread ID + Uint Length; //!< Length of message data in bytes + Uint8 Data[]; //!< Message data +} tMsg; + +typedef struct sProcess +{ + int nThreads; + int NativePID; + char *CWD; + char *Chroot; + int MaxFD; +} tProcess; + +struct sThread +{ + struct sThread *GlobalNext; + struct sThread *Next; + + int KernelTID; + + tTID TID, PID; + tUID UID, GID; + + struct sThread *Parent; + + char *ThreadName; + + int Status; // 0: Dead, 1: Active, 2: Paused, 3: Asleep + int ExitStatus; + int _errno; + + // Threads waiting for this thread to exit. + // Quit logic: + // - Wait for `WaitingThreads` to be non-null (maybe?) + // - Wake first in the queue, wait for it to be removed + // - Repeat + // - Free thread and quit kernel thread + struct sThread *WaitingThreads; + struct sThread *WaitingThreadsEnd; + + tProcess *Process; + + Uint32 Events, WaitMask; + void *EventSem; // Should be SDL_sem, but I don't want SDL in this header + + // Message queue + tMsg * volatile Messages; //!< Message Queue + tMsg *LastMessage; //!< Last Message (speeds up insertion) +}; + +enum { + THREAD_STAT_NULL, // Invalid process + THREAD_STAT_ACTIVE, // Running and schedulable process + THREAD_STAT_SLEEPING, // Message Sleep + THREAD_STAT_MUTEXSLEEP, // Mutex Sleep + THREAD_STAT_SEMAPHORESLEEP, // Semaphore Sleep + THREAD_STAT_QUEUESLEEP, // Queue + THREAD_STAT_EVENTSLEEP, // Event sleep + THREAD_STAT_WAITING, // ??? (Waiting for a thread) + THREAD_STAT_PREINIT, // Being created + THREAD_STAT_ZOMBIE, // Died/Killed, but parent not informed + THREAD_STAT_DEAD, // Awaiting burial (free) + THREAD_STAT_BURIED // If it's still on the list here, something's wrong +}; +extern tThread *Threads_GetThread(Uint TID); + +#endif + diff --git a/AcessNative/acesskernel_src/server.c b/AcessNative/acesskernel_src/server.c index 7bb50336..b9b2b19b 100644 --- a/AcessNative/acesskernel_src/server.c +++ b/AcessNative/acesskernel_src/server.c @@ -131,14 +131,14 @@ int Server_WorkerThread(void *ClientPtr) while( Client->CurrentRequest == NULL ) SDL_CondWait(Client->WaitFlag, Client->Mutex); + Log_Debug("AcessSrv", "Worker got message %p", Client->CurrentRequest); + if(Client->ClientID != cur_client_id) { Threads_SetThread( Client->ClientID ); cur_client_id = Client->ClientID; } - // Get the response - retHeader = SyscallRecieve(Client->CurrentRequest, &retSize); - + // Debug { int callid = Client->CurrentRequest->CallID; Log_Debug("AcessSrv", "Client %i request %i %s", @@ -147,7 +147,9 @@ int Server_WorkerThread(void *ClientPtr) ); } - + // Get the response + retHeader = SyscallRecieve(Client->CurrentRequest, &retSize); + if( !retHeader ) { // Return an error to the client printf("ERROR: SyscallRecieve failed\n"); diff --git a/AcessNative/acesskernel_src/syscalls.c b/AcessNative/acesskernel_src/syscalls.c index 58dc8017..b945df81 100644 --- a/AcessNative/acesskernel_src/syscalls.c +++ b/AcessNative/acesskernel_src/syscalls.c @@ -194,10 +194,21 @@ SYSCALL2(Syscall_SendMessage, "id", int, void *, return Proc_SendMessage(a0, Sizes[1], a1); ); -SYSCALL2(Syscall_GetMessage, "dd", Uint *, void *, - if( Sizes[0] < sizeof(*a0) ) +SYSCALL2(Syscall_GetMessage, "dd", uint32_t *, void *, + if( a0 && Sizes[0] < sizeof(*a0) ) { + Log_Notice("Syscalls", "Syscall_GetMessage - Arg 1 Undersize (%i < %i)", + Sizes[0], sizeof(*a0)); return -1; - return Proc_GetMessage(a0, a1); + } + Uint tmp; + int rv; + if( a0 ) { + rv = Proc_GetMessage(&tmp, a1); + *a0 = tmp; + } + else + rv = Proc_GetMessage(NULL, a1); + return rv; ); SYSCALL1(Syscall_WaitEvent, "i", int, @@ -298,7 +309,7 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength) } formatString[i] = '\0'; - //LOG("Request %i(%s) '%s'", Request->CallID, casSYSCALL_NAMES[Request->CallID], formatString); + LOG("Request %i(%s) '%s'", Request->CallID, casSYSCALL_NAMES[Request->CallID], formatString); { char argListData[argListLen]; @@ -341,7 +352,13 @@ tRequestHeader *SyscallRecieve(tRequestHeader *Request, int *ReturnLength) } // Check for non-resident data - if( Request->Params[i].Flags & ARG_FLAG_ZEROED ) + if( Request->Params[i].Length == 0 ) + { + returnData[i] = NULL; + *(void**)&argListData[argListLen] = NULL; + argListLen += sizeof(void*); + } + else if( Request->Params[i].Flags & ARG_FLAG_ZEROED ) { // Allocate and zero the buffer returnData[i] = calloc(1, Request->Params[i].Length); diff --git a/AcessNative/acesskernel_src/threads.c b/AcessNative/acesskernel_src/threads.c index 71fa2941..778917ce 100644 --- a/AcessNative/acesskernel_src/threads.c +++ b/AcessNative/acesskernel_src/threads.c @@ -16,6 +16,7 @@ #include #include #include +#include #undef CLONE_VM // Such a hack #undef off_t @@ -41,49 +42,6 @@ typedef struct sState } tState; #endif -typedef struct sProcess -{ - int nThreads; - int NativePID; - char *CWD; - char *Chroot; - int MaxFD; -} tProcess; - -struct sThread -{ - struct sThread *GlobalNext; - struct sThread *Next; - - int KernelTID; - - tTID TID, PID; - tUID UID, GID; - - struct sThread *Parent; - - char *ThreadName; - - int State; // 0: Dead, 1: Active, 2: Paused, 3: Asleep - int ExitStatus; - int _errno; - - // Threads waiting for this thread to exit. - // Quit logic: - // - Wait for `WaitingThreads` to be non-null (maybe?) - // - Wake first in the queue, wait for it to be removed - // - Repeat - // - Free thread and quit kernel thread - struct sThread *WaitingThreads; - struct sThread *WaitingThreadsEnd; - - tProcess *Process; - - Uint32 Events, WaitMask; - SDL_sem *EventSem; - -}; - // === PROTOTYPES === int Threads_Wake(tThread *Thread); @@ -95,7 +53,7 @@ tProcess gProcessZero = { .MaxFD = 100 }; tThread gThreadZero = { - .State=1, + .Status=THREAD_STAT_ACTIVE, .ThreadName="ThreadZero", .Process = &gProcessZero }; @@ -136,13 +94,17 @@ void Threads_SetThread(int TID) Log_Error("Threads", "_SetThread - Thread %i is not on global list", TID); } -tThread *Threads_GetThread(int TID) +tThread *Threads_GetThread(Uint TID) { tThread *thread; + Log_Debug("Threads", "Looking for TID %i", TID); for( thread = gpThreads; thread; thread = thread->GlobalNext ) { - if( thread->TID == TID ) + if( thread->TID == TID ) { + Log_Debug("Threads", "Found %p", thread); + Log_Debug("Threads", "- Name = %s", thread->ThreadName); return thread; + } } return NULL; } @@ -232,7 +194,7 @@ tTID Threads_WaitTID(int TID, int *Status) if(!thread) return -1; us->Next = NULL; - us->State = 3; + us->Status = THREAD_STAT_WAITING; // TODO: Locking if(thread->WaitingThreadsEnd) { @@ -298,7 +260,7 @@ void Threads_Exit(int TID, int Status) int Threads_Wake(tThread *Thread) { - Thread->State = 0; + Thread->Status = THREAD_STAT_ACTIVE; Threads_PostEvent(Thread, THREAD_EVENT_WAKEUP); return 0; } @@ -332,6 +294,9 @@ int Threads_Fork(void) return thread->PID; } +// -------------------------------------------------------------------- +// Mutexes +// -------------------------------------------------------------------- int Mutex_Acquire(tMutex *Mutex) { if(!Mutex->Protector.IsValid) { @@ -347,6 +312,9 @@ void Mutex_Release(tMutex *Mutex) pthread_mutex_unlock( &Mutex->Protector.Mutex ); } +// -------------------------------------------------------------------- +// Semaphores +// -------------------------------------------------------------------- void Semaphore_Init(tSemaphore *Sem, int InitValue, int MaxValue, const char *Module, const char *Name) { memset(Sem, 0, sizeof(tSemaphore)); @@ -368,6 +336,9 @@ int Semaphore_Signal(tSemaphore *Sem, int AmmountToAdd) return AmmountToAdd; } +// -------------------------------------------------------------------- +// Event handling +// -------------------------------------------------------------------- Uint32 Threads_WaitEvents(Uint32 Mask) { Uint32 rv; @@ -397,3 +368,8 @@ void Threads_PostEvent(tThread *Thread, Uint32 Events) } } +void Threads_ClearEvent(Uint32 EventMask) +{ + gpCurrentThread->Events &= ~EventMask; +} + diff --git a/AcessNative/acesskernel_src/time.c b/AcessNative/acesskernel_src/time.c new file mode 100644 index 00000000..89669cf4 --- /dev/null +++ b/AcessNative/acesskernel_src/time.c @@ -0,0 +1,40 @@ +/* + * Acess2 Native Kernel + * - Acess kernel emulation on another OS using SDL and UDP + * + * time.c + * - Timer code + */ +#include +#include + +struct sTimer { + tTimer *Next; + Sint64 FiresAfter; + void (*Callback)(void*); + void *Argument; + BOOL bActive; +}; + +// === CODE === +tTimer *Time_CreateTimer(int Delta, tTimerCallback *Callback, void *Argument) +{ + return NULL; +} + +tTimer *Time_AllocateTimer(tTimerCallback *Callback, void *Argument) +{ + return NULL; +} + +void Time_FreeTimer(tTimer *Timer) +{ +} + +void Time_ScheduleTimer(tTimer *Timer, int Delta) +{ +} + +void Time_RemoveTimer(tTimer *Timer) +{ +} diff --git a/AcessNative/ld-acess_src/binary.c b/AcessNative/ld-acess_src/binary.c index 62354318..8d11e975 100644 --- a/AcessNative/ld-acess_src/binary.c +++ b/AcessNative/ld-acess_src/binary.c @@ -24,6 +24,7 @@ extern uintptr_t ElfRelocate(void *Base); extern int ElfGetSymbol(void *Base, char *Name, uintptr_t *ret, size_t *size); extern int ciNumBuiltinSymbols; extern tSym caBuiltinSymbols[]; +extern char **gEnvP; // === PROTOTYPES === void Binary_AddToList(const char *Filename, void *Base, tBinFmt *Format); @@ -120,7 +121,7 @@ void *Binary_LoadLibrary(const char *Name) #if DEBUG printf("Calling '%s' entry point %p\n", Name, entry); #endif - entry(ret, 0, argv, NULL); + entry(ret, 0, argv, gEnvP); } return ret; diff --git a/AcessNative/ld-acess_src/elf_load.c b/AcessNative/ld-acess_src/elf_load.c index 590da377..8cafc01e 100644 --- a/AcessNative/ld-acess_src/elf_load.c +++ b/AcessNative/ld-acess_src/elf_load.c @@ -190,9 +190,9 @@ void *Elf64Load(int FD, Elf64_Ehdr *hdr) ENTER("iFD", FD); - #if BITS <= 32 - Warning("ELF64 being loaded in 32-bit env, this may not work"); - #endif + if( sizeof(void*) == 4) { + Warning("ELF64 being loaded in 32-bit env, this may not work"); + } // Check for a program header if(hdr->e_phoff == 0) { diff --git a/AcessNative/ld-acess_src/exports.c b/AcessNative/ld-acess_src/exports.c index 406e55f9..957a86e5 100644 --- a/AcessNative/ld-acess_src/exports.c +++ b/AcessNative/ld-acess_src/exports.c @@ -5,7 +5,7 @@ * - Exported functions */ #define DONT_INCLUDE_SYSCALL_NAMES 1 -#include "../../Usermode/include/acess/sys.h" +#include "../../Usermode/Libraries/ld-acess.so_src/include_exp/acess/sys.h" #include "../syscalls.h" #include "exports.h" #include @@ -68,14 +68,16 @@ int acess_reopen(int FD, const char *Path, int Flags) { size_t acess_read(int FD, void *Dest, size_t Bytes) { if(FD & NATIVE_FILE_MASK) return native_read(FD & (NATIVE_FILE_MASK-1), Dest, Bytes); - DEBUG("read(0x%x, 0x%x, *%p)", FD, Bytes, Dest); + if( FD > 2 ) + DEBUG("read(0x%x, 0x%x, *%p)", FD, Bytes, Dest); return _Syscall(SYS_READ, ">i >i 2 ) + 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); } @@ -95,8 +97,8 @@ uint64_t acess_tell(int FD) { int acess_ioctl(int fd, int id, void *data) { int len; - // NOTE: 1024 byte size is a hack DEBUG("ioctl(%i, %i, %p)", fd, id, data); + // NOTE: The length here is hacky and could break if( data == NULL ) len = 0; else @@ -267,7 +269,7 @@ int acess_SysGetMessage(int *SourceTID, void *Data) int lastlen; lastlen = _Syscall(SYS_GETMSG, "