aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/arm/dis-arm-multi.inc.h2
-rw-r--r--lib/arm/misc.h5
-rw-r--r--lib/arm/transform-dis-arm-multi.inc.h14
-rw-r--r--lib/jump-dis.c7
-rw-r--r--lib/jump-dis.h3
-rw-r--r--lib/transform-dis.c6
-rw-r--r--lib/transform-dis.h2
7 files changed, 21 insertions, 18 deletions
diff --git a/lib/arm/dis-arm-multi.inc.h b/lib/arm/dis-arm-multi.inc.h
index 56cde35..bf2767e 100644
--- a/lib/arm/dis-arm-multi.inc.h
+++ b/lib/arm/dis-arm-multi.inc.h
@@ -3,7 +3,7 @@
#include "dis-arm.inc.h"
static INLINE void P(dis)(tdis_ctx ctx) {
- if (ctx->pc_low_bit) {
+ if (ctx->arch.pc_low_bit) {
uint16_t op = *(uint16_t *) ctx->ptr;
bool is_32 = (op >> 13 & 7) == 7 && (op >> 11 & 3) != 0;
if (is_32)
diff --git a/lib/arm/misc.h b/lib/arm/misc.h
index 44d8e7a..047be2d 100644
--- a/lib/arm/misc.h
+++ b/lib/arm/misc.h
@@ -3,5 +3,8 @@
#define TARGET_DIS_HEADER "arm/dis-arm-multi.inc.h"
#define TARGET_TRANSFORM_DIS_HEADER "arm/transform-dis-arm-multi.inc.h"
#define MIN_INSN_SIZE 2
-struct arch_dis_ctx { unsigned thumb_it_length; };
+struct arch_dis_ctx {
+ unsigned thumb_it_length;
+ bool pc_low_bit;
+};
enum { IS_LDRD_STRD = 1 << 16 };
diff --git a/lib/arm/transform-dis-arm-multi.inc.h b/lib/arm/transform-dis-arm-multi.inc.h
index 662b501..f1b9b80 100644
--- a/lib/arm/transform-dis-arm-multi.inc.h
+++ b/lib/arm/transform-dis-arm-multi.inc.h
@@ -1,19 +1,19 @@
static inline void PUSHone(struct transform_dis_ctx *ctx, int Rt) {
- if (ctx->pc_low_bit)
+ if (ctx->arch.pc_low_bit)
op32(ctx, 0x0d04f84d | Rt << 28);
else
op32(ctx, 0xe52d0004 | Rt << 12);
}
static inline void POPone(struct transform_dis_ctx *ctx, int Rt) {
- if (ctx->pc_low_bit)
+ if (ctx->arch.pc_low_bit)
op32(ctx, 0x0b04f85d | Rt << 28);
else
op32(ctx, 0xe49d0004 | Rt << 12);
}
static inline void POPmulti(struct transform_dis_ctx *ctx, uint16_t mask) {
- if (ctx->pc_low_bit)
+ if (ctx->arch.pc_low_bit)
op32(ctx, 0x0000e8bd | mask << 16);
else
op32(ctx, 0xe8bd0000 | mask);
@@ -21,7 +21,7 @@ static inline void POPmulti(struct transform_dis_ctx *ctx, uint16_t mask) {
static inline void MOVW_MOVT(struct transform_dis_ctx *ctx, int Rd, uint32_t val) {
uint16_t hi = val >> 16, lo = (uint16_t) val;
- if (ctx->pc_low_bit) {
+ if (ctx->arch.pc_low_bit) {
op32(ctx, 0x0000f240 | Rd << 24 | lo >> 12 | (lo >> 11 & 1) << 10 |
(lo >> 8 & 7) << 28 | (lo & 0xff) << 16);
op32(ctx, 0x0000f2c0 | Rd << 24 | hi >> 12 | (hi >> 11 & 1) << 10 |
@@ -35,7 +35,7 @@ static inline void MOVW_MOVT(struct transform_dis_ctx *ctx, int Rd, uint32_t val
}
static inline void STRri(struct transform_dis_ctx *ctx, int Rt, int Rn, uint32_t off) {
- if (ctx->pc_low_bit)
+ if (ctx->arch.pc_low_bit)
op32(ctx, 0x0000f8c0 | Rn | Rt << 28 | off << 16);
else
op32(ctx, 0xe4800000 | Rn << 16 | Rt << 12 | off);
@@ -43,7 +43,7 @@ static inline void STRri(struct transform_dis_ctx *ctx, int Rt, int Rn, uint32_t
static inline void LDRxi(struct transform_dis_ctx *ctx, int Rt, int Rn, uint32_t off,
enum pcrel_load_mode load_mode) {
- if (ctx->pc_low_bit) {
+ if (ctx->arch.pc_low_bit) {
int subop, sign;
switch (load_mode) {
case PLM_U8: subop = 0; sign = 0; break;
@@ -118,7 +118,7 @@ static NOINLINE UNUSED void transform_dis_data(struct transform_dis_ctx *ctx,
}
if (out_mask & IS_LDRD_STRD)
in_regs |= 1 << (newval[0] + 1);
- uint32_t pc = ctx->pc + (ctx->pc_low_bit ? 4 : 8);
+ uint32_t pc = ctx->pc + (ctx->arch.pc_low_bit ? 4 : 8);
int scratch = __builtin_ctz(~(in_regs | (1 << out_reg)));
#ifdef TRANSFORM_DIS_VERBOSE
diff --git a/lib/jump-dis.c b/lib/jump-dis.c
index 2a4f94c..5e06460 100644
--- a/lib/jump-dis.c
+++ b/lib/jump-dis.c
@@ -25,7 +25,6 @@ struct jump_dis_ctx {
uintptr_t pc;
uintptr_t pc_patch_start;
uintptr_t pc_patch_end;
- bool pc_low_bit;
unsigned op;
const void *ptr;
int op_size;
@@ -119,15 +118,15 @@ static INLINE UNUSED void jump_dis_bad(struct jump_dis_ctx *ctx) {
static void jump_dis_dis(struct jump_dis_ctx *ctx);
-bool jump_dis_main(const void *code_ptr, uintptr_t pc_patch_start,
- uintptr_t pc_patch_end, bool pc_low_bit) {
+bool jump_dis_main(void *code_ptr, uintptr_t pc_patch_start, uintptr_t pc_patch_end,
+ struct arch_dis_ctx initial_dis_ctx) {
bool ret;
struct jump_dis_ctx ctx;
memset(&ctx, 0, sizeof(ctx));
ctx.pc_patch_start = pc_patch_start;
ctx.pc_patch_end = pc_patch_end;
- ctx.pc_low_bit = pc_low_bit;
ctx.pc = pc_patch_end;
+ ctx.arch = initial_dis_ctx;
while (1) {
ctx.bad_insn = false;
ctx.continue_after_this_insn = true;
diff --git a/lib/jump-dis.h b/lib/jump-dis.h
index c567096..575a84d 100644
--- a/lib/jump-dis.h
+++ b/lib/jump-dis.h
@@ -2,4 +2,5 @@
#include <stdint.h>
#include <stdbool.h>
-bool jump_dis_main(void *code_ptr, uintptr_t pc_patch_start, uintptr_t pc_patch_end, bool pc_low_bit);
+bool jump_dis_main(void *code_ptr, uintptr_t pc_patch_start, uintptr_t pc_patch_end,
+ struct arch_dis_ctx initial_dis_ctx);
diff --git a/lib/transform-dis.c b/lib/transform-dis.c
index 6067ea0..9edf89e 100644
--- a/lib/transform-dis.c
+++ b/lib/transform-dis.c
@@ -13,7 +13,6 @@ struct transform_dis_ctx {
bool modify;
int err;
- bool pc_low_bit;
uintptr_t pc_patch_start;
uintptr_t pc_patch_end;
uintptr_t pc;
@@ -73,13 +72,14 @@ int transform_dis_main(const void *restrict code_ptr,
void **restrict rewritten_ptr_ptr,
uintptr_t pc_patch_start,
uintptr_t pc_patch_end,
- bool pc_low_bit,
+ struct arch_dis_ctx initial_arch_ctx,
int *offset_by_pcdiff) {
struct transform_dis_ctx ctx;
+ memset(&ctx, 0, sizeof(ctx));
ctx.pc_patch_start = pc_patch_start;
ctx.pc_patch_end = pc_patch_end;
- ctx.pc_low_bit = pc_low_bit;
ctx.pc = pc_patch_start;
+ ctx.arch = initial_arch_ctx;
/* data is written to rewritten both by this function directly and, in case
* additional scaffolding is needed, by arch-specific transform_dis_* */
ctx.rewritten_ptr_ptr = rewritten_ptr_ptr;
diff --git a/lib/transform-dis.h b/lib/transform-dis.h
index 28e5d72..dec38a1 100644
--- a/lib/transform-dis.h
+++ b/lib/transform-dis.h
@@ -6,5 +6,5 @@ int transform_dis_main(const void *restrict code_ptr,
void **restrict rewritten_ptr_ptr,
uintptr_t pc_patch_start,
uintptr_t pc_patch_end,
- bool pc_low_bit,
+ struct arch_dis_ctx initial_arch_ctx,
int *offset_by_pcdiff);