aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorcomex2015-02-03 02:57:46 -0500
committercomex2015-02-03 02:57:46 -0500
commitef3f404f209c716bd2dc8ff5c0b559d25a2c5a92 (patch)
treeda331fb2b301d9752180e6ceb7a378c7234f21e1 /lib
parentfix ARM64 too, theoretically (diff)
downloadsubstitute-ef3f404f209c716bd2dc8ff5c0b559d25a2c5a92.tar.gz
Make the ARM branches actually go to the right place. I need automated tests before stable.
Diffstat (limited to 'lib')
-rw-r--r--lib/arm/dis-thumb.inc.h3
-rw-r--r--lib/arm/transform-dis-arm-multi.inc.h4
2 files changed, 4 insertions, 3 deletions
diff --git a/lib/arm/dis-thumb.inc.h b/lib/arm/dis-thumb.inc.h
index 8be137e..72865cf 100644
--- a/lib/arm/dis-thumb.inc.h
+++ b/lib/arm/dis-thumb.inc.h
@@ -61,7 +61,8 @@ static INLINE void P(t_cbtarget_target_B_2_tCBNZ)(tdis_ctx ctx, struct bitslice
P(branch)(ctx, ctx->pc + 4 + 2 * bs_get(target, ctx->op), CC_CBXZ);
if (TDIS_CTX_MODIFY(ctx)) {
/* change target, and flip z/nz if necessary (i.e. always) */
- unsigned new = bs_set(target, TDIS_CTX_NEWVAL(ctx, 0), ctx->op);
+ int new_target = (TDIS_CTX_NEWVAL(ctx, 0) - (ctx->pc + 4)) / 2;
+ unsigned new = bs_set(target, new_target, ctx->op);
if (TDIS_CTX_NEWVAL(ctx, 1))
new ^= 1 << 11;
TDIS_CTX_SET_NEWOP(ctx, new);
diff --git a/lib/arm/transform-dis-arm-multi.inc.h b/lib/arm/transform-dis-arm-multi.inc.h
index 1025ae0..e080866 100644
--- a/lib/arm/transform-dis-arm-multi.inc.h
+++ b/lib/arm/transform-dis-arm-multi.inc.h
@@ -159,10 +159,10 @@ static NOINLINE UNUSED void transform_dis_branch(struct transform_dis_ctx *ctx,
ctx->write_newop_here = NULL;
if ((cc & CC_ARMCC) == CC_ARMCC) {
actx.cond = invert_arm_cond(cc & 0xf);
- Bccrel(actx, 8);
+ Bccrel(actx, 2+8);
} else if ((cc & CC_CBXZ) == CC_CBXZ) {
ctx->modify = true;
- ctx->newval[0] = 2+8;
+ ctx->newval[0] = ctx->pc + 2+8;
ctx->newval[1] = 1; /* do invert */
void **codep = ctx->rewritten_ptr_ptr;
ctx->write_newop_here = *codep; *codep += 2;