diff options
author | Yifan Lu | 2016-11-03 23:10:30 -0700 |
---|---|---|
committer | Yifan Lu | 2016-11-03 23:10:30 -0700 |
commit | 89377379e8486b1220384c969bb2897a02e3283b (patch) | |
tree | 1464f14a94111008ef6ca8d34096b3ddacc1eb5e /lib/arm/arch-transform-dis.inc.h | |
parent | Made ARM patch alignment 0x4 so copy from kernel to user works (diff) | |
download | substitute-89377379e8486b1220384c969bb2897a02e3283b.tar.gz |
Implemented call rewrite support, fixes #3
Diffstat (limited to 'lib/arm/arch-transform-dis.inc.h')
-rw-r--r-- | lib/arm/arch-transform-dis.inc.h | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/lib/arm/arch-transform-dis.inc.h b/lib/arm/arch-transform-dis.inc.h index aa56a9c..b3efc77 100644 --- a/lib/arm/arch-transform-dis.inc.h +++ b/lib/arm/arch-transform-dis.inc.h @@ -174,8 +174,16 @@ void transform_dis_branch(struct transform_dis_ctx *ctx, uint_tptr dpc, int cc) void **codep = ctx->rewritten_ptr_ptr; ctx->write_newop_here = *codep; *codep += 2; } + /* If it's a call, we should jump back after the call */ actx.cond = 0xe; - LDR_PC(actx, dpc | ctx->arch.pc_low_bit); + if ((cc & CC_CALL)) { + POPmulti(actx, 1 << 7 | 1 << 14); // save lr, r7 (for stack alignment, chosen arbitary) + ADD_PC(actx, 14, actx.thumb ? (actx.pc & 2 ? 12 : 8) | 1 : 4); + LDR_PC(actx, dpc | ctx->arch.pc_low_bit); + POPmulti(actx, 1 << 7 | 1 << 14); // restore lr, r7 (for stack alignment) + } else { + LDR_PC(actx, dpc | ctx->arch.pc_low_bit); + } } static void transform_dis_pre_dis(struct transform_dis_ctx *ctx) { |