aboutsummaryrefslogtreecommitdiff
path: root/lib/x86
diff options
context:
space:
mode:
Diffstat (limited to 'lib/x86')
-rw-r--r--lib/x86/arch-transform-dis.inc.h9
-rw-r--r--lib/x86/dis-main.inc.h9
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);
}