aboutsummaryrefslogtreecommitdiff
path: root/test/test-td-simple.c
diff options
context:
space:
mode:
authorcomex2015-01-16 03:24:12 -0500
committercomex2015-01-16 04:22:55 -0500
commit8fb40a9c236e58b002e447b1c8ac124732a9dd8a (patch)
treef5f32cca52ac85eecc950e573640457696616712 /test/test-td-simple.c
parentadd a test assembly file, not used yet (diff)
downloadsubstitute-8fb40a9c236e58b002e447b1c8ac124732a9dd8a.tar.gz
jump dis - seemingly working(!)
Diffstat (limited to '')
-rw-r--r--test/test-td-simple.c49
1 files changed, 24 insertions, 25 deletions
diff --git a/test/test-td-simple.c b/test/test-td-simple.c
index 7f11423..e1524f5 100644
--- a/test/test-td-simple.c
+++ b/test/test-td-simple.c
@@ -4,18 +4,22 @@
#define IF_BOTHER_WITH_MODIFY(...) __VA_ARGS__
#include "dis.h"
-typedef struct { bool modify; } tdis_ret;
typedef struct tc {
uint32_t pc;
+ void *ptr;
uint32_t op;
uint32_t newop;
uint32_t newval[4];
-
+ bool modify;
+ int op_size;
} *tdis_ctx;
#define P(x) P_##x
+#define TDIS_CTX_MODIFY(ctx) ((ctx)->modify)
+#define TDIS_CTX_NEWVAL(ctx, n) ((ctx)->newval[n])
+#define TDIS_CTX_SET_NEWOP(ctx, new) ((ctx)->newop = (new))
NOINLINE UNUSED
-static tdis_ret P_data(struct tc *ctx, unsigned o0, unsigned o1, unsigned o2, unsigned o3, unsigned out_mask) {
+static void P_data(struct tc *ctx, unsigned o0, unsigned o1, unsigned o2, unsigned o3, unsigned out_mask) {
printf("data: %08x\n", ctx->op);
unsigned os[] = {o0, o1, o2, o3};
for(size_t i = 0; i < 4; i++) {
@@ -25,55 +29,50 @@ static tdis_ret P_data(struct tc *ctx, unsigned o0, unsigned o1, unsigned o2, un
printf(" reg %x: %s\n", val, out_mask & (1 << i) ? "out" : "in");
ctx->newval[i] = i;
}
- return (tdis_ret) {true};
+ ctx->modify = true;
}
NOINLINE UNUSED
-static tdis_ret P_pcrel(struct tc *ctx, uint32_t dpc, unsigned reg, enum pcrel_load_mode lm) {
+static void P_pcrel(struct tc *ctx, uint32_t dpc, unsigned reg, enum pcrel_load_mode lm) {
printf("adr: %08x => %08x r%u lm:%d\n", ctx->op, dpc, reg, lm);
- return (tdis_ret) {false};
+ ctx->modify = false;
}
NOINLINE UNUSED
-static tdis_ret P_ret(struct tc *ctx) {
+static void P_ret(struct tc *ctx) {
printf("ret: %08x\n", ctx->op);
- return (tdis_ret) {false};
+ ctx->modify = false;
}
NOINLINE UNUSED
-static tdis_ret P_branch(struct tc *ctx, uint32_t dpc) {
- printf("branch: %08x => %08x\n", ctx->op, dpc);
- return (tdis_ret) {false};
+static void P_branch(struct tc *ctx, uint32_t dpc, bool cond) {
+ printf("branch(%s): %08x => %08x\n", cond ? "cond" : "uncond", ctx->op, dpc);
+ ctx->modify = false;
}
NOINLINE UNUSED
-static tdis_ret P_unidentified(struct tc *ctx) {
+static void P_unidentified(struct tc *ctx) {
printf("unidentified: %08x\n", ctx->op);
- return (tdis_ret) {false};
+ ctx->modify = false;
}
NOINLINE UNUSED
-static tdis_ret P_bad(struct tc *ctx) {
+static void P_bad(struct tc *ctx) {
printf("bad: %08x\n", ctx->op);
- return (tdis_ret) {false};
+ ctx->modify = false;
}
#include HDR
-static tdis_ret P_dis(tdis_ctx ctx) {
- unsigned op = ctx->op;
- #include GENERATED_HEADER
- /* clang doesn't realize that this is unreachable and generates code like
- * "and ecx, 0x1f; cmp ecx, 0x1f; ja abort". Yeah, nice job there. */
- __builtin_abort();
-}
+#define P_(x) P(x)
int main(UNUSED int argc, char **argv) {
struct tc ctx;
ctx.pc = 0xdead0000;
- ctx.op = (uint32_t) strtoll(argv[1] ? argv[1] : "deadbeef", NULL, 16);
+ uint32_t op = strtoll(argv[1] ? argv[1] : "deadbeef", NULL, 16);
+ ctx.ptr = &op;
ctx.newop = 0;
- P_dis(&ctx);
- printf("==> %x\n", ctx.newop);
+ P_(xdis)(&ctx);
+ printf("==> %x (size=%d)\n", ctx.newop, ctx.op_size);
}