diff --git a/bindings/dotnet/UnicornManaged/Const/Common.fs b/bindings/dotnet/UnicornManaged/Const/Common.fs index ef9004e6..cfbe2216 100644 --- a/bindings/dotnet/UnicornManaged/Const/Common.fs +++ b/bindings/dotnet/UnicornManaged/Const/Common.fs @@ -63,6 +63,7 @@ module Common = let UC_ERR_FETCH_UNALIGNED = 18 let UC_ERR_HOOK_EXIST = 19 let UC_ERR_RESOURCE = 20 + let UC_ERR_UNHANDLED_INTERRUPT = 21 let UC_MEM_READ = 16 let UC_MEM_WRITE = 17 let UC_MEM_FETCH = 18 diff --git a/bindings/go/unicorn/unicorn_const.go b/bindings/go/unicorn/unicorn_const.go index 01b62fca..60fb2ab6 100644 --- a/bindings/go/unicorn/unicorn_const.go +++ b/bindings/go/unicorn/unicorn_const.go @@ -58,6 +58,7 @@ const ( ERR_FETCH_UNALIGNED = 18 ERR_HOOK_EXIST = 19 ERR_RESOURCE = 20 + ERR_UNHANDLED_INTERRUPT = 21 MEM_READ = 16 MEM_WRITE = 17 MEM_FETCH = 18 diff --git a/bindings/java/unicorn/UnicornConst.java b/bindings/java/unicorn/UnicornConst.java index 033267ae..0b60e6df 100644 --- a/bindings/java/unicorn/UnicornConst.java +++ b/bindings/java/unicorn/UnicornConst.java @@ -60,6 +60,7 @@ public interface UnicornConst { public static final int UC_ERR_FETCH_UNALIGNED = 18; public static final int UC_ERR_HOOK_EXIST = 19; public static final int UC_ERR_RESOURCE = 20; + public static final int UC_ERR_UNHANDLED_INTERRUPT = 21; public static final int UC_MEM_READ = 16; public static final int UC_MEM_WRITE = 17; public static final int UC_MEM_FETCH = 18; diff --git a/bindings/python/unicorn/unicorn_const.py b/bindings/python/unicorn/unicorn_const.py index 89ccd919..e99ae6c1 100644 --- a/bindings/python/unicorn/unicorn_const.py +++ b/bindings/python/unicorn/unicorn_const.py @@ -56,6 +56,7 @@ UC_ERR_WRITE_UNALIGNED = 17 UC_ERR_FETCH_UNALIGNED = 18 UC_ERR_HOOK_EXIST = 19 UC_ERR_RESOURCE = 20 +UC_ERR_UNHANDLED_INTERRUPT = 21 UC_MEM_READ = 16 UC_MEM_WRITE = 17 UC_MEM_FETCH = 18 diff --git a/include/unicorn/unicorn.h b/include/unicorn/unicorn.h index 2013fe06..caf3e953 100644 --- a/include/unicorn/unicorn.h +++ b/include/unicorn/unicorn.h @@ -145,6 +145,7 @@ typedef enum uc_err { UC_ERR_FETCH_UNALIGNED, // Unaligned fetch UC_ERR_HOOK_EXIST, // hook for this event already existed UC_ERR_RESOURCE, // Insufficient resource: uc_emu_start() + UC_ERR_UNHANDLED_INTERRUPT // Unhandled CPU interrupt. } uc_err; diff --git a/qemu/cpu-exec.c b/qemu/cpu-exec.c index b9eb9067..8c4dccae 100644 --- a/qemu/cpu-exec.c +++ b/qemu/cpu-exec.c @@ -130,9 +130,18 @@ int cpu_exec(struct uc_struct *uc, CPUArchState *env) // qq ret = cpu->exception_index; break; #else + bool catched = false; // Unicorn: call registered interrupt callbacks HOOK_FOREACH(uc, hook, UC_HOOK_INTR) { ((uc_cb_hookintr_t)hook->callback)(uc, cpu->exception_index, hook->user_data); + catched = true; + } + // Unicorn: If un-catched interrupt, stop executions. + if (!catched) { + cpu->halted = 1; + uc->invalid_error = UC_ERR_UNHANDLED_INTERRUPT; + ret = EXCP_HLT; + break; } cpu->exception_index = -1; #if defined(TARGET_X86_64) diff --git a/tests/regress/mov_gs_eax.py b/tests/regress/mov_gs_eax.py index fb659da7..dbc48f0a 100755 --- a/tests/regress/mov_gs_eax.py +++ b/tests/regress/mov_gs_eax.py @@ -13,15 +13,12 @@ class VldrPcInsn(regress.RegressTest): # mov gs, eax; mov eax, 1 code = '8ee8b801000000'.decode('hex') uc.mem_write(0x1000, code) - uc.reg_write(UC_X86_REG_EAX, 0xFFFFFFFF) - # this should throw an error - # the eax test is just to prove the second instruction doesn't execute - try: + + with self.assertRaises(UcError) as ex_ctx: uc.emu_start(0x1000, 0x1000 + len(code)) - except UcError: - return - self.assertEqual(uc.reg_read(UC_X86_REG_EAX), 1) + + self.assertEquals(ex_ctx.exception.errno, UC_ERR_UNHANDLED_INTERRUPT) if __name__ == '__main__': regress.main() diff --git a/uc.c b/uc.c index 6ab6d3c6..b6d40ce8 100644 --- a/uc.c +++ b/uc.c @@ -96,6 +96,8 @@ const char *uc_strerror(uc_err code) return "Fetch from unaligned memory (UC_ERR_FETCH_UNALIGNED)"; case UC_ERR_RESOURCE: return "Insufficient resource (UC_ERR_RESOURCE)"; + case UC_ERR_UNHANDLED_INTERRUPT: + return "Unhandled machine interrupt (UC_ERR_UNHANDLED_INTERRUPT)"; } }