diff options
author | Yifan Lu | 2016-10-08 22:41:57 -0700 |
---|---|---|
committer | Yifan Lu | 2016-10-08 22:44:43 -0700 |
commit | abf235858588a5943cd9f532a5f1757e2baab80b (patch) | |
tree | 96640eefa1c3494f85cff520e49dc6c5c46d9905 /lib/hook-functions.c | |
parent | Added support for platform specific aux data to execmem (diff) | |
download | substitute-abf235858588a5943cd9f532a5f1757e2baab80b.tar.gz |
Added slab allocator for trampoline in Vita platform
Added support for smaller (non-page) allocations for trampoline
Diffstat (limited to 'lib/hook-functions.c')
-rw-r--r-- | lib/hook-functions.c | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/lib/hook-functions.c b/lib/hook-functions.c index 996e781..11fa9ac 100644 --- a/lib/hook-functions.c +++ b/lib/hook-functions.c @@ -19,6 +19,7 @@ struct hook_internal { /* page allocated with execmem_alloc_unsealed - only if we had to allocate * one when processing this hook */ void *trampoline_page; + uintptr_t trampoline_addr; struct arch_dis_ctx arch_dis_ctx; }; @@ -72,6 +73,7 @@ static int check_intro_trampoline(void **trampoline_ptr_p, int *patch_size_p, bool *need_intro_trampoline_p, void **trampoline_page_p, + uintptr_t *trampoline_page_addr_p, struct arch_dis_ctx arch, void *opt) { void *trampoline_ptr = *trampoline_ptr_p; @@ -107,7 +109,7 @@ static int check_intro_trampoline(void **trampoline_ptr_p, goto end; } - execmem_free(trampoline_ptr, opt); + execmem_free(trampoline_ptr, trampoline_addr, opt); } /* Allocate new trampoline - try before pc (xxx only meaningful on arm64) */ @@ -121,7 +123,7 @@ static int check_intro_trampoline(void **trampoline_ptr_p, goto end; } - execmem_free(trampoline_ptr, opt); + execmem_free(trampoline_ptr, trampoline_addr, opt); ret = SUBSTITUTE_ERR_OUT_OF_RANGE; } @@ -130,6 +132,7 @@ end: *trampoline_addr_p = trampoline_addr; *trampoline_size_left_p = trampoline_size_left; *trampoline_page_p = trampoline_ptr; + *trampoline_page_addr_p = trampoline_addr; return ret; } @@ -191,7 +194,8 @@ int substitute_hook_functions(const struct substitute_function_hook *hooks, &trampoline_size_left, pc_patch_start, (uintptr_t) hook->replacement, &patch_size, &need_intro_trampoline, - &hi->trampoline_page, arch, + &hi->trampoline_page, + &hi->trampoline_addr, arch, hook->opt))) goto end; @@ -222,10 +226,13 @@ int substitute_hook_functions(const struct substitute_function_hook *hooks, &trampoline_size_left, hook->opt))) goto end; - /* NOTE: We assume that each page is large enough (min 0x1000) - * so we don't lose a reference by having one hook allocate two - * pages. */ + /* NOTE: We assume that each page is large enough (min + * TD_MAX_REWRITTEN_SIZE + 2 * MAX_JUMP_PATCH_SIZE) so we don't lose + * a reference by having one hook allocate two pages. Also must + * ensure this size is aligned to ARCH_MAX_CODE_ALIGNMENT otherwise + * MAX_JUMP_PATCH_SIZE might be wrong. */ hi->trampoline_page = trampoline_ptr; + hi->trampoline_addr = trampoline_addr; } void *outro_trampoline_real = trampoline_ptr; @@ -275,8 +282,9 @@ int substitute_hook_functions(const struct substitute_function_hook *hooks, for (size_t i = 0; i < nhooks; i++) { struct hook_internal *hi = &his[i]; void *page = hi->trampoline_page; + uintptr_t addr = hi->trampoline_addr; if (page) - execmem_seal(page, hooks[i].opt); + execmem_seal(page, addr, hooks[i].opt); fws[i].dst = hi->code; fws[i].src = hi->jump_patch; fws[i].len = hi->jump_patch_size; @@ -299,8 +307,9 @@ end: /* if we failed, get rid of the trampolines. */ for (size_t i = 0; i < nhooks; i++) { void *page = his[i].trampoline_page; + uintptr_t addr = his[i].trampoline_addr; if (page) - execmem_free(page, hooks[i].opt); + execmem_free(page, addr, hooks[i].opt); } end_dont_free: return ret; |