diff options
author | comex | 2015-03-01 23:07:15 -0500 |
---|---|---|
committer | comex | 2015-03-01 23:07:15 -0500 |
commit | 7f24621bec0b0a5b3cab9ec2dfc68929a2d49d25 (patch) | |
tree | 7c227bfa4d8010e23b726eed8efb6bc51746e3f5 /lib/arm | |
parent | seems to work (diff) | |
download | substitute-7f24621bec0b0a5b3cab9ec2dfc68929a2d49d25.tar.gz |
A number of critical fixes painstakingly discovered in the slowest way possible.
Diffstat (limited to 'lib/arm')
-rw-r--r-- | lib/arm/arch-transform-dis.inc.h | 6 | ||||
-rw-r--r-- | lib/arm/assemble.h | 3 | ||||
-rw-r--r-- | lib/arm/dis-thumb2.inc.h | 2 | ||||
-rw-r--r-- | lib/arm/jump-patch.h | 13 |
4 files changed, 15 insertions, 9 deletions
diff --git a/lib/arm/arch-transform-dis.inc.h b/lib/arm/arch-transform-dis.inc.h index 8569300..4c44913 100644 --- a/lib/arm/arch-transform-dis.inc.h +++ b/lib/arm/arch-transform-dis.inc.h @@ -12,6 +12,7 @@ static struct assemble_ctx tdctx_to_actx(const struct transform_dis_ctx *ctx) { } return (struct assemble_ctx) { ctx->rewritten_ptr_ptr, + (uint_tptr) (uintptr_t) ctx->rewritten_ptr_ptr, ctx->arch.pc_low_bit, cond }; @@ -121,7 +122,7 @@ void transform_dis_data(struct transform_dis_ctx *ctx, unsigned o0, unsigned o1, } static NOINLINE UNUSED -void transform_dis_pcrel(struct transform_dis_ctx *ctx, uintptr_t dpc, +void transform_dis_pcrel(struct transform_dis_ctx *ctx, uint_tptr dpc, struct arch_pcrel_info info) { #ifdef TRANSFORM_DIS_VERBOSE printf("transform_dis_pcrel: (0x%llx) dpc=0x%llx reg=%x mode=%d\n", @@ -149,7 +150,7 @@ void transform_dis_pcrel(struct transform_dis_ctx *ctx, uintptr_t dpc, } static NOINLINE UNUSED -void transform_dis_branch(struct transform_dis_ctx *ctx, uintptr_t dpc, int cc) { +void transform_dis_branch(struct transform_dis_ctx *ctx, uint_tptr dpc, int cc) { #ifdef TRANSFORM_DIS_VERBOSE printf("transform_dis (0x%llx): branch => 0x%llx\n", (unsigned long long) ctx->base.pc, @@ -192,6 +193,7 @@ static void transform_dis_pre_dis(struct transform_dis_ctx *ctx) { static void transform_dis_post_dis(struct transform_dis_ctx *ctx) { if (ctx->arch.bccrel_p) { struct assemble_ctx actx = {&ctx->arch.bccrel_p, + (uint_tptr) (uintptr_t) ctx->arch.bccrel_p, /*thumb*/ true, ctx->arch.bccrel_bits}; Bccrel(actx, *ctx->rewritten_ptr_ptr - ctx->arch.bccrel_p); diff --git a/lib/arm/assemble.h b/lib/arm/assemble.h index c0af020..2303a7a 100644 --- a/lib/arm/assemble.h +++ b/lib/arm/assemble.h @@ -3,6 +3,7 @@ struct assemble_ctx { void **codep; + uint_tptr pc; bool thumb; int cond; }; @@ -100,6 +101,8 @@ static inline void Bccrel(struct assemble_ctx ctx, int offset) { } static inline void LDR_PC(struct assemble_ctx ctx, uint32_t dpc) { + if (ctx.pc & 2) + op16(ctx.codep, 0xbf00); if (ctx.thumb) op32(ctx.codep, 0xf000f8df); else diff --git a/lib/arm/dis-thumb2.inc.h b/lib/arm/dis-thumb2.inc.h index 0a4c12c..b8082f3 100644 --- a/lib/arm/dis-thumb2.inc.h +++ b/lib/arm/dis-thumb2.inc.h @@ -197,7 +197,7 @@ static INLINE void P(thumb2_do_it)(tdis_ctx ctx) { static INLINE void P(dis_thumb2)(tdis_ctx ctx) { ctx->base.op = unaligned_r32(ctx->base.ptr); - ctx->base.op_size = ctx->base.newop_size = 2; + ctx->base.op_size = ctx->base.newop_size = 4; /* LLVM likes to think about Thumb2 instructions the way the ARM manual * does - 15..0 15..0 rather than 31..0 as actually laid out in memory... */ ctx->base.op = flip16(ctx->base.op); diff --git a/lib/arm/jump-patch.h b/lib/arm/jump-patch.h index b65a97d..8787070 100644 --- a/lib/arm/jump-patch.h +++ b/lib/arm/jump-patch.h @@ -2,17 +2,18 @@ #include "dis.h" #include "arm/assemble.h" #define MAX_JUMP_PATCH_SIZE 8 +#define MAX_EXTENDED_PATCH_SIZE (MAX_JUMP_PATCH_SIZE+14) -static inline int jump_patch_size(UNUSED uintptr_t pc, - UNUSED uintptr_t dpc, +static inline int jump_patch_size(uint_tptr pc, + UNUSED uint_tptr dpc, UNUSED struct arch_dis_ctx arch, UNUSED bool force) { - return 8; + return (pc & 2) ? 10 : 8; } -static inline void make_jump_patch(void **codep, UNUSED uintptr_t pc, - uintptr_t dpc, +static inline void make_jump_patch(void **codep, uint_tptr pc, + uint_tptr dpc, struct arch_dis_ctx arch) { - struct assemble_ctx actx = {codep, arch.pc_low_bit, 0xe}; + struct assemble_ctx actx = {codep, pc, arch.pc_low_bit, 0xe}; LDR_PC(actx, dpc); } |