move GOAL stack to GOAL memory (#114)

* move GOAL code stack to GOAL memory

* fix win arg reg and check rsp in debugger

* fix windows maybe and fix some incorrect logging formatters
This commit is contained in:
water111
2020-11-06 21:42:05 -05:00
committed by GitHub
parent c09541fa98
commit 71a894c393
10 changed files with 137 additions and 19 deletions
+93
View File
@@ -133,6 +133,47 @@ _call_goal_asm_linux:
pop r13
ret
global _call_goal_on_stack_asm_linux
_call_goal_on_stack_asm_linux:
;; RDI - stack pointer
;; RSI - unused
;; RDX - unused
;; RCX - function pointer (goes in r13)
;; R8 - st (goes in r14)
;; R9 - off (goes in r15)
;; x86 saved registers we need to modify for GOAL should be saved
push r13
push r14
push r15
;; stash current stack pointer in rsi
mov rsi, rsp
;; switch to new stack
mov rsp, rdi
;; back up old stack pointer
push rsi
;; set GOAL function pointer
mov r13, rcx
;; offset
mov r14, r8
;; symbol table
mov r15, r9
;; call GOAL by function pointer
call r13
;; get old stack pointer
pop rsi
mov rsp, rsi
;; retore x86 registers.
pop r15
pop r14
pop r13
ret
;; The _call_goal_asm function is used to call a GOAL function from C.
;; It supports up to 3 arguments and a return value.
@@ -184,4 +225,56 @@ _call_goal_asm_win32:
pop rbx
pop rdx
ret
global _call_goal_on_stack_asm_win32
_call_goal_on_stack_asm_win32:
;; arg0 (rcx) stack
;; arg1 (rdx) fp
;; arg2 (r8) st
;; arg3 (r9) off
push rdx ; 8
push rbx ; 16
push rbp ; 24
push rsi ; 32
push rdi ; 40
push r8 ; 48
push r9 ; 56
push r10 ; 64
push r11 ; 72
push r12 ; 80
push r13 ; 88
push r14 ; 96
push r15 ; 104
;; stack swap
mov rsi, rsp
mov rsp, rcx
push rsi
mov r13, rdx ;; fp
mov r14, r8 ;; st
mov r15, r9 ;; offset
call r13
;; restore stack
pop rsi
mov rsp, rsi
pop r15
pop r14
pop r13
pop r12
pop r11
pop r10
pop r9
pop r8
pop rdi
pop rsi
pop rbp
pop rbx
pop rdx
ret
+8 -11
View File
@@ -136,6 +136,8 @@ s32 goal_main(int argc, const char* const* argv) {
* Main loop to dispatch the GOAL kernel.
*/
void KernelCheckAndDispatch() {
u64 goal_stack = u64(g_ee_main_mem) + EE_MAIN_MEM_SIZE - 8;
while (!MasterExit) {
// try to get a message from the listener, and process it if needed
Ptr<char> new_message = WaitForMessageAndAck();
@@ -148,20 +150,15 @@ void KernelCheckAndDispatch() {
// dispatch the kernel
//(**kernel_dispatcher)();
// todo remove. this is added while KERNEL.CGO is broken.
if (MasterUseKernel) {
call_goal(Ptr<Function>(kernel_dispatcher->value), 0, 0, 0, s7.offset, g_ee_main_mem);
// use the GOAL kernel.
call_goal_on_stack(Ptr<Function>(kernel_dispatcher->value), goal_stack, s7.offset,
g_ee_main_mem);
} else {
// use a hack to just run the listener function if there's no GOAL kernel.
if (ListenerFunction->value != s7.offset) {
// fprintf(stderr, "Running Listener Function:\n");
// auto cptr = Ptr<u8>(ListenerFunction->value).c();
// for (int i = 0; i < 40; i++) {
// fprintf(stderr, "%x ", cptr[i]);
// }
// fprintf(stderr, "\n");
auto result =
call_goal(Ptr<Function>(ListenerFunction->value), 0, 0, 0, s7.offset, g_ee_main_mem);
// fprintf(stderr, "result of listener function: %lld\n", result);
auto result = call_goal_on_stack(Ptr<Function>(ListenerFunction->value), goal_stack,
s7.offset, g_ee_main_mem);
#ifdef __linux__
cprintf("%ld\n", result);
#else
+1 -1
View File
@@ -176,7 +176,7 @@ void BeginLoadingDGO(const char* name, Ptr<u8> buffer1, Ptr<u8> buffer2, Ptr<u8>
// file name
strcpy(sMsg[msgID].name, name);
spdlog::debug("[Begin Loading DGO RPC] {}, 0x{}, 0x{}, 0x{}", name, buffer1.offset,
spdlog::debug("[Begin Loading DGO RPC] {}, 0x{:x}, 0x{:x}, 0x{:x}", name, buffer1.offset,
buffer2.offset, currentHeap.offset);
// this RPC will return once we have loaded the first object file.
// but we call async, so we don't block here.
+4 -4
View File
@@ -302,8 +302,8 @@ int InitMachine() {
// initialize the global heap
u32 global_heap_size = GLOBAL_HEAP_END - HEAP_START;
float size_mb = ((float)global_heap_size) / (float)(1 << 20);
spdlog::info("gkernel: global heap 0x{} to 0x{} (size {} MB)", HEAP_START, GLOBAL_HEAP_END,
size_mb);
spdlog::info("gkernel: global heap 0x{:08x} to 0x{:08x} (size {:.3f} MB)", HEAP_START,
GLOBAL_HEAP_END, size_mb);
kinitheap(kglobalheap, Ptr<u8>(HEAP_START), global_heap_size);
// initialize the debug heap, if appropriate
@@ -312,8 +312,8 @@ int InitMachine() {
kinitheap(kdebugheap, Ptr<u8>(DEBUG_HEAP_START), debug_heap_size);
float debug_size_mb = ((float)debug_heap_size) / (float)(1 << 20);
float gap_size_mb = ((float)DEBUG_HEAP_START - GLOBAL_HEAP_END) / (float)(1 << 20);
spdlog::info("gkernel: global heap 0x{} to 0x{} (size {} MB, gap {} MB)", DEBUG_HEAP_START,
debug_heap_end, debug_size_mb, gap_size_mb);
spdlog::info("gkernel: debug heap 0x{:08x} to 0x{:08x} (size {:.3f} MB, gap {:.3f} MB)",
DEBUG_HEAP_START, debug_heap_end, debug_size_mb, gap_size_mb);
} else {
// if no debug, we make the kheapinfo structure NULL so GOAL knows not to use it.
kdebugheap.offset = 0;
+22
View File
@@ -997,13 +997,21 @@ extern "C" {
// defined in asm_funcs.asm
#ifdef __linux__
uint64_t _call_goal_asm_linux(u64 a0, u64 a1, u64 a2, void* fptr, void* st_ptr, void* offset);
uint64_t _call_goal_on_stack_asm_linux(u64 rsp,
u64 u0,
u64 u1,
void* fptr,
void* st_ptr,
void* offset);
#elif _WIN32
uint64_t _call_goal_asm_win32(u64 a0, u64 a1, u64 a2, void* fptr, void* st_ptr, void* offset);
uint64_t _call_goal_on_stack_asm_win32(u64 rsp, void* fptr, void* st_ptr, void* offset);
#endif
}
/*!
* Wrapper around _call_goal_asm for calling a GOAL function from C.
* Calls from the parent stack.
*/
u64 call_goal(Ptr<Function> f, u64 a, u64 b, u64 c, u64 st, void* offset) {
// auto st_ptr = (void*)((uint8_t*)(offset) + st); updated for the new compiler!
@@ -1017,6 +1025,20 @@ u64 call_goal(Ptr<Function> f, u64 a, u64 b, u64 c, u64 st, void* offset) {
#endif
}
/*!
* Wrapper around _call_goal_asm_on_stack for switching stacks and calling a GOAL function there.
*/
u64 call_goal_on_stack(Ptr<Function> f, u64 rsp, u64 st, void* offset) {
void* st_ptr = (void*)st;
void* fptr = f.c();
#ifdef __linux__
return _call_goal_on_stack_asm_linux(rsp, 0, 0, fptr, st_ptr, offset);
#elif _WIN32
return _call_goal_on_stack_asm_win32(rsp, fptr, st_ptr, offset);
#endif
}
/*!
* Call a GOAL method of a given type.
*/
+1
View File
@@ -89,6 +89,7 @@ u64 inspect_pair(u32 obj);
u64 inspect_binteger(u64 obj);
s32 InitHeapAndSymbol();
u64 call_goal(Ptr<Function> f, u64 a, u64 b, u64 c, u64 st, void* offset);
u64 call_goal_on_stack(Ptr<Function> f, u64 rsp, u64 st, void* offset);
void print_symbol_table();
u64 make_string_from_c(const char* c_str);
Ptr<Symbol> find_symbol_from_c(const char* name);
+1 -1
View File
@@ -385,7 +385,7 @@ void LoadDiscID() {
for (uint32_t i = 0; i < SECTOR_SIZE / 4; i++) {
CD_ID_SectorSum += CD_ID_Sector[i];
}
spdlog::info("[OVERLORD] DISK_ID.DIZ OK 0x{}\n", CD_ID_SectorSum);
spdlog::info("[OVERLORD] DISK_ID.DIZ OK 0x{:x}\n", CD_ID_SectorSum);
}
/*!
+1 -1
View File
@@ -120,7 +120,7 @@ void ee_runner(SystemThreadInterface& iface) {
}
spdlog::debug("Main memory mapped at 0x{:016x}", (u64)(g_ee_main_mem));
spdlog::debug("Main memory size 0x{} bytes ({} MB)", EE_MAIN_MEM_SIZE,
spdlog::debug("Main memory size 0x{:x} bytes ({:.3f} MB)", EE_MAIN_MEM_SIZE,
(double)EE_MAIN_MEM_SIZE / (1 << 20));
spdlog::debug("[EE] Initialization complete!");
+1 -1
View File
@@ -70,7 +70,7 @@ s32 sceDeci2Open(u16 protocol, void* opt, void (*handler)(s32 event, s32 param,
drv.active = true;
protocols[protocol_count++] = drv;
// printf("[DECI2] Add new protocol driver %d for 0x%x\n", drv.id, drv.protocol);
spdlog::info("[DECI2] Add new protocol driver {} for 0x{}", drv.id, drv.protocol);
spdlog::info("[DECI2] Add new protocol driver {} for 0x{:x}", drv.id, drv.protocol);
server->unlock();
if (protocol_count == 1) {
+5
View File
@@ -170,6 +170,11 @@ TEST(Debugger, SimpleBreakpoint) {
// instructions can be at most 15 bytes long.
EXPECT_TRUE(rip > expected_instr_before_rip && rip < expected_instr_before_rip + 15);
// check rsp in goal code to make sure the GOAL stack is in the right space.
auto rsp = compiler.get_debugger().get_regs().gprs[emitter::RSP];
EXPECT_TRUE(rsp < compiler.get_debugger().get_x86_base_addr() + EE_MAIN_MEM_SIZE);
EXPECT_TRUE(rsp > compiler.get_debugger().get_x86_base_addr() + EE_MAIN_MEM_SIZE - (16 * 1024));
EXPECT_TRUE(compiler.get_debugger().is_halted());
compiler.get_debugger().remove_addr_breakpoint(func_addr);
compiler.get_debugger().do_continue();