diff options
author | comex | 2015-02-14 23:14:14 -0500 |
---|---|---|
committer | comex | 2015-02-14 23:41:06 -0500 |
commit | 67ebaf0d22fefa885d29c3c697fbe61956d18354 (patch) | |
tree | f9d3f5395054e8eca4292b344b03b4c97f3fa3ad /lib/transform-dis.c | |
parent | test harness (diff) | |
download | substitute-67ebaf0d22fefa885d29c3c697fbe61956d18354.tar.gz |
Trampoline fixes.
The transformed code was incorrect because it assumed the pointer it was
writing to was where the code would execute, but it was actually
'rewritten_temp'. Changed transform_dis_main to take a pc_trampoline
pointer, which also helps the test harness. However, this means that it
has to be called after the trampoline has been allocated, while before
the trampoline allocation depended on the generated size; this change
doesn't bother to use two passes or anything, but just allocates a new
code buffer if the maximum possible size isn't available - not the end
of the world, since trampoline_ptr will still only be increased by the
actual size before the next hook in the series (if any).
Diffstat (limited to 'lib/transform-dis.c')
-rw-r--r-- | lib/transform-dis.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/lib/transform-dis.c b/lib/transform-dis.c index fe7482d..75abc82 100644 --- a/lib/transform-dis.c +++ b/lib/transform-dis.c @@ -16,6 +16,7 @@ struct transform_dis_ctx { int err; struct dis_ctx_base base; + uint_tptr pc_trampoline; uint_tptr pc_patch_start; /* this is only tentative - it will be updated to include parts of * instructions poking out, and instructions forced to be transformed by IT */ @@ -68,6 +69,7 @@ int transform_dis_main(const void *restrict code_ptr, void **restrict rewritten_ptr_ptr, uint_tptr pc_patch_start, uint_tptr *pc_patch_end_p, + uint_tptr pc_trampoline, struct arch_dis_ctx *arch_ctx_p, int *offset_by_pcdiff) { struct transform_dis_ctx ctx; @@ -86,6 +88,9 @@ int transform_dis_main(const void *restrict code_ptr, ctx.base.modify = false; ctx.err = 0; ctx.base.ptr = code_ptr + (ctx.base.pc - pc_patch_start); + ctx.pc_trampoline = pc_trampoline + + (*rewritten_ptr_ptr - rewritten_start); + const void *start = ctx.base.ptr; transform_dis_pre_dis(&ctx); @@ -94,13 +99,20 @@ int transform_dis_main(const void *restrict code_ptr, transform_dis_dis(&ctx); +#ifdef TRANSFORM_DIS_VERBOSE + printf("transform_dis (0x%llx): >> op_size=%d newop_size=%d\n", + (unsigned long long) ctx.base.pc, + ctx.base.op_size, + ctx.base.newop_size); +#endif + if (ctx.err) return ctx.err; if (ctx.write_newop_here != NULL) { if (ctx.base.modify) memcpy(ctx.write_newop_here, ctx.base.newop, ctx.base.newop_size); else - memcpy(ctx.write_newop_here, ctx.base.ptr, ctx.base.op_size); + memcpy(ctx.write_newop_here, start, ctx.base.op_size); if (*rewritten_ptr_ptr == rewritten_ptr) *rewritten_ptr_ptr += ctx.base.op_size; } |