Skip to content

Commit ad492d4

Browse files
Remove the size limit for memory read and write
Eliminate the maximum size restriction for uc_mem_read and uc_mem_write. This change is required to support applications, such as LLVM CFI, that map or unmap memory blocks with sizes equal to or greater than INT_MAX.
1 parent 7b8c63d commit ad492d4

File tree

15 files changed

+198
-206
lines changed

15 files changed

+198
-206
lines changed

bindings/dotnet/UnicornManaged/Binding/NativeBinding.fs

+12-12
Original file line numberDiff line numberDiff line change
@@ -6,34 +6,34 @@ open System.Runtime.InteropServices
66
module NativeBinding =
77

88
[<AutoOpen>]
9-
module private Imported =
9+
module private Imported =
1010

1111
[<DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)>]
1212
extern Int32 uc_version(UIntPtr major, UIntPtr minor)
1313

1414
[<DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)>]
15-
extern Int32 uc_open(UInt32 arch, UInt32 mode, UIntPtr[] engine)
15+
extern Int32 uc_open(UInt32 arch, UInt32 mode, UIntPtr[] engine)
1616

1717
[<DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)>]
18-
extern Int32 uc_close(UIntPtr eng)
18+
extern Int32 uc_close(UIntPtr eng)
1919

2020
[<DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)>]
21-
extern Int32 uc_mem_map(UIntPtr eng, UInt64 address, UIntPtr size, UInt32 perm)
21+
extern Int32 uc_mem_map(UIntPtr eng, UInt64 address, UInt64 size, UInt32 perm)
2222

2323
[<DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)>]
24-
extern Int32 uc_mem_map_ptr(UIntPtr eng, UInt64 address, UIntPtr size, UInt32 perm, UIntPtr ptr)
24+
extern Int32 uc_mem_map_ptr(UIntPtr eng, UInt64 address, UInt64 size, UInt32 perm, UIntPtr ptr)
2525

2626
[<DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)>]
27-
extern Int32 uc_mem_unmap(UIntPtr eng, UInt64 address, UIntPtr size)
27+
extern Int32 uc_mem_unmap(UIntPtr eng, UInt64 address, UInt64 size)
2828

2929
[<DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)>]
30-
extern Int32 uc_mem_protect(UIntPtr eng, UInt64 address, UIntPtr size, UInt32 perms)
31-
30+
extern Int32 uc_mem_protect(UIntPtr eng, UInt64 address, UInt64 size, UInt32 perms)
31+
3232
[<DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)>]
33-
extern Int32 uc_mem_write(UIntPtr eng, UInt64 address, Byte[] value, UIntPtr size)
33+
extern Int32 uc_mem_write(UIntPtr eng, UInt64 address, Byte[] value, UInt64 size)
3434

3535
[<DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)>]
36-
extern Int32 uc_mem_read(UIntPtr eng, UInt64 address, Byte[] value, UIntPtr size)
36+
extern Int32 uc_mem_read(UIntPtr eng, UInt64 address, Byte[] value, UInt64 size)
3737

3838
[<DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)>]
3939
extern Int32 uc_reg_write(UIntPtr eng, Int32 regId, Byte[] value)
@@ -67,7 +67,7 @@ module NativeBinding =
6767

6868
[<DllImport("unicorn", CallingConvention = CallingConvention.Cdecl, EntryPoint = "uc_hook_add")>]
6969
extern Int32 uc_hook_add_arg0_arg1(UIntPtr eng, UIntPtr hh, Int32 callbackType, UIntPtr callback, IntPtr userData, UInt64 hookbegin, UInt64 hookend, UInt64 arg0, UInt64 arg1)
70-
70+
7171
let instance =
7272
{new IBinding with
7373
member thi.Version(major, minor) = uc_version(major, minor)
@@ -90,4 +90,4 @@ module NativeBinding =
9090
member thi.HookAddNoarg(eng, hh, callbackType, callback, userData, hookBegin, hookEnd) = uc_hook_add_noarg(eng, hh, callbackType, callback, userData, hookBegin, hookEnd)
9191
member thi.HookAddArg0(eng, hh, callbackType, callback, userData, hookBegin, hookEnd, arg0) = uc_hook_add_arg0(eng, hh, callbackType, callback, userData, hookBegin, hookEnd, arg0)
9292
member thi.HookAddArg0Arg1(eng, hh, callbackType, callback, userData, hookBegin, hookEnd, arg0, arg1) = uc_hook_add_arg0_arg1(eng, hh, callbackType, callback, userData, hookBegin, hookEnd, arg0, arg1)
93-
}
93+
}

