Enable RzIL VM to halt on exceptions. (#5305)
* Print warnings if a runtime exception state is reached. * Enable the RzIL VM to halt on exceptions. --------- Co-authored-by: NOT XVilka <notxvilka@proton.me>
This commit is contained in:
parent
faf3c53168
commit
2602b1cdfa
16 changed files with 311 additions and 70 deletions
|
|
@ -8,6 +8,44 @@
|
|||
* @{
|
||||
*/
|
||||
|
||||
static RzILEventException get_halt_exc_options(RzCoreBind *coreb, void *core) {
|
||||
// core might be NULL for rz-asm.
|
||||
const char *exc = core ? coreb->cfgGet(core, "rzil.step.events.halt_on_exc") : NULL;
|
||||
if (RZ_STR_ISEMPTY(exc) || RZ_STR_EQ(exc, "none")) {
|
||||
return RZ_IL_EVENT_EXC_NONE;
|
||||
} else if (RZ_STR_EQ(exc, "all")) {
|
||||
return RZ_IL_EVENT_EXC_DIV_ZERO |
|
||||
RZ_IL_EVENT_EXC_FP_DIV_ZERO |
|
||||
RZ_IL_EVENT_EXC_FP_INVALID_OP |
|
||||
RZ_IL_EVENT_EXC_FP_OVERFLOW |
|
||||
RZ_IL_EVENT_EXC_FP_UNDERFLOW |
|
||||
RZ_IL_EVENT_EXC_FP_INEXACT;
|
||||
}
|
||||
RzILEventException he = 0;
|
||||
RzList *opts = rz_str_split_duplist_n(exc, ",", 0, true);
|
||||
RzListIter *it;
|
||||
const char *e;
|
||||
rz_list_foreach (opts, it, e) {
|
||||
if (RZ_STR_EQ("div0", e)) {
|
||||
he |= RZ_IL_EVENT_EXC_DIV_ZERO;
|
||||
} else if (RZ_STR_EQ("fp_div0", e)) {
|
||||
he |= RZ_IL_EVENT_EXC_FP_DIV_ZERO;
|
||||
} else if (RZ_STR_EQ("fp_inexact", e)) {
|
||||
he |= RZ_IL_EVENT_EXC_FP_INEXACT;
|
||||
} else if (RZ_STR_EQ("fp_underflow", e)) {
|
||||
he |= RZ_IL_EVENT_EXC_FP_UNDERFLOW;
|
||||
} else if (RZ_STR_EQ("fp_overflow", e)) {
|
||||
he |= RZ_IL_EVENT_EXC_FP_OVERFLOW;
|
||||
} else if (RZ_STR_EQ("fp_invalid_op", e)) {
|
||||
he |= RZ_IL_EVENT_EXC_FP_INVALID_OP;
|
||||
} else {
|
||||
RZ_LOG_WARN("Exception type '%s' in rzil.step.events.halt_on_exc is not handled!\n", e);
|
||||
}
|
||||
}
|
||||
rz_list_free(opts);
|
||||
return he;
|
||||
}
|
||||
|
||||
static void var_state_free(void *e, void *user) {
|
||||
RzAnalysisILInitStateVar *s = e;
|
||||
if (!s) {
|
||||
|
|
@ -175,7 +213,7 @@ new_real:
|
|||
}
|
||||
|
||||
static void setup_vm_from_config(RzAnalysis *analysis, RzAnalysisILVM *vm, RzAnalysisILConfig *cfg) {
|
||||
vm->vm = rz_il_vm_new(0, cfg->pc_size, cfg->big_endian);
|
||||
vm->vm = rz_il_vm_new(0, cfg->pc_size, cfg->big_endian, get_halt_exc_options(&analysis->coreb, analysis->core));
|
||||
if (!vm->vm) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3024,6 +3024,16 @@ static bool cb_flirt(void *user, void *data) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool rzil_halt_on_exec(void *user, void *data) {
|
||||
rz_return_val_if_fail(data, false);
|
||||
RzConfigNode *node = (RzConfigNode *)data;
|
||||
if (*node->value == '?') {
|
||||
print_node_options(node);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
RZ_API int rz_core_config_init(RzCore *core) {
|
||||
int i;
|
||||
char buf[128], *p, *tmpdir;
|
||||
|
|
@ -3920,6 +3930,9 @@ RZ_API int rz_core_config_init(RzCore *core) {
|
|||
/* RzIL config */
|
||||
SETB("rzil.step.events.read", false, "enables/disables printing aezse read event");
|
||||
SETB("rzil.step.events.write", true, "enables/disables printing aezse write event");
|
||||
n = NODECB("rzil.step.events.halt_on_exc", "div0,fp_invalid_op", &rzil_halt_on_exec);
|
||||
SETDESC(n, "Enables/disable exceptions the VM should halt if reached.");
|
||||
SETOPTIONS(n, "div0", "fp_div0", "fp_inexact", "fp_underflow", "fp_overflow", "fp_invalid_op", "none", "all", NULL);
|
||||
|
||||
/* FLIRT config */
|
||||
SETBPREF("flirt.sig.library", RZ_FLIRT_LIBRARY_NAME_DFL, "FLIRT library name for sig format");
|
||||
|
|
|
|||
|
|
@ -4,6 +4,31 @@
|
|||
|
||||
#include <rz_il/rz_il_events.h>
|
||||
|
||||
/**
|
||||
* Get the exception message for the exception id.
|
||||
* \param id The exception identifier.
|
||||
* \return The exception message.
|
||||
*/
|
||||
RZ_API const char *rz_il_event_exception_msg(const RzILEventException id) {
|
||||
switch (id) {
|
||||
case RZ_IL_EVENT_EXC_NONE:
|
||||
return "None";
|
||||
case RZ_IL_EVENT_EXC_DIV_ZERO:
|
||||
return "division by zero";
|
||||
case RZ_IL_EVENT_EXC_FP_INVALID_OP:
|
||||
return "float invalid operation";
|
||||
case RZ_IL_EVENT_EXC_FP_DIV_ZERO:
|
||||
return "float division by zero";
|
||||
case RZ_IL_EVENT_EXC_FP_OVERFLOW:
|
||||
return "float overflow";
|
||||
case RZ_IL_EVENT_EXC_FP_UNDERFLOW:
|
||||
return "float underflow";
|
||||
case RZ_IL_EVENT_EXC_FP_INEXACT:
|
||||
return "float inexact";
|
||||
}
|
||||
return "unknown exception";
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees an RzILEvent struct
|
||||
* \param evt, RzILEvent, pointer to the RzILEvent to free
|
||||
|
|
@ -14,7 +39,6 @@ RZ_API void rz_il_event_free(RZ_NULLABLE RzILEvent *evt) {
|
|||
}
|
||||
switch (evt->type) {
|
||||
case RZ_IL_EVENT_EXCEPTION:
|
||||
free(evt->data.exception);
|
||||
break;
|
||||
case RZ_IL_EVENT_PC_WRITE:
|
||||
rz_bv_free(evt->data.pc_write.old_pc);
|
||||
|
|
@ -47,10 +71,11 @@ RZ_API void rz_il_event_free(RZ_NULLABLE RzILEvent *evt) {
|
|||
|
||||
/**
|
||||
* Creates an RzILEvent of type RZ_IL_EVENT_EXCEPTION
|
||||
* \param exception, const char, pointer to the exception message
|
||||
* \param id The exception identifier.
|
||||
* \param msg Pointer to the exception message
|
||||
*/
|
||||
RZ_API RZ_OWN RzILEvent *rz_il_event_exception_new(RZ_NONNULL const char *exception) {
|
||||
rz_return_val_if_fail(exception, NULL);
|
||||
RZ_API RZ_OWN RzILEvent *rz_il_event_exception_new(RzILEventException id) {
|
||||
rz_return_val_if_fail(id != RZ_IL_EVENT_EXC_NONE, NULL);
|
||||
|
||||
RzILEvent *evt = RZ_NEW(RzILEvent);
|
||||
if (!evt) {
|
||||
|
|
@ -59,12 +84,7 @@ RZ_API RZ_OWN RzILEvent *rz_il_event_exception_new(RZ_NONNULL const char *except
|
|||
}
|
||||
|
||||
evt->type = RZ_IL_EVENT_EXCEPTION;
|
||||
evt->data.exception = rz_str_dup(exception);
|
||||
if (!evt->data.exception) {
|
||||
rz_il_event_free(evt);
|
||||
RZ_LOG_ERROR("RzIL: cannot allocate exception string\n");
|
||||
return NULL;
|
||||
}
|
||||
evt->data.exception = id;
|
||||
return evt;
|
||||
}
|
||||
|
||||
|
|
@ -198,4 +218,4 @@ RZ_API RZ_OWN RzILEvent *rz_il_event_var_write_new(RZ_NONNULL const char *name,
|
|||
}
|
||||
|
||||
return evt;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -872,7 +872,7 @@ RZ_API void rz_il_event_json(RZ_NONNULL RzILEvent *evt, RZ_NONNULL PJ *pj) {
|
|||
case RZ_IL_EVENT_EXCEPTION:
|
||||
pj_o(pj);
|
||||
pj_ks(pj, "type", "exception");
|
||||
pj_ks(pj, "exception", evt->data.exception);
|
||||
pj_ks(pj, "exception", rz_il_event_exception_msg(evt->data.exception));
|
||||
pj_end(pj);
|
||||
break;
|
||||
case RZ_IL_EVENT_PC_WRITE:
|
||||
|
|
|
|||
|
|
@ -1069,7 +1069,7 @@ RZ_API void rz_il_event_stringify(RZ_NONNULL const RzILEvent *evt, RZ_NONNULL Rz
|
|||
|
||||
switch (evt->type) {
|
||||
case RZ_IL_EVENT_EXCEPTION:
|
||||
rz_strbuf_appendf(sb, "exception(%s)", evt->data.exception);
|
||||
rz_strbuf_appendf(sb, "exception(%s)", rz_il_event_exception_msg(evt->data.exception));
|
||||
break;
|
||||
case RZ_IL_EVENT_PC_WRITE:
|
||||
tmp0 = rz_bv_as_hex_string(evt->data.pc_write.old_pc, false);
|
||||
|
|
|
|||
|
|
@ -18,8 +18,9 @@ extern RZ_IPI RzILOpEffectHandler rz_il_op_handler_effect_table_default[RZ_IL_OP
|
|||
* \param vm RzILVM, pointer to an empty VM
|
||||
* \param start_addr ut64, initiation pc address
|
||||
* \param addr_size ut32, size of the address in VM
|
||||
* \param halt_exc The exceptions the VM should halt for if encountered.
|
||||
*/
|
||||
RZ_API bool rz_il_vm_init(RzILVM *vm, ut64 start_addr, ut32 addr_size, bool big_endian) {
|
||||
RZ_API bool rz_il_vm_init(RzILVM *vm, ut64 start_addr, ut32 addr_size, bool big_endian, RzILEventException halt_exc) {
|
||||
rz_return_val_if_fail(vm, false);
|
||||
|
||||
if (!rz_il_var_set_init(&vm->global_vars)) {
|
||||
|
|
@ -60,6 +61,8 @@ RZ_API bool rz_il_vm_init(RzILVM *vm, ut64 start_addr, ut32 addr_size, bool big_
|
|||
vm->val_count = 0;
|
||||
vm->addr_size = addr_size;
|
||||
vm->big_endian = big_endian;
|
||||
vm->halt_exceptions = halt_exc;
|
||||
vm->halt = false;
|
||||
|
||||
vm->events = rz_pvector_new((RzPVectorFree)rz_il_event_free);
|
||||
if (!vm->events) {
|
||||
|
|
@ -101,13 +104,14 @@ RZ_API void rz_il_vm_fini(RzILVM *vm) {
|
|||
* \param vm RzILVM, pointer to an empty VM
|
||||
* \param start_addr ut64, initiation pc address
|
||||
* \param addr_size ut32, size of the address in VM
|
||||
* \param halt_exc The exceptions the VM should halt for if encountered.
|
||||
*/
|
||||
RZ_API RzILVM *rz_il_vm_new(ut64 start_addr, ut32 addr_size, bool big_endian) {
|
||||
RZ_API RzILVM *rz_il_vm_new(ut64 start_addr, ut32 addr_size, bool big_endian, RzILEventException halt_exc) {
|
||||
RzILVM *vm = RZ_NEW0(RzILVM);
|
||||
if (!vm) {
|
||||
return NULL;
|
||||
}
|
||||
rz_il_vm_init(vm, start_addr, addr_size, big_endian);
|
||||
rz_il_vm_init(vm, start_addr, addr_size, big_endian, halt_exc);
|
||||
return vm;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -284,6 +284,10 @@ RZ_API void rz_il_vm_event_add(RzILVM *vm, RzILEvent *evt) {
|
|||
rz_warn_if_reached();
|
||||
rz_il_event_free(evt);
|
||||
}
|
||||
if (evt->type == RZ_IL_EVENT_EXCEPTION && (vm->halt_exceptions & evt->data.exception)) {
|
||||
RZ_LOG_WARN("Reached exception '%s'. Requesting VM to halt.\n", rz_il_event_exception_msg(evt->data.exception));
|
||||
vm->halt = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -305,12 +309,23 @@ RZ_API bool rz_il_vm_step(RzILVM *vm, RzILOpEffect *op, ut64 fallthrough_addr) {
|
|||
rz_il_vm_clear_events(vm);
|
||||
|
||||
// Set the successor pc **before** evaluating. Any jmp/goto may then overwrite it again.
|
||||
ut64 old_pc = rz_bv_to_ut64(vm->pc);
|
||||
RzBitVector *next_pc = rz_bv_new_from_ut64(vm->pc->len, fallthrough_addr);
|
||||
rz_il_vm_event_add(vm, rz_il_event_pc_write_new(vm->pc, next_pc));
|
||||
rz_bv_free(vm->pc);
|
||||
vm->pc = next_pc;
|
||||
|
||||
bool succ = rz_il_evaluate_effect(vm, op);
|
||||
if (vm->halt) {
|
||||
RZ_LOG_WARN("Halting VM at 0x%" PFMT64x "!\n", old_pc);
|
||||
// Reset PC to halting instruction.
|
||||
RzBitVector *prev_pc = rz_bv_new_from_ut64(vm->pc->len, old_pc);
|
||||
rz_bv_free(vm->pc);
|
||||
vm->pc = prev_pc;
|
||||
// Don't reset vm->halt flag.
|
||||
// User should re-init VM.
|
||||
return false;
|
||||
}
|
||||
|
||||
// remove any local defined variable (local pure vars are unbound automatically)
|
||||
rz_il_var_set_reset(&vm->local_vars);
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ void *rz_il_handler_div(RzILVM *vm, RzILOpBitVector *op, RzILTypePure *type) {
|
|||
if (rz_bv_is_zero_vector(y)) {
|
||||
result = rz_bv_new(y->len);
|
||||
rz_bv_set_all(result, true);
|
||||
rz_il_vm_event_add(vm, rz_il_event_exception_new("division by zero"));
|
||||
rz_il_vm_event_add(vm, rz_il_event_exception_new(RZ_IL_EVENT_EXC_DIV_ZERO));
|
||||
} else {
|
||||
result = rz_bv_div(x, y);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -343,19 +343,19 @@ void *rz_il_handler_fexcept(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
|
|||
switch (args.e) {
|
||||
case RZ_FLOAT_E_DIV_ZERO:
|
||||
e = n->exception & RZ_FLOAT_E_DIV_ZERO;
|
||||
rz_il_vm_event_add(vm, rz_il_event_exception_new("float division by zero"));
|
||||
rz_il_vm_event_add(vm, rz_il_event_exception_new(RZ_IL_EVENT_EXC_FP_DIV_ZERO));
|
||||
break;
|
||||
case RZ_FLOAT_E_OVERFLOW:
|
||||
e = n->exception & RZ_FLOAT_E_OVERFLOW;
|
||||
rz_il_vm_event_add(vm, rz_il_event_exception_new("float overflow"));
|
||||
rz_il_vm_event_add(vm, rz_il_event_exception_new(RZ_IL_EVENT_EXC_FP_OVERFLOW));
|
||||
break;
|
||||
case RZ_FLOAT_E_UNDERFLOW:
|
||||
e = n->exception & RZ_FLOAT_E_UNDERFLOW;
|
||||
rz_il_vm_event_add(vm, rz_il_event_exception_new("float underflow"));
|
||||
rz_il_vm_event_add(vm, rz_il_event_exception_new(RZ_IL_EVENT_EXC_FP_UNDERFLOW));
|
||||
break;
|
||||
case RZ_FLOAT_E_INEXACT:
|
||||
e = n->exception & RZ_FLOAT_E_INEXACT;
|
||||
rz_il_vm_event_add(vm, rz_il_event_exception_new("float inexact"));
|
||||
rz_il_vm_event_add(vm, rz_il_event_exception_new(RZ_IL_EVENT_EXC_FP_INEXACT));
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,16 @@ typedef enum rz_il_event_id_t {
|
|||
RZ_IL_EVENT_VAR_WRITE,
|
||||
} RzILEventId;
|
||||
|
||||
typedef enum {
|
||||
RZ_IL_EVENT_EXC_NONE = 0,
|
||||
RZ_IL_EVENT_EXC_DIV_ZERO = 1 << 1,
|
||||
RZ_IL_EVENT_EXC_FP_INVALID_OP = 1 << 2,
|
||||
RZ_IL_EVENT_EXC_FP_DIV_ZERO = 1 << 3,
|
||||
RZ_IL_EVENT_EXC_FP_OVERFLOW = 1 << 4,
|
||||
RZ_IL_EVENT_EXC_FP_UNDERFLOW = 1 << 5,
|
||||
RZ_IL_EVENT_EXC_FP_INEXACT = 1 << 6,
|
||||
} RzILEventException;
|
||||
|
||||
typedef struct rz_il_vm_event_mem_read_t {
|
||||
RzILMemIndex index;
|
||||
RZ_NONNULL RzBitVector *address;
|
||||
|
|
@ -59,7 +69,7 @@ typedef struct rz_il_vm_event_var_write_t {
|
|||
typedef struct rz_il_vm_event_t {
|
||||
RzILEventId type;
|
||||
union {
|
||||
char *exception;
|
||||
RzILEventException exception;
|
||||
RzILEventPCWrite pc_write;
|
||||
RzILEventMemRead mem_read;
|
||||
RzILEventMemWrite mem_write;
|
||||
|
|
@ -68,13 +78,14 @@ typedef struct rz_il_vm_event_t {
|
|||
} data;
|
||||
} RzILEvent;
|
||||
|
||||
RZ_API RZ_OWN RzILEvent *rz_il_event_exception_new(RZ_NONNULL const char *exception);
|
||||
RZ_API RZ_OWN RzILEvent *rz_il_event_exception_new(RzILEventException type);
|
||||
RZ_API RZ_OWN RzILEvent *rz_il_event_pc_write_new(RZ_NONNULL const RzBitVector *old_pc, RZ_NONNULL const RzBitVector *new_pc);
|
||||
RZ_API RZ_OWN RzILEvent *rz_il_event_mem_read_new(RzILMemIndex index, RZ_NONNULL const RzBitVector *addr, RZ_NULLABLE const RzBitVector *value);
|
||||
RZ_API RZ_OWN RzILEvent *rz_il_event_var_read_new(RZ_NONNULL const char *name, RZ_NULLABLE const RzILVal *value);
|
||||
RZ_API RZ_OWN RzILEvent *rz_il_event_mem_write_new(RzILMemIndex index, RZ_NONNULL const RzBitVector *addr, RZ_NONNULL const RzBitVector *old_v, RZ_NONNULL const RzBitVector *new_v);
|
||||
RZ_API RZ_OWN RzILEvent *rz_il_event_var_write_new(RZ_NONNULL const char *name, RZ_NULLABLE const RzILVal *old_v, RZ_NONNULL const RzILVal *new_v);
|
||||
RZ_API void rz_il_event_free(RZ_NULLABLE RzILEvent *evt);
|
||||
RZ_API const char *rz_il_event_exception_msg(const RzILEventException id);
|
||||
|
||||
// Printing/Export
|
||||
RZ_API void rz_il_event_stringify(RZ_NONNULL const RzILEvent *evt, RZ_NONNULL RzStrBuf *sb);
|
||||
|
|
|
|||
|
|
@ -49,12 +49,14 @@ struct rz_il_vm_t {
|
|||
RzILOpEffectHandler *op_handler_effect_table; ///< Array of Handler, handler can be indexed by opcode
|
||||
RzPVector /*<RzILEvent *>*/ *events; ///< List of events that has happened in the last step
|
||||
bool big_endian; ///< Sets the endianness of the memory reads/writes operations
|
||||
RzILEventException halt_exceptions; ///< The exceptions the VM should halt if encountered.
|
||||
bool halt; ///< If set the VM should halt and notify the user.
|
||||
};
|
||||
|
||||
// VM high level operations
|
||||
RZ_API RzILVM *rz_il_vm_new(ut64 start_addr, ut32 addr_size, bool big_endian);
|
||||
RZ_API RzILVM *rz_il_vm_new(ut64 start_addr, ut32 addr_size, bool big_endian, RzILEventException halt_exc);
|
||||
RZ_API void rz_il_vm_free(RzILVM *vm);
|
||||
RZ_API bool rz_il_vm_init(RzILVM *vm, ut64 start_addr, ut32 addr_size, bool big_endian);
|
||||
RZ_API bool rz_il_vm_init(RzILVM *vm, ut64 start_addr, ut32 addr_size, bool big_endian, RzILEventException halt_exc);
|
||||
RZ_API void rz_il_vm_fini(RzILVM *vm);
|
||||
|
||||
RZ_API ut32 rz_il_vm_get_pc_len(RzILVM *vm);
|
||||
|
|
|
|||
|
|
@ -805,9 +805,11 @@ el~RzIL
|
|||
EOF
|
||||
EXPECT=<<EOF
|
||||
asm.cmt.il: Show RzIL expressions as comments
|
||||
rzil.step.events.halt_on_exc: Enables/disable exceptions the VM should halt if reached.
|
||||
rzil.step.events.read: enables/disables printing aezse read event
|
||||
rzil.step.events.write: enables/disables printing aezse write event
|
||||
---
|
||||
rzil.step.events.halt_on_exc: Enables/disable exceptions the VM should halt if reached.
|
||||
rzil.step.events.read: enables/disables printing aezse read event
|
||||
rzil.step.events.write: enables/disables printing aezse write event
|
||||
---
|
||||
|
|
@ -826,10 +828,12 @@ echo "---"
|
|||
el~RzIL
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
rzil.step.events.halt_on_exc: Enables/disable exceptions the VM should halt if reached.
|
||||
rzil.step.events.read: enables/disables printing aezse read event
|
||||
rzil.step.events.write: enables/disables printing aezse write event
|
||||
---
|
||||
asm.cmt.il: Show RzIL expressions as comments
|
||||
rzil.step.events.halt_on_exc: Enables/disable exceptions the VM should halt if reached.
|
||||
rzil.step.events.read: enables/disables printing aezse read event
|
||||
rzil.step.events.write: enables/disables printing aezse write event
|
||||
---
|
||||
|
|
@ -849,13 +853,16 @@ el~RzIL
|
|||
EOF
|
||||
EXPECT=<<EOF
|
||||
asm.cmt.il: Show RzIL expressions as comments
|
||||
rzil.step.events.halt_on_exc: Enables/disable exceptions the VM should halt if reached.
|
||||
rzil.step.events.read: enables/disables printing aezse read event
|
||||
rzil.step.events.write: enables/disables printing aezse write event
|
||||
---
|
||||
rzil.step.events.halt_on_exc: Enables/disable exceptions the VM should halt if reached.
|
||||
rzil.step.events.read: enables/disables printing aezse read event
|
||||
rzil.step.events.write: enables/disables printing aezse write event
|
||||
---
|
||||
asm.cmt.il: Show RzIL expressions as comments
|
||||
rzil.step.events.halt_on_exc: Enables/disable exceptions the VM should halt if reached.
|
||||
rzil.step.events.read: enables/disables printing aezse read event
|
||||
rzil.step.events.write: enables/disables printing aezse write event
|
||||
EOF
|
||||
|
|
|
|||
79
test/db/rzil/vm
Normal file
79
test/db/rzil/vm
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
NAME=Halt VM on exception
|
||||
FILE==
|
||||
ARGS=-a ppc -e cfg.bigendian=true -b 64
|
||||
CMDS=<<EOF
|
||||
|
||||
# li 3, 4
|
||||
# li 4, 0
|
||||
# divdu 5, 3, 4
|
||||
# invalid
|
||||
wx 38600004388000007ca3239200000000
|
||||
pd 4
|
||||
|
||||
e rzil.step.events.halt_on_exc=none
|
||||
aezi
|
||||
aezse 4
|
||||
aezv PC
|
||||
|
||||
e rzil.step.events.halt_on_exc=div0
|
||||
s 0x0
|
||||
aezi
|
||||
aezse 4
|
||||
aezv PC
|
||||
|
||||
e rzil.step.events.halt_on_exc=all
|
||||
s 0x0
|
||||
aezi
|
||||
aezse 4
|
||||
aezv PC
|
||||
|
||||
e rzil.step.events.halt_on_exc=fp_div0
|
||||
s 0x0
|
||||
aezi
|
||||
aezse 4
|
||||
aezv PC
|
||||
EOF
|
||||
EXPECT_ERR=<<EOF
|
||||
WARNING: Reached exception 'division by zero'. Requesting VM to halt.
|
||||
WARNING: Halting VM at 0x8!
|
||||
ERROR: RzIL: stepping failed with PC at 0x8.
|
||||
WARNING: Reached exception 'division by zero'. Requesting VM to halt.
|
||||
WARNING: Halting VM at 0x8!
|
||||
ERROR: RzIL: stepping failed with PC at 0x8.
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
0x00000000 li r3, 4
|
||||
0x00000004 li r4, 0
|
||||
0x00000008 divdu r5, r3, r4
|
||||
0x0000000c invalid
|
||||
pc_write(old: 0x0, new: 0x4)
|
||||
var_write(name: r3, old: 0x0, new: 0x4)
|
||||
pc_write(old: 0x4, new: 0x8)
|
||||
var_write(name: r4, old: 0x0, new: 0x0)
|
||||
pc_write(old: 0x8, new: 0xc)
|
||||
exception(division by zero)
|
||||
var_write(name: r5, old: 0x0, new: 0xffffffffffffffff)
|
||||
pc_write(old: 0xc, new: 0x10)
|
||||
PC: 0x0000000000000010
|
||||
pc_write(old: 0x0, new: 0x4)
|
||||
var_write(name: r3, old: 0x4, new: 0x4)
|
||||
pc_write(old: 0x4, new: 0x8)
|
||||
var_write(name: r4, old: 0x0, new: 0x0)
|
||||
PC: 0x0000000000000008
|
||||
pc_write(old: 0x0, new: 0x4)
|
||||
var_write(name: r3, old: 0x4, new: 0x4)
|
||||
pc_write(old: 0x4, new: 0x8)
|
||||
var_write(name: r4, old: 0x0, new: 0x0)
|
||||
PC: 0x0000000000000008
|
||||
pc_write(old: 0x0, new: 0x4)
|
||||
var_write(name: r3, old: 0x4, new: 0x4)
|
||||
pc_write(old: 0x4, new: 0x8)
|
||||
var_write(name: r4, old: 0x0, new: 0x0)
|
||||
pc_write(old: 0x8, new: 0xc)
|
||||
exception(division by zero)
|
||||
var_write(name: r5, old: 0xffffffffffffffff, new: 0xffffffffffffffff)
|
||||
pc_write(old: 0xc, new: 0x10)
|
||||
PC: 0x0000000000000010
|
||||
EOF
|
||||
RUN
|
||||
|
||||
|
|
@ -12,7 +12,7 @@ static bool test_il_extract32() {
|
|||
RzILValidateReport report;
|
||||
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
||||
bool valid = false;
|
||||
RzILVM *vm = rz_il_vm_new(0, 32, false);
|
||||
RzILVM *vm = rz_il_vm_new(0, 32, false, RZ_IL_EVENT_EXC_NONE);
|
||||
RzILVal *vm_result = NULL;
|
||||
|
||||
// Extract all
|
||||
|
|
@ -65,7 +65,7 @@ static bool test_il_extract64() {
|
|||
RzILValidateReport report;
|
||||
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
||||
bool valid = false;
|
||||
RzILVM *vm = rz_il_vm_new(0, 64, false);
|
||||
RzILVM *vm = rz_il_vm_new(0, 64, false, RZ_IL_EVENT_EXC_NONE);
|
||||
RzILVal *vm_result = NULL;
|
||||
|
||||
// Extract all
|
||||
|
|
@ -118,7 +118,7 @@ static bool test_il_sextract64() {
|
|||
RzILValidateReport report;
|
||||
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
||||
bool valid = false;
|
||||
RzILVM *vm = rz_il_vm_new(0, 64, false);
|
||||
RzILVM *vm = rz_il_vm_new(0, 64, false, RZ_IL_EVENT_EXC_NONE);
|
||||
RzILVal *vm_result = NULL;
|
||||
|
||||
// Extract all
|
||||
|
|
@ -171,7 +171,7 @@ static bool test_il_deposit32() {
|
|||
RzILValidateReport report;
|
||||
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
||||
bool valid = false;
|
||||
RzILVM *vm = rz_il_vm_new(0, 32, false);
|
||||
RzILVM *vm = rz_il_vm_new(0, 32, false, RZ_IL_EVENT_EXC_NONE);
|
||||
RzILVal *vm_result = NULL;
|
||||
|
||||
// Deposit all
|
||||
|
|
@ -241,7 +241,7 @@ static bool test_il_deposit64() {
|
|||
RzILValidateReport report;
|
||||
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
||||
bool valid = false;
|
||||
RzILVM *vm = rz_il_vm_new(0, 32, false);
|
||||
RzILVM *vm = rz_il_vm_new(0, 32, false, RZ_IL_EVENT_EXC_NONE);
|
||||
RzILVal *vm_result = NULL;
|
||||
|
||||
// Deposit all
|
||||
|
|
@ -311,7 +311,7 @@ static bool test_il_bswap16() {
|
|||
RzILValidateReport report;
|
||||
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
||||
bool valid = false;
|
||||
RzILVM *vm = rz_il_vm_new(0, 32, false);
|
||||
RzILVM *vm = rz_il_vm_new(0, 32, false, RZ_IL_EVENT_EXC_NONE);
|
||||
RzILVal *vm_result = NULL;
|
||||
|
||||
// Deposit all
|
||||
|
|
@ -336,7 +336,7 @@ static bool test_il_bswap32() {
|
|||
RzILValidateReport report;
|
||||
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
||||
bool valid = false;
|
||||
RzILVM *vm = rz_il_vm_new(0, 32, false);
|
||||
RzILVM *vm = rz_il_vm_new(0, 32, false, RZ_IL_EVENT_EXC_NONE);
|
||||
RzILVal *vm_result = NULL;
|
||||
|
||||
// Deposit all
|
||||
|
|
@ -361,7 +361,7 @@ static bool test_il_bswap64() {
|
|||
RzILValidateReport report;
|
||||
RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(24);
|
||||
bool valid = false;
|
||||
RzILVM *vm = rz_il_vm_new(0, 32, false);
|
||||
RzILVM *vm = rz_il_vm_new(0, 32, false, RZ_IL_EVENT_EXC_NONE);
|
||||
RzILVal *vm_result = NULL;
|
||||
|
||||
// Deposit all
|
||||
|
|
@ -382,7 +382,7 @@ static bool test_il_bswap64() {
|
|||
}
|
||||
|
||||
static bool test_il_fneq() {
|
||||
RzILVM *vm = rz_il_vm_new(0, 64, false);
|
||||
RzILVM *vm = rz_il_vm_new(0, 64, false, RZ_IL_EVENT_EXC_NONE);
|
||||
RzILBool *vm_result = NULL;
|
||||
RzILOpBool *result = NULL;
|
||||
|
||||
|
|
@ -452,7 +452,7 @@ static bool test_il_fneq() {
|
|||
}
|
||||
|
||||
static bool test_il_feq() {
|
||||
RzILVM *vm = rz_il_vm_new(0, 64, false);
|
||||
RzILVM *vm = rz_il_vm_new(0, 64, false, RZ_IL_EVENT_EXC_NONE);
|
||||
RzILBool *vm_result = NULL;
|
||||
RzILOpBool *result = NULL;
|
||||
|
||||
|
|
@ -522,7 +522,7 @@ static bool test_il_feq() {
|
|||
}
|
||||
|
||||
static bool test_il_flt() {
|
||||
RzILVM *vm = rz_il_vm_new(0, 64, false);
|
||||
RzILVM *vm = rz_il_vm_new(0, 64, false, RZ_IL_EVENT_EXC_NONE);
|
||||
RzILBool *vm_result = NULL;
|
||||
RzILOpBool *result = NULL;
|
||||
|
||||
|
|
@ -592,7 +592,7 @@ static bool test_il_flt() {
|
|||
}
|
||||
|
||||
static bool test_il_fle() {
|
||||
RzILVM *vm = rz_il_vm_new(0, 64, false);
|
||||
RzILVM *vm = rz_il_vm_new(0, 64, false, RZ_IL_EVENT_EXC_NONE);
|
||||
RzILBool *vm_result = NULL;
|
||||
RzILOpBool *result = NULL;
|
||||
|
||||
|
|
@ -662,7 +662,7 @@ static bool test_il_fle() {
|
|||
}
|
||||
|
||||
static bool test_il_fgt() {
|
||||
RzILVM *vm = rz_il_vm_new(0, 64, false);
|
||||
RzILVM *vm = rz_il_vm_new(0, 64, false, RZ_IL_EVENT_EXC_NONE);
|
||||
RzILBool *vm_result = NULL;
|
||||
RzILOpBool *result = NULL;
|
||||
|
||||
|
|
@ -732,7 +732,7 @@ static bool test_il_fgt() {
|
|||
}
|
||||
|
||||
static bool test_il_fge() {
|
||||
RzILVM *vm = rz_il_vm_new(0, 64, false);
|
||||
RzILVM *vm = rz_il_vm_new(0, 64, false, RZ_IL_EVENT_EXC_NONE);
|
||||
RzILBool *vm_result = NULL;
|
||||
RzILOpBool *result = NULL;
|
||||
|
||||
|
|
|
|||
|
|
@ -197,7 +197,7 @@ static bool test_il_vm_sync_to_reg() {
|
|||
rz_reg_setv(reg, "af", 0);
|
||||
rz_reg_setv(reg, "bf", 0);
|
||||
|
||||
RzILVM *vm = rz_il_vm_new(0, 64, false);
|
||||
RzILVM *vm = rz_il_vm_new(0, 64, false, RZ_IL_EVENT_EXC_NONE);
|
||||
RzILRegBinding *rb = rz_il_reg_binding_exactly(reg, RZ_ARRAY_SIZE(bind), bind);
|
||||
rz_il_vm_setup_reg_binding(vm, rb);
|
||||
|
||||
|
|
@ -274,7 +274,7 @@ static bool test_il_vm_sync_from_reg() {
|
|||
rz_reg_setv(reg, "af", 0);
|
||||
rz_reg_setv(reg, "bf", 1);
|
||||
|
||||
RzILVM *vm = rz_il_vm_new(0, 64, false);
|
||||
RzILVM *vm = rz_il_vm_new(0, 64, false, RZ_IL_EVENT_EXC_NONE);
|
||||
RzILRegBinding *rb = rz_il_reg_binding_exactly(reg, RZ_ARRAY_SIZE(bind), bind);
|
||||
rz_il_vm_setup_reg_binding(vm, rb);
|
||||
|
||||
|
|
|
|||
|
|
@ -4,16 +4,18 @@
|
|||
#include <rz_il.h>
|
||||
#include <rz_util.h>
|
||||
#include "minunit.h"
|
||||
#include "rz_il/rz_il_events.h"
|
||||
#include "rz_il/rz_il_opcodes.h"
|
||||
|
||||
static bool test_rzil_vm_init() {
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, true);
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, true, RZ_IL_EVENT_EXC_NONE);
|
||||
mu_assert_eq(vm->addr_size, 8, "VM Init");
|
||||
rz_il_vm_free(vm);
|
||||
mu_end;
|
||||
}
|
||||
|
||||
static bool test_rzil_vm_global_vars() {
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, true);
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, true, RZ_IL_EVENT_EXC_NONE);
|
||||
|
||||
// 1. create variables
|
||||
RzILVar *var_r1 = rz_il_vm_create_global_var(vm, "r1", rz_il_sort_pure_bool());
|
||||
|
|
@ -60,7 +62,7 @@ static bool test_rzil_vm_global_vars() {
|
|||
}
|
||||
|
||||
static bool test_rzil_vm_labels() {
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, true);
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, true, RZ_IL_EVENT_EXC_NONE);
|
||||
// create label
|
||||
RzBitVector *addr = rz_bv_new_from_ut64(16, 233);
|
||||
RzILEffectLabel *blackhole = rz_il_vm_create_label(vm, "blackhole", addr);
|
||||
|
|
@ -100,7 +102,7 @@ static bool test_rzil_vm_labels() {
|
|||
}
|
||||
|
||||
static bool test_rzil_vm_root_evaluation() {
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, false);
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, false, RZ_IL_EVENT_EXC_NONE);
|
||||
|
||||
// (ite (add 23 19)
|
||||
// true
|
||||
|
|
@ -132,7 +134,7 @@ static bool test_rzil_vm_root_evaluation() {
|
|||
}
|
||||
|
||||
static bool test_rzil_vm_step() {
|
||||
RzILVM *vm = rz_il_vm_new(0, 16, false);
|
||||
RzILVM *vm = rz_il_vm_new(0, 16, false, RZ_IL_EVENT_EXC_NONE);
|
||||
|
||||
RzILVar *var_r1 = rz_il_vm_create_global_var(vm, "r1", rz_il_sort_pure_bv(32));
|
||||
rz_il_vm_create_global_var(vm, "r2", rz_il_sort_pure_bv(32));
|
||||
|
|
@ -164,8 +166,57 @@ static bool test_rzil_vm_step() {
|
|||
mu_end;
|
||||
}
|
||||
|
||||
static bool test_rzil_vm_halt_on_exc() {
|
||||
ut64 expected_last_pc = 0x332; // The PC of the halting (div 0) instruction
|
||||
RzILEventException halt_for = RZ_IL_EVENT_EXC_DIV_ZERO;
|
||||
do {
|
||||
RzILVM *vm = rz_il_vm_new(0, 16, false, halt_for);
|
||||
|
||||
RzILVar *var_r1 = rz_il_vm_create_global_var(vm, "r1", rz_il_sort_pure_bv(32));
|
||||
RzILVar *var_r2 = rz_il_vm_create_global_var(vm, "r2", rz_il_sort_pure_bv(32));
|
||||
|
||||
RzILOpEffect *op = rz_il_op_new_set("r1", false, rz_il_op_new_bitv_from_ut64(32, 42));
|
||||
bool succ = rz_il_vm_step(vm, op, 0x331);
|
||||
rz_il_op_effect_free(op);
|
||||
mu_assert_true(succ, "success set r1");
|
||||
|
||||
op = rz_il_op_new_set("r2", false, rz_il_op_new_bitv_from_ut64(32, 0));
|
||||
succ = rz_il_vm_step(vm, op, 0x332);
|
||||
rz_il_op_effect_free(op);
|
||||
mu_assert_true(succ, "success set r2");
|
||||
|
||||
RzILOpPure *r1 = rz_il_op_new_var(var_r1->name, RZ_IL_VAR_KIND_GLOBAL);
|
||||
mu_assert_notnull(r1, "get val");
|
||||
RzILOpPure *r2 = rz_il_op_new_var(var_r2->name, RZ_IL_VAR_KIND_GLOBAL);
|
||||
mu_assert_notnull(r2, "get val");
|
||||
|
||||
op = rz_il_op_new_set("r2", false, rz_il_op_new_div(r1, r2));
|
||||
succ = rz_il_vm_step(vm, op, 0x333);
|
||||
rz_il_op_effect_free(op);
|
||||
|
||||
if (halt_for == RZ_IL_EVENT_EXC_DIV_ZERO) {
|
||||
mu_assert_false(succ, "VM did not halt after div0.");
|
||||
mu_assert_true(vm->halt, "VM halt flag not set.");
|
||||
} else {
|
||||
mu_assert_true(succ, "VM did halt after div0, but should not have.");
|
||||
mu_assert_false(vm->halt, "VM halt flag is set.");
|
||||
}
|
||||
RzBitVector *pc = vm->pc;
|
||||
mu_assert_notnull(pc, "pc");
|
||||
mu_assert_eq(rz_bv_to_ut64(pc), expected_last_pc, "VM pc doesn't match.");
|
||||
|
||||
rz_il_vm_free(vm);
|
||||
|
||||
// Do it again, this time don't halt on div 0
|
||||
// Expected PC is now one past div0 instruction (fallthrough address).
|
||||
expected_last_pc++;
|
||||
halt_for = RZ_IL_EVENT_EXC_NONE;
|
||||
} while (expected_last_pc == 0x334);
|
||||
|
||||
mu_end;
|
||||
}
|
||||
static bool test_rzil_vm_op_let() {
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, false);
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, false, RZ_IL_EVENT_EXC_NONE);
|
||||
|
||||
// simple case:
|
||||
// let preanswer = 41 in preanswer + 1
|
||||
|
|
@ -214,7 +265,7 @@ static bool test_rzil_vm_op_let() {
|
|||
}
|
||||
|
||||
static bool test_rzil_vm_op_cast() {
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, false);
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, false, RZ_IL_EVENT_EXC_NONE);
|
||||
|
||||
// 8 -> 8
|
||||
RzILOpPure *op = rz_il_op_new_cast(8, rz_il_op_new_b0(), rz_il_op_new_bitv_from_ut64(8, 0x42));
|
||||
|
|
@ -259,7 +310,7 @@ static bool test_rzil_vm_op_cast() {
|
|||
}
|
||||
|
||||
static bool test_rzil_vm_op_unsigned() {
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, false);
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, false, RZ_IL_EVENT_EXC_NONE);
|
||||
|
||||
// msb not set, filled with 0
|
||||
RzILOpPure *op = rz_il_op_new_unsigned(13, rz_il_op_new_bitv_from_ut64(8, 0x42));
|
||||
|
|
@ -286,7 +337,7 @@ static bool test_rzil_vm_op_unsigned() {
|
|||
}
|
||||
|
||||
static bool test_rzil_vm_op_signed() {
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, false);
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, false, RZ_IL_EVENT_EXC_NONE);
|
||||
|
||||
// msb not set, filled with 0
|
||||
RzILOpPure *op = rz_il_op_new_signed(13, rz_il_op_new_bitv_from_ut64(8, 0x42));
|
||||
|
|
@ -313,7 +364,7 @@ static bool test_rzil_vm_op_signed() {
|
|||
}
|
||||
|
||||
static bool test_rzil_vm_op_set() {
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, false);
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, false, RZ_IL_EVENT_EXC_NONE);
|
||||
|
||||
RzILVar *var_r1 = rz_il_vm_create_global_var(vm, "r1", rz_il_sort_pure_bv(32));
|
||||
rz_il_vm_create_global_var(vm, "r2", rz_il_sort_pure_bv(32));
|
||||
|
|
@ -401,7 +452,7 @@ static bool test_rzil_vm_op_set() {
|
|||
}
|
||||
|
||||
static bool test_rzil_vm_op_jmp() {
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, false);
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, false, RZ_IL_EVENT_EXC_NONE);
|
||||
|
||||
RzILOpEffect *op = rz_il_op_new_jmp(rz_il_op_new_bitv_from_ut64(8, 0x42));
|
||||
bool succ = rz_il_evaluate_effect(vm, op);
|
||||
|
|
@ -414,7 +465,7 @@ static bool test_rzil_vm_op_jmp() {
|
|||
}
|
||||
|
||||
static bool test_rzil_vm_op_goto_addr() {
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, false);
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, false, RZ_IL_EVENT_EXC_NONE);
|
||||
|
||||
RzBitVector *dst = rz_bv_new_from_ut64(8, 0x42);
|
||||
rz_il_vm_create_label(vm, "beach", dst);
|
||||
|
|
@ -431,7 +482,7 @@ static bool test_rzil_vm_op_goto_addr() {
|
|||
}
|
||||
|
||||
static bool test_rzil_vm_op_blk() {
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, false);
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, false, RZ_IL_EVENT_EXC_NONE);
|
||||
|
||||
RzILVar *var = rz_il_vm_create_global_var(vm, "leetbap", rz_il_sort_pure_bv(8));
|
||||
rz_il_vm_set_global_var(vm, var->name, rz_il_value_new_bitv(rz_bv_new_from_ut64(8, 0x42)));
|
||||
|
|
@ -475,7 +526,7 @@ static bool test_rzil_vm_op_blk() {
|
|||
* In the end, leetbap == 30618
|
||||
*/
|
||||
static bool test_rzil_vm_op_repeat() {
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, false);
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, false, RZ_IL_EVENT_EXC_NONE);
|
||||
|
||||
RzILVar *var = rz_il_vm_create_global_var(vm, "leetbap", rz_il_sort_pure_bv(16));
|
||||
rz_il_vm_set_global_var(vm, var->name, rz_il_value_new_bitv(rz_bv_new_from_ut64(16, 42)));
|
||||
|
|
@ -515,7 +566,7 @@ static void hook_test(RzILVM *vm, RzILOpEffect *op) {
|
|||
}
|
||||
|
||||
static bool test_rzil_vm_op_goto_hook() {
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, false);
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, false, RZ_IL_EVENT_EXC_NONE);
|
||||
|
||||
rz_il_vm_create_global_var(vm, "myvar", rz_il_sort_pure_bv(32));
|
||||
|
||||
|
|
@ -541,7 +592,7 @@ static bool test_rzil_vm_op_goto_hook() {
|
|||
|
||||
static bool test_rzil_vm_op_load() {
|
||||
const ut8 data[] = { 0x10, 0x11, 0x12, 0x42, 0x14, 0x15 };
|
||||
RzILVM *vm = rz_il_vm_new(0, 12, false);
|
||||
RzILVM *vm = rz_il_vm_new(0, 12, false, RZ_IL_EVENT_EXC_NONE);
|
||||
RzBuffer *buf = rz_buf_new_with_pointers(data, sizeof(data), false);
|
||||
rz_buf_set_overflow_byte(buf, 0xaa);
|
||||
rz_il_vm_add_mem(vm, 0, rz_il_mem_new(buf, 16));
|
||||
|
|
@ -591,7 +642,7 @@ static bool test_rzil_vm_op_load() {
|
|||
|
||||
static bool test_rzil_vm_op_store() {
|
||||
ut8 data[] = { 0x10, 0x11, 0x12, 0x42, 0x14, 0x15 };
|
||||
RzILVM *vm = rz_il_vm_new(0, 12, false);
|
||||
RzILVM *vm = rz_il_vm_new(0, 12, false, RZ_IL_EVENT_EXC_NONE);
|
||||
RzBuffer *buf = rz_buf_new_with_pointers(data, sizeof(data), false);
|
||||
rz_il_vm_add_mem(vm, 0, rz_il_mem_new(buf, 16));
|
||||
rz_buf_free(buf);
|
||||
|
|
@ -622,7 +673,7 @@ static bool test_rzil_vm_op_store() {
|
|||
|
||||
static bool test_rzil_vm_op_loadw_le() {
|
||||
const ut8 data[] = { 0x0, 0x1, 0x2, 0x42, 0x4, 0x5 };
|
||||
RzILVM *vm = rz_il_vm_new(0, 12, false);
|
||||
RzILVM *vm = rz_il_vm_new(0, 12, false, RZ_IL_EVENT_EXC_NONE);
|
||||
RzBuffer *buf = rz_buf_new_with_pointers(data, sizeof(data), false);
|
||||
rz_buf_set_overflow_byte(buf, 0xaa);
|
||||
rz_il_vm_add_mem(vm, 0, rz_il_mem_new(buf, 16));
|
||||
|
|
@ -653,7 +704,7 @@ static bool test_rzil_vm_op_loadw_le() {
|
|||
|
||||
static bool test_rzil_vm_op_storew_le() {
|
||||
ut8 data[] = { 0x0, 0x1, 0x2, 0x42, 0x4, 0x5 };
|
||||
RzILVM *vm = rz_il_vm_new(0, 12, false);
|
||||
RzILVM *vm = rz_il_vm_new(0, 12, false, RZ_IL_EVENT_EXC_NONE);
|
||||
RzBuffer *buf = rz_buf_new_with_pointers(data, sizeof(data), false);
|
||||
rz_il_vm_add_mem(vm, 0, rz_il_mem_new(buf, 16));
|
||||
rz_buf_free(buf);
|
||||
|
|
@ -684,7 +735,7 @@ static bool test_rzil_vm_op_storew_le() {
|
|||
|
||||
static bool test_rzil_vm_op_loadw_be() {
|
||||
const ut8 data[] = { 0x0, 0x1, 0x2, 0x42, 0x4, 0x5 };
|
||||
RzILVM *vm = rz_il_vm_new(0, 12, true);
|
||||
RzILVM *vm = rz_il_vm_new(0, 12, true, RZ_IL_EVENT_EXC_NONE);
|
||||
RzBuffer *buf = rz_buf_new_with_pointers(data, sizeof(data), false);
|
||||
rz_buf_set_overflow_byte(buf, 0xaa);
|
||||
rz_il_vm_add_mem(vm, 0, rz_il_mem_new(buf, 16));
|
||||
|
|
@ -715,7 +766,7 @@ static bool test_rzil_vm_op_loadw_be() {
|
|||
|
||||
static bool test_rzil_vm_op_storew_be() {
|
||||
ut8 data[] = { 0x0, 0x1, 0x2, 0x42, 0x4, 0x5 };
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, true);
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, true, RZ_IL_EVENT_EXC_NONE);
|
||||
RzBuffer *buf = rz_buf_new_with_pointers(data, sizeof(data), false);
|
||||
rz_il_vm_add_mem(vm, 0, rz_il_mem_new(buf, 16));
|
||||
rz_buf_free(buf);
|
||||
|
|
@ -745,7 +796,7 @@ static bool test_rzil_vm_op_storew_be() {
|
|||
}
|
||||
|
||||
static bool test_rzil_vm_op_append() {
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, true);
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, true, RZ_IL_EVENT_EXC_NONE);
|
||||
|
||||
RzILOpPure *op = rz_il_op_new_append(rz_il_op_new_bitv_from_ut64(16, 0xc0ff), rz_il_op_new_bitv_from_ut64(8, 0xee));
|
||||
RzBitVector *r = rz_il_evaluate_bitv(vm, op);
|
||||
|
|
@ -760,7 +811,7 @@ static bool test_rzil_vm_op_append() {
|
|||
}
|
||||
|
||||
static bool test_rzil_vm_op_shiftr() {
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, true);
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, true, RZ_IL_EVENT_EXC_NONE);
|
||||
|
||||
RzILOpPure *op = rz_il_op_new_shiftr(rz_il_op_new_b0(),
|
||||
rz_il_op_new_bitv_from_ut64(16, 0xc0ff), rz_il_op_new_bitv_from_ut64(4, 3));
|
||||
|
|
@ -785,7 +836,7 @@ static bool test_rzil_vm_op_shiftr() {
|
|||
}
|
||||
|
||||
static bool test_rzil_vm_op_shiftl() {
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, true);
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, true, RZ_IL_EVENT_EXC_NONE);
|
||||
|
||||
RzILOpPure *op = rz_il_op_new_shiftl(rz_il_op_new_b0(),
|
||||
rz_il_op_new_bitv_from_ut64(16, 0xc0ff), rz_il_op_new_bitv_from_ut64(4, 3));
|
||||
|
|
@ -810,7 +861,7 @@ static bool test_rzil_vm_op_shiftl() {
|
|||
}
|
||||
|
||||
static bool test_rzil_vm_op_compare() {
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, true);
|
||||
RzILVM *vm = rz_il_vm_new(0, 8, true, RZ_IL_EVENT_EXC_NONE);
|
||||
#define TEST_COMPARE(sign, name, lv, rv, expect) \
|
||||
do { \
|
||||
RzILOpBool *op = rz_il_op_new_##sign##name(rz_il_op_new_bitv_from_##sign##t64(32, lv), rz_il_op_new_bitv_from_##sign##t64(32, rv)); \
|
||||
|
|
@ -869,7 +920,7 @@ static bool test_rzil_vm_op_compare() {
|
|||
}
|
||||
|
||||
static bool test_rzil_vm_op_float() {
|
||||
RzILVM *vm = rz_il_vm_new(0, 64, false);
|
||||
RzILVM *vm = rz_il_vm_new(0, 64, false, RZ_IL_EVENT_EXC_NONE);
|
||||
|
||||
// let f = 2.14 in
|
||||
// (ite (is_fneg f)
|
||||
|
|
@ -946,7 +997,7 @@ static bool test_rzil_vm_op_float() {
|
|||
|
||||
static bool test_rzil_vm_op_fcast() {
|
||||
// cast of float
|
||||
RzILVM *vm = rz_il_vm_new(0, 64, false);
|
||||
RzILVM *vm = rz_il_vm_new(0, 64, false, RZ_IL_EVENT_EXC_NONE);
|
||||
RzFloat *act_float;
|
||||
RzFloat *expect_float;
|
||||
|
||||
|
|
@ -1028,7 +1079,7 @@ static bool test_rzil_vm_op_fexcept() {
|
|||
* 4. inexact result
|
||||
*/
|
||||
|
||||
RzILVM *vm = rz_il_vm_new(0, 32, false);
|
||||
RzILVM *vm = rz_il_vm_new(0, 32, false, RZ_IL_EVENT_EXC_NONE);
|
||||
RzFloat *result;
|
||||
RzILBool *e;
|
||||
RzILOpFloat *op;
|
||||
|
|
@ -1115,6 +1166,7 @@ bool all_tests() {
|
|||
mu_run_test(test_rzil_vm_op_float);
|
||||
mu_run_test(test_rzil_vm_op_fcast);
|
||||
mu_run_test(test_rzil_vm_op_fexcept);
|
||||
mu_run_test(test_rzil_vm_halt_on_exc);
|
||||
return tests_passed != tests_run;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue