From 16aaaa19a3ef4220726007d3e644ced0c9e06513 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Mon, 9 Sep 2019 01:08:34 +0200 Subject: Allow referencing code in imported file (right now for function calls, allow calling a function in another file) --- executor/x86_64/executor.c | 77 +++++++++++++++------------------------------- 1 file changed, 25 insertions(+), 52 deletions(-) (limited to 'executor/x86_64/executor.c') diff --git a/executor/x86_64/executor.c b/executor/x86_64/executor.c index 9083e14..c442da8 100644 --- a/executor/x86_64/executor.c +++ b/executor/x86_64/executor.c @@ -1,6 +1,7 @@ #include "../executor.h" #include "../../include/std/alloc.h" #include "../../include/std/buffer.h" +#include "../../include/std/log.h" #include "asm.h" #include @@ -17,11 +18,6 @@ */ #define MAX_LABELS 128 -typedef struct { - u32 asm_index; - u16 func_index; -} CallDefer; - typedef struct { u32 asm_index; u16 target_label; @@ -30,18 +26,17 @@ typedef struct { typedef struct { Asm asm; - usize *function_indices; - u16 num_functions; u16 func_counter; - Buffer/*CallDefer*/ call_defer; Buffer/*JumpDefer*/ jump_defer; u32 label_asm_index[MAX_LABELS]; int label_counter; } amal_executor_impl; +#define ASM_ENSURE_CAPACITY return_if_error(asm_ensure_capacity(&impl->asm, 256)); + #define IMPL_START \ amal_executor_impl *impl = (amal_executor_impl*)self; \ - return_if_error(asm_ensure_capacity(&impl->asm, 256)); + ASM_ENSURE_CAPACITY /* @reg will be a positive value when accessing local variables, in which case the first @@ -64,10 +59,7 @@ int amal_executor_init(amal_executor **self) { impl = (amal_executor_impl**)self; *impl = NULL; return_if_error(am_malloc(sizeof(amal_executor_impl), (void**)impl)); - (*impl)->function_indices = NULL; - (*impl)->num_functions = 0; (*impl)->func_counter = 0; - ignore_result_int(buffer_init(&(*impl)->call_defer, NULL)); ignore_result_int(buffer_init(&(*impl)->jump_defer, NULL)); (*impl)->label_counter = 0; return asm_init(&(*impl)->asm); @@ -76,8 +68,6 @@ int amal_executor_init(amal_executor **self) { void amal_executor_deinit(amal_executor *self) { amal_executor_impl *impl = (amal_executor_impl*)self; buffer_deinit(&impl->jump_defer); - buffer_deinit(&impl->call_defer); - am_free(impl->function_indices); asm_deinit(&impl->asm); am_free(impl); } @@ -93,26 +83,13 @@ u32 amal_exec_get_code_offset(amal_executor *self) { } int amal_executor_instructions_start(amal_executor *self, u16 num_functions) { - amal_executor_impl *impl = (amal_executor_impl*)self; - return_if_error(am_realloc(impl->function_indices, num_functions * sizeof(usize), (void**)&impl->function_indices)); - impl->num_functions = num_functions; + (void)self; + (void)num_functions; return 0; } int amal_executor_instructions_end(amal_executor *self) { amal_executor_impl *impl = (amal_executor_impl*)self; - CallDefer *call_defer = buffer_begin(&impl->call_defer); - CallDefer *call_defer_end = buffer_end(&impl->call_defer); - for(; call_defer != call_defer_end; ++call_defer) { - i32 func_offset; - if(call_defer->func_index >= impl->num_functions) { - amal_log_error("Program attempted to call a function that doesn't exist (index %u, while there are only %u functions)", call_defer->func_index, impl->num_functions); - return -1; - } - func_offset = (isize)impl->function_indices[call_defer->func_index] - (isize)call_defer->asm_index; - asm_override_call_rel32(&impl->asm, call_defer->asm_index, func_offset); - } - buffer_clear(&impl->call_defer); impl->func_counter = 0; return 0; } @@ -299,25 +276,16 @@ int amal_exec_pushd(amal_executor *self, BufferView data) { return 0; } -int amal_exec_call(amal_executor *self, u16 func_index, u8 num_args, i8 dst_reg) { - IMPL_START +int amal_exec_call(amal_executor *self, u32 code_offset, u8 num_args, i8 dst_reg) { + amal_executor_impl *impl = (amal_executor_impl*)self; /* TODO: Preserve necessary registers before call? */ /* TODO: This assumes all arguments are isize */ /* Do the function call */ isize asm_offset = asm_get_size(&impl->asm); - if(func_index < impl->func_counter) { - asm_call_rel32(&impl->asm, (isize)impl->function_indices[func_index] - asm_offset); - } else { - /* - The location of the function has not been defined yet. Use call instruction with dummy data and change - the location once the location to the function is known - */ - CallDefer call_defer; - call_defer.asm_index = asm_offset; - call_defer.func_index = func_index; - return_if_error(buffer_append(&impl->call_defer, &call_defer, sizeof(call_defer))); - asm_call_rel32(&impl->asm, 0); - } + ASM_ENSURE_CAPACITY + + assert(code_offset < asm_offset); + asm_call_rel32(&impl->asm, (isize)code_offset - asm_offset); /* Handle function result and cleanup */ { @@ -331,6 +299,11 @@ int amal_exec_call(amal_executor *self, u16 func_index, u8 num_args, i8 dst_reg) return 0; } +void amal_exec_call_overwrite(amal_executor *self, u32 call_code_offset, i32 new_target_rel32) { + amal_executor_impl *impl = (amal_executor_impl*)self; + asm_overwrite_call_rel32(&impl->asm, call_code_offset, new_target_rel32); +} + const Reg64 SYS_V_PARAM_REGS[] = { RDI, RSI, RDX, RCX }; /* @@ -379,9 +352,9 @@ int amal_exec_callr(i8 dst_reg, BufferView data) { */ int amal_exec_cmp(amal_executor *self, i8 dst_reg, i8 src_reg1, i8 src_reg2) { + AsmPtr dst, src1, src2; IMPL_START - AsmPtr dst, src1, src2; asm_ptr_init_disp(&dst, RBP, get_register_stack_offset(dst_reg)); asm_ptr_init_disp(&src1, RBP, get_register_stack_offset(src_reg1)); asm_ptr_init_disp(&src2, RBP, get_register_stack_offset(src_reg2)); @@ -424,8 +397,9 @@ int amal_exec_jz(amal_executor *self, i8 reg, u16 target_label) { } int amal_exec_jmp(amal_executor *self, u16 target_label) { - IMPL_START + amal_executor_impl *impl = (amal_executor_impl*)self; u32 asm_offset = asm_get_size(&impl->asm); + ASM_ENSURE_CAPACITY if(target_label < impl->label_counter) { asm_jmp(&impl->asm, (i32)impl->label_asm_index[target_label] - (i32)asm_offset); return 0; @@ -466,7 +440,6 @@ int amal_exec_func_start(amal_executor *self, u16 num_regs) { 64-bit Linux,BSD,Mac: RBX, RBP, R12-R15 */ IMPL_START - impl->function_indices[impl->func_counter++] = asm_get_size(&impl->asm); asm_pushr(&impl->asm, RBX); asm_pushr(&impl->asm, RBP); asm_mov_rr(&impl->asm, RBP, RSP); @@ -475,10 +448,10 @@ int amal_exec_func_start(amal_executor *self, u16 num_regs) { } int amal_exec_func_end(amal_executor *self) { - IMPL_START - + amal_executor_impl *impl = (amal_executor_impl*)self; JumpDefer *jump_defer = buffer_begin(&impl->jump_defer); JumpDefer *jump_defer_end = buffer_end(&impl->jump_defer); + ASM_ENSURE_CAPACITY for(; jump_defer != jump_defer_end; ++jump_defer) { i32 jump_offset; if(jump_defer->target_label >= impl->label_counter) { @@ -487,9 +460,9 @@ int amal_exec_func_end(amal_executor *self) { } jump_offset = (isize)impl->label_asm_index[jump_defer->target_label] - (isize)jump_defer->asm_index; if(jump_defer->condition) - asm_override_jcc_rel32(&impl->asm, jump_defer->asm_index, jump_offset); + asm_overwrite_jcc_rel32(&impl->asm, jump_defer->asm_index, jump_offset); else - asm_override_jmp_rel32(&impl->asm, jump_defer->asm_index, jump_offset); + asm_overwrite_jmp_rel32(&impl->asm, jump_defer->asm_index, jump_offset); } buffer_clear(&impl->jump_defer); impl->label_counter = 0; @@ -502,7 +475,7 @@ int amal_exec_func_end(amal_executor *self) { } int amal_exec_label(amal_executor *self) { - IMPL_START + amal_executor_impl *impl = (amal_executor_impl*)self; assert(impl->label_counter < MAX_LABELS); impl->label_asm_index[impl->label_counter++] = asm_get_size(&impl->asm); return 0; -- cgit v1.2.3