mirror of
https://github.com/yuzu-emu/unicorn
synced 2024-11-24 10:48:19 +00:00
Handle serialization of cpu context save (#1129)
* Handle the cpu context save in a more pythonic way, so the context can be serialized and reuse in an other process using the same emulator architecture and modes * Fix type error ; mistakes a size_t uint64_t ; breaks in 32bit... Backports commit 8987ad0fffadd16669aa3b402e7e8aaab70ad700 from qemu
This commit is contained in:
parent
221333ceaf
commit
bcef414231
3 changed files with 35 additions and 17 deletions
|
@ -138,6 +138,7 @@ _setup_prototype(_uc, "uc_context_alloc", ucerr, uc_engine, ctypes.POINTER(uc_co
|
|||
_setup_prototype(_uc, "uc_free", ucerr, ctypes.c_void_p)
|
||||
_setup_prototype(_uc, "uc_context_save", ucerr, uc_engine, uc_context)
|
||||
_setup_prototype(_uc, "uc_context_restore", ucerr, uc_engine, uc_context)
|
||||
_setup_prototype(_uc, "uc_context_size", ctypes.c_size_t, uc_engine)
|
||||
_setup_prototype(_uc, "uc_mem_regions", ucerr, uc_engine, ctypes.POINTER(ctypes.POINTER(_uc_mem_region)), ctypes.POINTER(ctypes.c_uint32))
|
||||
|
||||
# uc_hook_add is special due to variable number of arguments
|
||||
|
@ -582,24 +583,23 @@ class Uc(object):
|
|||
h = 0
|
||||
|
||||
def context_save(self):
|
||||
ptr = ctypes.cast(0, ctypes.c_voidp)
|
||||
status = _uc.uc_context_alloc(self._uch, ctypes.byref(ptr))
|
||||
size = _uc.uc_context_size(self._uch)
|
||||
|
||||
context = context_factory(size)
|
||||
|
||||
status = _uc.uc_context_save(self._uch, ctypes.byref(context))
|
||||
if status != uc.UC_ERR_OK:
|
||||
raise UcError(status)
|
||||
|
||||
status = _uc.uc_context_save(self._uch, ptr)
|
||||
if status != uc.UC_ERR_OK:
|
||||
raise UcError(status)
|
||||
|
||||
return SavedContext(ptr)
|
||||
return ctypes.string_at(ctypes.byref(context), ctypes.sizeof(context))
|
||||
|
||||
def context_update(self, context):
|
||||
status = _uc.uc_context_save(self._uch, context.pointer)
|
||||
status = _uc.uc_context_save(self._uch, context)
|
||||
if status != uc.UC_ERR_OK:
|
||||
raise UcError(status)
|
||||
|
||||
def context_restore(self, context):
|
||||
status = _uc.uc_context_restore(self._uch, context.pointer)
|
||||
status = _uc.uc_context_restore(self._uch, context)
|
||||
if status != uc.UC_ERR_OK:
|
||||
raise UcError(status)
|
||||
|
||||
|
@ -618,14 +618,15 @@ class Uc(object):
|
|||
_uc.uc_free(regions)
|
||||
|
||||
|
||||
class SavedContext(object):
|
||||
def __init__(self, pointer):
|
||||
self.pointer = pointer
|
||||
|
||||
def __del__(self):
|
||||
status = _uc.uc_free(self.pointer)
|
||||
if status != uc.UC_ERR_OK:
|
||||
raise UcError(status)
|
||||
def context_factory(size):
|
||||
class SavedContext(ctypes.Structure):
|
||||
_fields_ = [
|
||||
('size', ctypes.c_size_t),
|
||||
('data', ctypes.c_char*size)
|
||||
]
|
||||
ctxt = SavedContext()
|
||||
ctxt.size = size
|
||||
return ctxt
|
||||
|
||||
# print out debugging info
|
||||
def debug():
|
||||
|
|
|
@ -729,6 +729,17 @@ uc_err uc_context_save(uc_engine *uc, uc_context *context);
|
|||
UNICORN_EXPORT
|
||||
uc_err uc_context_restore(uc_engine *uc, uc_context *context);
|
||||
|
||||
/*
|
||||
Return the size needed to store the cpu context. Can be used to allocate a buffer
|
||||
to contain the cpu context and directly call uc_context_save.
|
||||
|
||||
@uc: handle returned by uc_open()
|
||||
|
||||
@return the size for needed to store the cpu context as as size_t.
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
size_t uc_context_size(uc_engine *uc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
6
uc.c
6
uc.c
|
@ -1304,6 +1304,12 @@ uc_err uc_free(void *mem)
|
|||
return UC_ERR_OK;
|
||||
}
|
||||
|
||||
UNICORN_EXPORT
|
||||
size_t uc_context_size(uc_engine *uc)
|
||||
{
|
||||
return cpu_context_size(uc->arch, uc->mode);
|
||||
}
|
||||
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_context_save(uc_engine *uc, uc_context *context)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue