Implement setjmp on PC
This commit is contained in:
parent
39549e415e
commit
bc6dbf0254
7 changed files with 180 additions and 38 deletions
|
|
@ -28,6 +28,7 @@ set(GAME_FILES
|
||||||
src/game/malloc.c
|
src/game/malloc.c
|
||||||
src/game/memory.c
|
src/game/memory.c
|
||||||
src/game/init.c
|
src/game/init.c
|
||||||
|
src/game/process.c
|
||||||
)
|
)
|
||||||
|
|
||||||
set(PORT_FILES
|
set(PORT_FILES
|
||||||
|
|
|
||||||
1
extern/aurora
vendored
Submodule
1
extern/aurora
vendored
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 6f6861215150abc4fa00197de43754525cac07a6
|
||||||
|
|
@ -20,6 +20,8 @@ typedef unsigned char u8;
|
||||||
typedef unsigned short int u16;
|
typedef unsigned short int u16;
|
||||||
typedef unsigned long u32;
|
typedef unsigned long u32;
|
||||||
typedef unsigned long long int u64;
|
typedef unsigned long long int u64;
|
||||||
|
|
||||||
|
typedef u32 size_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef volatile u8 vu8;
|
typedef volatile u8 vu8;
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,150 @@
|
||||||
|
|
||||||
#ifdef TARGET_PC
|
#ifdef TARGET_PC
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
#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
|
#else
|
||||||
#include "dolphin.h"
|
#include "dolphin.h"
|
||||||
|
|
||||||
|
|
@ -19,5 +163,11 @@ typedef struct jmp_buf {
|
||||||
s32 gcsetjmp(jmp_buf *jump);
|
s32 gcsetjmp(jmp_buf *jump);
|
||||||
s32 gclongjmp(jmp_buf *jump, s32 status);
|
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
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,10 @@
|
||||||
|
|
||||||
#include "game/jmp.h"
|
#include "game/jmp.h"
|
||||||
|
|
||||||
|
#ifdef TARGET_PC
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define PROCESS_STAT_PAUSE 0x1
|
#define PROCESS_STAT_PAUSE 0x1
|
||||||
#define PROCESS_STAT_UPAUSE 0x2
|
#define PROCESS_STAT_UPAUSE 0x2
|
||||||
#define PROCESS_STAT_PAUSE_EN 0x4
|
#define PROCESS_STAT_PAUSE_EN 0x4
|
||||||
|
|
|
||||||
|
|
@ -31,17 +31,17 @@ void *HuMemHeapInit(void *ptr, s32 size)
|
||||||
return block;
|
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);
|
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);
|
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);
|
s32 alloc_size = MEM_ALLOC_SIZE(size);
|
||||||
struct memory_block *block = heap_ptr;
|
struct memory_block *block = heap_ptr;
|
||||||
|
|
@ -72,7 +72,7 @@ static void *HuMemMemoryAlloc2(void *heap_ptr, s32 size, u32 num, u32 retaddr)
|
||||||
return NULL;
|
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;
|
struct memory_block *block = heap_ptr;
|
||||||
do {
|
do {
|
||||||
|
|
@ -90,7 +90,7 @@ static void HuMemTailMemoryAlloc2() //Required for string literal
|
||||||
OSReport("memory allocation(tail) error.\n");
|
OSReport("memory allocation(tail) error.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void HuMemMemoryFree(void *ptr, u32 retaddr)
|
void HuMemMemoryFree(void *ptr, size_t retaddr)
|
||||||
{
|
{
|
||||||
struct memory_block *block;
|
struct memory_block *block;
|
||||||
if(!ptr) {
|
if(!ptr) {
|
||||||
|
|
|
||||||
|
|
@ -84,13 +84,10 @@ Process *HuPrcCreate(void (*func)(void), u16 prio, u32 stack_size, s32 extra_siz
|
||||||
process->stat = 0;
|
process->stat = 0;
|
||||||
process->prio = prio;
|
process->prio = prio;
|
||||||
process->sleep_time = 0;
|
process->sleep_time = 0;
|
||||||
process->base_sp = ((u32)HuMemMemoryAlloc(heap, stack_size, FAKE_RETADDR)) + stack_size - 8;
|
process->base_sp = ((size_t)HuMemMemoryAlloc(heap, stack_size, FAKE_RETADDR)) + stack_size - 8;
|
||||||
#ifdef TARGET_PC
|
SETJMP(process->jump);
|
||||||
#else
|
SETJMP_SET_IP(process->jump, func);
|
||||||
gcsetjmp(&process->jump);
|
SETJMP_SET_SP(process->jump, process->base_sp);
|
||||||
process->jump.lr = (u32)func;
|
|
||||||
process->jump.sp = process->base_sp;
|
|
||||||
#endif
|
|
||||||
process->dtor = NULL;
|
process->dtor = NULL;
|
||||||
process->user_data = NULL;
|
process->user_data = NULL;
|
||||||
LinkProcess(&processtop, process);
|
LinkProcess(&processtop, process);
|
||||||
|
|
@ -140,12 +137,10 @@ void HuPrcChildWatch()
|
||||||
Process *curr = HuPrcCurrentGet();
|
Process *curr = HuPrcCurrentGet();
|
||||||
if (curr->child) {
|
if (curr->child) {
|
||||||
curr->exec = EXEC_CHILDWATCH;
|
curr->exec = EXEC_CHILDWATCH;
|
||||||
#ifdef TARGET_PC
|
if (SETJMP(curr->jump) == 0)
|
||||||
#else
|
{
|
||||||
if (gcsetjmp(&curr->jump) == 0) {
|
LONGJMP(processjmpbuf, 1);
|
||||||
gclongjmp(&processjmpbuf, 1);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -196,10 +191,7 @@ static void gcTerminateProcess(Process *process)
|
||||||
}
|
}
|
||||||
UnlinkProcess(&processtop, process);
|
UnlinkProcess(&processtop, process);
|
||||||
processcnt--;
|
processcnt--;
|
||||||
#ifdef TARGET_PC
|
longjmp(processjmpbuf, 2);
|
||||||
#else
|
|
||||||
gclongjmp(&processjmpbuf, 2);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HuPrcEnd()
|
void HuPrcEnd()
|
||||||
|
|
@ -217,12 +209,9 @@ void HuPrcSleep(s32 time)
|
||||||
process->exec = EXEC_SLEEP;
|
process->exec = EXEC_SLEEP;
|
||||||
process->sleep_time = time;
|
process->sleep_time = time;
|
||||||
}
|
}
|
||||||
#ifdef TARGET_PC
|
if (SETJMP(process->jump) == 0) {
|
||||||
#else
|
LONGJMP(processjmpbuf, 1);
|
||||||
if (gcsetjmp(&process->jump) == 0) {
|
|
||||||
gclongjmp(&processjmpbuf, 1);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HuPrcVSleep()
|
void HuPrcVSleep()
|
||||||
|
|
@ -251,15 +240,15 @@ void HuPrcCall(s32 tick)
|
||||||
Process *process;
|
Process *process;
|
||||||
s32 ret;
|
s32 ret;
|
||||||
processcur = processtop;
|
processcur = processtop;
|
||||||
#ifdef TARGET_PC
|
ret = setjmp(processjmpbuf);
|
||||||
#else
|
|
||||||
ret = gcsetjmp(&processjmpbuf);
|
|
||||||
#endif
|
|
||||||
while (1) {
|
while (1) {
|
||||||
switch (ret) {
|
switch (ret) {
|
||||||
case 2:
|
case 2:
|
||||||
HuMemDirectFree(processcur->heap);
|
HuMemDirectFree(processcur->heap);
|
||||||
case 1:
|
case 1:
|
||||||
|
#ifdef TARGET_PC
|
||||||
|
processcur = processcur->next;
|
||||||
|
#else
|
||||||
if (((u8 *)(processcur->heap))[4] != 165) {
|
if (((u8 *)(processcur->heap))[4] != 165) {
|
||||||
printf("stack overlap error.(process pointer %x)\n", processcur);
|
printf("stack overlap error.(process pointer %x)\n", processcur);
|
||||||
while (1)
|
while (1)
|
||||||
|
|
@ -268,6 +257,7 @@ void HuPrcCall(s32 tick)
|
||||||
else {
|
else {
|
||||||
processcur = processcur->next;
|
processcur = processcur->next;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
process = processcur;
|
process = processcur;
|
||||||
|
|
@ -305,15 +295,9 @@ void HuPrcCall(s32 tick)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EXEC_KILLED:
|
case EXEC_KILLED:
|
||||||
#ifdef TARGET_PC
|
SETJMP_SET_IP(process->jump, HuPrcEnd);
|
||||||
#else
|
|
||||||
process->jump.lr = (u32)HuPrcEnd;
|
|
||||||
#endif
|
|
||||||
case EXEC_NORMAL:
|
case EXEC_NORMAL:
|
||||||
#ifdef TARGET_PC
|
LONGJMP(process->jump, 1);
|
||||||
#else
|
|
||||||
gclongjmp(&process->jump, 1);
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue