diff --git a/.gitignore b/.gitignore index 7adf5b9e..50b09750 100644 --- a/.gitignore +++ b/.gitignore @@ -81,3 +81,5 @@ bindings/python/build/ config.log regress/map_crash +regress/sigill +regress/sigill2 diff --git a/qemu/target-i386/unicorn.c b/qemu/target-i386/unicorn.c index b3111cb0..8235c0e5 100644 --- a/qemu/target-i386/unicorn.c +++ b/qemu/target-i386/unicorn.c @@ -938,6 +938,16 @@ int x86_uc_machine_init(struct uc_struct *uc) return machine_initialize(uc); } +static bool x86_stop_interrupt(int intno) +{ + switch(intno) { + default: + return false; + case EXCP06_ILLOP: + return true; + } +} + void pc_machine_init(struct uc_struct *uc); __attribute__ ((visibility ("default"))) @@ -954,5 +964,6 @@ void x86_uc_init(struct uc_struct* uc) uc->reg_reset = x86_reg_reset; uc->release = x86_release; uc->set_pc = x86_set_pc; + uc->stop_interrupt = x86_stop_interrupt; uc_common_init(uc); } diff --git a/regress/Makefile b/regress/Makefile index 8f8d2556..d0becfea 100644 --- a/regress/Makefile +++ b/regress/Makefile @@ -1,7 +1,7 @@ CFLAGS += -I../include LDFLAGS = -L.. -lunicorn -TESTS = map_crash sigill +TESTS = map_crash sigill sigill2 all: $(TESTS) diff --git a/regress/sigill2.c b/regress/sigill2.c new file mode 100644 index 00000000..97cd7199 --- /dev/null +++ b/regress/sigill2.c @@ -0,0 +1,29 @@ +#include +#include +#include +#include + +#define UC_BUG_WRITE_SIZE 128 +#define UC_BUG_WRITE_ADDR 0x2000 + +int main() +{ + int size; + uint8_t *buf; + uch uh; + uch uh_trap; + uc_err err = uc_open (UC_ARCH_X86, UC_MODE_64, &uh); + if (err) { + fprintf (stderr, "Cannot initialize unicorn\n"); + return 1; + } + size = UC_BUG_WRITE_SIZE; + if (!uc_mem_map (uh, UC_BUG_WRITE_ADDR, size)) { + uc_mem_write (uh, UC_BUG_WRITE_ADDR, + (const uint8_t*)"\xff\xff\xff\xff\xff\xff\xff\xff", 8); + } + err = uc_emu_start (uh, UC_BUG_WRITE_ADDR, UC_BUG_WRITE_ADDR+8, 0, 1); + uc_close (&uh); + printf ("Error = %u (%s)\n", err, uc_strerror(err)); + return err? -1: 0; +} diff --git a/uc.c b/uc.c index cef74de1..c1d6479c 100644 --- a/uc.c +++ b/uc.c @@ -410,6 +410,11 @@ uc_err uc_emu_start(uch handle, uint64_t begin, uint64_t until, uint64_t timeout // invalid handle return UC_ERR_UCH; + // reset the counter + uc->emu_counter = 0; + uc->stop_request = false; + uc->invalid_error = UC_ERR_OK; + switch(uc->arch) { default: break; @@ -474,11 +479,6 @@ uc_err uc_emu_start(uch handle, uint64_t begin, uint64_t until, uint64_t timeout // emulation is done uc->emulation_done = true; - // reset the counter - uc->emu_counter = 0; - uc->stop_request = false; - uc->invalid_error = UC_ERR_OK; - return uc->invalid_error; }