Commit 5b9f3445 authored by Lovis J.I. Zenz's avatar Lovis J.I. Zenz
Browse files

added arm7 tester draft; adapted arm7 decoder and translator, extended...

added arm7 tester draft; adapted arm7 decoder and translator, extended rreil_id in libs/cgdsl, and adapted Makefile structure accordingly; renamed arm.mk arm7.mk and adapted Makefile_arm7 accordingly
parent 0bc3c1ec
Pipeline #1806 passed with stage
in 2 minutes and 46 seconds
......@@ -5,7 +5,7 @@ MLTONFLAGS=
CFLAGS=-g3 -fPIC -Wall -Iinclude
LFLAGS=-shared
include arm.mk
include arm7.mk
#GDSL=gdsl
GDSL_MEX=_manual
......@@ -16,16 +16,16 @@ GDSLFLAGS=--maxIter=42
GDSL_BASIS_HL=specifications/basis/prelude.ml specifications/basis/bbtree.ml
GDSL_RREIL_HL = \
specifications/rreil/fmap.ml \
specifications/rreil/rreil.ml \
specifications/rreil/rreil-cleanup.ml \
specifications/rreil/rreil-cif.ml \
specifications/rreil/rreil-examples.ml \
specifications/rreil/rreil-forward-subst.ml \
specifications/rreil/rreil-liveness.ml \
specifications/rreil/rreil-opt.ml \
specifications/rreil/rreil-cif.ml \
specifications/rreil/rreil-pretty.ml \
specifications/rreil/rreil-translator.ml \
specifications/rreil/fmap.ml \
specifications/rreil/rreil-opt.ml \
specifications/rreil/rreil-translator.ml
GDSL_OPT_HL = \
specifications/rreil/rreil-liveness.ml \
specifications/rreil/rreil-forward-subst.ml \
specifications/rreil/forward-subst/delayed-forward-subst/inline.ml \
specifications/rreil/forward-subst/delayed-forward-subst/substitute.ml \
specifications/rreil/forward-subst/delayed-forward-subst/substmap.ml \
......@@ -33,15 +33,17 @@ GDSL_RREIL_HL = \
specifications/rreil/forward-subst/forward-subst/substitute.ml \
specifications/rreil/forward-subst/forward-subst/substmap.ml \
specifications/rreil/forward-subst/forward-subst/simplify-expressions.ml \
specifications/rreil/fusion/fusion.ml
specifications/rreil/fusion/fusion.ml \
specifications/rreil/rreil-cleanup.ml
GDSL_ARM7_HL=specifications/arm7/arm7.ml specifications/arm7/arm7-pretty.ml specifications/arm7/arm7-asm.ml
GDSL_ARM7_TRANS_HL=specifications/arm7/arm7-rreil-registermapping.ml specifications/arm7/arm7-rreil-translator.ml
GDSL_ARM7_OPT_HL=specifications/arm7/arm7-liveness.ml
GDSL_ARM7_TEST_HL=specifications/arm7/arm7-rreil-pretty.ml
GDSL_ASM_HL=specifications/asm/asm.ml specifications/asm/asm-pretty.ml specifications/asm/asm-cif.ml
GDSL_ARM7_HL=specifications/arm7/arm7.ml specifications/arm7/arm7-pretty.ml specifications/arm7/arm7-asm.ml
GDSL_ARM7_TRANS_HL=specifications/arm7/arm7-rreil-registermapping.ml specifications/arm7/arm7-rreil-translator.ml specifications/arm7/arm7-rreil-pretty.ml specifications/arm7/arm7-liveness.ml
GDSL_SOURCES=$(GDSL_BASIS_HL) $(GDSL_RREIL_HL) $(GDSL_ASM_HL) $(GDSL_ARM7_HL) $(GDSL_ARM7_TRANS_HL) $(GDSL_OPT_HL)
GDSL_SOURCES=$(GDSL_BASIS_HL) $(GDSL_RREIL_HL) $(GDSL_ARM7_HL) $(GDSL_ARM7_TRANS_HL) $(GDSL_OPT_HL) $(GDSL_ARM7_OPT_HL) $(GDSL_ARM7_TEST_HL) $(GDSL_ASM_HL)
.PHONY: libs tools
......@@ -65,6 +67,6 @@ libs: lib$(GDSL).so
$(MAKE) -C $@/
clean:
$(MAKE) -C libs/ clean
$(MAKE) -C libs/ clean
$(MAKE) -C tools/ clean
rm -f $(GDSL_EXEC) $(GDSL).o $(GDSL_COMP).c $(GDSL_COMP).h lib$(GDSL).so
export GDSL_ARCH=arm7
\ No newline at end of file
......@@ -9,6 +9,10 @@ ifeq ($(GDSL_ARCH),x86)
LIBS+=x86 x86-tester x86-generator
endif
ifeq ($(GDSL_ARCH),arm7)
LIBS+=arm7 arm7-tester
endif
.PHONY all: $(LIBS)
$(LIBS):
......
MLTK=../..
CC=gcc
#CC=clang
INCDS=-Iinclude -I$(MLTK)/include
DEFINES=-DGDSL_ARM7
CFLAGS=-c -g3 -std=c11 -pedantic -Wall -Wfatal-errors $(DEFINES) $(INCDS)
LIBRARY=libarm7-rreil-sim.a
SOURCES=memory.c context.c simulator/ops.c simulator/regacc.c simulator/simulator.c simulator/tracking.c
all: pre-build $(LIBRARY)
SPRE=src
BPRE=build
BDIRS=$(BPRE) $(BPRE)/simulator
pre-build:
mkdir -p $(BDIRS)
OBJECTS=$(addprefix $(BPRE)/, $(SOURCES:.c=.o))
$(LIBRARY): $(OBJECTS)
ar -r $@ $(OBJECTS)
$(OBJECTS): $(BPRE)/%.o : $(SPRE)/%.c
$(CC) $(CFLAGS) $< -o $@
clean:
rm -rf $(BDIRS) $(LIBRARY)
/*
* context.h
*
* Created on: 07.02.2019
* Author: zenzl
* Based on: ../../rreil-sim/include/context.h by jucs
*/
#ifndef CONTEXT_H_
#define CONTEXT_H_
#include <stdlib.h>
#include <stdint.h>
#include <simulator/tracking.h>
#include <simulator/register.h>
struct data {
uint8_t *data;
uint8_t *defined;
size_t bit_length;
};
enum memory_allocation_type {
MEMORY_ALLOCATION_TYPE_ACCESS, MEMORY_ALLOCATION_TYPE_JUMP
};
struct memory_allocation {
enum memory_allocation_type type;
uint8_t *data;
size_t data_size;
void *address;
};
typedef void (context_load_t)(void *, uint8_t **, uint8_t *, uint64_t, uint64_t);
typedef void (context_store_t)(void *, uint8_t *, uint8_t *, uint64_t, uint64_t);
typedef void (context_jump_t)(void *, uint8_t *, uint64_t);
struct context {
struct register_ *shared_registers;
struct register_ *arm7_registers;
struct register_ *temporary_registers;
struct {
struct memory_allocation *allocations;
size_t allocations_length;
size_t allocations_size;
context_load_t *load;
context_store_t *store;
context_jump_t *jump;
void *closure;
} memory;
};
extern struct memory_allocation *memory_allocation_init(void *address);
extern struct context *context_init(context_load_t *load,
context_store_t *store, context_jump_t *jump, void *closure);
extern void context_data_define(struct data *data);
extern void context_data_undefine(struct data *data);
extern void context_data_clear(struct data *data);
extern struct context *context_copy(struct context *source);
extern void context_free(struct context *context);
extern void context_arm7_print(struct context *context);
extern char context_compare_print(struct tracking_trace *trace,
struct context *context_cpu, struct context *context_rreil,
char test_unused);
#endif /* CONTEXT_H_ */
\ No newline at end of file
/*
* memory.h
*
* Created on: 07.02.2019
* Author: zenzl
* Based on: ../../rreil-sim/include/memory.h by jucs
*/
#ifndef MEMORY_H_
#define MEMORY_H_
#include <stdlib.h>
#include <stdint.h>
#include <context.h>
extern void *memory_ptr_get(uint8_t *address, uint64_t address_size);
extern void memory_load(struct context *context, uint8_t **buffer,
uint8_t *address, uint64_t address_size, uint64_t access_size,
uint8_t *source);
extern void memory_store(struct context *context, uint8_t *buffer,
uint8_t *address, uint64_t address_size, uint64_t access_size);
extern void memory_jump(struct context *context, uint8_t *address,
uint64_t address_size);
#endif /* MEMORY_H_ */
/*
* simulator_ops.h
*
* Created on: 07.02.2019
* Author: zenzl
* Based on: ../../../rreil-sim/include/simulatr/ops.h by jucs
*/
#ifndef SIMULATOR_OPS_H_
#define SIMULATOR_OPS_H_
extern struct data simulator_op_add(struct data opnd1, struct data opnd2);
extern struct data simulator_op_sub(struct data opnd1, struct data opnd2);
extern struct data simulator_op_mul(struct data opnd1, struct data opnd2);
extern struct data simulator_op_div(struct data opnd1, struct data opnd2);
extern struct data simulator_op_divs(struct data opnd1, struct data opnd2);
extern struct data simulator_op_mod(struct data opnd1, struct data opnd2);
extern struct data simulator_op_mods(struct data opnd1, struct data opnd2);
extern struct data simulator_op_shl(struct data opnd1, struct data opnd2);
extern struct data simulator_op_shr(struct data opnd1, struct data opnd2);
extern struct data simulator_op_shrs(struct data opnd1, struct data opnd2);
extern struct data simulator_op_and(struct data opnd1, struct data opnd2);
extern struct data simulator_op_or(struct data opnd1, struct data opnd2);
extern struct data simulator_op_xor(struct data opnd1, struct data opnd2);
extern struct data simulator_op_not(struct data opnd);
extern struct data simulator_op_zx(size_t to, struct data opnd1);
extern struct data simulator_op_sx(size_t to, struct data opnd1);
extern struct data simulator_op_cmp_eq(struct data opnd1, struct data opnd2);
extern struct data simulator_op_cmp_neq(struct data opnd1, struct data opnd2);
extern struct data simulator_op_cmp_les(struct data opnd1, struct data opnd2);
extern struct data simulator_op_cmp_leu(struct data opnd1, struct data opnd2);
extern struct data simulator_op_cmp_lts(struct data opnd1, struct data opnd2);
extern struct data simulator_op_cmp_ltu(struct data opnd1, struct data opnd2);
#endif /* SIMULATOR_OPS_H_ */
\ No newline at end of file
/*
* simulator_regacc.h
*
* Created on: 07.02.2019
* Author: zenzl
* Based on: ../../../rreil-sim/include/simulator/regacc.h by jucs
*/
#ifndef SIMULATOR_REGACC_H_
#define SIMULATOR_REGACC_H_
#include <stdlib.h>
#include <stdint.h>
#include <simulator/simulator.h>
extern void simulator_register_read(struct context *context,
struct rreil_id *id, struct data data, size_t bit_offset);
extern void simulator_register_generic_write(struct register_ *reg,
struct data data, size_t bit_offset);
extern void simulator_register_write(struct context *context,
struct rreil_id *id, struct data data, size_t bit_offset);
#endif /* SIMULATOR_REGACC_H_ */
/*
* register.h
*
* Created on: 07.02.2019
* Author: zenzl
* Based on: ../../../rreil-sim/include/simulator/register.h by jucs
*/
#ifndef REGISTER_H_
#define REGISTER_H_
#include <stdlib.h>
#include <stdint.h>
struct register_ {
uint8_t *data;
uint8_t *defined;
size_t bit_length;
};
#endif /* REGISTER_H_ */
/*
* simulator.h
*
* Created on: 07.02.2019
* Author: zenzl
* Based on: ../../../rreil-sim/include/simulator/simulator.h by jucs
*/
#ifndef SIMULATOR_H_
#define SIMULATOR_H_
#include <stdint.h>
#include <rreil/rreil.h>
#include <context.h>
enum simulator_error {
SIMULATOR_ERROR_NONE = 0,
SIMULATOR_ERROR_UNALIGNED_STORE = 1,
SIMULATOR_ERROR_UNDEFINED_ADDRESS = 2,
SIMULATOR_ERROR_UNDEFINED_STORE = 4,
SIMULATOR_ERROR_UNDEFINED_BRANCH = 8,
SIMULATOR_ERROR_FLOP_UNIMPLEMENTED = 16,
SIMULATOR_ERROR_PRIMITIVE_UNKNOWN = 32,
SIMULATOR_ERROR_PRIMITIVE_SIGNATURE_INVALID = 64,
SIMULATOR_ERROR_MAX_LOOP_ITERATIONS_COUNT_EXCEEDED = 128,
SIMULATOR_ERROR_EXCEPTION = 256
};
#define SIMULATOR_ERRORS_COUNT 10
extern enum simulator_error simulator_statements_simulate(struct context *context,
struct rreil_statements *statements);
#endif /* SIMULATOR_H_ */
/*
* simulator_tracking.h
*
* Created on: 07.02.2019
* Author: zenzl
* Based on: ../../../rreil-sim/inlcude/simulator/tracking.h by jucs
*/
#ifndef SIMULATOR_TRACKING_H_
#define SIMULATOR_TRACKING_H_
#include <stdlib.h>
#include <simulator/register.h>
#include <rreil/rreil.h>
struct arm7_register_access {
struct register_ *arm7_registers;
size_t *arm7_indices;
size_t arm7_indices_length;
size_t arm7_indices_size;
};
struct memory_access {
size_t data_size;
void *address;
};
struct tracking_trace {
struct {
struct arm7_register_access read;
struct arm7_register_access written;
struct arm7_register_access dereferenced;
} reg;
struct {
struct {
struct memory_access *accesses;
size_t accesses_length;
size_t accesses_size;
} written;
char used;
} mem;
};
extern void tracking_statements_trace(struct tracking_trace *trace,
struct rreil_statements *statements);
extern struct tracking_trace *tracking_trace_init();
extern void tracking_trace_free(struct tracking_trace *trace);
extern void tracking_trace_memory_write_add(struct tracking_trace *trace,
struct memory_access access);
extern void tracking_trace_print(struct tracking_trace *trace);
#endif /* SIMULATOR_TRACKING_H_ */
\ No newline at end of file
/*
* context.c
*
* Created on: 07.02.2019
* Author: zenzl
* Based on: ../../rreil-sim/src/context.c by jucs
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <rreil/rreil.h>
#include <arm7.h>
#include <context.h>
#include <util.h>
struct memory_allocation *memory_allocation_init(void *address) {
struct memory_allocation *allocation = (struct memory_allocation*)malloc(sizeof(struct memory_allocation));
allocation->address = address;
allocation->data = NULL;
allocation->data_size = 0;
return allocation;
}
struct context *context_init(context_load_t *load, context_store_t *store, context_jump_t *jump, void *closure) {
struct context *context = (struct context*)malloc(sizeof(struct context));
context->shared_registers = (struct register_*)calloc(RREIL_ID_SHARED_COUNT, sizeof(struct register_));
context->arm7_registers = (struct register_*)calloc(ARM7_ID_COUNT, sizeof(struct register_));
context->temporary_registers = (struct register_*)calloc(
RREIL_ID_TEMPORARY_COUNT, sizeof(struct register_));
context->memory.allocations = NULL;
context->memory.allocations_length = 0;
context->memory.allocations_size = 0;
context->memory.load = load;
context->memory.store = store;
context->memory.jump = jump;
context->memory.closure = closure;
return context;
}
void context_data_define(struct data *data) {
data->defined = (uint8_t*)malloc(data->bit_length / 8 + 1);
membit_one_fill(data->defined, 0, data->bit_length);
}
void context_data_undefine(struct data *data) {
data->defined = (uint8_t*)malloc(data->bit_length / 8 + 1);
membit_zero_fill(data->defined, 0, data->bit_length);
}
void context_data_clear(struct data *data) {
if(data) {
free(data->data);
free(data->defined);
}
}
static void copy(size_t i, struct register_ *registers, uint8_t **field_to, uint8_t *field_from) {
*field_to = (uint8_t*)malloc(registers[i].bit_length / 8 + 1);
memcpy(*field_to, field_from, registers[i].bit_length / 8 + (registers[i].bit_length % 8 > 0));
}
static void copy_registers(size_t count, struct register_ *registers, struct register_ *registers_source) {
for(size_t i = 0; i < count; ++i) {
registers[i].bit_length = registers_source[i].bit_length;
copy(i, registers, &registers[i].data, registers_source[i].data);
copy(i, registers, &registers[i].defined, registers_source[i].defined);
}
}
struct context *context_copy(struct context *source) {
struct context *context = (struct context*)malloc(sizeof(struct context));
context->shared_registers = (struct register_*)malloc(
RREIL_ID_SHARED_COUNT * sizeof(struct register_));
copy_registers(RREIL_ID_SHARED_COUNT, context->shared_registers, source->shared_registers);
context->arm7_registers = (struct register_*)malloc(
ARM7_ID_COUNT * sizeof(struct register_));
copy_registers(ARM7_ID_COUNT, context->arm7_registers, source->arm7_registers);
context->temporary_registers = (struct register_*)malloc(
RREIL_ID_TEMPORARY_COUNT * sizeof(struct register_));
copy_registers(RREIL_ID_TEMPORARY_COUNT, context->temporary_registers, source->temporary_registers);
context->memory.allocations = (struct memory_allocation *)malloc(
source->memory.allocations_size * sizeof(struct memory_allocation));
context->memory.allocations_length = source->memory.allocations_length;
context->memory.allocations_size = source->memory.allocations_size;
for(size_t i = 0; i < context->memory.allocations_length; ++i) {
struct memory_allocation *source_a = &source->memory.allocations[i];
struct memory_allocation *destination_a = &context->memory.allocations[i];
destination_a->address = source_a->address;
destination_a->data_size = source_a->data_size;
destination_a->data = (uint8_t*)malloc(destination_a->data_size);
memcpy(destination_a->data, source_a->data, source_a->data_size);
destination_a->type = source_a->type;
}
context->memory.load = source->memory.load;
context->memory.store = source->memory.store;
context->memory.jump = source->memory.jump;
context->memory.closure = source->memory.closure;
return context;
}
static void register_clear(struct register_ *register_) {
if(register_) {
free(register_->data);
free(register_->defined);
}
}
void context_free(struct context *context) {
if(context) {
/*
* Todo: ...
*/
for(size_t i = 0; i < RREIL_ID_SHARED_COUNT; ++i)
register_clear(&context->shared_registers[i]);
free(context->shared_registers);
for(size_t i = 0; i < ARM7_ID_COUNT; ++i)
register_clear(&context->arm7_registers[i]);
free(context->arm7_registers);
for(size_t i = 0; i < RREIL_ID_TEMPORARY_COUNT; ++i)
register_clear(&context->temporary_registers[i]);
free(context->temporary_registers);
/*
* Todo: Unmapping ;-)
*/
for(size_t i = 0; i < context->memory.allocations_length; ++i)
free(context->memory.allocations[i].data);
free(context->memory.allocations);
free(context);
}
}
static void print(struct register_ *reg, uint8_t *ptr) {
if(reg->bit_length % 8) {
uint8_t top = ptr[reg->bit_length / 8] & reg->defined[reg->bit_length / 8];
uint8_t mask = (1 << (reg->bit_length % 8)) - 1;
printf("%02x", (top & mask));
}
for(size_t i = reg->bit_length / 8; i > 0; --i)
printf("%02x", ptr[i - 1] & reg->defined[i - 1]);
}
void context_arm7_print(struct context *context) {
for(size_t i = 0; i < ARM7_ID_COUNT; ++i) {
enum arm7_id id_arm7 = (enum arm7_id)i;
struct register_ *reg = &context->arm7_registers[id_arm7];
if(!reg->bit_length) continue;
/*
* Todo: Extra function for printing
*/
printf("Register ");
arm7_id_print(stdout, id_arm7);
printf(": ");
size_t rest = 0;
size_t reg_size = arm7_sizeof(id_arm7);
if(reg_size > reg->bit_length) rest = reg_size - reg->bit_length;
for(size_t i = 0; i < rest / 8; ++i)
printf("00");
if(reg->bit_length) {
print(reg, reg->data);
printf(" [defined:");
print(reg, reg->defined);
printf("]");
}
printf("\n");
}
for(size_t i = 0; i < context->memory.allocations_length; ++i) {
struct memory_allocation *allocation = &context->memory.allocations[i];
/*
* Todo Combine with compare-thing
*/
printf("Memory access (@0x");
for(size_t i = sizeof(allocation->address); i > 0; --i) {
uint8_t *addr_ptr = (uint8_t*)&allocation->address;
printf("%02x", addr_ptr[i - 1]);
}
printf("): ");
if(allocation->type == MEMORY_ALLOCATION_TYPE_ACCESS) for(size_t i = allocation->data_size; i > 0; --i)
printf("%02x", allocation->data[i - 1]);
else printf("JUMP");
printf("\n");
}
}
static void context_compare_registers(struct register_ *reg_cpu, struct register_ *reg_rreil,
void (*callback)(char *found, enum arm7_id reg), enum arm7_id reg, char *found) {
for(size_t j = 0; j < reg_cpu->bit_length / 8 + (reg_cpu->bit_length % 8 > 0); ++j)
if((reg_cpu->data[j] & reg_rreil->defined[j]) != (reg_rreil->data[j] & reg_rreil->defined[j])) {
callback(found, reg);
break;
}
}
static void context_compare_registers_using_trace(struct tracking_trace *trace, struct context *context_cpu,
struct context *context_rreil, void (*callback)(char *found, enum arm7_id reg), char *found) {
for(size_t i = 0; i < trace->reg.written.arm7_indices_length; ++i) {
size_t index = trace->reg.written.arm7_indices[i];
enum arm7_id reg = (enum arm7_id)index;
struct register_ *reg_cpu = &context_cpu->arm7_registers[index];
struct register_ *reg_rreil = &context_rreil->arm7_registers[index];
context_compare_registers(reg_cpu, reg_rreil, callback, reg, found);
}
}