diff options
| author | ladevieq <ladevie.quentin@gmail.com> | 2026-07-27 22:35:43 +0200 |
|---|---|---|
| committer | ladevieq <ladevie.quentin@gmail.com> | 2026-07-27 22:35:43 +0200 |
| commit | 8067876cd3853fc5c6ea3e0cc078ea212886449d (patch) | |
| tree | 15387b79a4375c99f14e23cdd4f8eed8b7fa4653 /src/stack_walk.c | |
| parent | d8ffcc98796d308f57ae0a71d60a1033d41df364 (diff) | |
Implement function prologue unwind in stack walk code
Diffstat (limited to 'src/stack_walk.c')
| -rw-r--r-- | src/stack_walk.c | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/src/stack_walk.c b/src/stack_walk.c index a161f6f..db5f236 100644 --- a/src/stack_walk.c +++ b/src/stack_walk.c @@ -266,7 +266,7 @@ void walk_stack(void* ctx) { u64 unwind_offset = module->functions_unwind[sym_index]; u32 start = module->functions_start[sym_index]; #endif - print("%s!%s\n", module->name, name); + print("%s!%s\n", module->base_name, name); // print("rsp value is %xu\n", rsp); // print("rbp value is %xu\n", rbp); @@ -278,18 +278,19 @@ void walk_stack(void* ctx) { size_t total_size = sizeof(*u_info) + (u_info->count_of_unwind_codes - 1U) * sizeof(struct UNWIND_CODE); assert(total_size < 4096U); - // TODO: Do this once for the first function - if (start <= addr && addr < u_info->size_of_prolog) { + u64 func_start = (u64)module->base_addr + start; + u32 code_index = 0U; + // Undo prolog + if (func_start <= addr && addr < func_start + u_info->size_of_prolog) { + u32 RIP_offset = addr - func_start; // print("RIP is in prolog\n"); - } else if (1) { - // print("RIP is in epilog\n"); - // u8* byte_code = (u8*)addr; - addr = (u64)module->base_addr + start + u_info->size_of_prolog; - } else { - // print("RIP is in body\n"); + struct UNWIND_CODE* cur_code = &u_info->unwind_code[code_index]; + while (cur_code->offset_in_prolog != RIP_offset){ + cur_code = &u_info->unwind_code[++code_index]; + } } - for (u32 code_index = 0U; code_index < u_info->count_of_unwind_codes;) { + for (; code_index < u_info->count_of_unwind_codes;) { struct UNWIND_CODE* cur_code = &u_info->unwind_code[code_index]; switch (cur_code->unwind_operation_code) { case UWOP_PUSH_NONVOL: |
