From eb93cee2a22cde812ccd6b9bd418d36185c058f5 Mon Sep 17 00:00:00 2001 From: comex Date: Sun, 8 Feb 2015 23:45:24 -0500 Subject: Refactor disassembly so x86 works, and add x86 transform-dis. This patch is a monolithic mess, because I was too lazy to do the refactor first (that would require some stash fun, since I wasn't actually sure before doing x86 transform-dis what would be needed). Anyway, the resulting code should be cleaner - less duplication. This breaks ARM/ARM64. --- lib/x86/arch-transform-dis.inc.h | 58 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 lib/x86/arch-transform-dis.inc.h (limited to 'lib/x86/arch-transform-dis.inc.h') diff --git a/lib/x86/arch-transform-dis.inc.h b/lib/x86/arch-transform-dis.inc.h new file mode 100644 index 0000000..bb86cf9 --- /dev/null +++ b/lib/x86/arch-transform-dis.inc.h @@ -0,0 +1,58 @@ +/* Pretty trivial, but in its own file to match the other architectures. */ +#include "x86/jump-patch.h" + +static void transform_dis_pcrel(struct transform_dis_ctx *ctx, uint64_t dpc, + struct arch_pcrel_info info) { + /* push %reg; mov $dpc, %reg; ; pop %reg */ + /* reg is rcx, or rax if the instruction might be using rcx. */ + int rax = info.reg == 1; + void *code = *ctx->rewritten_ptr_ptr; + /* push */ + op8(&code, rax ? 0x50 : 0x51); + /* mov */ +#ifdef TARGET_x86_64 + op8(&code, 0x48); + op8(&code, rax ? 0xb8 : 0xb9); + op64(&code, dpc); +#else + op8(&code, rax ? 0xb8 : 0xb9); + op32(&code, dpc); +#endif + ctx->write_newop_here = code; + code += ctx->base.op_size; + /* pop */ + op8(&code, rax ? 0x58 : 0x59); + *ctx->rewritten_ptr_ptr = code; + ctx->base.newop[0] = rax ? 0 : 1; + ctx->base.modify = true; +} + +static void transform_dis_branch(struct transform_dis_ctx *ctx, uint_tptr dpc, + int cc) { + if (dpc >= ctx->pc_patch_start && dpc < ctx->pc_patch_end) { + ctx->err = SUBSTITUTE_ERR_FUNC_BAD_INSN_AT_START; + return; + } + void *code = *ctx->rewritten_ptr_ptr; + + ctx->write_newop_here = code; + code += ctx->base.op_size; + + struct arch_dis_ctx arch; + uintptr_t source = (uintptr_t) code + 2; + int size = jump_patch_size(source, dpc, arch, true); + /* if not taken, jmp past the big jump - this is a bit suboptimal but not that bad */ + op8(&code, 0xeb); + op8(&code, size); + make_jump_patch(&code, source, dpc, arch); + + *ctx->rewritten_ptr_ptr = code; + ctx->base.newop[0] = 2; + ctx->base.modify = true; + + if (!cc) + transform_dis_ret(ctx); +} + +static void transform_dis_pre_dis(UNUSED struct transform_dis_ctx *ctx) {} +static void transform_dis_post_dis(UNUSED struct transform_dis_ctx *ctx) {} -- cgit v1.2.3