aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReiko Asakura2021-02-17 10:16:20 -0500
committerReiko Asakura2021-02-17 10:16:20 -0500
commit2f285db8573f30f78a3a5a17329ae4d0ab097c86 (patch)
tree725217e0f9d1ab49d9973281c4041f34aea503dd
parentFix always_inline attribute warning (diff)
downloadsubstitute-2f285db8573f30f78a3a5a17329ae4d0ab097c86.tar.gz
Fix wrong T bit in BLX(imm)->BLX(reg) transform
-rw-r--r--lib/arm/arch-transform-dis.inc.h2
-rw-r--r--lib/arm/dis-thumb2.inc.h3
2 files changed, 3 insertions, 2 deletions
diff --git a/lib/arm/arch-transform-dis.inc.h b/lib/arm/arch-transform-dis.inc.h
index 0b4f41c..9d30738 100644
--- a/lib/arm/arch-transform-dis.inc.h
+++ b/lib/arm/arch-transform-dis.inc.h
@@ -197,7 +197,7 @@ void transform_dis_branch(struct transform_dis_ctx *ctx, uint_tptr dpc, int cc)
actx.cond = 0xe;
/* If it's a call, we should jump back after the call */
if ((cc & CC_CALL) == CC_CALL) {
- MOVW_MOVT(actx, 14, dpc | ctx->arch.pc_low_bit);
+ MOVW_MOVT(actx, 14, dpc);
BLXr(actx, 14);
} else {
// otherwise we can't clobber LR
diff --git a/lib/arm/dis-thumb2.inc.h b/lib/arm/dis-thumb2.inc.h
index 4203c01..98ba5ac 100644
--- a/lib/arm/dis-thumb2.inc.h
+++ b/lib/arm/dis-thumb2.inc.h
@@ -175,7 +175,8 @@ static INLINE void P(t_bltarget_func_1_tBL)(tdis_ctx ctx, struct bitslice func)
unsigned S = crap >> 24 & 1;
if (!S)
crap ^= (3 << 22);
- return P(branch)(ctx, ctx->base.pc + 4 + sext(crap, 25), CC_CALL);
+ /* Set Thumb bit because this call will be transformed into a BLX (reg) */
+ return P(branch)(ctx, (ctx->base.pc + 4 + sext(crap, 25)) | 1, CC_CALL);
}
static INLINE void P(t_blxtarget_func_1_tBLXi)(tdis_ctx ctx, struct bitslice func) {