diff --git a/CMakeLists.txt b/CMakeLists.txt index 50aaa17c..5552ebf9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,6 +28,7 @@ set(GAME_FILES src/game/malloc.c src/game/memory.c src/game/init.c + src/game/process.c ) set(PORT_FILES diff --git a/extern/aurora b/extern/aurora new file mode 160000 index 00000000..6f686121 --- /dev/null +++ b/extern/aurora @@ -0,0 +1 @@ +Subproject commit 6f6861215150abc4fa00197de43754525cac07a6 diff --git a/include/dolphin/types.h b/include/dolphin/types.h index 822ec081..cd351fbb 100644 --- a/include/dolphin/types.h +++ b/include/dolphin/types.h @@ -20,6 +20,8 @@ typedef unsigned char u8; typedef unsigned short int u16; typedef unsigned long u32; typedef unsigned long long int u64; + +typedef u32 size_t; #endif typedef volatile u8 vu8; diff --git a/include/game/jmp.h b/include/game/jmp.h index a2c9c5a0..29fe0a3b 100755 --- a/include/game/jmp.h +++ b/include/game/jmp.h @@ -3,6 +3,150 @@ #ifdef TARGET_PC #include +#include + + +#define SETJMP setjmp +#define LONGJMP longjmp + +#ifndef _JMP_BUF_DEFINED +#if defined(_M_IX86) || defined(__i386__) +typedef struct __JUMP_BUFFER { + uint32_t Ebp; + uint32_t Ebx; + uint32_t Edi; + uint32_t Esi; + uint32_t Esp; + uint32_t Eip; + uint32_t Registration; + uint32_t TryLevel; + uint32_t Cookie; + uint32_t UnwindFunc; + uint32_t UnwindData[6]; +} _JUMP_BUFFER; +#elif defined(_M_X64) || defined(__x86_64__) +#ifndef SETJMP_FLOAT128 +// TODO do we need to align this? +typedef struct _SETJMP_FLOAT128 { + uint64_t Part[2]; +} SETJMP_FLOAT128; +#endif +typedef struct _JUMP_BUFFER { + uint64_t Frame; + uint64_t Rbx; + uint64_t Rsp; + uint64_t Rbp; + uint64_t Rsi; + uint64_t Rdi; + uint64_t R12; + uint64_t R13; + uint64_t R14; + uint64_t R15; + uint64_t Rip; + uint32_t MxCsr; + uint16_t FpCsr; + uint16_t Spare; + + SETJMP_FLOAT128 Xmm6; + SETJMP_FLOAT128 Xmm7; + SETJMP_FLOAT128 Xmm8; + SETJMP_FLOAT128 Xmm9; + SETJMP_FLOAT128 Xmm10; + SETJMP_FLOAT128 Xmm11; + SETJMP_FLOAT128 Xmm12; + SETJMP_FLOAT128 Xmm13; + SETJMP_FLOAT128 Xmm14; + SETJMP_FLOAT128 Xmm15; +} _JUMP_BUFFER; +#elif defined(_M_ARM) || defined(__arm__) +typedef struct _JUMP_BUFFER { + uint32_t Frame; + + uint32_t R4; + uint32_t R5; + uint32_t R6; + uint32_t R7; + uint32_t R8; + uint32_t R9; + uint32_t R10; + uint32_t R11; + + uint32_t Sp; + uint32_t Pc; + uint32_t Fpscr; + uint32_t long D[8]; // D8-D15 VFP/NEON regs +} _JUMP_BUFFER; +#elif defined(_M_ARM64) || defined(__arch64__) +typedef struct _JUMP_BUFFER { + uint64_t Frame; + uint64_t Reserved; + uint64_t X19; // x19 -- x28: callee saved registers + uint64_t X20; + uint64_t X21; + uint64_t X22; + uint64_t X23; + uint64_t X24; + uint64_t X25; + uint64_t X26; + uint64_t X27; + uint64_t X28; + uint64_t Fp; // x29 frame pointer + uint64_t Lr; // x30 link register + uint64_t Sp; // x31 stack pointer + uint32_t Fpcr; // fp control register + uint32_t Fpsr; // fp status register + + double D[8]; // D8-D15 FP regs +} _JUMP_BUFFER; +#elif defined(__riscv) +typedef struct _JUMP_BUFFER { + uint32_t ra; + uint32_t sp; + uint32_t s0; + uint32_t s1; + uint32_t s2; + uint32_t s3; + uint32_t s4; + uint32_t s5; + uint32_t s6; + uint32_t s7; + uint32_t s8; + uint32_t s9; + uint32_t s10; + uint32_t s11; + + #if __riscv_xlen == 64 + uint64_t fs0; + uint64_t fs1; + uint64_t fs2; + uint64_t fs3; + uint64_t fs4; + uint64_t fs5; + uint64_t fs6; + uint64_t fs7; + uint64_t fs8; + uint64_t fs9; + uint64_t fs10; + uint64_t fs11; + #endif +} _JUMP_BUFFER; +#endif +#endif + +#if defined(_M_IX86) || defined(__i386__) || defined(_M_X64) || defined(__x86_64__) +#define SETJMP_SET_IP(jump, func) ((_JUMP_BUFFER *)((jump)))->Eip = (size_t)func +#define SETJMP_SET_SP(jump, sp) ((_JUMP_BUFFER *)((jump)))->Esp = (size_t)sp +#elif defined(_M_ARM) || defined(__arm__) +#define SETJMP_SET_IP(jump, func) ((_JUMP_BUFFER *)((jump)))->Pc = (size_t)func +#define SETJMP_SET_SP(jump, sp) ((_JUMP_BUFFER *)((jump)))->Sp = (size_t)sp +#elif defined(_M_ARM64) || defined(__arch64__) +#define SETJMP_SET_IP(jump, func) ((_JUMP_BUFFER *)((jump)))->Lr = (size_t)func +#define SETJMP_SET_SP(jump, sp) ((_JUMP_BUFFER *)((jump)))->Sp = (size_t)sp +#elif defined(__riscv) +#define SETJMP_SET_IP(jump, func) ((_JUMP_BUFFER *)((jump)))->Lr = (size_t)func +#define SETJMP_SET_SP(jump, sp) ((_JUMP_BUFFER *)((jump)))->Sp = (size_t)sp +#endif + #else #include "dolphin.h" @@ -19,5 +163,11 @@ typedef struct jmp_buf { s32 gcsetjmp(jmp_buf *jump); s32 gclongjmp(jmp_buf *jump, s32 status); +#define SETJMP(jump) gcsetjmp(&(jump)) +#define SETJMP(jump, status) gclongjump(&(jump), (status)) + +#define SETJMP_SET_IP(jump, func) jmp_buf->lr = (u32)func +#define SETJMP_SET_IP(jump, sp) jmp_buf->sp = (u32)sp #endif + #endif diff --git a/include/game/process.h b/include/game/process.h index e51bdab7..c8b43d89 100644 --- a/include/game/process.h +++ b/include/game/process.h @@ -5,6 +5,10 @@ #include "game/jmp.h" +#ifdef TARGET_PC +#include +#endif + #define PROCESS_STAT_PAUSE 0x1 #define PROCESS_STAT_UPAUSE 0x2 #define PROCESS_STAT_PAUSE_EN 0x4 diff --git a/src/game/memory.c b/src/game/memory.c index d7c0374d..9a2cd504 100644 --- a/src/game/memory.c +++ b/src/game/memory.c @@ -31,17 +31,17 @@ void *HuMemHeapInit(void *ptr, s32 size) return block; } -void *HuMemMemoryAllocNum(void *heap_ptr, s32 size, u32 num, u32 retaddr) +void *HuMemMemoryAllocNum(void *heap_ptr, s32 size, u32 num, size_t retaddr) { return HuMemMemoryAlloc2(heap_ptr, size, num, retaddr); } -void *HuMemMemoryAlloc(void *heap_ptr, s32 size, u32 retaddr) +void *HuMemMemoryAlloc(void *heap_ptr, s32 size, size_t retaddr) { return HuMemMemoryAlloc2(heap_ptr, size, -256, retaddr); } -static void *HuMemMemoryAlloc2(void *heap_ptr, s32 size, u32 num, u32 retaddr) +static void *HuMemMemoryAlloc2(void *heap_ptr, s32 size, u32 num, size_t retaddr) { s32 alloc_size = MEM_ALLOC_SIZE(size); struct memory_block *block = heap_ptr; @@ -72,7 +72,7 @@ static void *HuMemMemoryAlloc2(void *heap_ptr, s32 size, u32 num, u32 retaddr) return NULL; } -void HuMemMemoryFreeNum(void *heap_ptr, u32 num, u32 retaddr) +void HuMemMemoryFreeNum(void *heap_ptr, u32 num, size_t retaddr) { struct memory_block *block = heap_ptr; do { @@ -90,7 +90,7 @@ static void HuMemTailMemoryAlloc2() //Required for string literal OSReport("memory allocation(tail) error.\n"); } -void HuMemMemoryFree(void *ptr, u32 retaddr) +void HuMemMemoryFree(void *ptr, size_t retaddr) { struct memory_block *block; if(!ptr) { diff --git a/src/game/process.c b/src/game/process.c index ec3e2993..e2d423ab 100644 --- a/src/game/process.c +++ b/src/game/process.c @@ -84,13 +84,10 @@ Process *HuPrcCreate(void (*func)(void), u16 prio, u32 stack_size, s32 extra_siz process->stat = 0; process->prio = prio; process->sleep_time = 0; - process->base_sp = ((u32)HuMemMemoryAlloc(heap, stack_size, FAKE_RETADDR)) + stack_size - 8; -#ifdef TARGET_PC -#else - gcsetjmp(&process->jump); - process->jump.lr = (u32)func; - process->jump.sp = process->base_sp; -#endif + process->base_sp = ((size_t)HuMemMemoryAlloc(heap, stack_size, FAKE_RETADDR)) + stack_size - 8; + SETJMP(process->jump); + SETJMP_SET_IP(process->jump, func); + SETJMP_SET_SP(process->jump, process->base_sp); process->dtor = NULL; process->user_data = NULL; LinkProcess(&processtop, process); @@ -140,12 +137,10 @@ void HuPrcChildWatch() Process *curr = HuPrcCurrentGet(); if (curr->child) { curr->exec = EXEC_CHILDWATCH; -#ifdef TARGET_PC -#else - if (gcsetjmp(&curr->jump) == 0) { - gclongjmp(&processjmpbuf, 1); + if (SETJMP(curr->jump) == 0) + { + LONGJMP(processjmpbuf, 1); } -#endif } } @@ -196,10 +191,7 @@ static void gcTerminateProcess(Process *process) } UnlinkProcess(&processtop, process); processcnt--; -#ifdef TARGET_PC -#else - gclongjmp(&processjmpbuf, 2); -#endif + longjmp(processjmpbuf, 2); } void HuPrcEnd() @@ -217,12 +209,9 @@ void HuPrcSleep(s32 time) process->exec = EXEC_SLEEP; process->sleep_time = time; } -#ifdef TARGET_PC -#else - if (gcsetjmp(&process->jump) == 0) { - gclongjmp(&processjmpbuf, 1); + if (SETJMP(process->jump) == 0) { + LONGJMP(processjmpbuf, 1); } -#endif } void HuPrcVSleep() @@ -251,15 +240,15 @@ void HuPrcCall(s32 tick) Process *process; s32 ret; processcur = processtop; -#ifdef TARGET_PC -#else - ret = gcsetjmp(&processjmpbuf); -#endif + ret = setjmp(processjmpbuf); while (1) { switch (ret) { case 2: HuMemDirectFree(processcur->heap); case 1: + #ifdef TARGET_PC + processcur = processcur->next; + #else if (((u8 *)(processcur->heap))[4] != 165) { printf("stack overlap error.(process pointer %x)\n", processcur); while (1) @@ -268,6 +257,7 @@ void HuPrcCall(s32 tick) else { processcur = processcur->next; } + #endif break; } process = processcur; @@ -305,15 +295,9 @@ void HuPrcCall(s32 tick) break; case EXEC_KILLED: -#ifdef TARGET_PC -#else - process->jump.lr = (u32)HuPrcEnd; -#endif + SETJMP_SET_IP(process->jump, HuPrcEnd); case EXEC_NORMAL: -#ifdef TARGET_PC -#else - gclongjmp(&process->jump, 1); -#endif + LONGJMP(process->jump, 1); break; } }