mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-02-02 03:31:15 +00:00
Merge branch 'master' of https://github.com/unicorn-engine/unicorn
This commit is contained in:
commit
600a1af710
|
@ -90,7 +90,7 @@ func (u *uc) HookAdd(htype int, cb interface{}, extra ...uint64) (Hook, error) {
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
// special case for mask
|
// special case for mask
|
||||||
if htype&(HOOK_MEM_READ_INVALID|HOOK_MEM_WRITE_INVALID|HOOK_MEM_FETCH_INVALID|
|
if htype&(HOOK_MEM_READ_UNMAPPED|HOOK_MEM_WRITE_UNMAPPED|HOOK_MEM_FETCH_UNMAPPED|
|
||||||
HOOK_MEM_READ_PROT|HOOK_MEM_WRITE_PROT|HOOK_MEM_FETCH_PROT) != 0 {
|
HOOK_MEM_READ_PROT|HOOK_MEM_WRITE_PROT|HOOK_MEM_FETCH_PROT) != 0 {
|
||||||
rangeMode = true
|
rangeMode = true
|
||||||
callback = C.hookMemInvalid_cgo
|
callback = C.hookMemInvalid_cgo
|
||||||
|
|
|
@ -39,26 +39,25 @@ const (
|
||||||
ERR_HANDLE = 3
|
ERR_HANDLE = 3
|
||||||
ERR_MODE = 4
|
ERR_MODE = 4
|
||||||
ERR_VERSION = 5
|
ERR_VERSION = 5
|
||||||
ERR_READ_INVALID = 6
|
ERR_READ_UNMAPPED = 6
|
||||||
ERR_WRITE_INVALID = 7
|
ERR_WRITE_UNMAPPED = 7
|
||||||
ERR_FETCH_INVALID = 8
|
ERR_FETCH_UNMAPPED = 8
|
||||||
ERR_CODE_INVALID = 9
|
ERR_HOOK = 9
|
||||||
ERR_HOOK = 10
|
ERR_INSN_INVALID = 10
|
||||||
ERR_INSN_INVALID = 11
|
ERR_MAP = 11
|
||||||
ERR_MAP = 12
|
ERR_WRITE_PROT = 12
|
||||||
ERR_WRITE_PROT = 13
|
ERR_READ_PROT = 13
|
||||||
ERR_READ_PROT = 14
|
ERR_FETCH_PROT = 14
|
||||||
ERR_FETCH_PROT = 15
|
ERR_ARG = 15
|
||||||
ERR_ARG = 16
|
ERR_READ_UNALIGNED = 16
|
||||||
ERR_READ_UNALIGNED = 17
|
ERR_WRITE_UNALIGNED = 17
|
||||||
ERR_WRITE_UNALIGNED = 18
|
ERR_FETCH_UNALIGNED = 18
|
||||||
ERR_FETCH_UNALIGNED = 19
|
|
||||||
MEM_READ = 16
|
MEM_READ = 16
|
||||||
MEM_WRITE = 17
|
MEM_WRITE = 17
|
||||||
MEM_FETCH = 18
|
MEM_FETCH = 18
|
||||||
MEM_READ_INVALID = 19
|
MEM_READ_UNMAPPED = 19
|
||||||
MEM_WRITE_INVALID = 20
|
MEM_WRITE_UNMAPPED = 20
|
||||||
MEM_FETCH_INVALID = 21
|
MEM_FETCH_UNMAPPED = 21
|
||||||
MEM_WRITE_PROT = 22
|
MEM_WRITE_PROT = 22
|
||||||
MEM_READ_PROT = 23
|
MEM_READ_PROT = 23
|
||||||
MEM_FETCH_PROT = 24
|
MEM_FETCH_PROT = 24
|
||||||
|
@ -66,9 +65,9 @@ const (
|
||||||
HOOK_INSN = 2
|
HOOK_INSN = 2
|
||||||
HOOK_CODE = 4
|
HOOK_CODE = 4
|
||||||
HOOK_BLOCK = 8
|
HOOK_BLOCK = 8
|
||||||
HOOK_MEM_READ_INVALID = 16
|
HOOK_MEM_READ_UNMAPPED = 16
|
||||||
HOOK_MEM_WRITE_INVALID = 32
|
HOOK_MEM_WRITE_UNMAPPED = 32
|
||||||
HOOK_MEM_FETCH_INVALID = 64
|
HOOK_MEM_FETCH_UNMAPPED = 64
|
||||||
HOOK_MEM_READ_PROT = 128
|
HOOK_MEM_READ_PROT = 128
|
||||||
HOOK_MEM_WRITE_PROT = 256
|
HOOK_MEM_WRITE_PROT = 256
|
||||||
HOOK_MEM_FETCH_PROT = 512
|
HOOK_MEM_FETCH_PROT = 512
|
||||||
|
|
|
@ -419,7 +419,7 @@ public class Sample_x86 {
|
||||||
u.hook_add(new MyCodeHook(), 1, 0, null);
|
u.hook_add(new MyCodeHook(), 1, 0, null);
|
||||||
|
|
||||||
// intercept invalid memory events
|
// intercept invalid memory events
|
||||||
u.hook_add(new MyWriteInvalidHook(), Unicorn.UC_HOOK_MEM_WRITE_INVALID, null);
|
u.hook_add(new MyWriteInvalidHook(), Unicorn.UC_HOOK_MEM_WRITE_UNMAPPED, null);
|
||||||
|
|
||||||
// emulate machine code in infinite time
|
// emulate machine code in infinite time
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -72,9 +72,9 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, S
|
||||||
//required to load native method implementations
|
//required to load native method implementations
|
||||||
static {
|
static {
|
||||||
System.loadLibrary("unicorn_java"); //loads unicorn.dll or libunicorn.so
|
System.loadLibrary("unicorn_java"); //loads unicorn.dll or libunicorn.so
|
||||||
eventMemMap.put(UC_HOOK_MEM_READ_INVALID, UC_MEM_READ_INVALID);
|
eventMemMap.put(UC_HOOK_MEM_READ_UNMAPPED, UC_MEM_READ_UNMAPPED);
|
||||||
eventMemMap.put(UC_HOOK_MEM_WRITE_INVALID, UC_MEM_WRITE_INVALID);
|
eventMemMap.put(UC_HOOK_MEM_WRITE_UNMAPPED, UC_MEM_WRITE_UNMAPPED);
|
||||||
eventMemMap.put(UC_HOOK_MEM_FETCH_INVALID, UC_MEM_FETCH_INVALID);
|
eventMemMap.put(UC_HOOK_MEM_FETCH_UNMAPPED, UC_MEM_FETCH_UNMAPPED);
|
||||||
eventMemMap.put(UC_HOOK_MEM_READ_PROT, UC_MEM_READ_PROT);
|
eventMemMap.put(UC_HOOK_MEM_READ_PROT, UC_MEM_READ_PROT);
|
||||||
eventMemMap.put(UC_HOOK_MEM_WRITE_PROT, UC_MEM_WRITE_PROT);
|
eventMemMap.put(UC_HOOK_MEM_WRITE_PROT, UC_MEM_WRITE_PROT);
|
||||||
eventMemMap.put(UC_HOOK_MEM_FETCH_PROT, UC_MEM_FETCH_PROT);
|
eventMemMap.put(UC_HOOK_MEM_FETCH_PROT, UC_MEM_FETCH_PROT);
|
||||||
|
@ -140,10 +140,10 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, S
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoke all UC_HOOK_MEM_XXX_INVALID andor UC_HOOK_MEM_XXX_PROT callbacks registered
|
* Invoke all UC_HOOK_MEM_XXX_UNMAPPED andor UC_HOOK_MEM_XXX_PROT callbacks registered
|
||||||
* for a specific Unicorn.
|
* for a specific Unicorn.
|
||||||
* This function gets invoked from the native C callback registered for
|
* This function gets invoked from the native C callback registered for
|
||||||
* for UC_HOOK_MEM_XXX_INVALID or UC_HOOK_MEM_XXX_PROT
|
* for UC_HOOK_MEM_XXX_UNMAPPED or UC_HOOK_MEM_XXX_PROT
|
||||||
*
|
*
|
||||||
* @param eng A Unicorn uc_engine* eng returned by uc_open
|
* @param eng A Unicorn uc_engine* eng returned by uc_open
|
||||||
* @param type The type of event that is taking place
|
* @param type The type of event that is taking place
|
||||||
|
@ -535,12 +535,12 @@ public class Unicorn implements UnicornConst, ArmConst, Arm64Const, M68kConst, S
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook registration for UC_HOOK_MEM_XXX_INVALID and UC_HOOK_MEM_XXX_PROT hooks.
|
* Hook registration for UC_HOOK_MEM_XXX_UNMAPPED and UC_HOOK_MEM_XXX_PROT hooks.
|
||||||
* The registered callback function will be invoked whenever a read or write is
|
* The registered callback function will be invoked whenever a read or write is
|
||||||
* attempted from an invalid or protected memory address.
|
* attempted from an invalid or protected memory address.
|
||||||
*
|
*
|
||||||
* @param callback Implementation of a EventMemHook interface
|
* @param callback Implementation of a EventMemHook interface
|
||||||
* @param type Type of memory event being hooked such as UC_HOOK_MEM_READ_INVALID or UC_HOOK_MEM_WRITE_PROT
|
* @param type Type of memory event being hooked such as UC_HOOK_MEM_READ_UNMAPPED or UC_HOOK_MEM_WRITE_PROT
|
||||||
* @param user_data User data to be passed to the callback function each time the event is triggered
|
* @param user_data User data to be passed to the callback function each time the event is triggered
|
||||||
*/
|
*/
|
||||||
public void hook_add(EventMemHook callback, int type, Object user_data) throws UnicornException {
|
public void hook_add(EventMemHook callback, int type, Object user_data) throws UnicornException {
|
||||||
|
|
|
@ -41,26 +41,25 @@ public interface UnicornConst {
|
||||||
public static final int UC_ERR_HANDLE = 3;
|
public static final int UC_ERR_HANDLE = 3;
|
||||||
public static final int UC_ERR_MODE = 4;
|
public static final int UC_ERR_MODE = 4;
|
||||||
public static final int UC_ERR_VERSION = 5;
|
public static final int UC_ERR_VERSION = 5;
|
||||||
public static final int UC_ERR_READ_INVALID = 6;
|
public static final int UC_ERR_READ_UNMAPPED = 6;
|
||||||
public static final int UC_ERR_WRITE_INVALID = 7;
|
public static final int UC_ERR_WRITE_UNMAPPED = 7;
|
||||||
public static final int UC_ERR_FETCH_INVALID = 8;
|
public static final int UC_ERR_FETCH_UNMAPPED = 8;
|
||||||
public static final int UC_ERR_CODE_INVALID = 9;
|
public static final int UC_ERR_HOOK = 9;
|
||||||
public static final int UC_ERR_HOOK = 10;
|
public static final int UC_ERR_INSN_INVALID = 10;
|
||||||
public static final int UC_ERR_INSN_INVALID = 11;
|
public static final int UC_ERR_MAP = 11;
|
||||||
public static final int UC_ERR_MAP = 12;
|
public static final int UC_ERR_WRITE_PROT = 12;
|
||||||
public static final int UC_ERR_WRITE_PROT = 13;
|
public static final int UC_ERR_READ_PROT = 13;
|
||||||
public static final int UC_ERR_READ_PROT = 14;
|
public static final int UC_ERR_FETCH_PROT = 14;
|
||||||
public static final int UC_ERR_FETCH_PROT = 15;
|
public static final int UC_ERR_ARG = 15;
|
||||||
public static final int UC_ERR_ARG = 16;
|
public static final int UC_ERR_READ_UNALIGNED = 16;
|
||||||
public static final int UC_ERR_READ_UNALIGNED = 17;
|
public static final int UC_ERR_WRITE_UNALIGNED = 17;
|
||||||
public static final int UC_ERR_WRITE_UNALIGNED = 18;
|
public static final int UC_ERR_FETCH_UNALIGNED = 18;
|
||||||
public static final int UC_ERR_FETCH_UNALIGNED = 19;
|
|
||||||
public static final int UC_MEM_READ = 16;
|
public static final int UC_MEM_READ = 16;
|
||||||
public static final int UC_MEM_WRITE = 17;
|
public static final int UC_MEM_WRITE = 17;
|
||||||
public static final int UC_MEM_FETCH = 18;
|
public static final int UC_MEM_FETCH = 18;
|
||||||
public static final int UC_MEM_READ_INVALID = 19;
|
public static final int UC_MEM_READ_UNMAPPED = 19;
|
||||||
public static final int UC_MEM_WRITE_INVALID = 20;
|
public static final int UC_MEM_WRITE_UNMAPPED = 20;
|
||||||
public static final int UC_MEM_FETCH_INVALID = 21;
|
public static final int UC_MEM_FETCH_UNMAPPED = 21;
|
||||||
public static final int UC_MEM_WRITE_PROT = 22;
|
public static final int UC_MEM_WRITE_PROT = 22;
|
||||||
public static final int UC_MEM_READ_PROT = 23;
|
public static final int UC_MEM_READ_PROT = 23;
|
||||||
public static final int UC_MEM_FETCH_PROT = 24;
|
public static final int UC_MEM_FETCH_PROT = 24;
|
||||||
|
@ -68,9 +67,9 @@ public interface UnicornConst {
|
||||||
public static final int UC_HOOK_INSN = 2;
|
public static final int UC_HOOK_INSN = 2;
|
||||||
public static final int UC_HOOK_CODE = 4;
|
public static final int UC_HOOK_CODE = 4;
|
||||||
public static final int UC_HOOK_BLOCK = 8;
|
public static final int UC_HOOK_BLOCK = 8;
|
||||||
public static final int UC_HOOK_MEM_READ_INVALID = 16;
|
public static final int UC_HOOK_MEM_READ_UNMAPPED = 16;
|
||||||
public static final int UC_HOOK_MEM_WRITE_INVALID = 32;
|
public static final int UC_HOOK_MEM_WRITE_UNMAPPED = 32;
|
||||||
public static final int UC_HOOK_MEM_FETCH_INVALID = 64;
|
public static final int UC_HOOK_MEM_FETCH_UNMAPPED = 64;
|
||||||
public static final int UC_HOOK_MEM_READ_PROT = 128;
|
public static final int UC_HOOK_MEM_READ_PROT = 128;
|
||||||
public static final int UC_HOOK_MEM_WRITE_PROT = 256;
|
public static final int UC_HOOK_MEM_WRITE_PROT = 256;
|
||||||
public static final int UC_HOOK_MEM_FETCH_PROT = 512;
|
public static final int UC_HOOK_MEM_FETCH_PROT = 512;
|
||||||
|
|
|
@ -31,9 +31,8 @@ public interface UnicornErrors {
|
||||||
public static final int UC_ERR_VERSION = 6; // Unsupported version (bindings)
|
public static final int UC_ERR_VERSION = 6; // Unsupported version (bindings)
|
||||||
public static final int UC_ERR_MEM_READ = 7; // Quit emulation due to invalid memory READ: uc_emu_start()
|
public static final int UC_ERR_MEM_READ = 7; // Quit emulation due to invalid memory READ: uc_emu_start()
|
||||||
public static final int UC_ERR_MEM_WRITE = 8; // Quit emulation due to invalid memory WRITE: uc_emu_start()
|
public static final int UC_ERR_MEM_WRITE = 8; // Quit emulation due to invalid memory WRITE: uc_emu_start()
|
||||||
public static final int UC_ERR_CODE_INVALID = 9; // Quit emulation due to invalid code address: uc_emu_start()
|
public static final int UC_ERR_HOOK = 9; // Invalid hook type: uc_hook_add()
|
||||||
public static final int UC_ERR_HOOK = 10; // Invalid hook type: uc_hook_add()
|
public static final int UC_ERR_INSN_INVALID = 10; // Quit emulation due to invalid instruction: uc_emu_start()
|
||||||
public static final int UC_ERR_INSN_INVALID = 11; // Quit emulation due to invalid instruction: uc_emu_start()
|
public static final int UC_ERR_MAP = 11; // Invalid memory mapping: uc_mem_map()
|
||||||
public static final int UC_ERR_MAP = 12; // Invalid memory mapping: uc_mem_map()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -160,7 +160,7 @@ static void cb_hookmem(uc_engine *eng, uc_mem_type type,
|
||||||
(*cachedJVM)->DetachCurrentThread(cachedJVM);
|
(*cachedJVM)->DetachCurrentThread(cachedJVM);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Callback function for handling memory events (for UC_HOOK_MEM_INVALID)
|
// Callback function for handling memory events (for UC_HOOK_MEM_UNMAPPED)
|
||||||
// @type: this memory is being READ, or WRITE
|
// @type: this memory is being READ, or WRITE
|
||||||
// @address: address where the code is being executed
|
// @address: address where the code is being executed
|
||||||
// @size: size of data being read or written
|
// @size: size of data being read or written
|
||||||
|
@ -389,9 +389,9 @@ JNIEXPORT jlong JNICALL Java_unicorn_Unicorn_registerHook__JI
|
||||||
}
|
}
|
||||||
err = uc_hook_add((uc_engine*)eng, &hh, (uc_hook_type)type, cb_hookintr, env);
|
err = uc_hook_add((uc_engine*)eng, &hh, (uc_hook_type)type, cb_hookintr, env);
|
||||||
break;
|
break;
|
||||||
case UC_HOOK_MEM_FETCH_INVALID: // Hook for all invalid memory access events
|
case UC_HOOK_MEM_FETCH_UNMAPPED: // Hook for all invalid memory access events
|
||||||
case UC_HOOK_MEM_READ_INVALID: // Hook for all invalid memory access events
|
case UC_HOOK_MEM_READ_UNMAPPED: // Hook for all invalid memory access events
|
||||||
case UC_HOOK_MEM_WRITE_INVALID: // Hook for all invalid memory access events
|
case UC_HOOK_MEM_WRITE_UNMAPPED: // Hook for all invalid memory access events
|
||||||
case UC_HOOK_MEM_FETCH_PROT: // Hook for all invalid memory access events
|
case UC_HOOK_MEM_FETCH_PROT: // Hook for all invalid memory access events
|
||||||
case UC_HOOK_MEM_READ_PROT: // Hook for all invalid memory access events
|
case UC_HOOK_MEM_READ_PROT: // Hook for all invalid memory access events
|
||||||
case UC_HOOK_MEM_WRITE_PROT: // Hook for all invalid memory access events
|
case UC_HOOK_MEM_WRITE_PROT: // Hook for all invalid memory access events
|
||||||
|
|
|
@ -33,7 +33,7 @@ def hook_code(uc, address, size, user_data):
|
||||||
|
|
||||||
# callback for tracing invalid memory access (READ or WRITE)
|
# callback for tracing invalid memory access (READ or WRITE)
|
||||||
def hook_mem_invalid(uc, access, address, size, value, user_data):
|
def hook_mem_invalid(uc, access, address, size, value, user_data):
|
||||||
if access == UC_MEM_WRITE_INVALID:
|
if access == UC_MEM_WRITE_UNMAPPED:
|
||||||
print(">>> Missing memory is being WRITE at 0x%x, data size = %u, data value = 0x%x" \
|
print(">>> Missing memory is being WRITE at 0x%x, data size = %u, data value = 0x%x" \
|
||||||
%(address, size, value))
|
%(address, size, value))
|
||||||
# map this memory in with 2MB in size
|
# map this memory in with 2MB in size
|
||||||
|
@ -231,7 +231,7 @@ def test_i386_invalid_mem_write():
|
||||||
#mu.hook_add(UC_HOOK_CODE, hook_code)
|
#mu.hook_add(UC_HOOK_CODE, hook_code)
|
||||||
|
|
||||||
# intercept invalid memory events
|
# intercept invalid memory events
|
||||||
mu.hook_add(UC_HOOK_MEM_READ_INVALID | UC_HOOK_MEM_WRITE_INVALID, hook_mem_invalid)
|
mu.hook_add(UC_HOOK_MEM_READ_UNMAPPED | UC_HOOK_MEM_WRITE_UNMAPPED, hook_mem_invalid)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# emulate machine code in infinite time
|
# emulate machine code in infinite time
|
||||||
|
|
|
@ -272,8 +272,8 @@ class Uc(object):
|
||||||
cb = ctypes.cast(UC_HOOK_CODE_CB(self._hookcode_cb), UC_HOOK_CODE_CB)
|
cb = ctypes.cast(UC_HOOK_CODE_CB(self._hookcode_cb), UC_HOOK_CODE_CB)
|
||||||
status = _uc.uc_hook_add(self._uch, ctypes.byref(_h2), htype, cb, \
|
status = _uc.uc_hook_add(self._uch, ctypes.byref(_h2), htype, cb, \
|
||||||
ctypes.cast(self._callback_count, ctypes.c_void_p), begin, end)
|
ctypes.cast(self._callback_count, ctypes.c_void_p), begin, end)
|
||||||
elif htype & UC_HOOK_MEM_READ_INVALID or htype & UC_HOOK_MEM_WRITE_INVALID or \
|
elif htype & UC_HOOK_MEM_READ_UNMAPPED or htype & UC_HOOK_MEM_WRITE_UNMAPPED or \
|
||||||
htype & UC_HOOK_MEM_FETCH_INVALID or htype & UC_HOOK_MEM_READ_PROT or \
|
htype & UC_HOOK_MEM_FETCH_UNMAPPED or htype & UC_HOOK_MEM_READ_PROT or \
|
||||||
htype & UC_HOOK_MEM_WRITE_PROT or htype & UC_HOOK_MEM_FETCH_PROT:
|
htype & UC_HOOK_MEM_WRITE_PROT or htype & UC_HOOK_MEM_FETCH_PROT:
|
||||||
cb = ctypes.cast(UC_HOOK_MEM_INVALID_CB(self._hook_mem_invalid_cb), UC_HOOK_MEM_INVALID_CB)
|
cb = ctypes.cast(UC_HOOK_MEM_INVALID_CB(self._hook_mem_invalid_cb), UC_HOOK_MEM_INVALID_CB)
|
||||||
status = _uc.uc_hook_add(self._uch, ctypes.byref(_h2), htype, \
|
status = _uc.uc_hook_add(self._uch, ctypes.byref(_h2), htype, \
|
||||||
|
|
|
@ -37,26 +37,25 @@ UC_ERR_ARCH = 2
|
||||||
UC_ERR_HANDLE = 3
|
UC_ERR_HANDLE = 3
|
||||||
UC_ERR_MODE = 4
|
UC_ERR_MODE = 4
|
||||||
UC_ERR_VERSION = 5
|
UC_ERR_VERSION = 5
|
||||||
UC_ERR_READ_INVALID = 6
|
UC_ERR_READ_UNMAPPED = 6
|
||||||
UC_ERR_WRITE_INVALID = 7
|
UC_ERR_WRITE_UNMAPPED = 7
|
||||||
UC_ERR_FETCH_INVALID = 8
|
UC_ERR_FETCH_UNMAPPED = 8
|
||||||
UC_ERR_CODE_INVALID = 9
|
UC_ERR_HOOK = 9
|
||||||
UC_ERR_HOOK = 10
|
UC_ERR_INSN_INVALID = 10
|
||||||
UC_ERR_INSN_INVALID = 11
|
UC_ERR_MAP = 11
|
||||||
UC_ERR_MAP = 12
|
UC_ERR_WRITE_PROT = 12
|
||||||
UC_ERR_WRITE_PROT = 13
|
UC_ERR_READ_PROT = 13
|
||||||
UC_ERR_READ_PROT = 14
|
UC_ERR_FETCH_PROT = 14
|
||||||
UC_ERR_FETCH_PROT = 15
|
UC_ERR_ARG = 15
|
||||||
UC_ERR_ARG = 16
|
UC_ERR_READ_UNALIGNED = 16
|
||||||
UC_ERR_READ_UNALIGNED = 17
|
UC_ERR_WRITE_UNALIGNED = 17
|
||||||
UC_ERR_WRITE_UNALIGNED = 18
|
UC_ERR_FETCH_UNALIGNED = 18
|
||||||
UC_ERR_FETCH_UNALIGNED = 19
|
|
||||||
UC_MEM_READ = 16
|
UC_MEM_READ = 16
|
||||||
UC_MEM_WRITE = 17
|
UC_MEM_WRITE = 17
|
||||||
UC_MEM_FETCH = 18
|
UC_MEM_FETCH = 18
|
||||||
UC_MEM_READ_INVALID = 19
|
UC_MEM_READ_UNMAPPED = 19
|
||||||
UC_MEM_WRITE_INVALID = 20
|
UC_MEM_WRITE_UNMAPPED = 20
|
||||||
UC_MEM_FETCH_INVALID = 21
|
UC_MEM_FETCH_UNMAPPED = 21
|
||||||
UC_MEM_WRITE_PROT = 22
|
UC_MEM_WRITE_PROT = 22
|
||||||
UC_MEM_READ_PROT = 23
|
UC_MEM_READ_PROT = 23
|
||||||
UC_MEM_FETCH_PROT = 24
|
UC_MEM_FETCH_PROT = 24
|
||||||
|
@ -64,9 +63,9 @@ UC_HOOK_INTR = 1
|
||||||
UC_HOOK_INSN = 2
|
UC_HOOK_INSN = 2
|
||||||
UC_HOOK_CODE = 4
|
UC_HOOK_CODE = 4
|
||||||
UC_HOOK_BLOCK = 8
|
UC_HOOK_BLOCK = 8
|
||||||
UC_HOOK_MEM_READ_INVALID = 16
|
UC_HOOK_MEM_READ_UNMAPPED = 16
|
||||||
UC_HOOK_MEM_WRITE_INVALID = 32
|
UC_HOOK_MEM_WRITE_UNMAPPED = 32
|
||||||
UC_HOOK_MEM_FETCH_INVALID = 64
|
UC_HOOK_MEM_FETCH_UNMAPPED = 64
|
||||||
UC_HOOK_MEM_READ_PROT = 128
|
UC_HOOK_MEM_READ_PROT = 128
|
||||||
UC_HOOK_MEM_WRITE_PROT = 256
|
UC_HOOK_MEM_WRITE_PROT = 256
|
||||||
UC_HOOK_MEM_FETCH_PROT = 512
|
UC_HOOK_MEM_FETCH_PROT = 512
|
||||||
|
|
|
@ -185,6 +185,7 @@ struct uc_struct {
|
||||||
void *qemu_thread_data; // to support cross compile to Windows (qemu-thread-win32.c)
|
void *qemu_thread_data; // to support cross compile to Windows (qemu-thread-win32.c)
|
||||||
uint32_t target_page_size;
|
uint32_t target_page_size;
|
||||||
uint32_t target_page_align;
|
uint32_t target_page_align;
|
||||||
|
uint64_t next_pc; // save next PC for some special cases
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "qemu_macro.h"
|
#include "qemu_macro.h"
|
||||||
|
|
|
@ -111,10 +111,9 @@ typedef enum uc_err {
|
||||||
UC_ERR_HANDLE, // Invalid handle
|
UC_ERR_HANDLE, // Invalid handle
|
||||||
UC_ERR_MODE, // Invalid/unsupported mode: uc_open()
|
UC_ERR_MODE, // Invalid/unsupported mode: uc_open()
|
||||||
UC_ERR_VERSION, // Unsupported version (bindings)
|
UC_ERR_VERSION, // Unsupported version (bindings)
|
||||||
UC_ERR_READ_INVALID, // Quit emulation due to invalid memory READ: uc_emu_start()
|
UC_ERR_READ_UNMAPPED, // Quit emulation due to READ on unmapped memory: uc_emu_start()
|
||||||
UC_ERR_WRITE_INVALID, // Quit emulation due to invalid memory WRITE: uc_emu_start()
|
UC_ERR_WRITE_UNMAPPED, // Quit emulation due to WRITE on unmapped memory: uc_emu_start()
|
||||||
UC_ERR_FETCH_INVALID, // Quit emulation due to invalid memory FETCH: uc_emu_start()
|
UC_ERR_FETCH_UNMAPPED, // Quit emulation due to FETCH on unmapped memory: uc_emu_start()
|
||||||
UC_ERR_CODE_INVALID, // Quit emulation due to invalid code address: uc_emu_start()
|
|
||||||
UC_ERR_HOOK, // Invalid hook type: uc_hook_add()
|
UC_ERR_HOOK, // Invalid hook type: uc_hook_add()
|
||||||
UC_ERR_INSN_INVALID, // Quit emulation due to invalid instruction: uc_emu_start()
|
UC_ERR_INSN_INVALID, // Quit emulation due to invalid instruction: uc_emu_start()
|
||||||
UC_ERR_MAP, // Invalid memory mapping: uc_mem_map()
|
UC_ERR_MAP, // Invalid memory mapping: uc_mem_map()
|
||||||
|
@ -156,9 +155,9 @@ typedef enum uc_mem_type {
|
||||||
UC_MEM_READ = 16, // Memory is read from
|
UC_MEM_READ = 16, // Memory is read from
|
||||||
UC_MEM_WRITE, // Memory is written to
|
UC_MEM_WRITE, // Memory is written to
|
||||||
UC_MEM_FETCH, // Memory is fetched
|
UC_MEM_FETCH, // Memory is fetched
|
||||||
UC_MEM_READ_INVALID, // Unmapped memory is read from
|
UC_MEM_READ_UNMAPPED, // Unmapped memory is read from
|
||||||
UC_MEM_WRITE_INVALID, // Unmapped memory is written to
|
UC_MEM_WRITE_UNMAPPED, // Unmapped memory is written to
|
||||||
UC_MEM_FETCH_INVALID, // Unmapped memory is fetched
|
UC_MEM_FETCH_UNMAPPED, // Unmapped memory is fetched
|
||||||
UC_MEM_WRITE_PROT, // Write to write protected, but mapped, memory
|
UC_MEM_WRITE_PROT, // Write to write protected, but mapped, memory
|
||||||
UC_MEM_READ_PROT, // Read from read protected, but mapped, memory
|
UC_MEM_READ_PROT, // Read from read protected, but mapped, memory
|
||||||
UC_MEM_FETCH_PROT, // Fetch from non-executable, but mapped, memory
|
UC_MEM_FETCH_PROT, // Fetch from non-executable, but mapped, memory
|
||||||
|
@ -166,13 +165,13 @@ typedef enum uc_mem_type {
|
||||||
|
|
||||||
// All type of hooks for uc_hook_add() API.
|
// All type of hooks for uc_hook_add() API.
|
||||||
typedef enum uc_hook_type {
|
typedef enum uc_hook_type {
|
||||||
UC_HOOK_INTR = 1 << 0, // Hook all interrupt events
|
UC_HOOK_INTR = 1 << 0, // Hook all interrupt/syscall events
|
||||||
UC_HOOK_INSN = 1 << 1, // Hook a particular instruction
|
UC_HOOK_INSN = 1 << 1, // Hook a particular instruction
|
||||||
UC_HOOK_CODE = 1 << 2, // Hook a range of code
|
UC_HOOK_CODE = 1 << 2, // Hook a range of code
|
||||||
UC_HOOK_BLOCK = 1 << 3, // Hook basic blocks
|
UC_HOOK_BLOCK = 1 << 3, // Hook basic blocks
|
||||||
UC_HOOK_MEM_READ_INVALID = 1 << 4, // Hook for invalid memory read events
|
UC_HOOK_MEM_READ_UNMAPPED = 1 << 4, // Hook for memory read on unmapped memory
|
||||||
UC_HOOK_MEM_WRITE_INVALID = 1 << 5, // Hook for invalid memory write events
|
UC_HOOK_MEM_WRITE_UNMAPPED = 1 << 5, // Hook for invalid memory write events
|
||||||
UC_HOOK_MEM_FETCH_INVALID = 1 << 6, // Hook for invalid memory fetch for execution events
|
UC_HOOK_MEM_FETCH_UNMAPPED = 1 << 6, // Hook for invalid memory fetch for execution events
|
||||||
UC_HOOK_MEM_READ_PROT = 1 << 7, // Hook for memory read on read-protected memory
|
UC_HOOK_MEM_READ_PROT = 1 << 7, // Hook for memory read on read-protected memory
|
||||||
UC_HOOK_MEM_WRITE_PROT = 1 << 8, // Hook for memory write on write-protected memory
|
UC_HOOK_MEM_WRITE_PROT = 1 << 8, // Hook for memory write on write-protected memory
|
||||||
UC_HOOK_MEM_FETCH_PROT = 1 << 9, // Hook for memory fetch on non-executable memory
|
UC_HOOK_MEM_FETCH_PROT = 1 << 9, // Hook for memory fetch on non-executable memory
|
||||||
|
@ -182,17 +181,17 @@ typedef enum uc_hook_type {
|
||||||
} uc_hook_type;
|
} uc_hook_type;
|
||||||
|
|
||||||
// hook type for all events of unmapped memory access
|
// hook type for all events of unmapped memory access
|
||||||
#define UC_HOOK_MEM_INVALID (UC_HOOK_MEM_READ_INVALID + UC_HOOK_MEM_WRITE_INVALID + UC_HOOK_MEM_FETCH_INVALID)
|
#define UC_HOOK_MEM_UNMAPPED (UC_HOOK_MEM_READ_UNMAPPED + UC_HOOK_MEM_WRITE_UNMAPPED + UC_HOOK_MEM_FETCH_UNMAPPED)
|
||||||
// hook type for all events of illegal protected memory access
|
// hook type for all events of illegal protected memory access
|
||||||
#define UC_HOOK_MEM_PROT (UC_HOOK_MEM_READ_PROT + UC_HOOK_MEM_WRITE_PROT + UC_HOOK_MEM_FETCH_PROT)
|
#define UC_HOOK_MEM_PROT (UC_HOOK_MEM_READ_PROT + UC_HOOK_MEM_WRITE_PROT + UC_HOOK_MEM_FETCH_PROT)
|
||||||
// hook type for all events of illegal read memory access
|
// hook type for all events of illegal read memory access
|
||||||
#define UC_HOOK_MEM_READ_ERR (UC_HOOK_MEM_READ_PROT + UC_HOOK_MEM_READ_INVALID)
|
#define UC_HOOK_MEM_READ_INVALID (UC_HOOK_MEM_READ_PROT + UC_HOOK_MEM_READ_UNMAPPED)
|
||||||
// hook type for all events of illegal write memory access
|
// hook type for all events of illegal write memory access
|
||||||
#define UC_HOOK_MEM_WRITE_ERR (UC_HOOK_MEM_WRITE_PROT + UC_HOOK_MEM_WRITE_INVALID)
|
#define UC_HOOK_MEM_WRITE_INVALID (UC_HOOK_MEM_WRITE_PROT + UC_HOOK_MEM_WRITE_UNMAPPED)
|
||||||
// hook type for all events of illegal fetch memory access
|
// hook type for all events of illegal fetch memory access
|
||||||
#define UC_HOOK_MEM_FETCH_ERR (UC_HOOK_MEM_FETCH_PROT + UC_HOOK_MEM_FETCH_INVALID)
|
#define UC_HOOK_MEM_FETCH_INVALID (UC_HOOK_MEM_FETCH_PROT + UC_HOOK_MEM_FETCH_UNMAPPED)
|
||||||
// hook type for all events of illegal memory access
|
// hook type for all events of illegal memory access
|
||||||
#define UC_HOOK_MEM_ERR (UC_HOOK_MEM_INVALID + UC_HOOK_MEM_PROT)
|
#define UC_HOOK_MEM_INVALID (UC_HOOK_MEM_UNMAPPED + UC_HOOK_MEM_PROT)
|
||||||
|
|
||||||
// Callback function for hooking memory (UC_MEM_READ, UC_MEM_WRITE & UC_MEM_FETCH)
|
// Callback function for hooking memory (UC_MEM_READ, UC_MEM_WRITE & UC_MEM_FETCH)
|
||||||
// @type: this memory is being READ, or WRITE
|
// @type: this memory is being READ, or WRITE
|
||||||
|
@ -203,7 +202,7 @@ typedef enum uc_hook_type {
|
||||||
typedef void (*uc_cb_hookmem_t)(uc_engine *uc, uc_mem_type type,
|
typedef void (*uc_cb_hookmem_t)(uc_engine *uc, uc_mem_type type,
|
||||||
uint64_t address, int size, int64_t value, void *user_data);
|
uint64_t address, int size, int64_t value, void *user_data);
|
||||||
|
|
||||||
// Callback function for handling invalid memory access events (UC_MEM_*_INVALID and
|
// Callback function for handling invalid memory access events (UC_MEM_*_UNMAPPED and
|
||||||
// UC_MEM_*PROT events)
|
// UC_MEM_*PROT events)
|
||||||
// @type: this memory is being READ, or WRITE
|
// @type: this memory is being READ, or WRITE
|
||||||
// @address: address where the code is being executed
|
// @address: address where the code is being executed
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/* Autogen header for Unicorn Engine - DONOT MODIFY */
|
/* Autogen header for Unicorn Engine - DONOT MODIFY */
|
||||||
#ifndef UNICORN_AUTOGEN_AARCH64_H
|
#ifndef UNICORN_AUTOGEN_AARCH64_H
|
||||||
#define UNICORN_AUTOGEN_AARCH64_H
|
#define UNICORN_AUTOGEN_AARCH64_H
|
||||||
|
#define helper_power_down helper_power_down_aarch64
|
||||||
#define check_exit_request check_exit_request_aarch64
|
#define check_exit_request check_exit_request_aarch64
|
||||||
#define address_space_unregister address_space_unregister_aarch64
|
#define address_space_unregister address_space_unregister_aarch64
|
||||||
#define tb_invalidate_phys_page_fast tb_invalidate_phys_page_fast_aarch64
|
#define tb_invalidate_phys_page_fast tb_invalidate_phys_page_fast_aarch64
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/* Autogen header for Unicorn Engine - DONOT MODIFY */
|
/* Autogen header for Unicorn Engine - DONOT MODIFY */
|
||||||
#ifndef UNICORN_AUTOGEN_ARM_H
|
#ifndef UNICORN_AUTOGEN_ARM_H
|
||||||
#define UNICORN_AUTOGEN_ARM_H
|
#define UNICORN_AUTOGEN_ARM_H
|
||||||
|
#define helper_power_down helper_power_down_arm
|
||||||
#define check_exit_request check_exit_request_arm
|
#define check_exit_request check_exit_request_arm
|
||||||
#define address_space_unregister address_space_unregister_arm
|
#define address_space_unregister address_space_unregister_arm
|
||||||
#define tb_invalidate_phys_page_fast tb_invalidate_phys_page_fast_arm
|
#define tb_invalidate_phys_page_fast tb_invalidate_phys_page_fast_arm
|
||||||
|
|
|
@ -108,18 +108,6 @@ int cpu_exec(struct uc_struct *uc, CPUArchState *env) // qq
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((uc->arch == UC_ARCH_X86 && cpu->exception_index == 0x99) || // X86's Int 0x99
|
|
||||||
(uc->arch == UC_ARCH_ARM && cpu->exception_index == 2) || /* ARM's EXCP_SWI */
|
|
||||||
(uc->arch == UC_ARCH_ARM64 && cpu->exception_index == 2) || /* ARM's EXCP_SWI */
|
|
||||||
(uc->arch == UC_ARCH_MIPS && cpu->exception_index == 17) || /* Mips's EXCP_SYSCALL */
|
|
||||||
(uc->arch == UC_ARCH_SPARC && cpu->exception_index == 0x80) || /* Sparc's TT_TRAP */
|
|
||||||
(uc->arch == UC_ARCH_SPARC && cpu->exception_index == 0x100) || /* Sparc64's TT_TRAP */
|
|
||||||
(uc->arch == UC_ARCH_M68K && cpu->exception_index == 0x2f) /* M68K's EXCP_TRAP15 */
|
|
||||||
) {
|
|
||||||
cpu->halted = 1;
|
|
||||||
ret = EXCP_HLT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (cpu->exception_index >= EXCP_INTERRUPT) {
|
if (cpu->exception_index >= EXCP_INTERRUPT) {
|
||||||
/* exit request from the cpu execution loop */
|
/* exit request from the cpu execution loop */
|
||||||
ret = cpu->exception_index;
|
ret = cpu->exception_index;
|
||||||
|
@ -148,6 +136,9 @@ int cpu_exec(struct uc_struct *uc, CPUArchState *env) // qq
|
||||||
// point EIP to the next instruction after INT
|
// point EIP to the next instruction after INT
|
||||||
env->eip = env->exception_next_eip;
|
env->eip = env->exception_next_eip;
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(TARGET_MIPS) || defined(TARGET_MIPS64)
|
||||||
|
env->active_tc.PC = uc->next_pc;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -209,7 +200,7 @@ int cpu_exec(struct uc_struct *uc, CPUArchState *env) // qq
|
||||||
have_tb_lock = true;
|
have_tb_lock = true;
|
||||||
tb = tb_find_fast(env); // qq
|
tb = tb_find_fast(env); // qq
|
||||||
if (!tb) { // invalid TB due to invalid code?
|
if (!tb) { // invalid TB due to invalid code?
|
||||||
uc->invalid_error = UC_ERR_CODE_INVALID;
|
uc->invalid_error = UC_ERR_FETCH_UNMAPPED;
|
||||||
ret = EXCP_HLT;
|
ret = EXCP_HLT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
|
|
||||||
static void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr);
|
static void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr);
|
||||||
static bool tlb_is_dirty_ram(CPUTLBEntry *tlbe);
|
static bool tlb_is_dirty_ram(CPUTLBEntry *tlbe);
|
||||||
static ram_addr_t qemu_ram_addr_from_host_nofail(struct uc_struct *uc, void *ptr);
|
static bool qemu_ram_addr_from_host_nofail(struct uc_struct *uc, void *ptr, ram_addr_t *addr);
|
||||||
static void tlb_add_large_page(CPUArchState *env, target_ulong vaddr,
|
static void tlb_add_large_page(CPUArchState *env, target_ulong vaddr,
|
||||||
target_ulong size);
|
target_ulong size);
|
||||||
static void tlb_set_dirty1(CPUTLBEntry *tlb_entry, target_ulong vaddr);
|
static void tlb_set_dirty1(CPUTLBEntry *tlb_entry, target_ulong vaddr);
|
||||||
|
@ -292,6 +292,7 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
|
||||||
int mmu_idx, page_index, pd;
|
int mmu_idx, page_index, pd;
|
||||||
void *p;
|
void *p;
|
||||||
MemoryRegion *mr;
|
MemoryRegion *mr;
|
||||||
|
ram_addr_t ram_addr;
|
||||||
CPUState *cpu = ENV_GET_CPU(env1);
|
CPUState *cpu = ENV_GET_CPU(env1);
|
||||||
|
|
||||||
page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
|
page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
|
||||||
|
@ -301,7 +302,6 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
|
||||||
cpu_ldub_code(env1, addr);
|
cpu_ldub_code(env1, addr);
|
||||||
//check for NX related error from softmmu
|
//check for NX related error from softmmu
|
||||||
if (env1->invalid_error == UC_ERR_FETCH_PROT) {
|
if (env1->invalid_error == UC_ERR_FETCH_PROT) {
|
||||||
env1->invalid_error = UC_ERR_CODE_INVALID;
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -316,23 +316,27 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
|
||||||
//cpu_abort(cpu, "Trying to execute code outside RAM or ROM at 0x"
|
//cpu_abort(cpu, "Trying to execute code outside RAM or ROM at 0x"
|
||||||
// TARGET_FMT_lx "\n", addr); // qq
|
// TARGET_FMT_lx "\n", addr); // qq
|
||||||
env1->invalid_addr = addr;
|
env1->invalid_addr = addr;
|
||||||
env1->invalid_error = UC_ERR_CODE_INVALID;
|
env1->invalid_error = UC_ERR_FETCH_UNMAPPED;
|
||||||
return -1; // qq FIXME
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p = (void *)((uintptr_t)addr + env1->tlb_table[mmu_idx][page_index].addend);
|
p = (void *)((uintptr_t)addr + env1->tlb_table[mmu_idx][page_index].addend);
|
||||||
return qemu_ram_addr_from_host_nofail(cpu->uc, p);
|
if (!qemu_ram_addr_from_host_nofail(cpu->uc, p, &ram_addr)) {
|
||||||
|
env1->invalid_addr = addr;
|
||||||
|
env1->invalid_error = UC_ERR_FETCH_UNMAPPED;
|
||||||
|
return -1;
|
||||||
|
} else
|
||||||
|
return ram_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ram_addr_t qemu_ram_addr_from_host_nofail(struct uc_struct *uc, void *ptr)
|
static bool qemu_ram_addr_from_host_nofail(struct uc_struct *uc, void *ptr, ram_addr_t *ram_addr)
|
||||||
{
|
{
|
||||||
ram_addr_t ram_addr;
|
if (qemu_ram_addr_from_host(uc, ptr, ram_addr) == NULL) {
|
||||||
|
// fprintf(stderr, "Bad ram pointer %p\n", ptr);
|
||||||
if (qemu_ram_addr_from_host(uc, ptr, &ram_addr) == NULL) {
|
return false;
|
||||||
fprintf(stderr, "Bad ram pointer %p\n", ptr);
|
|
||||||
abort();
|
|
||||||
}
|
}
|
||||||
return ram_addr;
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tlb_set_dirty1(CPUTLBEntry *tlb_entry, target_ulong vaddr)
|
static void tlb_set_dirty1(CPUTLBEntry *tlb_entry, target_ulong vaddr)
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
symbols = (
|
symbols = (
|
||||||
|
'helper_power_down',
|
||||||
'check_exit_request',
|
'check_exit_request',
|
||||||
'address_space_unregister',
|
'address_space_unregister',
|
||||||
'tb_invalidate_phys_page_fast',
|
'tb_invalidate_phys_page_fast',
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
|
#include <setjmp.h>
|
||||||
|
|
||||||
/* Workaround for older versions of MinGW. */
|
/* Workaround for older versions of MinGW. */
|
||||||
#ifndef ECONNREFUSED
|
#ifndef ECONNREFUSED
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/* Autogen header for Unicorn Engine - DONOT MODIFY */
|
/* Autogen header for Unicorn Engine - DONOT MODIFY */
|
||||||
#ifndef UNICORN_AUTOGEN_M68K_H
|
#ifndef UNICORN_AUTOGEN_M68K_H
|
||||||
#define UNICORN_AUTOGEN_M68K_H
|
#define UNICORN_AUTOGEN_M68K_H
|
||||||
|
#define helper_power_down helper_power_down_m68k
|
||||||
#define check_exit_request check_exit_request_m68k
|
#define check_exit_request check_exit_request_m68k
|
||||||
#define address_space_unregister address_space_unregister_m68k
|
#define address_space_unregister address_space_unregister_m68k
|
||||||
#define tb_invalidate_phys_page_fast tb_invalidate_phys_page_fast_m68k
|
#define tb_invalidate_phys_page_fast tb_invalidate_phys_page_fast_m68k
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/* Autogen header for Unicorn Engine - DONOT MODIFY */
|
/* Autogen header for Unicorn Engine - DONOT MODIFY */
|
||||||
#ifndef UNICORN_AUTOGEN_MIPS_H
|
#ifndef UNICORN_AUTOGEN_MIPS_H
|
||||||
#define UNICORN_AUTOGEN_MIPS_H
|
#define UNICORN_AUTOGEN_MIPS_H
|
||||||
|
#define helper_power_down helper_power_down_mips
|
||||||
#define check_exit_request check_exit_request_mips
|
#define check_exit_request check_exit_request_mips
|
||||||
#define address_space_unregister address_space_unregister_mips
|
#define address_space_unregister address_space_unregister_mips
|
||||||
#define tb_invalidate_phys_page_fast tb_invalidate_phys_page_fast_mips
|
#define tb_invalidate_phys_page_fast tb_invalidate_phys_page_fast_mips
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/* Autogen header for Unicorn Engine - DONOT MODIFY */
|
/* Autogen header for Unicorn Engine - DONOT MODIFY */
|
||||||
#ifndef UNICORN_AUTOGEN_MIPS64_H
|
#ifndef UNICORN_AUTOGEN_MIPS64_H
|
||||||
#define UNICORN_AUTOGEN_MIPS64_H
|
#define UNICORN_AUTOGEN_MIPS64_H
|
||||||
|
#define helper_power_down helper_power_down_mips64
|
||||||
#define check_exit_request check_exit_request_mips64
|
#define check_exit_request check_exit_request_mips64
|
||||||
#define address_space_unregister address_space_unregister_mips64
|
#define address_space_unregister address_space_unregister_mips64
|
||||||
#define tb_invalidate_phys_page_fast tb_invalidate_phys_page_fast_mips64
|
#define tb_invalidate_phys_page_fast tb_invalidate_phys_page_fast_mips64
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/* Autogen header for Unicorn Engine - DONOT MODIFY */
|
/* Autogen header for Unicorn Engine - DONOT MODIFY */
|
||||||
#ifndef UNICORN_AUTOGEN_MIPS64EL_H
|
#ifndef UNICORN_AUTOGEN_MIPS64EL_H
|
||||||
#define UNICORN_AUTOGEN_MIPS64EL_H
|
#define UNICORN_AUTOGEN_MIPS64EL_H
|
||||||
|
#define helper_power_down helper_power_down_mips64el
|
||||||
#define check_exit_request check_exit_request_mips64el
|
#define check_exit_request check_exit_request_mips64el
|
||||||
#define address_space_unregister address_space_unregister_mips64el
|
#define address_space_unregister address_space_unregister_mips64el
|
||||||
#define tb_invalidate_phys_page_fast tb_invalidate_phys_page_fast_mips64el
|
#define tb_invalidate_phys_page_fast tb_invalidate_phys_page_fast_mips64el
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/* Autogen header for Unicorn Engine - DONOT MODIFY */
|
/* Autogen header for Unicorn Engine - DONOT MODIFY */
|
||||||
#ifndef UNICORN_AUTOGEN_MIPSEL_H
|
#ifndef UNICORN_AUTOGEN_MIPSEL_H
|
||||||
#define UNICORN_AUTOGEN_MIPSEL_H
|
#define UNICORN_AUTOGEN_MIPSEL_H
|
||||||
|
#define helper_power_down helper_power_down_mipsel
|
||||||
#define check_exit_request check_exit_request_mipsel
|
#define check_exit_request check_exit_request_mipsel
|
||||||
#define address_space_unregister address_space_unregister_mipsel
|
#define address_space_unregister address_space_unregister_mipsel
|
||||||
#define tb_invalidate_phys_page_fast tb_invalidate_phys_page_fast_mipsel
|
#define tb_invalidate_phys_page_fast tb_invalidate_phys_page_fast_mipsel
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/* Autogen header for Unicorn Engine - DONOT MODIFY */
|
/* Autogen header for Unicorn Engine - DONOT MODIFY */
|
||||||
#ifndef UNICORN_AUTOGEN_POWERPC_H
|
#ifndef UNICORN_AUTOGEN_POWERPC_H
|
||||||
#define UNICORN_AUTOGEN_POWERPC_H
|
#define UNICORN_AUTOGEN_POWERPC_H
|
||||||
|
#define helper_power_down helper_power_down_powerpc
|
||||||
#define check_exit_request check_exit_request_powerpc
|
#define check_exit_request check_exit_request_powerpc
|
||||||
#define address_space_unregister address_space_unregister_powerpc
|
#define address_space_unregister address_space_unregister_powerpc
|
||||||
#define tb_invalidate_phys_page_fast tb_invalidate_phys_page_fast_powerpc
|
#define tb_invalidate_phys_page_fast tb_invalidate_phys_page_fast_powerpc
|
||||||
|
|
|
@ -185,14 +185,14 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||||
// memory can be unmapped while reading or fetching
|
// memory can be unmapped while reading or fetching
|
||||||
if (mr == NULL) {
|
if (mr == NULL) {
|
||||||
#if defined(SOFTMMU_CODE_ACCESS)
|
#if defined(SOFTMMU_CODE_ACCESS)
|
||||||
error_code = UC_ERR_FETCH_INVALID;
|
error_code = UC_ERR_FETCH_UNMAPPED;
|
||||||
if (uc->hook_mem_fetch_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_fetch_idx].callback)(
|
if (uc->hook_mem_fetch_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_fetch_idx].callback)(
|
||||||
uc, UC_MEM_FETCH_INVALID, addr, DATA_SIZE, 0,
|
uc, UC_MEM_FETCH_UNMAPPED, addr, DATA_SIZE, 0,
|
||||||
uc->hook_callbacks[uc->hook_mem_fetch_idx].user_data)) {
|
uc->hook_callbacks[uc->hook_mem_fetch_idx].user_data)) {
|
||||||
#else
|
#else
|
||||||
error_code = UC_ERR_READ_INVALID;
|
error_code = UC_ERR_READ_UNMAPPED;
|
||||||
if (uc->hook_mem_read_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_read_idx].callback)(
|
if (uc->hook_mem_read_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_read_idx].callback)(
|
||||||
uc, UC_MEM_READ_INVALID, addr, DATA_SIZE, 0,
|
uc, UC_MEM_READ_UNMAPPED, addr, DATA_SIZE, 0,
|
||||||
uc->hook_callbacks[uc->hook_mem_read_idx].user_data)) {
|
uc->hook_callbacks[uc->hook_mem_read_idx].user_data)) {
|
||||||
#endif
|
#endif
|
||||||
env->invalid_error = UC_ERR_OK;
|
env->invalid_error = UC_ERR_OK;
|
||||||
|
@ -284,7 +284,7 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||||
ioaddr = env->iotlb[mmu_idx][index];
|
ioaddr = env->iotlb[mmu_idx][index];
|
||||||
if (ioaddr == 0) {
|
if (ioaddr == 0) {
|
||||||
env->invalid_addr = addr;
|
env->invalid_addr = addr;
|
||||||
env->invalid_error = UC_ERR_READ_INVALID;
|
env->invalid_error = UC_ERR_READ_UNMAPPED;
|
||||||
// printf("Invalid memory read at " TARGET_FMT_lx "\n", addr);
|
// printf("Invalid memory read at " TARGET_FMT_lx "\n", addr);
|
||||||
cpu_exit(env->uc->current_cpu);
|
cpu_exit(env->uc->current_cpu);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -376,14 +376,14 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||||
// memory can be unmapped while reading or fetching
|
// memory can be unmapped while reading or fetching
|
||||||
if (mr == NULL) {
|
if (mr == NULL) {
|
||||||
#if defined(SOFTMMU_CODE_ACCESS)
|
#if defined(SOFTMMU_CODE_ACCESS)
|
||||||
error_code = UC_ERR_FETCH_INVALID;
|
error_code = UC_ERR_FETCH_UNMAPPED;
|
||||||
if (uc->hook_mem_fetch_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_fetch_idx].callback)(
|
if (uc->hook_mem_fetch_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_fetch_idx].callback)(
|
||||||
uc, UC_MEM_FETCH_INVALID, addr, DATA_SIZE, 0,
|
uc, UC_MEM_FETCH_UNMAPPED, addr, DATA_SIZE, 0,
|
||||||
uc->hook_callbacks[uc->hook_mem_fetch_idx].user_data)) {
|
uc->hook_callbacks[uc->hook_mem_fetch_idx].user_data)) {
|
||||||
#else
|
#else
|
||||||
error_code = UC_ERR_READ_INVALID;
|
error_code = UC_ERR_READ_UNMAPPED;
|
||||||
if (uc->hook_mem_read_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_read_idx].callback)(
|
if (uc->hook_mem_read_idx != 0 && ((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_read_idx].callback)(
|
||||||
uc, UC_MEM_READ_INVALID, addr, DATA_SIZE, 0,
|
uc, UC_MEM_READ_UNMAPPED, addr, DATA_SIZE, 0,
|
||||||
uc->hook_callbacks[uc->hook_mem_read_idx].user_data)) {
|
uc->hook_callbacks[uc->hook_mem_read_idx].user_data)) {
|
||||||
#endif
|
#endif
|
||||||
env->invalid_error = UC_ERR_OK;
|
env->invalid_error = UC_ERR_OK;
|
||||||
|
@ -475,7 +475,7 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||||
|
|
||||||
if (ioaddr == 0) {
|
if (ioaddr == 0) {
|
||||||
env->invalid_addr = addr;
|
env->invalid_addr = addr;
|
||||||
env->invalid_error = UC_ERR_READ_INVALID;
|
env->invalid_error = UC_ERR_READ_UNMAPPED;
|
||||||
// printf("Invalid memory read at " TARGET_FMT_lx "\n", addr);
|
// printf("Invalid memory read at " TARGET_FMT_lx "\n", addr);
|
||||||
cpu_exit(env->uc->current_cpu);
|
cpu_exit(env->uc->current_cpu);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -612,11 +612,11 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||||
// Unicorn: callback on invalid memory
|
// Unicorn: callback on invalid memory
|
||||||
if (uc->hook_mem_write_idx && mr == NULL) {
|
if (uc->hook_mem_write_idx && mr == NULL) {
|
||||||
if (!((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_write_idx].callback)(
|
if (!((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_write_idx].callback)(
|
||||||
uc, UC_MEM_WRITE_INVALID, addr, DATA_SIZE, (int64_t)val,
|
uc, UC_MEM_WRITE_UNMAPPED, addr, DATA_SIZE, (int64_t)val,
|
||||||
uc->hook_callbacks[uc->hook_mem_write_idx].user_data)) {
|
uc->hook_callbacks[uc->hook_mem_write_idx].user_data)) {
|
||||||
// save error & quit
|
// save error & quit
|
||||||
env->invalid_addr = addr;
|
env->invalid_addr = addr;
|
||||||
env->invalid_error = UC_ERR_WRITE_INVALID;
|
env->invalid_error = UC_ERR_WRITE_UNMAPPED;
|
||||||
// printf("***** Invalid memory write at " TARGET_FMT_lx "\n", addr);
|
// printf("***** Invalid memory write at " TARGET_FMT_lx "\n", addr);
|
||||||
cpu_exit(uc->current_cpu);
|
cpu_exit(uc->current_cpu);
|
||||||
return;
|
return;
|
||||||
|
@ -673,7 +673,7 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||||
ioaddr = env->iotlb[mmu_idx][index];
|
ioaddr = env->iotlb[mmu_idx][index];
|
||||||
if (ioaddr == 0) {
|
if (ioaddr == 0) {
|
||||||
env->invalid_addr = addr;
|
env->invalid_addr = addr;
|
||||||
env->invalid_error = UC_ERR_WRITE_INVALID;
|
env->invalid_error = UC_ERR_WRITE_UNMAPPED;
|
||||||
// printf("***** Invalid memory write at " TARGET_FMT_lx "\n", addr);
|
// printf("***** Invalid memory write at " TARGET_FMT_lx "\n", addr);
|
||||||
cpu_exit(env->uc->current_cpu);
|
cpu_exit(env->uc->current_cpu);
|
||||||
return;
|
return;
|
||||||
|
@ -759,11 +759,11 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||||
// Unicorn: callback on invalid memory
|
// Unicorn: callback on invalid memory
|
||||||
if (uc->hook_mem_write_idx && mr == NULL) {
|
if (uc->hook_mem_write_idx && mr == NULL) {
|
||||||
if (!((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_write_idx].callback)(
|
if (!((uc_cb_eventmem_t)uc->hook_callbacks[uc->hook_mem_write_idx].callback)(
|
||||||
uc, UC_MEM_WRITE_INVALID, addr, DATA_SIZE, (int64_t)val,
|
uc, UC_MEM_WRITE_UNMAPPED, addr, DATA_SIZE, (int64_t)val,
|
||||||
uc->hook_callbacks[uc->hook_mem_write_idx].user_data)) {
|
uc->hook_callbacks[uc->hook_mem_write_idx].user_data)) {
|
||||||
// save error & quit
|
// save error & quit
|
||||||
env->invalid_addr = addr;
|
env->invalid_addr = addr;
|
||||||
env->invalid_error = UC_ERR_WRITE_INVALID;
|
env->invalid_error = UC_ERR_WRITE_UNMAPPED;
|
||||||
// printf("***** Invalid memory write at " TARGET_FMT_lx "\n", addr);
|
// printf("***** Invalid memory write at " TARGET_FMT_lx "\n", addr);
|
||||||
cpu_exit(uc->current_cpu);
|
cpu_exit(uc->current_cpu);
|
||||||
return;
|
return;
|
||||||
|
@ -820,7 +820,7 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||||
ioaddr = env->iotlb[mmu_idx][index];
|
ioaddr = env->iotlb[mmu_idx][index];
|
||||||
if (ioaddr == 0) {
|
if (ioaddr == 0) {
|
||||||
env->invalid_addr = addr;
|
env->invalid_addr = addr;
|
||||||
env->invalid_error = UC_ERR_WRITE_INVALID;
|
env->invalid_error = UC_ERR_WRITE_UNMAPPED;
|
||||||
// printf("***** Invalid memory write at " TARGET_FMT_lx "\n", addr);
|
// printf("***** Invalid memory write at " TARGET_FMT_lx "\n", addr);
|
||||||
cpu_exit(env->uc->current_cpu);
|
cpu_exit(env->uc->current_cpu);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/* Autogen header for Unicorn Engine - DONOT MODIFY */
|
/* Autogen header for Unicorn Engine - DONOT MODIFY */
|
||||||
#ifndef UNICORN_AUTOGEN_SPARC_H
|
#ifndef UNICORN_AUTOGEN_SPARC_H
|
||||||
#define UNICORN_AUTOGEN_SPARC_H
|
#define UNICORN_AUTOGEN_SPARC_H
|
||||||
|
#define helper_power_down helper_power_down_sparc
|
||||||
#define check_exit_request check_exit_request_sparc
|
#define check_exit_request check_exit_request_sparc
|
||||||
#define address_space_unregister address_space_unregister_sparc
|
#define address_space_unregister address_space_unregister_sparc
|
||||||
#define tb_invalidate_phys_page_fast tb_invalidate_phys_page_fast_sparc
|
#define tb_invalidate_phys_page_fast tb_invalidate_phys_page_fast_sparc
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/* Autogen header for Unicorn Engine - DONOT MODIFY */
|
/* Autogen header for Unicorn Engine - DONOT MODIFY */
|
||||||
#ifndef UNICORN_AUTOGEN_SPARC64_H
|
#ifndef UNICORN_AUTOGEN_SPARC64_H
|
||||||
#define UNICORN_AUTOGEN_SPARC64_H
|
#define UNICORN_AUTOGEN_SPARC64_H
|
||||||
|
#define helper_power_down helper_power_down_sparc64
|
||||||
#define check_exit_request check_exit_request_sparc64
|
#define check_exit_request check_exit_request_sparc64
|
||||||
#define address_space_unregister address_space_unregister_sparc64
|
#define address_space_unregister address_space_unregister_sparc64
|
||||||
#define tb_invalidate_phys_page_fast tb_invalidate_phys_page_fast_sparc64
|
#define tb_invalidate_phys_page_fast tb_invalidate_phys_page_fast_sparc64
|
||||||
|
|
|
@ -10974,7 +10974,8 @@ static void disas_a64_insn(CPUARMState *env, DisasContext *s)
|
||||||
|
|
||||||
// Unicorn: end address tells us to stop emulation
|
// Unicorn: end address tells us to stop emulation
|
||||||
if (s->pc == s->uc->addr_end) {
|
if (s->pc == s->uc->addr_end) {
|
||||||
gen_exception_insn(s, 0, EXCP_SWI, 0);
|
// imitate WFI instruction to halt emulation
|
||||||
|
s->is_jmp = DISAS_WFI;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11107,8 +11108,9 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu,
|
||||||
|
|
||||||
// Unicorn: early check to see if the address of this block is the until address
|
// Unicorn: early check to see if the address of this block is the until address
|
||||||
if (tb->pc == env->uc->addr_end) {
|
if (tb->pc == env->uc->addr_end) {
|
||||||
|
// imitate WFI instruction to halt emulation
|
||||||
gen_tb_start(tcg_ctx);
|
gen_tb_start(tcg_ctx);
|
||||||
gen_exception_insn(dc, 0, EXCP_SWI, 0);
|
dc->is_jmp = DISAS_WFI;
|
||||||
goto done_generating;
|
goto done_generating;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10396,7 +10396,8 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) // qq
|
||||||
|
|
||||||
// Unicorn: end address tells us to stop emulation
|
// Unicorn: end address tells us to stop emulation
|
||||||
if (s->pc == s->uc->addr_end) {
|
if (s->pc == s->uc->addr_end) {
|
||||||
gen_exception_insn(s, 0, EXCP_SWI, 0);
|
// imitate WFI instruction to halt emulation
|
||||||
|
s->is_jmp = DISAS_WFI;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11230,9 +11231,10 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
|
||||||
|
|
||||||
// Unicorn: early check to see if the address of this block is the until address
|
// Unicorn: early check to see if the address of this block is the until address
|
||||||
if (tb->pc == env->uc->addr_end) {
|
if (tb->pc == env->uc->addr_end) {
|
||||||
|
// imitate WFI instruction to halt emulation
|
||||||
gen_tb_start(tcg_ctx);
|
gen_tb_start(tcg_ctx);
|
||||||
gen_exception_insn(dc, 0, EXCP_SWI, 0);
|
dc->is_jmp = DISAS_WFI;
|
||||||
goto done_generating;
|
goto tb_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unicorn: trace this block on request
|
// Unicorn: trace this block on request
|
||||||
|
@ -11289,6 +11291,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
|
||||||
store_cpu_field(tcg_ctx, tmp, condexec_bits);
|
store_cpu_field(tcg_ctx, tmp, condexec_bits);
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
//printf(">>> arm pc = %x\n", dc->pc);
|
||||||
#ifdef CONFIG_USER_ONLY
|
#ifdef CONFIG_USER_ONLY
|
||||||
/* Intercept jump to the magic kernel page. */
|
/* Intercept jump to the magic kernel page. */
|
||||||
if (dc->pc >= 0xffff0000) {
|
if (dc->pc >= 0xffff0000) {
|
||||||
|
@ -11370,7 +11373,8 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
|
||||||
|
|
||||||
// end address tells us to stop emulation
|
// end address tells us to stop emulation
|
||||||
if (dc->pc == dc->uc->addr_end) {
|
if (dc->pc == dc->uc->addr_end) {
|
||||||
gen_exception_insn(dc, 0, EXCP_SWI, 0);
|
// imitate WFI instruction to halt emulation
|
||||||
|
dc->is_jmp = DISAS_WFI;
|
||||||
} else {
|
} else {
|
||||||
insn = arm_ldl_code(env, dc->pc, dc->bswap_code);
|
insn = arm_ldl_code(env, dc->pc, dc->bswap_code);
|
||||||
dc->pc += 4;
|
dc->pc += 4;
|
||||||
|
@ -11413,6 +11417,8 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
|
||||||
block_full = true;
|
block_full = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tb_end:
|
||||||
|
|
||||||
/* At this stage dc->condjmp will only be set when the skipped
|
/* At this stage dc->condjmp will only be set when the skipped
|
||||||
instruction was a conditional branch or trap, and the PC has
|
instruction was a conditional branch or trap, and the PC has
|
||||||
already been written. */
|
already been written. */
|
||||||
|
|
|
@ -4751,7 +4751,11 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
|
||||||
|
|
||||||
// end address tells us to stop emulation
|
// end address tells us to stop emulation
|
||||||
if (s->pc == s->uc->addr_end) {
|
if (s->pc == s->uc->addr_end) {
|
||||||
gen_interrupt(s, 0x99, pc_start - s->cs_base, pc_start - s->cs_base);
|
// imitate the HLT instruction
|
||||||
|
gen_update_cc_op(s);
|
||||||
|
gen_jmp_im(s, pc_start - s->cs_base);
|
||||||
|
gen_helper_hlt(tcg_ctx, cpu_env, tcg_const_i32(tcg_ctx, s->pc - pc_start));
|
||||||
|
s->is_jmp = DISAS_TB_JUMP;
|
||||||
return s->pc;
|
return s->pc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8361,8 +8365,11 @@ static inline void gen_intermediate_code_internal(uint8_t *gen_opc_cc_op,
|
||||||
|
|
||||||
// early check to see if the address of this block is the until address
|
// early check to see if the address of this block is the until address
|
||||||
if (tb->pc == env->uc->addr_end) {
|
if (tb->pc == env->uc->addr_end) {
|
||||||
|
// imitate the HLT instruction
|
||||||
gen_tb_start(tcg_ctx);
|
gen_tb_start(tcg_ctx);
|
||||||
gen_interrupt(dc, 0x99, tb->pc - tb->cs_base, tb->pc - tb->cs_base);
|
gen_jmp_im(dc, tb->pc - tb->cs_base);
|
||||||
|
gen_helper_hlt(tcg_ctx, tcg_ctx->cpu_env, tcg_const_i32(tcg_ctx, 0));
|
||||||
|
dc->is_jmp = DISAS_TB_JUMP;
|
||||||
goto done_generating;
|
goto done_generating;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3038,7 +3038,7 @@ static void disas_m68k_insn(CPUM68KState * env, DisasContext *s)
|
||||||
|
|
||||||
// Unicorn: end address tells us to stop emulation
|
// Unicorn: end address tells us to stop emulation
|
||||||
if (s->pc == s->uc->addr_end) {
|
if (s->pc == s->uc->addr_end) {
|
||||||
gen_exception(s, s->pc, EXCP_TRAP15);
|
gen_exception(s, s->pc, EXCP_HLT);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3104,7 +3104,7 @@ gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb,
|
||||||
// Unicorn: early check to see if the address of this block is the until address
|
// Unicorn: early check to see if the address of this block is the until address
|
||||||
if (tb->pc == env->uc->addr_end) {
|
if (tb->pc == env->uc->addr_end) {
|
||||||
gen_tb_start(tcg_ctx);
|
gen_tb_start(tcg_ctx);
|
||||||
gen_exception(dc, dc->pc, EXCP_TRAP15);
|
gen_exception(dc, dc->pc, EXCP_HLT);
|
||||||
goto done_generating;
|
goto done_generating;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11322,7 +11322,7 @@ static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx, int is_slot)
|
static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx, bool is_bc_slot)
|
||||||
{
|
{
|
||||||
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
||||||
TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
|
TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
|
||||||
|
@ -11343,7 +11343,7 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx, int is_slot)
|
||||||
n_bytes = 2;
|
n_bytes = 2;
|
||||||
|
|
||||||
// Unicorn: trace this instruction on request
|
// Unicorn: trace this instruction on request
|
||||||
if (!is_slot && env->uc->hook_insn) {
|
if (!is_bc_slot && env->uc->hook_insn) {
|
||||||
struct hook_struct *trace = hook_find(env->uc, UC_HOOK_CODE, ctx->pc);
|
struct hook_struct *trace = hook_find(env->uc, UC_HOOK_CODE, ctx->pc);
|
||||||
if (trace)
|
if (trace)
|
||||||
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, trace->callback, env->uc, ctx->pc, trace->user_data);
|
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, trace->callback, env->uc, ctx->pc, trace->user_data);
|
||||||
|
@ -13928,7 +13928,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int is_slot)
|
static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, bool is_bc_slot)
|
||||||
{
|
{
|
||||||
TCGContext *tcg_ctx = env->uc->tcg_ctx;
|
TCGContext *tcg_ctx = env->uc->tcg_ctx;
|
||||||
TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
|
TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr;
|
||||||
|
@ -13943,7 +13943,7 @@ static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int is_sl
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unicorn: trace this instruction on request
|
// Unicorn: trace this instruction on request
|
||||||
if (!is_slot && env->uc->hook_insn) {
|
if (!is_bc_slot && env->uc->hook_insn) {
|
||||||
struct hook_struct *trace = hook_find(env->uc, UC_HOOK_CODE, ctx->pc);
|
struct hook_struct *trace = hook_find(env->uc, UC_HOOK_CODE, ctx->pc);
|
||||||
if (trace)
|
if (trace)
|
||||||
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, trace->callback, env->uc, ctx->pc, trace->user_data);
|
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, trace->callback, env->uc, ctx->pc, trace->user_data);
|
||||||
|
@ -18503,7 +18503,7 @@ static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int is_slot)
|
static void decode_opc (CPUMIPSState *env, DisasContext *ctx, bool is_bc_slot)
|
||||||
{
|
{
|
||||||
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
||||||
#if defined(TARGET_MIPS64)
|
#if defined(TARGET_MIPS64)
|
||||||
|
@ -18523,7 +18523,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int is_slot)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unicorn: trace this instruction on request
|
// Unicorn: trace this instruction on request
|
||||||
if (!is_slot && env->uc->hook_insn) {
|
if (!is_bc_slot && env->uc->hook_insn) {
|
||||||
struct hook_struct *trace = hook_find(env->uc, UC_HOOK_CODE, ctx->pc);
|
struct hook_struct *trace = hook_find(env->uc, UC_HOOK_CODE, ctx->pc);
|
||||||
if (trace)
|
if (trace)
|
||||||
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, trace->callback, env->uc, ctx->pc, trace->user_data);
|
gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, trace->callback, env->uc, ctx->pc, trace->user_data);
|
||||||
|
@ -19171,6 +19171,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
|
||||||
int max_insns;
|
int max_insns;
|
||||||
int insn_bytes;
|
int insn_bytes;
|
||||||
int is_slot = 0;
|
int is_slot = 0;
|
||||||
|
bool is_bc_slot = false;
|
||||||
TCGContext *tcg_ctx = env->uc->tcg_ctx;
|
TCGContext *tcg_ctx = env->uc->tcg_ctx;
|
||||||
TCGArg *save_opparam_ptr = NULL;
|
TCGArg *save_opparam_ptr = NULL;
|
||||||
bool block_full = false;
|
bool block_full = false;
|
||||||
|
@ -19211,7 +19212,8 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
|
||||||
// Unicorn: early check to see if the address of this block is the until address
|
// Unicorn: early check to see if the address of this block is the until address
|
||||||
if (tb->pc == env->uc->addr_end) {
|
if (tb->pc == env->uc->addr_end) {
|
||||||
gen_tb_start(tcg_ctx);
|
gen_tb_start(tcg_ctx);
|
||||||
generate_exception(&ctx, EXCP_SYSCALL);
|
gen_helper_wait(tcg_ctx, tcg_ctx->cpu_env);
|
||||||
|
ctx.bstate = BS_EXCP;
|
||||||
goto done_generating;
|
goto done_generating;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19229,6 +19231,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
|
||||||
|
|
||||||
gen_tb_start(tcg_ctx);
|
gen_tb_start(tcg_ctx);
|
||||||
while (ctx.bstate == BS_NONE) {
|
while (ctx.bstate == BS_NONE) {
|
||||||
|
// printf(">>> mips pc = %x\n", ctx.pc);
|
||||||
if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
|
if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
|
||||||
QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
|
QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
|
||||||
if (bp->pc == ctx.pc) {
|
if (bp->pc == ctx.pc) {
|
||||||
|
@ -19261,7 +19264,8 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
|
||||||
|
|
||||||
// Unicorn: end address tells us to stop emulation
|
// Unicorn: end address tells us to stop emulation
|
||||||
if (ctx.pc == ctx.uc->addr_end) {
|
if (ctx.pc == ctx.uc->addr_end) {
|
||||||
generate_exception(&ctx, EXCP_SYSCALL);
|
gen_helper_wait(tcg_ctx, tcg_ctx->cpu_env);
|
||||||
|
ctx.bstate = BS_EXCP;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
// Unicorn: save param buffer
|
// Unicorn: save param buffer
|
||||||
|
@ -19269,16 +19273,18 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
|
||||||
save_opparam_ptr = tcg_ctx->gen_opparam_ptr;
|
save_opparam_ptr = tcg_ctx->gen_opparam_ptr;
|
||||||
|
|
||||||
is_slot = ctx.hflags & MIPS_HFLAG_BMASK;
|
is_slot = ctx.hflags & MIPS_HFLAG_BMASK;
|
||||||
|
is_bc_slot = (is_slot & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BC;
|
||||||
|
|
||||||
if (!(ctx.hflags & MIPS_HFLAG_M16)) {
|
if (!(ctx.hflags & MIPS_HFLAG_M16)) {
|
||||||
ctx.opcode = cpu_ldl_code(env, ctx.pc);
|
ctx.opcode = cpu_ldl_code(env, ctx.pc);
|
||||||
insn_bytes = 4;
|
insn_bytes = 4;
|
||||||
decode_opc(env, &ctx, is_slot);
|
decode_opc(env, &ctx, is_bc_slot);
|
||||||
} else if (ctx.insn_flags & ASE_MICROMIPS) {
|
} else if (ctx.insn_flags & ASE_MICROMIPS) {
|
||||||
ctx.opcode = cpu_lduw_code(env, ctx.pc);
|
ctx.opcode = cpu_lduw_code(env, ctx.pc);
|
||||||
insn_bytes = decode_micromips_opc(env, &ctx, is_slot);
|
insn_bytes = decode_micromips_opc(env, &ctx, is_bc_slot);
|
||||||
} else if (ctx.insn_flags & ASE_MIPS16) {
|
} else if (ctx.insn_flags & ASE_MIPS16) {
|
||||||
ctx.opcode = cpu_lduw_code(env, ctx.pc);
|
ctx.opcode = cpu_lduw_code(env, ctx.pc);
|
||||||
insn_bytes = decode_mips16_opc(env, &ctx, is_slot);
|
insn_bytes = decode_mips16_opc(env, &ctx, is_bc_slot);
|
||||||
} else {
|
} else {
|
||||||
generate_exception(&ctx, EXCP_RI);
|
generate_exception(&ctx, EXCP_RI);
|
||||||
ctx.bstate = BS_STOP;
|
ctx.bstate = BS_STOP;
|
||||||
|
@ -19286,7 +19292,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unicorn: patch the callback for the instruction size
|
// Unicorn: patch the callback for the instruction size
|
||||||
if (env->uc->hook_insn)
|
if (!is_bc_slot && env->uc->hook_insn)
|
||||||
*(save_opparam_ptr + 1) = insn_bytes;
|
*(save_opparam_ptr + 1) = insn_bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19298,6 +19304,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
|
||||||
is_slot = 1;
|
is_slot = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_slot) {
|
if (is_slot) {
|
||||||
gen_branch(&ctx, insn_bytes);
|
gen_branch(&ctx, insn_bytes);
|
||||||
}
|
}
|
||||||
|
@ -19341,6 +19348,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
|
||||||
switch (ctx.bstate) {
|
switch (ctx.bstate) {
|
||||||
case BS_STOP:
|
case BS_STOP:
|
||||||
gen_goto_tb(&ctx, 0, ctx.pc);
|
gen_goto_tb(&ctx, 0, ctx.pc);
|
||||||
|
env->uc->next_pc = ctx.pc;
|
||||||
break;
|
break;
|
||||||
case BS_NONE:
|
case BS_NONE:
|
||||||
save_cpu_state(&ctx, 0);
|
save_cpu_state(&ctx, 0);
|
||||||
|
|
|
@ -241,7 +241,7 @@ target_ulong helper_tsubcctv(CPUSPARCState *env, target_ulong src1,
|
||||||
helper_raise_exception(env, TT_TOVF);
|
helper_raise_exception(env, TT_TOVF);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef TARGET_SPARC64
|
//#ifndef TARGET_SPARC64
|
||||||
void helper_power_down(CPUSPARCState *env)
|
void helper_power_down(CPUSPARCState *env)
|
||||||
{
|
{
|
||||||
CPUState *cs = CPU(sparc_env_get_cpu(env));
|
CPUState *cs = CPU(sparc_env_get_cpu(env));
|
||||||
|
@ -252,4 +252,4 @@ void helper_power_down(CPUSPARCState *env)
|
||||||
env->npc = env->pc + 4;
|
env->npc = env->pc + 4;
|
||||||
cpu_loop_exit(cs);
|
cpu_loop_exit(cs);
|
||||||
}
|
}
|
||||||
#endif
|
//#endif
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
DEF_HELPER_5(uc_tracecode, void, i32, ptr, ptr, i64, ptr)
|
DEF_HELPER_5(uc_tracecode, void, i32, ptr, ptr, i64, ptr)
|
||||||
|
DEF_HELPER_1(power_down, void, env)
|
||||||
|
|
||||||
#ifndef TARGET_SPARC64
|
#ifndef TARGET_SPARC64
|
||||||
DEF_HELPER_1(rett, void, env)
|
DEF_HELPER_1(rett, void, env)
|
||||||
DEF_HELPER_2(wrpsr, void, env, tl)
|
DEF_HELPER_2(wrpsr, void, env, tl)
|
||||||
DEF_HELPER_1(rdpsr, tl, env)
|
DEF_HELPER_1(rdpsr, tl, env)
|
||||||
DEF_HELPER_1(power_down, void, env)
|
|
||||||
#else
|
#else
|
||||||
DEF_HELPER_2(wrpil, void, env, tl)
|
DEF_HELPER_2(wrpil, void, env, tl)
|
||||||
DEF_HELPER_2(wrpstate, void, env, tl)
|
DEF_HELPER_2(wrpstate, void, env, tl)
|
||||||
|
|
|
@ -5419,6 +5419,14 @@ static inline void gen_intermediate_code_internal(SPARCCPU *cpu,
|
||||||
if (max_insns == 0)
|
if (max_insns == 0)
|
||||||
max_insns = CF_COUNT_MASK;
|
max_insns = CF_COUNT_MASK;
|
||||||
|
|
||||||
|
// Unicorn: early check to see if the address of this block is the until address
|
||||||
|
if (tb->pc == env->uc->addr_end) {
|
||||||
|
gen_tb_start(tcg_ctx);
|
||||||
|
save_state(dc);
|
||||||
|
gen_helper_power_down(tcg_ctx, tcg_ctx->cpu_env);
|
||||||
|
goto done_generating;
|
||||||
|
}
|
||||||
|
|
||||||
// Unicorn: trace this block on request
|
// Unicorn: trace this block on request
|
||||||
// Only hook this block if it is not broken from previous translation due to
|
// Only hook this block if it is not broken from previous translation due to
|
||||||
// full translation cache
|
// full translation cache
|
||||||
|
@ -5462,7 +5470,9 @@ static inline void gen_intermediate_code_internal(SPARCCPU *cpu,
|
||||||
// gen_io_start();
|
// gen_io_start();
|
||||||
// Unicorn: end address tells us to stop emulation
|
// Unicorn: end address tells us to stop emulation
|
||||||
if (dc->pc == dc->uc->addr_end) {
|
if (dc->pc == dc->uc->addr_end) {
|
||||||
insn = 0x91d02000; // generate TRAP to end this TB
|
save_state(dc);
|
||||||
|
gen_helper_power_down(tcg_ctx, tcg_ctx->cpu_env);
|
||||||
|
break;
|
||||||
} else {
|
} else {
|
||||||
last_pc = dc->pc;
|
last_pc = dc->pc;
|
||||||
insn = cpu_ldl_code(env, dc->pc);
|
insn = cpu_ldl_code(env, dc->pc);
|
||||||
|
@ -5511,6 +5521,8 @@ static inline void gen_intermediate_code_internal(SPARCCPU *cpu,
|
||||||
tcg_gen_exit_tb(tcg_ctx, 0);
|
tcg_gen_exit_tb(tcg_ctx, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done_generating:
|
||||||
gen_tb_end(tcg_ctx, tb, num_insns);
|
gen_tb_end(tcg_ctx, tb, num_insns);
|
||||||
*tcg_ctx->gen_opc_ptr = INDEX_op_end;
|
*tcg_ctx->gen_opc_ptr = INDEX_op_end;
|
||||||
if (spc) {
|
if (spc) {
|
||||||
|
|
|
@ -2586,8 +2586,13 @@ int tcg_gen_code(TCGContext *s, tcg_insn_unit *gen_code_buf) // qq
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//printf("====== before gen code\n");
|
||||||
|
//tcg_dump_ops(s);
|
||||||
tcg_gen_code_common(s, gen_code_buf, -1); // qq
|
tcg_gen_code_common(s, gen_code_buf, -1); // qq
|
||||||
|
|
||||||
|
//printf("====== after gen code\n");
|
||||||
|
//tcg_dump_ops(s);
|
||||||
|
|
||||||
/* flush instruction cache */
|
/* flush instruction cache */
|
||||||
flush_icache_range((uintptr_t)s->code_buf, (uintptr_t)s->code_ptr);
|
flush_icache_range((uintptr_t)s->code_buf, (uintptr_t)s->code_ptr);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/* Autogen header for Unicorn Engine - DONOT MODIFY */
|
/* Autogen header for Unicorn Engine - DONOT MODIFY */
|
||||||
#ifndef UNICORN_AUTOGEN_X86_64_H
|
#ifndef UNICORN_AUTOGEN_X86_64_H
|
||||||
#define UNICORN_AUTOGEN_X86_64_H
|
#define UNICORN_AUTOGEN_X86_64_H
|
||||||
|
#define helper_power_down helper_power_down_x86_64
|
||||||
#define check_exit_request check_exit_request_x86_64
|
#define check_exit_request check_exit_request_x86_64
|
||||||
#define address_space_unregister address_space_unregister_x86_64
|
#define address_space_unregister address_space_unregister_x86_64
|
||||||
#define tb_invalidate_phys_page_fast tb_invalidate_phys_page_fast_x86_64
|
#define tb_invalidate_phys_page_fast tb_invalidate_phys_page_fast_x86_64
|
||||||
|
|
|
@ -79,10 +79,10 @@ static bool hook_mem_invalid(uc_engine *uc, uc_mem_type type,
|
||||||
default:
|
default:
|
||||||
printf("not ok - UC_HOOK_MEM_INVALID type: %d at 0x%" PRIx64 "\n", type, addr);
|
printf("not ok - UC_HOOK_MEM_INVALID type: %d at 0x%" PRIx64 "\n", type, addr);
|
||||||
return false;
|
return false;
|
||||||
case UC_MEM_READ_INVALID:
|
case UC_MEM_READ_UNMAPPED:
|
||||||
printf("not ok - Read from invalid memory at 0x%"PRIx64 ", data size = %u\n", addr, size);
|
printf("not ok - Read from invalid memory at 0x%"PRIx64 ", data size = %u\n", addr, size);
|
||||||
return false;
|
return false;
|
||||||
case UC_MEM_WRITE_INVALID:
|
case UC_MEM_WRITE_UNMAPPED:
|
||||||
printf("not ok - Write to invalid memory at 0x%"PRIx64 ", data size = %u, data value = 0x%"PRIx64 "\n", addr, size, value);
|
printf("not ok - Write to invalid memory at 0x%"PRIx64 ", data size = %u, data value = 0x%"PRIx64 "\n", addr, size, value);
|
||||||
return false;
|
return false;
|
||||||
case UC_MEM_FETCH_PROT:
|
case UC_MEM_FETCH_PROT:
|
||||||
|
@ -147,7 +147,7 @@ static void do_nx_demo(bool cause_fault)
|
||||||
|
|
||||||
// intercept code and invalid memory events
|
// intercept code and invalid memory events
|
||||||
if (uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK ||
|
if (uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK ||
|
||||||
uc_hook_add(uc, &trace1, UC_HOOK_MEM_ERR,
|
uc_hook_add(uc, &trace1, UC_HOOK_MEM_INVALID,
|
||||||
hook_mem_invalid, NULL) != UC_ERR_OK) {
|
hook_mem_invalid, NULL) != UC_ERR_OK) {
|
||||||
printf("not ok - Failed to install hooks\n");
|
printf("not ok - Failed to install hooks\n");
|
||||||
return;
|
return;
|
||||||
|
@ -228,7 +228,7 @@ static void do_perms_demo(bool change_perms)
|
||||||
// intercept code and invalid memory events
|
// intercept code and invalid memory events
|
||||||
if (uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK ||
|
if (uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK ||
|
||||||
uc_hook_add(uc, &trace1,
|
uc_hook_add(uc, &trace1,
|
||||||
UC_HOOK_MEM_READ_INVALID | UC_HOOK_MEM_WRITE_INVALID | UC_HOOK_MEM_FETCH_INVALID | UC_HOOK_MEM_FETCH_PROT | UC_HOOK_MEM_WRITE_PROT | UC_HOOK_MEM_READ_PROT,
|
UC_HOOK_MEM_INVALID,
|
||||||
hook_mem_invalid, NULL) != UC_ERR_OK) {
|
hook_mem_invalid, NULL) != UC_ERR_OK) {
|
||||||
printf("not ok - Failed to install hooks\n");
|
printf("not ok - Failed to install hooks\n");
|
||||||
return;
|
return;
|
||||||
|
@ -306,7 +306,7 @@ static void do_unmap_demo(bool do_unmap)
|
||||||
// intercept code and invalid memory events
|
// intercept code and invalid memory events
|
||||||
if (uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK ||
|
if (uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0) != UC_ERR_OK ||
|
||||||
uc_hook_add(uc, &trace1,
|
uc_hook_add(uc, &trace1,
|
||||||
UC_HOOK_MEM_READ_INVALID | UC_HOOK_MEM_WRITE_INVALID | UC_HOOK_MEM_FETCH_INVALID | UC_HOOK_MEM_FETCH_PROT | UC_HOOK_MEM_WRITE_PROT | UC_HOOK_MEM_READ_PROT,
|
UC_HOOK_MEM_INVALID,
|
||||||
hook_mem_invalid, NULL) != UC_ERR_OK) {
|
hook_mem_invalid, NULL) != UC_ERR_OK) {
|
||||||
printf("not ok - Failed to install hooks\n");
|
printf("not ok - Failed to install hooks\n");
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -59,8 +59,8 @@ static void test_sparc(void)
|
||||||
// tracing all basic blocks with customized callback
|
// tracing all basic blocks with customized callback
|
||||||
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
|
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, (uint64_t)1, (uint64_t)0);
|
||||||
|
|
||||||
// tracing one instruction at ADDRESS with customized callback
|
// tracing all instructions with customized callback
|
||||||
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)ADDRESS, (uint64_t)ADDRESS);
|
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0);
|
||||||
|
|
||||||
// emulate machine code in infinite time (last param = 0), or when
|
// emulate machine code in infinite time (last param = 0), or when
|
||||||
// finishing all the code.
|
// finishing all the code.
|
||||||
|
|
|
@ -73,7 +73,7 @@ static bool hook_mem_invalid(uc_engine *uc, uc_mem_type type,
|
||||||
default:
|
default:
|
||||||
// return false to indicate we want to stop emulation
|
// return false to indicate we want to stop emulation
|
||||||
return false;
|
return false;
|
||||||
case UC_MEM_WRITE_INVALID:
|
case UC_MEM_WRITE_UNMAPPED:
|
||||||
printf(">>> Missing memory is being WRITE at 0x%"PRIx64 ", data size = %u, data value = 0x%"PRIx64 "\n",
|
printf(">>> Missing memory is being WRITE at 0x%"PRIx64 ", data size = %u, data value = 0x%"PRIx64 "\n",
|
||||||
address, size, value);
|
address, size, value);
|
||||||
// map this memory in with 2MB in size
|
// map this memory in with 2MB in size
|
||||||
|
@ -421,7 +421,7 @@ static void test_i386_invalid_mem_write(void)
|
||||||
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0);
|
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)1, (uint64_t)0);
|
||||||
|
|
||||||
// intercept invalid memory events
|
// intercept invalid memory events
|
||||||
uc_hook_add(uc, &trace3, UC_HOOK_MEM_READ_INVALID | UC_HOOK_MEM_WRITE_INVALID, hook_mem_invalid, NULL);
|
uc_hook_add(uc, &trace3, UC_HOOK_MEM_READ_UNMAPPED | UC_HOOK_MEM_WRITE_UNMAPPED, hook_mem_invalid, NULL);
|
||||||
|
|
||||||
// emulate machine code in infinite time
|
// emulate machine code in infinite time
|
||||||
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(X86_CODE32_MEM_WRITE) - 1, 0, 0);
|
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(X86_CODE32_MEM_WRITE) - 1, 0, 0);
|
||||||
|
|
|
@ -10,8 +10,9 @@ class BxHang(regress.RegressTest):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
uc = Uc(UC_ARCH_ARM, UC_MODE_ARM)
|
uc = Uc(UC_ARCH_ARM, UC_MODE_ARM)
|
||||||
uc.mem_map(0x1000, 0x1000)
|
uc.mem_map(0x1000, 0x1000)
|
||||||
uc.mem_write(0x1000, '1eff2f010000a0e1'.decode('hex'))
|
uc.mem_write(0x1000, '1eff2f010000a0e1'.decode('hex')) # bxeq lr; mov r0, r0
|
||||||
uc.count = 0
|
uc.count = 0
|
||||||
|
|
||||||
def hook_block(uc, addr, *args):
|
def hook_block(uc, addr, *args):
|
||||||
print 'enter block 0x%04x' % addr
|
print 'enter block 0x%04x' % addr
|
||||||
uc.count += 1
|
uc.count += 1
|
||||||
|
|
30
tests/regress/bad_ram.py
Executable file
30
tests/regress/bad_ram.py
Executable file
|
@ -0,0 +1,30 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
from unicorn import *
|
||||||
|
from unicorn.x86_const import *
|
||||||
|
|
||||||
|
import regress
|
||||||
|
|
||||||
|
|
||||||
|
class Hang(regress.RegressTest):
|
||||||
|
|
||||||
|
def runTest(self):
|
||||||
|
PAGE_SIZE = 0x5000
|
||||||
|
CODE_ADDR = 0x400000
|
||||||
|
RSP_ADDR = 0x200000
|
||||||
|
binary1 = "\xCA\x24\x5D" # retf 0x5d24
|
||||||
|
mu = Uc(UC_ARCH_X86, UC_MODE_64)
|
||||||
|
|
||||||
|
mu.mem_map(CODE_ADDR, PAGE_SIZE)
|
||||||
|
mu.mem_map(RSP_ADDR, PAGE_SIZE)
|
||||||
|
|
||||||
|
mu.mem_write(CODE_ADDR, binary1)
|
||||||
|
mu.reg_write(UC_X86_REG_RSP, RSP_ADDR)
|
||||||
|
try:
|
||||||
|
self.assertEqual(mu.emu_start(CODE_ADDR, CODE_ADDR + PAGE_SIZE, 0), UC_ERR_FETCH_INVALID)
|
||||||
|
except UcError as e:
|
||||||
|
print("ERROR: %s" % e)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
regress.main()
|
13
tests/regress/ensure_typedef_consts_generated.py
Normal file
13
tests/regress/ensure_typedef_consts_generated.py
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
"""See https://github.com/unicorn-engine/unicorn/issues/161
|
||||||
|
|
||||||
|
Ensure that constants which are specified via a typedef, rather than an enum,
|
||||||
|
are included in the bindings by the script for autogenerating mappings for
|
||||||
|
constants.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import unicorn
|
||||||
|
|
||||||
|
try:
|
||||||
|
unicorn.UC_HOOK_MEM_UNMAPPED
|
||||||
|
except AttributeError:
|
||||||
|
assert(False and "Definition for UC_HOOK_MEM_UNMAPPED not generated")
|
|
@ -22,7 +22,7 @@ class JumEbxHang(regress.RegressTest):
|
||||||
with self.assertRaises(UcError) as m:
|
with self.assertRaises(UcError) as m:
|
||||||
mu.emu_start(CODE_ADDR, CODE_ADDR + 2, count=1)
|
mu.emu_start(CODE_ADDR, CODE_ADDR + 2, count=1)
|
||||||
|
|
||||||
self.assertEqual(m.exception.errno, unicorn.UC_ERR_CODE_INVALID)
|
self.assertEqual(m.exception.errno, unicorn.UC_ERR_FETCH_UNMAPPED)
|
||||||
|
|
||||||
print(">>> jmp ebx (ebx = 0xaa96a47f)");
|
print(">>> jmp ebx (ebx = 0xaa96a47f)");
|
||||||
mu = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32)
|
mu = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32)
|
||||||
|
@ -33,7 +33,7 @@ class JumEbxHang(regress.RegressTest):
|
||||||
with self.assertRaises(UcError) as m:
|
with self.assertRaises(UcError) as m:
|
||||||
mu.emu_start(CODE_ADDR, CODE_ADDR + 2, count=1)
|
mu.emu_start(CODE_ADDR, CODE_ADDR + 2, count=1)
|
||||||
|
|
||||||
self.assertEqual(m.exception.errno, unicorn.UC_ERR_CODE_INVALID)
|
self.assertEqual(m.exception.errno, unicorn.UC_ERR_FETCH_UNMAPPED)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
regress.main()
|
regress.main()
|
||||||
|
|
|
@ -224,7 +224,7 @@ int main(int argc, char **argv, char **envp)
|
||||||
}
|
}
|
||||||
|
|
||||||
// intercept invalid memory events
|
// intercept invalid memory events
|
||||||
if (uc_hook_add(uc, &trace1, UC_HOOK_MEM_WRITE_INVALID, hook_mem_invalid, NULL) != UC_ERR_OK) {
|
if (uc_hook_add(uc, &trace1, UC_HOOK_MEM_WRITE_UNMAPPED, hook_mem_invalid, NULL) != UC_ERR_OK) {
|
||||||
printf("not ok %d - Failed to install memory invalid handler\n", log_num++);
|
printf("not ok %d - Failed to install memory invalid handler\n", log_num++);
|
||||||
return 7;
|
return 7;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -28,13 +28,13 @@ class MipsExcept(regress.RegressTest):
|
||||||
uc.reg_write(UC_MIPS_REG_SP, 0xFFFFFFF0)
|
uc.reg_write(UC_MIPS_REG_SP, 0xFFFFFFF0)
|
||||||
uc.emu_start(CODE, CODE + len(asm), 200)
|
uc.emu_start(CODE, CODE + len(asm), 200)
|
||||||
|
|
||||||
self.assertEqual(UC_ERR_READ_INVALID, m.exception.errno)
|
self.assertEqual(UC_ERR_READ_UNMAPPED, m.exception.errno)
|
||||||
|
|
||||||
with self.assertRaises(UcError) as m:
|
with self.assertRaises(UcError) as m:
|
||||||
uc.reg_write(UC_MIPS_REG_SP, 0x80000000)
|
uc.reg_write(UC_MIPS_REG_SP, 0x80000000)
|
||||||
uc.emu_start(CODE, CODE + len(asm), 100)
|
uc.emu_start(CODE, CODE + len(asm), 100)
|
||||||
|
|
||||||
self.assertEqual(UC_ERR_READ_INVALID, m.exception.errno)
|
self.assertEqual(UC_ERR_READ_UNMAPPED, m.exception.errno)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
regress.main()
|
regress.main()
|
||||||
|
|
51
tests/regress/mips_single_step_sp.py
Executable file
51
tests/regress/mips_single_step_sp.py
Executable file
|
@ -0,0 +1,51 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
from unicorn import *
|
||||||
|
from unicorn.mips_const import *
|
||||||
|
|
||||||
|
import regress
|
||||||
|
|
||||||
|
def code_hook(uc, addr, size, user_data):
|
||||||
|
print 'code hook: pc=%08x sp=%08x' % (addr, uc.reg_read(UC_MIPS_REG_SP))
|
||||||
|
|
||||||
|
def run(step=False):
|
||||||
|
addr = 0x4010dc
|
||||||
|
|
||||||
|
code = (
|
||||||
|
'f8ff0124' # addiu $at, $zero, -8
|
||||||
|
'24e8a103' # and $sp, $sp, $at
|
||||||
|
'09f82003' # jalr $t9
|
||||||
|
'e8ffbd23' # addi $sp, $sp, -0x18
|
||||||
|
'b8ffbd27' # addiu $sp, $sp, -0x48
|
||||||
|
'00000000' # nop
|
||||||
|
).decode('hex')
|
||||||
|
|
||||||
|
uc = Uc(UC_ARCH_MIPS, UC_MODE_MIPS32 + UC_MODE_LITTLE_ENDIAN)
|
||||||
|
if step:
|
||||||
|
uc.hook_add(UC_HOOK_CODE, code_hook)
|
||||||
|
|
||||||
|
uc.reg_write(UC_MIPS_REG_SP, 0x60800000)
|
||||||
|
uc.reg_write(UC_MIPS_REG_T9, addr + len(code) - 8)
|
||||||
|
|
||||||
|
print 'sp =', hex(uc.reg_read(UC_MIPS_REG_SP))
|
||||||
|
print 'at =', hex(uc.reg_read(UC_MIPS_REG_AT))
|
||||||
|
print '<run> (single step: %s)' % (str(step))
|
||||||
|
|
||||||
|
uc.mem_map(addr & ~(0x1000 - 1), 0x2000)
|
||||||
|
uc.mem_write(addr, code)
|
||||||
|
uc.emu_start(addr, addr + len(code))
|
||||||
|
|
||||||
|
print 'sp =', hex(uc.reg_read(UC_MIPS_REG_SP))
|
||||||
|
print 'at =', hex(uc.reg_read(UC_MIPS_REG_AT))
|
||||||
|
print
|
||||||
|
return uc.reg_read(UC_MIPS_REG_SP)
|
||||||
|
|
||||||
|
|
||||||
|
class MipsSingleStep(regress.RegressTest):
|
||||||
|
def test(self):
|
||||||
|
sp1 = run(step=False)
|
||||||
|
sp2 = run(step=True)
|
||||||
|
self.assertEqual(sp1, sp2)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
regress.main()
|
27
tests/regress/mips_syscall_pc.py
Executable file
27
tests/regress/mips_syscall_pc.py
Executable file
|
@ -0,0 +1,27 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
from unicorn import *
|
||||||
|
from unicorn.mips_const import *
|
||||||
|
|
||||||
|
import regress
|
||||||
|
|
||||||
|
def intr_hook(uc, intno, data):
|
||||||
|
print 'interrupt=%d, v0=%d, pc=0x%08x' % (intno, uc.reg_read(UC_MIPS_REG_V0), uc.reg_read(UC_MIPS_REG_PC))
|
||||||
|
|
||||||
|
class MipsSyscall(regress.RegressTest):
|
||||||
|
def test(self):
|
||||||
|
addr = 0x40000
|
||||||
|
code = '0c000000'.decode('hex') # syscall
|
||||||
|
|
||||||
|
uc = Uc(UC_ARCH_MIPS, UC_MODE_MIPS32 + UC_MODE_LITTLE_ENDIAN)
|
||||||
|
uc.mem_map(addr, 0x1000)
|
||||||
|
uc.mem_write(addr, code)
|
||||||
|
uc.reg_write(UC_MIPS_REG_V0, 100)
|
||||||
|
uc.hook_add(UC_HOOK_INTR, intr_hook)
|
||||||
|
|
||||||
|
uc.emu_start(addr, addr+len(code))
|
||||||
|
self.assertEqual(0x40004, uc.reg_read(UC_MIPS_REG_PC))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
regress.main()
|
|
@ -24,7 +24,7 @@ class RegWriteSignExt(regress.RegressTest):
|
||||||
# jmp ebx
|
# jmp ebx
|
||||||
mu.mem_write(0x10000000, b'\xff\xe3')
|
mu.mem_write(0x10000000, b'\xff\xe3')
|
||||||
|
|
||||||
mu.hook_add(unicorn.UC_HOOK_MEM_FETCH_INVALID | unicorn.UC_HOOK_MEM_FETCH_PROT, hook_mem_invalid)
|
mu.hook_add(unicorn.UC_HOOK_MEM_FETCH_UNMAPPED | unicorn.UC_HOOK_MEM_FETCH_PROT, hook_mem_invalid)
|
||||||
mu.emu_start(0x10000000, 0x10000000 + 2, count=1)
|
mu.emu_start(0x10000000, 0x10000000 + 2, count=1)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -142,7 +142,7 @@ int main(int argc, char **argv, char **envp)
|
||||||
//uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)0x400000, (uint64_t)0x400fff);
|
//uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, (uint64_t)0x400000, (uint64_t)0x400fff);
|
||||||
|
|
||||||
// intercept invalid memory events
|
// intercept invalid memory events
|
||||||
uc_hook_add(uc, &trace1, UC_HOOK_MEM_WRITE_INVALID | UC_HOOK_MEM_WRITE_PROT, hook_mem_invalid, NULL);
|
uc_hook_add(uc, &trace1, UC_HOOK_MEM_WRITE_UNMAPPED | UC_HOOK_MEM_WRITE_PROT, hook_mem_invalid, NULL);
|
||||||
|
|
||||||
// emulate machine code in infinite time
|
// emulate machine code in infinite time
|
||||||
printf("BEGIN execution - 1\n");
|
printf("BEGIN execution - 1\n");
|
||||||
|
|
|
@ -164,7 +164,7 @@ def print_registers(mu):
|
||||||
|
|
||||||
print_registers(uc)
|
print_registers(uc)
|
||||||
|
|
||||||
assert uc.reg_read(UC_SPARC_REG_PC) == 128 # make sure we executed all instructions
|
assert uc.reg_read(UC_SPARC_REG_PC) == 132 # make sure we executed all instructions
|
||||||
assert uc.reg_read(UC_SPARC_REG_SP) == 101
|
assert uc.reg_read(UC_SPARC_REG_SP) == 101
|
||||||
assert uc.reg_read(UC_SPARC_REG_FP) == 201
|
assert uc.reg_read(UC_SPARC_REG_FP) == 201
|
||||||
|
|
||||||
|
|
|
@ -408,7 +408,7 @@ static void test_i386_invalid_mem_read(void **state)
|
||||||
|
|
||||||
// emulate machine code in infinite time
|
// emulate machine code in infinite time
|
||||||
err = uc_emu_start(uc, address, address+sizeof(code), 0, 0);
|
err = uc_emu_start(uc, address, address+sizeof(code), 0, 0);
|
||||||
uc_assert_err(UC_ERR_READ_INVALID, err);
|
uc_assert_err(UC_ERR_READ_UNMAPPED, err);
|
||||||
|
|
||||||
uc_assert_success(uc_close(uc));
|
uc_assert_success(uc_close(uc));
|
||||||
}
|
}
|
||||||
|
@ -438,7 +438,7 @@ static void test_i386_invalid_mem_write(void **state)
|
||||||
|
|
||||||
// emulate machine code in infinite time
|
// emulate machine code in infinite time
|
||||||
err = uc_emu_start(uc, address, address+sizeof(code), 0, 0);
|
err = uc_emu_start(uc, address, address+sizeof(code), 0, 0);
|
||||||
uc_assert_err(UC_ERR_WRITE_INVALID, err);
|
uc_assert_err(UC_ERR_WRITE_UNMAPPED, err);
|
||||||
|
|
||||||
|
|
||||||
uc_assert_success(uc_close(uc));
|
uc_assert_success(uc_close(uc));
|
||||||
|
@ -469,7 +469,7 @@ static void test_i386_jump_invalid(void **state)
|
||||||
|
|
||||||
// emulate machine code in infinite time
|
// emulate machine code in infinite time
|
||||||
err = uc_emu_start(uc, address, address+sizeof(code), 0, 0);
|
err = uc_emu_start(uc, address, address+sizeof(code), 0, 0);
|
||||||
uc_assert_err(UC_ERR_CODE_INVALID, err);
|
uc_assert_err(UC_ERR_FETCH_UNMAPPED, err);
|
||||||
|
|
||||||
|
|
||||||
uc_assert_success(uc_close(uc));
|
uc_assert_success(uc_close(uc));
|
||||||
|
|
40
uc.c
40
uc.c
|
@ -69,14 +69,12 @@ const char *uc_strerror(uc_err code)
|
||||||
return "Invalid mode (UC_ERR_MODE)";
|
return "Invalid mode (UC_ERR_MODE)";
|
||||||
case UC_ERR_VERSION:
|
case UC_ERR_VERSION:
|
||||||
return "Different API version between core & binding (UC_ERR_VERSION)";
|
return "Different API version between core & binding (UC_ERR_VERSION)";
|
||||||
case UC_ERR_READ_INVALID:
|
case UC_ERR_READ_UNMAPPED:
|
||||||
return "Invalid memory read (UC_ERR_READ_INVALID)";
|
return "Invalid memory read (UC_ERR_READ_UNMAPPED)";
|
||||||
case UC_ERR_WRITE_INVALID:
|
case UC_ERR_WRITE_UNMAPPED:
|
||||||
return "Invalid memory write (UC_ERR_WRITE_INVALID)";
|
return "Invalid memory write (UC_ERR_WRITE_UNMAPPED)";
|
||||||
case UC_ERR_FETCH_INVALID:
|
case UC_ERR_FETCH_UNMAPPED:
|
||||||
return "Invalid memory fetch (UC_ERR_FETCH_INVALID)";
|
return "Invalid memory fetch (UC_ERR_FETCH_UNMAPPED)";
|
||||||
case UC_ERR_CODE_INVALID:
|
|
||||||
return "Invalid code address (UC_ERR_CODE_INVALID)";
|
|
||||||
case UC_ERR_HOOK:
|
case UC_ERR_HOOK:
|
||||||
return "Invalid hook type (UC_ERR_HOOK)";
|
return "Invalid hook type (UC_ERR_HOOK)";
|
||||||
case UC_ERR_INSN_INVALID:
|
case UC_ERR_INSN_INVALID:
|
||||||
|
@ -343,7 +341,7 @@ uc_err uc_mem_read(uc_engine *uc, uint64_t address, void *_bytes, size_t size)
|
||||||
uint8_t *bytes = _bytes;
|
uint8_t *bytes = _bytes;
|
||||||
|
|
||||||
if (!check_mem_area(uc, address, size))
|
if (!check_mem_area(uc, address, size))
|
||||||
return UC_ERR_READ_INVALID;
|
return UC_ERR_READ_UNMAPPED;
|
||||||
|
|
||||||
size_t count = 0, len;
|
size_t count = 0, len;
|
||||||
|
|
||||||
|
@ -364,7 +362,7 @@ uc_err uc_mem_read(uc_engine *uc, uint64_t address, void *_bytes, size_t size)
|
||||||
if (count == size)
|
if (count == size)
|
||||||
return UC_ERR_OK;
|
return UC_ERR_OK;
|
||||||
else
|
else
|
||||||
return UC_ERR_READ_INVALID;
|
return UC_ERR_READ_UNMAPPED;
|
||||||
}
|
}
|
||||||
|
|
||||||
UNICORN_EXPORT
|
UNICORN_EXPORT
|
||||||
|
@ -373,7 +371,7 @@ uc_err uc_mem_write(uc_engine *uc, uint64_t address, const void *_bytes, size_t
|
||||||
const uint8_t *bytes = _bytes;
|
const uint8_t *bytes = _bytes;
|
||||||
|
|
||||||
if (!check_mem_area(uc, address, size))
|
if (!check_mem_area(uc, address, size))
|
||||||
return UC_ERR_WRITE_INVALID;
|
return UC_ERR_WRITE_UNMAPPED;
|
||||||
|
|
||||||
size_t count = 0, len;
|
size_t count = 0, len;
|
||||||
|
|
||||||
|
@ -404,7 +402,7 @@ uc_err uc_mem_write(uc_engine *uc, uint64_t address, const void *_bytes, size_t
|
||||||
if (count == size)
|
if (count == size)
|
||||||
return UC_ERR_OK;
|
return UC_ERR_OK;
|
||||||
else
|
else
|
||||||
return UC_ERR_WRITE_INVALID;
|
return UC_ERR_WRITE_UNMAPPED;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TIMEOUT_STEP 2 // microseconds
|
#define TIMEOUT_STEP 2 // microseconds
|
||||||
|
@ -842,15 +840,15 @@ static uc_err _hook_mem_invalid(struct uc_struct* uc, int type, uc_cb_eventmem_t
|
||||||
uc->hook_callbacks[i].callback = callback;
|
uc->hook_callbacks[i].callback = callback;
|
||||||
uc->hook_callbacks[i].user_data = user_data;
|
uc->hook_callbacks[i].user_data = user_data;
|
||||||
*evh = i;
|
*evh = i;
|
||||||
if (type & UC_HOOK_MEM_READ_INVALID)
|
if (type & UC_HOOK_MEM_READ_UNMAPPED)
|
||||||
uc->hook_mem_read_idx = i;
|
uc->hook_mem_read_idx = i;
|
||||||
if (type & UC_HOOK_MEM_READ_PROT)
|
if (type & UC_HOOK_MEM_READ_PROT)
|
||||||
uc->hook_mem_read_prot_idx = i;
|
uc->hook_mem_read_prot_idx = i;
|
||||||
if (type & UC_HOOK_MEM_WRITE_INVALID)
|
if (type & UC_HOOK_MEM_WRITE_UNMAPPED)
|
||||||
uc->hook_mem_write_idx = i;
|
uc->hook_mem_write_idx = i;
|
||||||
if (type & UC_HOOK_MEM_WRITE_PROT)
|
if (type & UC_HOOK_MEM_WRITE_PROT)
|
||||||
uc->hook_mem_write_prot_idx = i;
|
uc->hook_mem_write_prot_idx = i;
|
||||||
if (type & UC_HOOK_MEM_FETCH_INVALID)
|
if (type & UC_HOOK_MEM_FETCH_UNMAPPED)
|
||||||
uc->hook_mem_fetch_idx = i;
|
uc->hook_mem_fetch_idx = i;
|
||||||
if (type & UC_HOOK_MEM_FETCH_PROT)
|
if (type & UC_HOOK_MEM_FETCH_PROT)
|
||||||
uc->hook_mem_fetch_prot_idx = i;
|
uc->hook_mem_fetch_prot_idx = i;
|
||||||
|
@ -940,14 +938,14 @@ uc_err uc_hook_add(uc_engine *uc, uc_hook *hh, int type, void *callback, void *u
|
||||||
|
|
||||||
va_start(valist, user_data);
|
va_start(valist, user_data);
|
||||||
|
|
||||||
if (type & UC_HOOK_MEM_READ_INVALID)
|
if (type & UC_HOOK_MEM_READ_UNMAPPED)
|
||||||
ret = _hook_mem_invalid(uc, UC_HOOK_MEM_READ_INVALID, callback, user_data, hh);
|
ret = _hook_mem_invalid(uc, UC_HOOK_MEM_READ_UNMAPPED, callback, user_data, hh);
|
||||||
|
|
||||||
if (type & UC_HOOK_MEM_WRITE_INVALID)
|
if (type & UC_HOOK_MEM_WRITE_UNMAPPED)
|
||||||
ret = _hook_mem_invalid(uc, UC_HOOK_MEM_WRITE_INVALID, callback, user_data, hh);
|
ret = _hook_mem_invalid(uc, UC_HOOK_MEM_WRITE_UNMAPPED, callback, user_data, hh);
|
||||||
|
|
||||||
if (type & UC_HOOK_MEM_FETCH_INVALID)
|
if (type & UC_HOOK_MEM_FETCH_UNMAPPED)
|
||||||
ret = _hook_mem_invalid(uc, UC_HOOK_MEM_FETCH_INVALID, callback, user_data, hh);
|
ret = _hook_mem_invalid(uc, UC_HOOK_MEM_FETCH_UNMAPPED, callback, user_data, hh);
|
||||||
|
|
||||||
if (type & UC_HOOK_MEM_READ_PROT)
|
if (type & UC_HOOK_MEM_READ_PROT)
|
||||||
ret = _hook_mem_invalid(uc, UC_HOOK_MEM_READ_PROT, callback, user_data, hh);
|
ret = _hook_mem_invalid(uc, UC_HOOK_MEM_READ_PROT, callback, user_data, hh);
|
||||||
|
|
Loading…
Reference in a new issue