mirror of
https://github.com/ptitSeb/box64.git
synced 2024-11-30 13:26:03 +08:00
Added first attempt at function wrapping
This commit is contained in:
parent
292897da46
commit
73332983fc
@ -373,36 +373,132 @@ typedef void (*wrapper_t)(x64emu_t* emu, uintptr_t fnc);
|
||||
# Next part: function definitions
|
||||
|
||||
# Helper variables
|
||||
arg = [
|
||||
reg_arg = ["R_RDI", "R_RSI", "R_RDX", "R_RCX", "R_R8", "R_R9"]
|
||||
# vreg: value is in a general register
|
||||
# E e v c w i I C W u U f d D K l L p V O S 2 P G N, M
|
||||
vreg = [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0]
|
||||
# vxmm: value is in a XMM register
|
||||
# E e v c w i I C W u U f d D K l L p V O S 2 P G N, M
|
||||
vxmm = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||
# vother: value is elsewere
|
||||
# E e v c w i I C W u U f d D K l L p V O S 2 P G N, M
|
||||
vother = [1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1]
|
||||
# vstack: value is on the stack (or out of register)
|
||||
# E e v c w i I C W u U f d D K l L p V O S 2 P G N, M
|
||||
vstack = [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0]
|
||||
arg_s = [
|
||||
"", # E
|
||||
"", # e
|
||||
"", # v
|
||||
"*(int8_t*)(R_RSP + {p}), ", # c
|
||||
"*(int16_t*)(R_RSP + {p}), ", # w
|
||||
"*(int32_t*)(R_RSP + {p}), ", # i
|
||||
"*(int64_t*)(R_RSP + {p}), ", # I
|
||||
"*(uint8_t*)(R_RSP + {p}), ", # C
|
||||
"*(uint16_t*)(R_RSP + {p}), ", # W
|
||||
"*(uint32_t*)(R_RSP + {p}), ", # u
|
||||
"*(uint64_t*)(R_RSP + {p}), ", # U
|
||||
"*(float*)(R_RSP + {p}), ", # f
|
||||
"*(double*)(R_RSP + {p}), ", # d
|
||||
"*(long double*)(R_RSP + {p}), ", # D
|
||||
"FromLD((void*)(R_RSP + {p})), ", # K
|
||||
"*(intptr_t*)(R_RSP + {p}), ", # l
|
||||
"*(uintptr_t*)(R_RSP + {p}), ", # L
|
||||
"*(void**)(R_RSP + {p}), ", # p
|
||||
"(void*)(R_RSP + {p}), ", # V
|
||||
"of_convert(*(int32_t*)(R_RSP + {p})), ", # O
|
||||
"io_convert(*(void**)(R_RSP + {p})), ", # S
|
||||
"(_2uint_struct_t){{*(uintptr_t*)(R_RSP + {p}),*(uintptr_t*)(R_RSP + {p} + 4)}}, ", # 2
|
||||
"", # P
|
||||
"", # G
|
||||
"*(void**)(R_RSP + {p}), ", # N
|
||||
"*(void**)(R_RSP + {p}),*(void**)(R_RSP + {p} + 4), ", # M
|
||||
]
|
||||
arg_r = [
|
||||
"", # E
|
||||
"", # e
|
||||
"", # v
|
||||
"(int8_t){p}, ", # c
|
||||
"(int16_t){p}, ", # w
|
||||
"(int32_t){p}, ", # i
|
||||
"(int64_t){p}, ", # I
|
||||
"(uint8_t){p}, ", # C
|
||||
"(uint16_t){p}, ", # W
|
||||
"(uint32_t){p}, ", # u
|
||||
"(uint64_t){p}, ", # U
|
||||
"", # f
|
||||
"", # d
|
||||
"", # D
|
||||
"", # K
|
||||
"(intptr_t){p} ", # l
|
||||
"(uintptr_t){p}, ", # L
|
||||
"(void*){p}, ", # p
|
||||
"", # V
|
||||
"of_convert((int32_t){p}), ", # O
|
||||
"io_convert((void*){p}), ", # S
|
||||
"", # 2
|
||||
"", # P
|
||||
"", # G
|
||||
"", # N
|
||||
"", # M
|
||||
]
|
||||
arg_x = [
|
||||
"", # E
|
||||
"", # e
|
||||
"", # v
|
||||
"", # c
|
||||
"", # w
|
||||
"", # i
|
||||
"", # I
|
||||
"", # C
|
||||
"", # W
|
||||
"", # u
|
||||
"", # U
|
||||
"emu->xmm[{p}].f[0]), ", # f
|
||||
"emu->xmm[{p}].d[0]), ", # d
|
||||
"", # D
|
||||
"", # K
|
||||
"", # l
|
||||
"", # L
|
||||
"", # p
|
||||
"", # V
|
||||
"", # O
|
||||
"", # S
|
||||
"", # 2
|
||||
"", # P
|
||||
"", # G
|
||||
"", # N
|
||||
"", # M
|
||||
]
|
||||
arg_o = [
|
||||
"emu, ", # E
|
||||
"&emu, ", # e
|
||||
"", # v
|
||||
"*(int8_t*)(R_RSP + {p}), ", # c
|
||||
"*(int16_t*)(R_RSP + {p}), ", # w
|
||||
"*(int32_t*)(R_RSP + {p}), ", # i
|
||||
"*(int64_t*)(R_RSP + {p}), ", # I
|
||||
"*(uint8_t*)(R_RSP + {p}), ", # C
|
||||
"*(uint16_t*)(R_RSP + {p}), ", # W
|
||||
"*(uint32_t*)(R_RSP + {p}), ", # u
|
||||
"*(uint64_t*)(R_RSP + {p}), ", # U
|
||||
"*(float*)(R_RSP + {p}), ", # f
|
||||
"*(double*)(R_RSP + {p}), ", # d
|
||||
"*(long double*)(R_RSP + {p}), ", # D
|
||||
"FromLD((void*)(R_RSP + {p})), ", # K
|
||||
"*(intptr_t*)(R_RSP + {p}), ", # l
|
||||
"*(uintptr_t*)(R_RSP + {p}), ", # L
|
||||
"*(void**)(R_RSP + {p}), ", # p
|
||||
"(void*)(R_RSP + {p}), ", # V
|
||||
"of_convert(*(int32_t*)(R_RSP + {p})), ", # O
|
||||
"io_convert(*(void**)(R_RSP + {p})), ", # S
|
||||
"(_2uint_struct_t){{*(uintptr_t*)(R_RSP + {p}),*(uintptr_t*)(R_RSP + {p} + 4)}}, ", # 2
|
||||
"", # c
|
||||
"", # w
|
||||
"", # i
|
||||
"", # I
|
||||
"", # C
|
||||
"", # W
|
||||
"", # u
|
||||
"", # U
|
||||
"", # f
|
||||
"", # d
|
||||
"", # D
|
||||
"", # K
|
||||
"", # l
|
||||
"", # L
|
||||
"", # p
|
||||
"", # V
|
||||
"", # O
|
||||
"", # S
|
||||
"", # 2
|
||||
"arg{p}, ", # P
|
||||
"&arg{p}, ", # G
|
||||
"*(void**)(R_RSP + {p}), ", # N
|
||||
"*(void**)(R_RSP + {p}), ", # N
|
||||
"*(void**)(R_RSP + {p}),*(void**)(R_RSP + {p} + 4), ", # M
|
||||
]
|
||||
# E e v c w i I C W u U f d D K l L p V O S 2 P G N, M
|
||||
deltas = [0, 0, 4, 4, 4, 4, 8, 4, 4, 4, 8, 4, 8, 12, 12, 8, 8, 8, 0, 4, 4, 8, 4, 4, 0, 0]
|
||||
|
||||
vals = [
|
||||
"\n#error Invalid return type: emulator\n", # E
|
||||
"\n#error Invalid return type: &emulator\n", # e
|
||||
@ -415,8 +511,8 @@ typedef void (*wrapper_t)(x64emu_t* emu, uintptr_t fnc);
|
||||
"R_RAX=(unsigned short)fn({0});", # W
|
||||
"R_RAX=(uint32_t)fn({0});", # u
|
||||
"R_RAX=fn({0});", # U
|
||||
"float fl=fn({0}); fpu_do_push(emu); ST0val = fl;", # f
|
||||
"double db=fn({0}); fpu_do_push(emu); ST0val = db;", # d
|
||||
"emu->xmm[0].f[0]=fn({0});", # f
|
||||
"emu->xmm[0].d[0]=fn({0});", # d
|
||||
"long double ld=fn({0}); fpu_do_push(emu); ST0val = ld;", # D
|
||||
"double db=fn({0}); fpu_do_push(emu); ST0val = db;", # K
|
||||
"R_RAX=(intptr_t)fn({0});", # l
|
||||
@ -432,26 +528,31 @@ typedef void (*wrapper_t)(x64emu_t* emu, uintptr_t fnc);
|
||||
"\n#error Invalid return type: ... with 2 args\n", # M
|
||||
]
|
||||
# Asserts
|
||||
if len(values) != len(arg):
|
||||
raise NotImplementedError("len(values) = {lenval} != len(arg) = {lenarg}".format(lenval=len(values), lenarg=len(arg)))
|
||||
if len(values) != len(deltas):
|
||||
raise NotImplementedError("len(values) = {lenval} != len(deltas) = {lendeltas}".format(lenval=len(values), lendeltas=len(deltas)))
|
||||
if len(values) != len(arg_s):
|
||||
raise NotImplementedError("len(values) = {lenval} != len(arg_s) = {lenargs}".format(lenval=len(values), lenargr=len(arg_s)))
|
||||
if len(values) != len(arg_r):
|
||||
raise NotImplementedError("len(values) = {lenval} != len(arg_r) = {lenargr}".format(lenval=len(values), lenargr=len(arg_r)))
|
||||
if len(values) != len(vals):
|
||||
raise NotImplementedError("len(values) = {lenval} != len(vals) = {lenvals}".format(lenval=len(values), lenvals=len(vals)))
|
||||
|
||||
# Helper functions to write the function definitions
|
||||
def function_args(args, d=4):
|
||||
def function_args(args, d=8, r=0, x=0):
|
||||
if len(args) == 0:
|
||||
return ""
|
||||
if d % 4 != 0:
|
||||
raise ValueError("{d} is not a multiple of 4. Did you try passing a V and something else?".format(d=d))
|
||||
|
||||
if args[0] == "0":
|
||||
return "(void*)(R_RSP + {p}), ".format(p=d) + function_args(args[1:], d + 4)
|
||||
return "0, " + function_args(args[1:], d, r, x)
|
||||
elif args[0] == "1":
|
||||
return "1, " + function_args(args[1:], d)
|
||||
return "1, " + function_args(args[1:], d, r, x)
|
||||
|
||||
return arg[values.index(args[0])].format(p=d) + function_args(args[1:], d + deltas[values.index(args[0])])
|
||||
idx = values.index(args[0])
|
||||
if r<5 and vreg[idx]>0:
|
||||
return arg_r[idx].format(p=reg_arg[r]) + function_args(args[1:], d, r+1, x)
|
||||
if x<7 and vxmm[idx]>0:
|
||||
return arg_x[idx].format(p=x) + function_args(args[1:], d, r, x+1)
|
||||
if vstack[idx]>0:
|
||||
return arg_s[idx].format(p=d) + function_args(args[1:], d+8*vstack[idx], r, x)
|
||||
return arg_o[idx].format(p=d) + function_args(args[1:], d + vother[idx]*8, r, x)
|
||||
|
||||
def function_writer(f, N, W, rettype, args):
|
||||
f.write("void {0}(x64emu_t *emu, uintptr_t fcn) {2} {1} fn = ({1})fcn; ".format(N, W, "{"))
|
||||
|
@ -99,30 +99,30 @@ typedef int32_t (*iFEpippppp_t)(x64emu_t*, void*, int32_t, void*, void*, void*,
|
||||
|
||||
void vFE(x64emu_t *emu, uintptr_t fcn) { vFE_t fn = (vFE_t)fcn; fn(emu); }
|
||||
void vFv(x64emu_t *emu, uintptr_t fcn) { vFv_t fn = (vFv_t)fcn; fn(); }
|
||||
void iFu(x64emu_t *emu, uintptr_t fcn) { iFu_t fn = (iFu_t)fcn; R_RAX=fn(*(uint32_t*)(R_RSP + 4)); }
|
||||
void iFp(x64emu_t *emu, uintptr_t fcn) { iFp_t fn = (iFp_t)fcn; R_RAX=fn(*(void**)(R_RSP + 4)); }
|
||||
void lFp(x64emu_t *emu, uintptr_t fcn) { lFp_t fn = (lFp_t)fcn; R_RAX=(intptr_t)fn(*(void**)(R_RSP + 4)); }
|
||||
void iFu(x64emu_t *emu, uintptr_t fcn) { iFu_t fn = (iFu_t)fcn; R_RAX=fn((uint32_t)R_RDI); }
|
||||
void iFp(x64emu_t *emu, uintptr_t fcn) { iFp_t fn = (iFp_t)fcn; R_RAX=fn((void*)R_RDI); }
|
||||
void lFp(x64emu_t *emu, uintptr_t fcn) { lFp_t fn = (lFp_t)fcn; R_RAX=(intptr_t)fn((void*)R_RDI); }
|
||||
void pFE(x64emu_t *emu, uintptr_t fcn) { pFE_t fn = (pFE_t)fcn; R_RAX=(uintptr_t)fn(emu); }
|
||||
void pFp(x64emu_t *emu, uintptr_t fcn) { pFp_t fn = (pFp_t)fcn; R_RAX=(uintptr_t)fn(*(void**)(R_RSP + 4)); }
|
||||
void vFEp(x64emu_t *emu, uintptr_t fcn) { vFEp_t fn = (vFEp_t)fcn; fn(emu, *(void**)(R_RSP + 4)); }
|
||||
void vFpp(x64emu_t *emu, uintptr_t fcn) { vFpp_t fn = (vFpp_t)fcn; fn(*(void**)(R_RSP + 4), *(void**)(R_RSP + 12)); }
|
||||
void iFEp(x64emu_t *emu, uintptr_t fcn) { iFEp_t fn = (iFEp_t)fcn; R_RAX=fn(emu, *(void**)(R_RSP + 4)); }
|
||||
void iFip(x64emu_t *emu, uintptr_t fcn) { iFip_t fn = (iFip_t)fcn; R_RAX=fn(*(int32_t*)(R_RSP + 4), *(void**)(R_RSP + 8)); }
|
||||
void iFup(x64emu_t *emu, uintptr_t fcn) { iFup_t fn = (iFup_t)fcn; R_RAX=fn(*(uint32_t*)(R_RSP + 4), *(void**)(R_RSP + 8)); }
|
||||
void pFEp(x64emu_t *emu, uintptr_t fcn) { pFEp_t fn = (pFEp_t)fcn; R_RAX=(uintptr_t)fn(emu, *(void**)(R_RSP + 4)); }
|
||||
void vFEpu(x64emu_t *emu, uintptr_t fcn) { vFEpu_t fn = (vFEpu_t)fcn; fn(emu, *(void**)(R_RSP + 4), *(uint32_t*)(R_RSP + 12)); }
|
||||
void iFEpp(x64emu_t *emu, uintptr_t fcn) { iFEpp_t fn = (iFEpp_t)fcn; R_RAX=fn(emu, *(void**)(R_RSP + 4), *(void**)(R_RSP + 12)); }
|
||||
void iFpiu(x64emu_t *emu, uintptr_t fcn) { iFpiu_t fn = (iFpiu_t)fcn; R_RAX=fn(*(void**)(R_RSP + 4), *(int32_t*)(R_RSP + 12), *(uint32_t*)(R_RSP + 16)); }
|
||||
void pFEpi(x64emu_t *emu, uintptr_t fcn) { pFEpi_t fn = (pFEpi_t)fcn; R_RAX=(uintptr_t)fn(emu, *(void**)(R_RSP + 4), *(int32_t*)(R_RSP + 12)); }
|
||||
void pFEpp(x64emu_t *emu, uintptr_t fcn) { pFEpp_t fn = (pFEpp_t)fcn; R_RAX=(uintptr_t)fn(emu, *(void**)(R_RSP + 4), *(void**)(R_RSP + 12)); }
|
||||
void vFEpup(x64emu_t *emu, uintptr_t fcn) { vFEpup_t fn = (vFEpup_t)fcn; fn(emu, *(void**)(R_RSP + 4), *(uint32_t*)(R_RSP + 12), *(void**)(R_RSP + 16)); }
|
||||
void iFEupp(x64emu_t *emu, uintptr_t fcn) { iFEupp_t fn = (iFEupp_t)fcn; R_RAX=fn(emu, *(uint32_t*)(R_RSP + 4), *(void**)(R_RSP + 8), *(void**)(R_RSP + 16)); }
|
||||
void iFEpip(x64emu_t *emu, uintptr_t fcn) { iFEpip_t fn = (iFEpip_t)fcn; R_RAX=fn(emu, *(void**)(R_RSP + 4), *(int32_t*)(R_RSP + 12), *(void**)(R_RSP + 16)); }
|
||||
void iFEppp(x64emu_t *emu, uintptr_t fcn) { iFEppp_t fn = (iFEppp_t)fcn; R_RAX=fn(emu, *(void**)(R_RSP + 4), *(void**)(R_RSP + 12), *(void**)(R_RSP + 20)); }
|
||||
void iFuipp(x64emu_t *emu, uintptr_t fcn) { iFuipp_t fn = (iFuipp_t)fcn; R_RAX=fn(*(uint32_t*)(R_RSP + 4), *(int32_t*)(R_RSP + 8), *(void**)(R_RSP + 12), *(void**)(R_RSP + 20)); }
|
||||
void pFEppi(x64emu_t *emu, uintptr_t fcn) { pFEppi_t fn = (pFEppi_t)fcn; R_RAX=(uintptr_t)fn(emu, *(void**)(R_RSP + 4), *(void**)(R_RSP + 12), *(int32_t*)(R_RSP + 20)); }
|
||||
void pFEppp(x64emu_t *emu, uintptr_t fcn) { pFEppp_t fn = (pFEppp_t)fcn; R_RAX=(uintptr_t)fn(emu, *(void**)(R_RSP + 4), *(void**)(R_RSP + 12), *(void**)(R_RSP + 20)); }
|
||||
void iFipppi(x64emu_t *emu, uintptr_t fcn) { iFipppi_t fn = (iFipppi_t)fcn; R_RAX=fn(*(int32_t*)(R_RSP + 4), *(void**)(R_RSP + 8), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24), *(int32_t*)(R_RSP + 32)); }
|
||||
void iFEpippppp(x64emu_t *emu, uintptr_t fcn) { iFEpippppp_t fn = (iFEpippppp_t)fcn; R_RAX=fn(emu, *(void**)(R_RSP + 4), *(int32_t*)(R_RSP + 12), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24), *(void**)(R_RSP + 32), *(void**)(R_RSP + 40), *(void**)(R_RSP + 48)); }
|
||||
void pFp(x64emu_t *emu, uintptr_t fcn) { pFp_t fn = (pFp_t)fcn; R_RAX=(uintptr_t)fn((void*)R_RDI); }
|
||||
void vFEp(x64emu_t *emu, uintptr_t fcn) { vFEp_t fn = (vFEp_t)fcn; fn(emu, (void*)R_RDI); }
|
||||
void vFpp(x64emu_t *emu, uintptr_t fcn) { vFpp_t fn = (vFpp_t)fcn; fn((void*)R_RDI, (void*)R_RSI); }
|
||||
void iFEp(x64emu_t *emu, uintptr_t fcn) { iFEp_t fn = (iFEp_t)fcn; R_RAX=fn(emu, (void*)R_RDI); }
|
||||
void iFip(x64emu_t *emu, uintptr_t fcn) { iFip_t fn = (iFip_t)fcn; R_RAX=fn((int32_t)R_RDI, (void*)R_RSI); }
|
||||
void iFup(x64emu_t *emu, uintptr_t fcn) { iFup_t fn = (iFup_t)fcn; R_RAX=fn((uint32_t)R_RDI, (void*)R_RSI); }
|
||||
void pFEp(x64emu_t *emu, uintptr_t fcn) { pFEp_t fn = (pFEp_t)fcn; R_RAX=(uintptr_t)fn(emu, (void*)R_RDI); }
|
||||
void vFEpu(x64emu_t *emu, uintptr_t fcn) { vFEpu_t fn = (vFEpu_t)fcn; fn(emu, (void*)R_RDI, (uint32_t)R_RSI); }
|
||||
void iFEpp(x64emu_t *emu, uintptr_t fcn) { iFEpp_t fn = (iFEpp_t)fcn; R_RAX=fn(emu, (void*)R_RDI, (void*)R_RSI); }
|
||||
void iFpiu(x64emu_t *emu, uintptr_t fcn) { iFpiu_t fn = (iFpiu_t)fcn; R_RAX=fn((void*)R_RDI, (int32_t)R_RSI, (uint32_t)R_RDX); }
|
||||
void pFEpi(x64emu_t *emu, uintptr_t fcn) { pFEpi_t fn = (pFEpi_t)fcn; R_RAX=(uintptr_t)fn(emu, (void*)R_RDI, (int32_t)R_RSI); }
|
||||
void pFEpp(x64emu_t *emu, uintptr_t fcn) { pFEpp_t fn = (pFEpp_t)fcn; R_RAX=(uintptr_t)fn(emu, (void*)R_RDI, (void*)R_RSI); }
|
||||
void vFEpup(x64emu_t *emu, uintptr_t fcn) { vFEpup_t fn = (vFEpup_t)fcn; fn(emu, (void*)R_RDI, (uint32_t)R_RSI, (void*)R_RDX); }
|
||||
void iFEupp(x64emu_t *emu, uintptr_t fcn) { iFEupp_t fn = (iFEupp_t)fcn; R_RAX=fn(emu, (uint32_t)R_RDI, (void*)R_RSI, (void*)R_RDX); }
|
||||
void iFEpip(x64emu_t *emu, uintptr_t fcn) { iFEpip_t fn = (iFEpip_t)fcn; R_RAX=fn(emu, (void*)R_RDI, (int32_t)R_RSI, (void*)R_RDX); }
|
||||
void iFEppp(x64emu_t *emu, uintptr_t fcn) { iFEppp_t fn = (iFEppp_t)fcn; R_RAX=fn(emu, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX); }
|
||||
void iFuipp(x64emu_t *emu, uintptr_t fcn) { iFuipp_t fn = (iFuipp_t)fcn; R_RAX=fn((uint32_t)R_RDI, (int32_t)R_RSI, (void*)R_RDX, (void*)R_RCX); }
|
||||
void pFEppi(x64emu_t *emu, uintptr_t fcn) { pFEppi_t fn = (pFEppi_t)fcn; R_RAX=(uintptr_t)fn(emu, (void*)R_RDI, (void*)R_RSI, (int32_t)R_RDX); }
|
||||
void pFEppp(x64emu_t *emu, uintptr_t fcn) { pFEppp_t fn = (pFEppp_t)fcn; R_RAX=(uintptr_t)fn(emu, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX); }
|
||||
void iFipppi(x64emu_t *emu, uintptr_t fcn) { iFipppi_t fn = (iFipppi_t)fcn; R_RAX=fn((int32_t)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (int32_t)R_R8); }
|
||||
void iFEpippppp(x64emu_t *emu, uintptr_t fcn) { iFEpippppp_t fn = (iFEpippppp_t)fcn; R_RAX=fn(emu, (void*)R_RDI, (int32_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, *(void**)(R_RSP + 16), *(void**)(R_RSP + 24)); }
|
||||
|
||||
void pFEv(x64emu_t *emu, uintptr_t fcn) { pFE_t fn = (pFE_t)fcn; R_RAX=(uintptr_t)fn(emu); }
|
||||
|
Loading…
Reference in New Issue
Block a user