diff options
author | comex | 2015-02-23 00:41:29 -0500 |
---|---|---|
committer | comex | 2015-02-23 00:54:13 -0500 |
commit | b63f1dff9dc736f7fa66f04976436f1f3fe2ac5d (patch) | |
tree | db70eb338a0107fdc70992ea2522fd03f2ecf32e /lib/x86 | |
parent | fix some i386 stuff (diff) | |
download | substitute-b63f1dff9dc736f7fa66f04976436f1f3fe2ac5d.tar.gz |
Ban calls within transform regions in threadsafe mode.
Diffstat (limited to 'lib/x86')
-rw-r--r-- | lib/x86/arch-transform-dis.inc.h | 9 | ||||
-rw-r--r-- | lib/x86/dis-main.inc.h | 9 |
2 files changed, 10 insertions, 8 deletions
diff --git a/lib/x86/arch-transform-dis.inc.h b/lib/x86/arch-transform-dis.inc.h index 56e41eb..a4be424 100644 --- a/lib/x86/arch-transform-dis.inc.h +++ b/lib/x86/arch-transform-dis.inc.h @@ -81,10 +81,7 @@ static void transform_dis_branch(struct transform_dis_ctx *ctx, uint_tptr dpc, *ctx->rewritten_ptr_ptr = code; return; } - if (dpc >= ctx->pc_patch_start && dpc < ctx->pc_patch_end) { - ctx->err = SUBSTITUTE_ERR_FUNC_BAD_INSN_AT_START; - return; - } + transform_dis_branch_top(ctx, dpc, cc); void *code = *ctx->rewritten_ptr_ptr; struct arch_dis_ctx arch; @@ -109,10 +106,8 @@ static void transform_dis_branch(struct transform_dis_ctx *ctx, uint_tptr dpc, transform_dis_ret(ctx); } else { ctx->write_newop_here = NULL; - make_jmp_or_call(&code, ctx->pc_trampoline, dpc, cc & CC_CALL); - if (!(cc & CC_CALL)) - transform_dis_ret(ctx); + make_jmp_or_call(&code, ctx->pc_trampoline, dpc, cc & CC_CALL); } *ctx->rewritten_ptr_ptr = code; } diff --git a/lib/x86/dis-main.inc.h b/lib/x86/dis-main.inc.h index 9959409..b6064e9 100644 --- a/lib/x86/dis-main.inc.h +++ b/lib/x86/dis-main.inc.h @@ -44,6 +44,7 @@ VEX last byte 1:0: {none, 66, f3, f2} #define I_JIMM_ONLY 0x80 /* imm is jump offset */ #define I_JIMM (0x80|I_JMP) #define I_BAD 0x80 +#define I_CALL 0x100 /* not really in the table */ #ifdef TARGET_x86_64 #define if64(_64, _32) _64 #else @@ -119,7 +120,7 @@ static void P(dis)(tdis_ctx ctx) { int mod, rm = 0; restart:; uint8_t byte1 = *ptr++; - uint8_t bits = onebyte_bits[byte1]; + int bits = onebyte_bits[byte1]; /* printf("b1=%x bytes=%x\n", byte1, bits); */ if ((bits & I_TYPE_MASK) == I_SPEC) { if (byte1 == 0x0f) { @@ -134,6 +135,8 @@ restart:; int subop = modrm >> 3 & 7; if (subop == 4 || subop == 5) /* JMP */ bits = I_JMP | I_MODA; + else if (subop == 2 || subop == 3) /* CALL */ + bits = I_CALL | I_MODA; else bits = I_MODA; } else { @@ -283,6 +286,8 @@ got_bits: UNUSED #ifdef TARGET_x86_64 } else if ((bits & I_MODA) == I_MODA && mod == 0 && rm == 5) { int32_t disp = *(int32_t *) (orig + modrm_off + 1); + if (bits & I_CALL) + P(indirect_call)(ctx); /* unlike ARM, we can always switch to non-pcrel without making the * instruction from scratch, so we don't have 'reg' and 'lm' */ struct arch_pcrel_info info = { @@ -319,6 +324,8 @@ got_bits: UNUSED #endif } else if ((bits & I_TYPE_MASK) == I_JMP) { P(ret)(ctx); + } else if (bits & I_CALL) { + P(indirect_call)(ctx); } else { P(unidentified)(ctx); } |