aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile18
-rw-r--r--lib/dis.h14
-rw-r--r--lib/jump-dis-arm-multi.c6
-rw-r--r--lib/jump-dis.c (renamed from lib/jump-dis.inc.h)32
-rw-r--r--lib/jump-dis.h5
-rw-r--r--lib/substitute-internal.h25
-rw-r--r--test/test-jump-dis.c2
7 files changed, 75 insertions, 27 deletions
diff --git a/Makefile b/Makefile
index 2318f7d..6c13837 100644
--- a/Makefile
+++ b/Makefile
@@ -30,7 +30,7 @@ out/%.o: lib/%.c Makefile $(HEADERS)
$(CC) -fvisibility=hidden -std=c11 -c -o $@ $<
out/%.o: lib/%.S Makefile $(HEADERS)
$(CC) -fvisibility=hidden -c -o $@ $<
-out/jump-dis-arm-multi.o: generated/generic-dis-arm.inc.h generated/generic-dis-thumb.inc.h generated/generic-dis-thumb2.inc.h
+out/jump-dis.o: $(GENERATED)
LIB_OBJS := \
out/find-syms.o \
@@ -38,7 +38,7 @@ LIB_OBJS := \
out/objc.o \
out/objc-asm.o \
out/substrate-compat.o \
- out/jump-dis-arm-multi.o
+ out/jump-dis.o
out/libsubstitute.dylib: $(LIB_OBJS)
$(CC) -o $@ $(LIB_OBJS) $(LIB_LDFLAGS)
@@ -47,15 +47,17 @@ out/test-$(1): test/test-$(2).[cm]* $(HEADERS) $(GENERATED) Makefile out/libsubs
$(3) -g -o $$@ $$< -Ilib -Isubstrate -Lout -lsubstitute
all: out/test-$(1)
endef
-$(eval $(call define_test,tdarm-simple,td-simple,$(CC) -std=c11 -DHDR='"dis-arm.inc.h"' -Dxdis=dis_arm))
-$(eval $(call define_test,tdthumb-simple,td-simple,$(CC) -std=c11 -DHDR='"dis-thumb.inc.h"' -Dxdis=dis_thumb))
-$(eval $(call define_test,tdthumb2-simple,td-simple,$(CC) -std=c11 -DHDR='"dis-thumb2.inc.h"' -Dxdis=dis_thumb2))
-$(eval $(call define_test,tdarm64-simple,td-simple,$(CC) -std=c11 -DHDR='"dis-arm64.inc.h"' -Dxdis=dis))
-$(eval $(call define_test,dis,dis,$(CC) -std=c11))
+$(eval $(call define_test,tdarm-simple,td-simple,$(CC) -std=c11 -DHDR='"dis-arm.inc.h"' -Dxdis=dis_arm -DFORCE_TARGET_arm))
+$(eval $(call define_test,tdthumb-simple,td-simple,$(CC) -std=c11 -DHDR='"dis-thumb.inc.h"' -Dxdis=dis_thumb -DFORCE_TARGET_arm))
+$(eval $(call define_test,tdthumb2-simple,td-simple,$(CC) -std=c11 -DHDR='"dis-thumb2.inc.h"' -Dxdis=dis_thumb2 -DFORCE_TARGET_arm))
+$(eval $(call define_test,tdarm64-simple,td-simple,$(CC) -std=c11 -DHDR='"dis-arm64.inc.h"' -Dxdis=dis -DFORCE_TARGET_arm64))
+$(eval $(call define_test,dis-arm,dis,$(CC) -std=c11 -DFORCE_TARGET_arm))
+$(eval $(call define_test,dis-arm64,dis,$(CC) -std=c11 -DFORCE_TARGET_arm64))
+$(eval $(call define_test,jump-dis-arm,jump-dis,$(CC) -std=c11 -DFORCE_TARGET_arm))
+$(eval $(call define_test,jump-dis-arm64,jump-dis,$(CC) -std=c11 -DFORCE_TARGET_arm64))
$(eval $(call define_test,find-syms,find-syms,$(CC) -std=c89))
$(eval $(call define_test,find-syms-cpp,find-syms,$(CXX) -x c++ -std=c++98))
$(eval $(call define_test,substrate,substrate,$(CXX) -std=c++98))
-$(eval $(call define_test,jump-dis,jump-dis,$(CC) -std=c11))
$(eval $(call define_test,imp-forwarding,imp-forwarding,$(CC) -std=c11 -framework Foundation -lobjc))
$(eval $(call define_test,objc-hook,objc-hook,$(CC) -std=c11 -framework Foundation -lsubstitute))
$(eval $(call define_test,interpose,interpose,$(CC) -std=c11 -lsubstitute))
diff --git a/lib/dis.h b/lib/dis.h
index 5a26d84..5a49723 100644
--- a/lib/dis.h
+++ b/lib/dis.h
@@ -104,3 +104,17 @@ static const unsigned null_op = -0x100;
return; \
} while (0)
+#if defined(TARGET_x86_64)
+ #define MIN_INSN_SIZE 1
+ #error "no x86 dis yet"
+#elif defined(TARGET_i386)
+ #define MIN_INSN_SIZE 1
+ #error "no x86 dis yet"
+#elif defined(TARGET_arm)
+ #define MIN_INSN_SIZE 2
+ #define TARGET_DIS_HEADER "dis-arm-multi.inc.h"
+#elif defined(TARGET_arm64)
+ #define MIN_INSN_SIZE 4
+ #define TARGET_DIS_HEADER "dis-arm64.inc.h"
+#endif
+
diff --git a/lib/jump-dis-arm-multi.c b/lib/jump-dis-arm-multi.c
deleted file mode 100644
index b5967f5..0000000
--- a/lib/jump-dis-arm-multi.c
+++ /dev/null
@@ -1,6 +0,0 @@
-enum {
- MIN_INSN_SIZE = 2
-};
-#define P(x) jump_dis_##x
-#include "jump-dis.inc.h"
-#include "dis-arm-multi.inc.h"
diff --git a/lib/jump-dis.inc.h b/lib/jump-dis.c
index a070a74..c7c7346 100644
--- a/lib/jump-dis.inc.h
+++ b/lib/jump-dis.c
@@ -1,3 +1,5 @@
+#include "substitute-internal.h"
+#ifndef TARGET_UNSUPPORTED
#include "dis.h"
#include <stdint.h>
#include <stdbool.h>
@@ -36,12 +38,15 @@ struct jump_dis_ctx {
size_t queue_count;
};
+#undef P
+#define P(x) jump_dis_##x
+
#define tdis_ctx struct jump_dis_ctx *
#define TDIS_CTX_MODIFY(ctx) 0
#define TDIS_CTX_NEWVAL(ctx, n) 0
#define TDIS_CTX_SET_NEWOP(ctx, new) ((void) 0)
-static void P(add_to_queue)(struct jump_dis_ctx *ctx, uintptr_t pc) {
+static void jump_dis_add_to_queue(struct jump_dis_ctx *ctx, uintptr_t pc) {
size_t diff = (pc - ctx->pc_patch_start) / MIN_INSN_SIZE;
if (diff >= JUMP_ANALYSIS_MAX_INSNS) {
#ifdef JUMP_DIS_VERBOSE
@@ -73,21 +78,21 @@ static void P(add_to_queue)(struct jump_dis_ctx *ctx, uintptr_t pc) {
}
-static INLINE inline void P(data)(UNUSED struct jump_dis_ctx *ctx, UNUSED unsigned o0, UNUSED unsigned o1, UNUSED unsigned o2, UNUSED unsigned o3, UNUSED unsigned out_mask) {
+static INLINE inline void jump_dis_data(UNUSED struct jump_dis_ctx *ctx, UNUSED unsigned o0, UNUSED unsigned o1, UNUSED unsigned o2, UNUSED unsigned o3, UNUSED unsigned out_mask) {
/* on ARM, ignore mov PC jumps, as they're unlikely to be in the same function */
}
-static INLINE inline void P(pcrel)(struct jump_dis_ctx *ctx, uintptr_t dpc, UNUSED unsigned reg, UNUSED bool is_load) {
+static INLINE inline void jump_dis_pcrel(struct jump_dis_ctx *ctx, uintptr_t dpc, UNUSED unsigned reg, UNUSED bool is_load) {
ctx->bad_insn = dpc >= ctx->pc_patch_start && dpc < ctx->pc_patch_end;
}
NOINLINE UNUSED
-static void P(ret)(struct jump_dis_ctx *ctx) {
+static void jump_dis_ret(struct jump_dis_ctx *ctx) {
ctx->continue_after_this_insn = false;
}
NOINLINE UNUSED
-static void P(branch)(struct jump_dis_ctx *ctx, uintptr_t dpc, bool conditional) {
+static void jump_dis_branch(struct jump_dis_ctx *ctx, uintptr_t dpc, bool conditional) {
if (dpc >= ctx->pc_patch_start && dpc < ctx->pc_patch_end) {
ctx->bad_insn = true;
return;
@@ -95,22 +100,22 @@ static void P(branch)(struct jump_dis_ctx *ctx, uintptr_t dpc, bool conditional)
#ifdef JUMP_DIS_VERBOSE
printf("jump-dis: enqueueing %llx\n", (unsigned long long) dpc);
#endif
- P(add_to_queue)(ctx, dpc);
+ jump_dis_add_to_queue(ctx, dpc);
ctx->continue_after_this_insn = conditional;
}
NOINLINE UNUSED
-static void P(unidentified)(UNUSED struct jump_dis_ctx *ctx) {
+static void jump_dis_unidentified(UNUSED struct jump_dis_ctx *ctx) {
}
NOINLINE UNUSED
-static void P(bad)(struct jump_dis_ctx *ctx) {
+static void jump_dis_bad(struct jump_dis_ctx *ctx) {
ctx->continue_after_this_insn = false;
}
-static void P(dis)(tdis_ctx ctx);
+static void jump_dis_dis(tdis_ctx ctx);
-bool P(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, bool pc_low_bit) {
bool ret;
struct jump_dis_ctx ctx;
memset(&ctx, 0, sizeof(ctx));
@@ -122,7 +127,7 @@ bool P(main)(void *code_ptr, uintptr_t pc_patch_start, uintptr_t pc_patch_end, b
ctx.bad_insn = false;
ctx.continue_after_this_insn = true;
ctx.ptr = code_ptr + (ctx.pc - pc_patch_start);
- P(dis)(&ctx);
+ jump_dis_dis(&ctx);
#ifdef JUMP_DIS_VERBOSE
printf("jump-dis: pc=%llx op=%08x size=%x bad=%d continue_after=%d\n",
(unsigned long long) ctx.pc,
@@ -136,7 +141,7 @@ bool P(main)(void *code_ptr, uintptr_t pc_patch_start, uintptr_t pc_patch_end, b
goto fail;
}
if (ctx.continue_after_this_insn)
- P(add_to_queue)(&ctx, ctx.pc + ctx.op_size);
+ jump_dis_add_to_queue(&ctx, ctx.pc + ctx.op_size);
/* get next address */
if (ctx.queue_read_off == ctx.queue_write_off)
@@ -151,3 +156,6 @@ fail:
free(ctx.queue);
return ret;
}
+
+#include TARGET_DIS_HEADER
+#endif /* TARGET_UNSUPPORTED */
diff --git a/lib/jump-dis.h b/lib/jump-dis.h
new file mode 100644
index 0000000..c567096
--- /dev/null
+++ b/lib/jump-dis.h
@@ -0,0 +1,5 @@
+#pragma once
+#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);
diff --git a/lib/substitute-internal.h b/lib/substitute-internal.h
index 2550d2a..cf50a99 100644
--- a/lib/substitute-internal.h
+++ b/lib/substitute-internal.h
@@ -26,3 +26,28 @@ typedef struct section section_x;
#define LC_SEGMENT_X LC_SEGMENT
#endif
#endif
+
+/* FORCE_* are for tests */
+#if defined(FORCE_TARGET_x86_64)
+ #define TARGET_x86_64
+#elif defined(FORCE_TARGET_i386)
+ #define TARGET_i386
+ #define TARGET_UNSUPPORTED
+#elif defined(FORCE_TARGET_arm)
+ #define TARGET_arm
+#elif defined(FORCE_TARGET_arm64)
+ #define TARGET_arm64
+#elif defined(__x86_64__)
+ #define TARGET_x86_64
+#elif defined(__i386__)
+ #define TARGET_i386
+#elif defined(__arm__)
+ #define TARGET_arm
+#elif defined(__arm64__)
+ #define TARGET_arm64
+#else
+ #error target?
+#endif
+#if defined(TARGET_x86_64) || defined(TARGET_i386)
+ #define TARGET_UNSUPPORTED
+#endif
diff --git a/test/test-jump-dis.c b/test/test-jump-dis.c
index 161c80c..1afa4e5 100644
--- a/test/test-jump-dis.c
+++ b/test/test-jump-dis.c
@@ -1,6 +1,6 @@
#define JUMP_DIS_VERBOSE
#include <stdio.h>
-#include "jump-dis-arm-multi.c"
+#include "jump-dis.c"
#include <stdlib.h>
int main(UNUSED int argc, char **argv) {
static char buf[1048576];