bindings/go/unicorn/unicorn.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -190,14 +190,14 @@ func (u *uc) MemWrite(addr uint64, data []byte) error {
190190
if len(data) == 0 {
191191
return nil
192192
}
193-
return errReturn(C.uc_mem_write(u.handle, C.uint64_t(addr), unsafe.Pointer(&data[0]), C.size_t(len(data))))
193+
return errReturn(C.uc_mem_write(u.handle, C.uint64_t(addr), unsafe.Pointer(&data[0]), C.uint64_t(len(data))))
194194
}
195195

196196
func (u *uc) MemReadInto(dst []byte, addr uint64) error {
197197
if len(dst) == 0 {
198198
return nil
199199
}
200-
return errReturn(C.uc_mem_read(u.handle, C.uint64_t(addr), unsafe.Pointer(&dst[0]), C.size_t(len(dst))))
200+
return errReturn(C.uc_mem_read(u.handle, C.uint64_t(addr), unsafe.Pointer(&dst[0]), C.uint64_t(len(dst))))
201201
}
202202

203203
func (u *uc) MemRead(addr, size uint64) ([]byte, error) {
@@ -206,23 +206,23 @@ func (u *uc) MemRead(addr, size uint64) ([]byte, error) {
206206
}
207207

208208
func (u *uc) MemMapProt(addr, size uint64, prot int) error {
209-
return errReturn(C.uc_mem_map(u.handle, C.uint64_t(addr), C.size_t(size), C.uint32_t(prot)))
209+
return errReturn(C.uc_mem_map(u.handle, C.uint64_t(addr), C.uint64_t(size), C.uint32_t(prot)))
210210
}
211211

212212
func (u *uc) MemMap(addr, size uint64) error {
213213
return u.MemMapProt(addr, size, PROT_ALL)
214214
}
215215

216216
func (u *uc) MemMapPtr(addr, size uint64, prot int, ptr unsafe.Pointer) error {
217-
return errReturn(C.uc_mem_map_ptr(u.handle, C.uint64_t(addr), C.size_t(size), C.uint32_t(prot), ptr))
217+
return errReturn(C.uc_mem_map_ptr(u.handle, C.uint64_t(addr), C.uint64_t(size), C.uint32_t(prot), ptr))
218218
}
219219

220220
func (u *uc) MemProtect(addr, size uint64, prot int) error {
221-
return errReturn(C.uc_mem_protect(u.handle, C.uint64_t(addr), C.size_t(size), C.uint32_t(prot)))
221+
return errReturn(C.uc_mem_protect(u.handle, C.uint64_t(addr), C.uint64_t(size), C.uint32_t(prot)))
222222
}
223223

224224
func (u *uc) MemUnmap(addr, size uint64) error {
225-
return errReturn(C.uc_mem_unmap(u.handle, C.uint64_t(addr), C.size_t(size)))
225+
return errReturn(C.uc_mem_unmap(u.handle, C.uint64_t(addr), C.uint64_t(size)))
226226
}
227227

228228
func (u *uc) Query(queryType int) (uint64, error) {

bindings/java/unicorn_Unicorn.c

+6-6
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn_mem_1write
447447
uc_engine *eng = getEngine(env, self);
448448
jbyte *array = (*env)->GetByteArrayElements(env, bytes, NULL);
449449
jsize size = (*env)->GetArrayLength(env, bytes);
450-
uc_err err = uc_mem_write(eng, (uint64_t)address, array, (size_t)size);
450+
uc_err err = uc_mem_write(eng, (uint64_t)address, array, (uint64_t)size);
451451

452452
if (err != UC_ERR_OK) {
453453
throwException(env, err);
@@ -467,7 +467,7 @@ JNIEXPORT jbyteArray JNICALL Java_unicorn_Unicorn_mem_1read
467467

468468
jbyteArray bytes = (*env)->NewByteArray(env, (jsize)size);
469469
jbyte *array = (*env)->GetByteArrayElements(env, bytes, NULL);
470-
uc_err err = uc_mem_read(eng, (uint64_t)address, array, (size_t)size);
470+
uc_err err = uc_mem_read(eng, (uint64_t)address, array, (uint64_t)size);
471471
if (err != UC_ERR_OK) {
472472
throwException(env, err);
473473
}
@@ -634,7 +634,7 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn_mem_1map
634634
(JNIEnv *env, jobject self, jlong address, jlong size, jint perms) {
635635
uc_engine *eng = getEngine(env, self);
636636

637-
uc_err err = uc_mem_map(eng, (uint64_t)address, (size_t)size, (uint32_t)perms);
637+
uc_err err = uc_mem_map(eng, (uint64_t)address, (uint64_t)size, (uint32_t)perms);
638638
if (err != UC_ERR_OK) {
639639
throwException(env, err);
640640
}
@@ -649,7 +649,7 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn_mem_1map_1ptr
649649
(JNIEnv *env, jobject self, jlong address, jlong size, jint perms, jbyteArray block) {
650650
uc_engine *eng = getEngine(env, self);
651651
jbyte *array = (*env)->GetByteArrayElements(env, block, NULL);
652-
uc_err err = uc_mem_map_ptr(eng, (uint64_t)address, (size_t)size, (uint32_t)perms, (void*)array);
652+
uc_err err = uc_mem_map_ptr(eng, (uint64_t)address, (uint64_t)size, (uint32_t)perms, (void*)array);
653653
if (err != UC_ERR_OK) {
654654
throwException(env, err);
655655
}
@@ -667,7 +667,7 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn_mem_1unmap
667667
(JNIEnv *env, jobject self, jlong address, jlong size) {
668668
uc_engine *eng = getEngine(env, self);
669669

670-
uc_err err = uc_mem_unmap(eng, (uint64_t)address, (size_t)size);
670+
uc_err err = uc_mem_unmap(eng, (uint64_t)address, (uint64_t)size);
671671
if (err != UC_ERR_OK) {
672672
throwException(env, err);
673673
}
@@ -685,7 +685,7 @@ JNIEXPORT void JNICALL Java_unicorn_Unicorn_mem_1protect
685685
(JNIEnv *env, jobject self, jlong address, jlong size, jint perms) {
686686
uc_engine *eng = getEngine(env, self);
687687

688-
uc_err err = uc_mem_protect(eng, (uint64_t)address, (size_t)size, (uint32_t)perms);
688+
uc_err err = uc_mem_protect(eng, (uint64_t)address, (uint64_t)size, (uint32_t)perms);
689689
if (err != UC_ERR_OK) {
690690
throwException(env, err);
691691
}

bindings/pascal/unicorn/Unicorn_dyn.pas

+6-6
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ uc_mem_region = record
291291
for detailed error).
292292
*)
293293
uc_mem_write_ : function (uc : uc_engine; address : UInt64; const bytes : Pointer;
294-
size : Cardinal) : uc_err; cdecl;
294+
size : UInt64) : uc_err; cdecl;
295295

296296
(*
297297
Read a range of bytes in memory.
@@ -307,7 +307,7 @@ uc_mem_region = record
307307
for detailed error).
308308
*)
309309
uc_mem_read_ : function (uc : uc_engine; address : UInt64; bytes : Pointer;
310-
size : Cardinal) : uc_err; cdecl;
310+
size : UInt64) : uc_err; cdecl;
311311

312312
(*
313313
Emulate machine code in a specific duration of time.
@@ -400,7 +400,7 @@ function (uc : uc_engine; var hh : uc_hook; _type : integer;
400400
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
401401
for detailed error).
402402
*)
403-
uc_mem_map : function (uc : uc_engine; address : UInt64; size : Cardinal; perms : UInt32) : uc_err; cdecl;
403+
uc_mem_map : function (uc : uc_engine; address : UInt64; size : UInt64; perms : UInt32) : uc_err; cdecl;
404404

405405

406406
(*
@@ -422,7 +422,7 @@ function (uc : uc_engine; var hh : uc_hook; _type : integer;
422422
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
423423
for detailed error).
424424
*)
425-
uc_mem_map_ptr : function(uc : uc_engine; address : UInt64; size : Cardinal; perms : UInt32; ptr : Pointer) : uc_err; cdecl;
425+
uc_mem_map_ptr : function(uc : uc_engine; address : UInt64; size : UInt64; perms : UInt32; ptr : Pointer) : uc_err; cdecl;
426426

427427

428428
(*
@@ -438,7 +438,7 @@ function (uc : uc_engine; var hh : uc_hook; _type : integer;
438438
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum \
439439
for detailed error).
440440
*)
441-
uc_mem_unmap : function (uc : uc_engine; address : UInt64; size : Cardinal) : uc_err; cdecl ;
441+
uc_mem_unmap : function (uc : uc_engine; address : UInt64; size : UInt64) : uc_err; cdecl ;
442442

443443
(*
444444
Set memory permissions for emulation memory.
@@ -456,7 +456,7 @@ function (uc : uc_engine; var hh : uc_hook; _type : integer;
456456
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum \
457457
for detailed error).
458458
*)
459-
uc_mem_protect : function (uc : uc_engine; address : UInt64; size : Cardinal; perms : UInt32) : uc_err; cdecl ;
459+
uc_mem_protect : function (uc : uc_engine; address : UInt64; size : UInt64; perms : UInt32) : uc_err; cdecl ;
460460

461461
(*
462462
Retrieve all memory regions mapped by uc_mem_map() and uc_mem_map_ptr()

bindings/python/unicorn/unicorn.py

+25-25
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ def _load_lib(path, lib_name):
103103
for _path in _path_list:
104104
if _path is None:
105105
continue
106-
106+
107107
_uc = _load_lib(_path, "libunicorn.so")
108108
if _uc is not None:
109109
# In this case, show a warning for users
@@ -153,16 +153,16 @@ class uc_tb(ctypes.Structure):
153153
_setup_prototype(_uc, "uc_errno", ucerr, uc_engine)
154154
_setup_prototype(_uc, "uc_reg_read", ucerr, uc_engine, ctypes.c_int, ctypes.c_void_p)
155155
_setup_prototype(_uc, "uc_reg_write", ucerr, uc_engine, ctypes.c_int, ctypes.c_void_p)
156-
_setup_prototype(_uc, "uc_mem_read", ucerr, uc_engine, ctypes.c_uint64, ctypes.POINTER(ctypes.c_char), ctypes.c_size_t)
157-
_setup_prototype(_uc, "uc_mem_write", ucerr, uc_engine, ctypes.c_uint64, ctypes.POINTER(ctypes.c_char), ctypes.c_size_t)
156+
_setup_prototype(_uc, "uc_mem_read", ucerr, uc_engine, ctypes.c_uint64, ctypes.POINTER(ctypes.c_char), ctypes.c_uint64)
157+
_setup_prototype(_uc, "uc_mem_write", ucerr, uc_engine, ctypes.c_uint64, ctypes.POINTER(ctypes.c_char), ctypes.c_uint64)
158158
_setup_prototype(_uc, "uc_emu_start", ucerr, uc_engine, ctypes.c_uint64, ctypes.c_uint64, ctypes.c_uint64, ctypes.c_size_t)
159159
_setup_prototype(_uc, "uc_emu_stop", ucerr, uc_engine)
160160
_setup_prototype(_uc, "uc_hook_del", ucerr, uc_engine, uc_hook_h)
161-
_setup_prototype(_uc, "uc_mmio_map", ucerr, uc_engine, ctypes.c_uint64, ctypes.c_size_t, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p)
162-
_setup_prototype(_uc, "uc_mem_map", ucerr, uc_engine, ctypes.c_uint64, ctypes.c_size_t, ctypes.c_uint32)
163-
_setup_prototype(_uc, "uc_mem_map_ptr", ucerr, uc_engine, ctypes.c_uint64, ctypes.c_size_t, ctypes.c_uint32, ctypes.c_void_p)
164-
_setup_prototype(_uc, "uc_mem_unmap", ucerr, uc_engine, ctypes.c_uint64, ctypes.c_size_t)
165-
_setup_prototype(_uc, "uc_mem_protect", ucerr, uc_engine, ctypes.c_uint64, ctypes.c_size_t, ctypes.c_uint32)
161+
_setup_prototype(_uc, "uc_mmio_map", ucerr, uc_engine, ctypes.c_uint64, ctypes.c_uint64, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p)
162+
_setup_prototype(_uc, "uc_mem_map", ucerr, uc_engine, ctypes.c_uint64, ctypes.c_uint64, ctypes.c_uint32)
163+
_setup_prototype(_uc, "uc_mem_map_ptr", ucerr, uc_engine, ctypes.c_uint64, ctypes.c_uint64, ctypes.c_uint32, ctypes.c_void_p)
164+
_setup_prototype(_uc, "uc_mem_unmap", ucerr, uc_engine, ctypes.c_uint64, ctypes.c_uint64)
165+
_setup_prototype(_uc, "uc_mem_protect", ucerr, uc_engine, ctypes.c_uint64, ctypes.c_uint64, ctypes.c_uint32)
166166
_setup_prototype(_uc, "uc_query", ucerr, uc_engine, ctypes.c_uint32, ctypes.POINTER(ctypes.c_size_t))
167167
_setup_prototype(_uc, "uc_context_alloc", ucerr, uc_engine, ctypes.POINTER(uc_context))
168168
_setup_prototype(_uc, "uc_free", ucerr, ctypes.c_void_p)
@@ -593,7 +593,7 @@ def _mmio_map_write_cb(self, handle, offset, size, value, user_data):
593593
(cb, data) = self._callbacks[user_data]
594594
cb(self, offset, size, value, data)
595595

596-
def mmio_map(self, address: int, size: int,
596+
def mmio_map(self, address: int, size: int,
597597
read_cb: UC_MMIO_READ_TYPE, user_data_read: Any,
598598
write_cb: UC_MMIO_WRITE_TYPE, user_data_write: Any):
599599
internal_read_cb = ctypes.cast(UC_MMIO_READ_CB(self._mmio_map_read_cb), UC_MMIO_READ_CB)
@@ -609,7 +609,7 @@ def mmio_map(self, address: int, size: int,
609609
status = _uc.uc_mmio_map(self._uch, address, size, internal_read_cb, read_count, internal_write_cb, write_count)
610610
if status != uc.UC_ERR_OK:
611611
raise UcError(status)
612-
612+
613613
# https://docs.python.org/3/library/ctypes.html#callback-functions
614614
self._ctype_cbs.append(internal_read_cb)
615615
self._ctype_cbs.append(internal_write_cb)
@@ -731,12 +731,12 @@ def __ctl(self, ctl, nr, rw):
731731

732732
def __ctl_r(self, ctl, nr):
733733
return self.__ctl(ctl, nr, uc.UC_CTL_IO_READ)
734-
734+
735735
def __ctl_w(self, ctl, nr):
736736
return self.__ctl(ctl, nr, uc.UC_CTL_IO_WRITE)
737-
737+
738738
def __ctl_rw(self, ctl, nr):
739-
return self.__ctl(ctl, nr, uc.UC_CTL_IO_READ_WRITE)
739+
return self.__ctl(ctl, nr, uc.UC_CTL_IO_READ_WRITE)
740740

741741
def __ctl_r_1_arg(self, ctl, ctp):
742742
arg = ctp()
@@ -746,7 +746,7 @@ def __ctl_r_1_arg(self, ctl, ctp):
746746
def __ctl_w_1_arg(self, ctl, val, ctp):
747747
arg = ctp(val)
748748
self.ctl(self.__ctl_w(ctl, 1), arg)
749-
749+
750750
def __ctl_w_2_arg(self, ctl, val1, val2, ctp1, ctp2):
751751
arg1 = ctp1(val1)
752752
arg2 = ctp2(val2)
@@ -763,7 +763,7 @@ def ctl_get_mode(self):
763763

764764
def ctl_get_page_size(self):
765765
return self.__ctl_r_1_arg(uc.UC_CTL_UC_PAGE_SIZE, ctypes.c_uint32)
766-
766+
767767
def ctl_set_page_size(self, val: int):
768768
self.__ctl_w_1_arg(uc.UC_CTL_UC_PAGE_SIZE, val, ctypes.c_uint32)
769769

@@ -772,10 +772,10 @@ def ctl_get_arch(self):
772772

773773
def ctl_get_timeout(self):
774774
return self.__ctl_r_1_arg(uc.UC_CTL_UC_TIMEOUT, ctypes.c_uint64)
775-
775+
776776
def ctl_exits_enabled(self, val: bool):
777777
self.__ctl_w_1_arg(uc.UC_CTL_UC_USE_EXITS, val, ctypes.c_int)
778-
778+
779779
def ctl_get_exits_cnt(self):
780780
return self.__ctl_r_1_arg(uc.UC_CTL_UC_EXITS_CNT, ctypes.c_size_t)
781781

@@ -793,7 +793,7 @@ def ctl_set_exits(self, exits: List[int]):
793793

794794
def ctl_get_cpu_model(self):
795795
return self.__ctl_r_1_arg(uc.UC_CTL_CPU_MODEL, ctypes.c_int)
796-
796+
797797
def ctl_set_cpu_model(self, val: int):
798798
self.__ctl_w_1_arg(uc.UC_CTL_CPU_MODEL, val, ctypes.c_int)
799799

@@ -802,7 +802,7 @@ def ctl_remove_cache(self, addr: int, end: int):
802802

803803
def ctl_request_cache(self, addr: int):
804804
return self.__ctl_rw_1_1_arg(uc.UC_CTL_TB_REQUEST_CACHE, addr, ctypes.c_uint64, uc_tb)
805-
805+
806806
def ctl_flush_tb(self):
807807
self.ctl(self.__ctl_w(uc.UC_CTL_TB_FLUSH, 0))
808808

@@ -963,7 +963,7 @@ def size(self):
963963
@property
964964
def arch(self):
965965
return self._arch
966-
966+
967967
@property
968968
def mode(self):
969969
return self._mode
@@ -1012,11 +1012,11 @@ def __del__(self):
10121012
UC_HOOK_TCG_OPCODE_TYPE = Callable[[Uc, int, int, int, Any], None]
10131013

10141014
UC_HOOK_CALLBACK_TYPE = Union[
1015-
UC_HOOK_CODE_TYPE,
1016-
UC_HOOK_INSN_INVALID_TYPE,
1017-
UC_HOOK_MEM_INVALID_TYPE,
1018-
UC_HOOK_MEM_ACCESS_TYPE,
1019-
UC_HOOK_INSN_IN_TYPE,
1015+
UC_HOOK_CODE_TYPE,
1016+
UC_HOOK_INSN_INVALID_TYPE,
1017+
UC_HOOK_MEM_INVALID_TYPE,
1018+
UC_HOOK_MEM_ACCESS_TYPE,
1019+
UC_HOOK_INSN_IN_TYPE,
10201020
UC_HOOK_INSN_OUT_TYPE,
10211021
UC_HOOK_INSN_SYSCALL_TYPE,
10221022
UC_HOOK_INSN_SYS_TYPE,

0 commit comments

Comments
 (0)