Compare commits

...
23 Commits
Author SHA1 Message Date
ptitSeb 9243ea4ca1 Bumped to v0.1.2 2021-07-03 14:42:17 +02:00
ptitSeb 2e871fc68a Added another name for wine64 2021-07-03 11:10:24 +02:00
ptitSeb 30eb08f8af More README updates 2021-07-03 11:05:49 +02:00
ptitSeb 7f51495877 Improved README 2021-07-03 10:49:59 +02:00
ptitSeb 112bc0d83f More libc wrapped functions 2021-07-03 10:32:48 +02:00
ptitSeb 501a4a8956 Made elf LOADADDR default again 2021-07-03 10:32:34 +02:00
ptitSeb bb4c06f107 More the LOADADDR of the box64 elf a 32bits value 2021-07-03 09:46:48 +02:00
ptitSeb 65fae1077f One more wrapped libc function 2021-07-03 09:46:28 +02:00
ptitSeb e3a36591aa Added even more libc wrapped functions (needed by Wine) 2021-07-02 22:23:31 +02:00
ptitSeb a597f6701f Added a couple of libc wrapped functions 2021-07-02 17:33:23 +02:00
ptitSeb 3b19a7fe1d Added 64 D1/D3 opcodes ([DYNAREC] too) 2021-07-02 17:30:52 +02:00
ptitSeb ccf9775658 Added some more libc wrapped functions 2021-07-02 16:40:41 +02:00
ptitSeb 762a499648 Fixed a typo 2021-07-02 16:34:24 +02:00
ptitSeb aa56188e7e Set default to NOLOADADDR, as many system doesn't like it 2021-07-02 16:05:41 +02:00
ptitSeb 1d92e65fcc Updated docs 2021-07-02 15:47:45 +02:00
ptitSeb a6f132f6da Added 64 0F AF opcode ([DYNAREC] Too) 2021-07-02 15:41:10 +02:00
ptitSeb cb75b670b6 Fixed nextFree memory search function (fixing regression with RaceTheSun and probably a few other) 2021-07-02 15:03:43 +02:00
ptitSeb 7bb9dd18da [DYNAREC] Improved the fast native call path 2021-07-02 14:37:09 +02:00
ptitSeb 140254f311 [DYNAREC] Fixed DIV opcode, and added test17 about div/idiv 2021-07-02 10:17:28 +02:00
ptitSeb 56401f6675 Improved low memory pre-allocation and added 47bits pre-allocation for Wine64 2021-07-01 17:09:03 +02:00
ptitSeb 99ba7707f6 [DYNAREC] Added CF opcode and optimized native call 2021-06-28 13:19:56 +02:00
ptitSeb ea1ef4e602 [DYNAREC] Added 66 98 CBW opcode 2021-06-28 10:53:46 +02:00
ptitSeb 78b6113d8b Start of a new dev. cycle 2021-06-27 12:28:12 +02:00
29 changed files with 901 additions and 264 deletions

No files matched your search

+9
View File
@@ -1,3 +1,12 @@
v0.1.2
======
* OpenSource!
* A few more opcode added to the Interpretor and the Dynarec
* Improved Native Function calling
* Added some function to limit allocated memory to 47bits space (for Wine)
* Improved and Fixed the functions to limit allocated memory to 32bits space
* Wine is starting now, but not everything and every version works
v0.1.0
======
* Improvement to ElfLoader
+8 -2
View File
@@ -7,7 +7,7 @@ option(RK3326 "Set to ON if targeting an Rockchip RK3326 based device" ${RK3326}
option(RK3399 "Set to ON if targeting an Rockchip RK3399 based device" ${RK3399})
option(USE_CCACHE "Set to ON to use ccache if present in the system" ${USE_CCACHE})
option(HAVE_TRACE "Set to ON to have Trace ability (needs ZydisInfo library)" ${HAVE_TRACE})
option(NOLOADADDR "Set to ON to avoid fixing the load address of Box64" ${NO_LOADAADR})
option(NOLOADADDR "Set to ON to avoid fixing the load address of Box64" OFF)
option(NOGIT "Set to ON if not building from a git clone repo (like when building from a zip download from github)" ${NOGIT})
if(RK3399 OR RPI4ARM64 OR RK3326)
set(LD80BITS OFF CACHE BOOL "")
@@ -74,7 +74,8 @@ else()
set(BOX64 box64)
endif()
set(BOX64_ELF_ADDRESS "0x500062800000") #random load address...
#set(BOX64_ELF_ADDRESS "0x500062800000") #random load address...
set(BOX64_ELF_ADDRESS "0x64800000") #low address
if(LD80BITS)
add_definitions(-DHAVE_LD80BITS)
@@ -513,6 +514,11 @@ add_test(test16 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref16.txt
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
add_test(test17 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test17 -D TEST_OUTPUT=tmpfile.txt
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref17.txt
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
file(GLOB extension_tests "${CMAKE_SOURCE_DIR}/tests/extensions/*.c")
foreach(file ${extension_tests})
get_filename_component(testname "${file}" NAME_WE)
+4 -2
View File
@@ -7,9 +7,11 @@ Linux Userspace x86_64 Emulator with a twist
Box64 lets you run x86_64 Linux programs (such as games) on non-x86_64 Linux systems, like ARM (host system needs to be 64bit little-endian).
Because Box64 uses the native versions of some "system" libraries, like libc, libm, SDL, and OpenGL, it's easy to integrate and use with most applications, and performance can be surprisingly high in some cases.
You can find many more Box64 video on Youtube in the [MicroLinux](https://www.youtube.com/channel/UCwFQAEj1lp3out4n7BeBatQ), [Pi Labs](https://www.youtube.com/channel/UCgfQjdc5RceRlTGfuthBs7g) or [The Byteman](https://www.youtube.com/channel/UCEr8lpIJ3B5Ctc5BvcOHSnA) Channels
Box64 integrates a DynaRec (dynamic recompiler) for the ARM64 platform, providing a speed boost between 5 to 10 times faster than only using the interpreter.
Because Box64 uses the native versions of some "system" libraries, like libc, libm, SDL, and OpenGL, it's easy to integrate and use with most applications, and performance can be surprisingly high in many cases. Take a look at thoses bench analysis for an example [here](https://box86.org/index.php/2021/06/game-performances/).
Box64 integrates a DynaRec (dynamic recompiler) for the ARM64 platform, providing a speed boost between 5 to 10 times faster than only using the interpreter. Some high level information on how the Dynarec work can be found [here](https://box86.org/2021/07/inner-workings-a-high%e2%80%91level-view-of-box86-and-a-low%e2%80%91level-view-of-the-dynarec/).
Some x86 internal opcodes use parts of "Realmode X86 Emulator Library", see [x86primop.c](src/emu/x86primop.c) for copyright details
+7 -4
View File
@@ -503,7 +503,7 @@ def main(root: str, files: Sequence[Filename], ver: str):
pass
# Detect simple wrappings
simple_wraps: Dict[ClausesStr, List[FunctionType]] = {}
simple_wraps: Dict[ClausesStr, List[Tuple[FunctionType, int]]] = {}
# H could be allowed maybe?
allowed_simply: str = "v"
@@ -537,9 +537,12 @@ def main(root: str, files: Sequence[Filename], ver: str):
break
else:
# No character in forbidden_simply
if (regs_count <= 6) and (fpr_count <= 4):
if (regs_count <= 6) and (fpr_count <= 8):
# All checks passed!
simple_wraps.setdefault(k, []).append(v)
ret_val = 1 + fpr_count
if v[0] in allowed_fpr:
ret_val = -ret_val
simple_wraps.setdefault(k, []).append((v, ret_val))
simple_idxs = list(simple_wraps.keys())
simple_idxs.sort(key=lambda x: Clauses(x).splitdef())
@@ -911,7 +914,7 @@ int isSimpleWrapper(wrapper_t fun);
if k != "()":
file.write("#if " + k + "\n")
for v in simple_wraps[k]:
file.write("\tif (fun == &" + v + ") return 1;\n")
file.write("\tif (fun == &" + v[0] + ") return " + str(v[1]) + ";\n")
if k != "()":
file.write("#endif\n")
file.write("\treturn 0;\n}\n")
+1 -1
View File
@@ -3,6 +3,6 @@
#define BOX64_MAJOR 0
#define BOX64_MINOR 1
#define BOX64_REVISION 0
#define BOX64_REVISION 2
#endif //__BOX64_VERSION_H_
+138 -33
View File
@@ -826,6 +826,51 @@ void setProtection(uintptr_t addr, size_t size, uint32_t prot)
pthread_mutex_unlock(&mutex_prot);
}
void allocProtection(uintptr_t addr, size_t size, uint32_t prot)
{
dynarec_log(LOG_DEBUG, "allocProtection %p:%p 0x%x\n", (void*)addr, (void*)(addr+size-1), prot);
uintptr_t idx = (addr>>MEMPROT_SHIFT);
uintptr_t end = ((addr+size-1LL)>>MEMPROT_SHIFT);
int ret;
pthread_mutex_lock(&mutex_prot);
for (uintptr_t i=idx; i<=end; ++i) {
const uint32_t key = (i>>MEMPROT_SHIFT2)&0xffffffff;
khint_t k = kh_put(memprot, memprot, key, &ret);
if(ret) {
uint8_t *m = (uint8_t*)calloc(1, MEMPROT_SIZE);
kh_value(memprot, k) = m;
}
const uintptr_t start = i&(MEMPROT_SIZE-1);
const uintptr_t finish = (((i|(MEMPROT_SIZE-1))<end)?(MEMPROT_SIZE-1):end)&(MEMPROT_SIZE-1);
uint8_t* block = kh_value(memprot, k);
for(uintptr_t ii = start; ii<=finish; ++ii) {
if(!block[ii])
block[ii] = prot;
}
i+=finish-start; // +1 from the "for" loop
}
pthread_mutex_unlock(&mutex_prot);
}
void loadProtectionFromMap()
{
char buf[500];
FILE *f = fopen("/proc/self/maps", "r");
if(!f)
return;
while(!feof(f)) {
char* ret = fgets(buf, sizeof(buf), f);
(void)ret;
char r, w, x;
uintptr_t s, e;
if(sscanf(buf, "%lx-%lx %c%c%c", &s, &e, &r, &w, &x)==5) {
int prot = ((r=='r')?PROT_READ:0)|((w=='w')?PROT_WRITE:0)|((x=='x')?PROT_EXEC:0);
allocProtection(s, e-s, prot);
}
}
fclose(f);
}
static int blockempty(uint8_t* mem)
{
for (int i=0; i<(MEMPROT_SIZE); ++i)
@@ -881,52 +926,112 @@ int availableBlock(uint8_t* p, size_t n)
return 0;
return 1;
}
static uintptr_t nextFree(uintptr_t addr)
{
do {
const uint32_t key = (addr>>32)&0xffffffff;
khint_t k = kh_get(memprot, memprot, key);
if(k==kh_end(memprot)) {
return addr;
}
uint8_t *block = kh_value(memprot, k);
for (uintptr_t i=(addr&0xffffffffLL)>>MEMPROT_SHIFT; i<MEMPROT_SIZE; ++i)
if(!block[i]) {
return (addr&~0xffffffffLL)+(i<<MEMPROT_SHIFT);
}
addr += 0x100000000LL;
addr &= ~0xffffffffLL;
} while(1);
}
static uintptr_t maxFree(uintptr_t addr, uintptr_t sz)
{
uintptr_t mfree = 0;
do {
const uint32_t key = (addr>>32)&0xffffffff;
khint_t k = kh_get(memprot, memprot, key);
if(k==kh_end(memprot)) {
mfree+=0x100000000LL;
if(mfree>sz) {
return addr;
}
} else {
uint8_t *block = kh_value(memprot, k);
for (uintptr_t i=(addr&0xffffffffLL)>>MEMPROT_SHIFT; i<MEMPROT_SIZE; ++i)
if(!block[i]) {
mfree+=1<<MEMPROT_SHIFT;
} else
return mfree;
}
addr += 0x100000000LL;
addr &= ~0xffffffffLL;
} while(1);
}
void* find32bitBlock(size_t size)
{
return findBlockNearHint(LOWEST, size);
}
void* find47bitBlock(size_t size)
{
// slow iterative search... Would need something better one day
const uint32_t key = 0; // upper value is 0 by request
uintptr_t addr = 0x100000000LL;
pthread_mutex_lock(&mutex_prot);
khint_t k = kh_get(memprot, memprot, key);
if(k==kh_end(memprot)) {
pthread_mutex_unlock(&mutex_prot);
return LOWEST;
}
uint8_t *prot = kh_val(memprot, k);
pthread_mutex_unlock(&mutex_prot);
void* p = (void*)LOWEST;
int pages = (size+MEMPROT_SIZE-1)>>MEMPROT_SHIFT;
do {
const uintptr_t idx = ((uintptr_t)p)>>MEMPROT_SHIFT;
if(availableBlock(prot+idx, pages))
return p;
p += 0x10000;
} while(p!=(void*)0xffff0000);
addr = nextFree(addr);
uintptr_t sz = maxFree(addr, size);
if(sz>=size) {
pthread_mutex_unlock(&mutex_prot);
return (void*)addr;
}
addr += sz;
} while(addr<0x800000000000LL);
// search in 32bits as a backup
addr = (uintptr_t)LOWEST;
do {
addr = nextFree(addr);
uintptr_t sz = maxFree(addr, size);
if(sz>=size) {
pthread_mutex_unlock(&mutex_prot);
return (void*)addr;
}
addr += sz;
} while(addr<0x100000000LL);
pthread_mutex_unlock(&mutex_prot);
printf_log(LOG_NONE, "Warning: cannot find a 0x%zx block in 47bits address space\n", size);
return NULL;
}
void* find47bitBlockNearHint(void* hint, size_t size)
{
// slow iterative search... Would need something better one day
uintptr_t addr = (uintptr_t)hint;
pthread_mutex_lock(&mutex_prot);
do {
addr = nextFree(addr);
uintptr_t sz = maxFree(addr, size);
if(sz>=size) {
pthread_mutex_unlock(&mutex_prot);
return (void*)addr;
}
addr += sz;
} while(addr<0x800000000000LL);
pthread_mutex_unlock(&mutex_prot);
printf_log(LOG_NONE, "Warning: cannot find a 0x%zx block in 32bits address space\n", size);
return NULL;
}
void* findBlockNearHint(void* hint, size_t size)
{
// slow iterative search... Would need something better one day
if(!hint) hint=LOWEST;
const uint32_t key = (((uintptr_t)hint)>>32)&0xffffffff;
uintptr_t addr = (uintptr_t)hint;
pthread_mutex_lock(&mutex_prot);
khint_t k = kh_get(memprot, memprot, key);
if(k==kh_end(memprot)) {
pthread_mutex_unlock(&mutex_prot);
return hint;
}
uint8_t *prot = kh_val(memprot, k);
pthread_mutex_unlock(&mutex_prot);
void* p = hint;
void* end = (void*)((uintptr_t)hint+0x100000000LL);
uintptr_t step = (size+0xfff)&~0xfff;
int pages = (size+MEMPROT_SIZE-1)>>MEMPROT_SHIFT;
do {
const uintptr_t idx = (((uintptr_t)p)&0xffffffff)>>MEMPROT_SHIFT;
if(availableBlock(prot+idx, pages))
return p;
p += step;
} while(p!=end);
addr = nextFree(addr);
uintptr_t sz = maxFree(addr, size);
if(sz>=size) {
pthread_mutex_unlock(&mutex_prot);
return (void*)addr;
}
addr += sz;
} while(addr<0x100000000LL);
pthread_mutex_unlock(&mutex_prot);
printf_log(LOG_NONE, "Warning: cannot find a 0x%zx block in 32bits address space\n", size);
return NULL;
}
+1
View File
@@ -19,6 +19,7 @@ arm64_next:
stp x14, x15, [sp, (8 * 6)]
stp x16, x17, [sp, (8 * 8)]
str x18, [sp, (8 * 10)]
mov x2, lr // "from" is in lr, so put in x2
// call the function
bl LinkNext
+62 -37
View File
@@ -24,6 +24,8 @@
#include "dynarec_arm64_functions.h"
#include "dynarec_arm64_helper.h"
int isSimpleWrapper(wrapper_t fun);
uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog)
{
uint8_t nextop, opcode;
@@ -1556,19 +1558,26 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MESSAGE(LOG_DUMP, "Native Call to %s\n", GetNativeName(GetNativeFnc(ip)));
x87_forget(dyn, ninst, x3, x4, 0);
sse_purge07cache(dyn, ninst, x3);
GETIP(ip+1); // read the 0xCC
STORE_XEMU_CALL(xRIP);
CALL_S(x64Int3, -1);
LOAD_XEMU_CALL(xRIP);
addr+=8+8;
TABLE64(x3, addr); // expected return address
CMPSx_REG(xRIP, x3);
B_MARK(cNE);
LDRw_U12(w1, xEmu, offsetof(x64emu_t, quit));
CBZw_NEXT(w1);
MARK;
LOAD_XEMU_REM();
jump_to_epilog(dyn, 0, xRIP, ninst);
tmp = isSimpleWrapper(*(wrapper_t*)(addr));
if(box64_log<2 && tmp) {
//GETIP(ip+3+8+8); // read the 0xCC
call_n(dyn, ninst, *(void**)(addr+8), tmp);
addr+=8+8;
} else {
GETIP(ip+1); // read the 0xCC
STORE_XEMU_CALL(xRIP);
CALL_S(x64Int3, -1);
LOAD_XEMU_CALL(xRIP);
addr+=8+8;
TABLE64(x3, addr); // expected return address
CMPSx_REG(xRIP, x3);
B_MARK(cNE);
LDRw_U12(w1, xEmu, offsetof(x64emu_t, quit));
CBZw_NEXT(w1);
MARK;
LOAD_XEMU_REM();
jump_to_epilog(dyn, 0, xRIP, ninst);
}
}
} else {
#if 1
@@ -1587,6 +1596,15 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
#endif
}
break;
case 0xCF:
INST_NAME("IRET");
SETFLAGS(X_ALL, SF_SET); // Not a hack, EFLAGS are restored
BARRIER(2);
iret_to_epilog(dyn, ninst, rex.w);
*need_epilog = 0;
*ok = 0;
break;
case 0xD0:
case 0xD2: // TODO: Jump if CL is 0
nextop = F8;
@@ -1979,26 +1997,32 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MESSAGE(LOG_DUMP, "Native Call to %s (retn=%d)\n", GetNativeName(GetNativeFnc(dyn->insts[ninst].natcall-1)), dyn->insts[ninst].retn);
// calling a native function
sse_purge07cache(dyn, ninst, x3);
GETIP_(dyn->insts[ninst].natcall); // read the 0xCC already
STORE_XEMU_CALL(xRIP);
CALL_S(x64Int3, -1);
LOAD_XEMU_CALL(xRIP);
TABLE64(x3, dyn->insts[ninst].natcall);
ADDx_U12(x3, x3, 2+8+8);
CMPSx_REG(xRIP, x3);
B_MARK(cNE); // Not the expected address, exit dynarec block
POP1(xRIP); // pop the return address
if(dyn->insts[ninst].retn) {
ADDx_U12(xRSP, xRSP, dyn->insts[ninst].retn);
if(box64_log<2 && dyn->insts && (tmp=isSimpleWrapper(*(wrapper_t*)(dyn->insts[ninst].natcall+2)))) {
//GETIP(ip+3+8+8); // read the 0xCC
call_n(dyn, ninst, *(void**)(dyn->insts[ninst].natcall+2+8), tmp);
POP1(xRIP); // pop the return address
} else {
GETIP_(dyn->insts[ninst].natcall); // read the 0xCC already
STORE_XEMU_CALL(xRIP);
CALL_S(x64Int3, -1);
LOAD_XEMU_CALL(xRIP);
TABLE64(x3, dyn->insts[ninst].natcall);
ADDx_U12(x3, x3, 2+8+8);
CMPSx_REG(xRIP, x3);
B_MARK(cNE); // Not the expected address, exit dynarec block
POP1(xRIP); // pop the return address
if(dyn->insts[ninst].retn) {
ADDx_U12(xRSP, xRSP, dyn->insts[ninst].retn);
}
TABLE64(x3, addr);
CMPSx_REG(xRIP, x3);
B_MARK(cNE); // Not the expected address again
LDRw_U12(w1, xEmu, offsetof(x64emu_t, quit));
CBZw_NEXT(w1); // not quitting, so lets continue
MARK;
LOAD_XEMU_REM(); // load remaining register, has they have changed
jump_to_epilog(dyn, 0, xRIP, ninst);
}
TABLE64(x3, addr);
CMPSx_REG(xRIP, x3);
B_MARK(cNE); // Not the expected address again
LDRw_U12(w1, xEmu, offsetof(x64emu_t, quit));
CBZw_NEXT(w1); // not quitting, so lets continue
MARK;
LOAD_XEMU_REM(); // load remaining register, has they have changed
jump_to_epilog(dyn, 0, xRIP, ninst);
break;
default:
if(ninst && dyn->insts && dyn->insts[ninst-1].x64.set_flags) {
@@ -2214,7 +2238,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
GETEDH(x1, 0); // get edd changed addr, so cannot be called 2 times for same op...
CBZxw_MARK(xRDX);
if(ed!=x1) {MOVxw_REG(x1, ed);}
if(ed!=x1) {MOVx_REG(x1, ed);}
CALL(div64, -1);
B_NEXT_nocond;
MARK;
@@ -2240,24 +2264,25 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
if(ninst && dyn->insts
&& dyn->insts[ninst-1].x64.addr
&& *(uint8_t*)(dyn->insts[ninst-1].x64.addr)==0x99) {
&& *(uint8_t*)(dyn->insts[ninst-1].x64.addr)==0x48
&& *(uint8_t*)(dyn->insts[ninst-1].x64.addr+1)==0x99) {
SET_DFNONE(x2)
GETED(0);
SDIVx(x2, xRAX, ed);
MSUBx(xRDX, x2, ed, xRAX);
MOVw_REG(xRAX, x2);
MOVx_REG(xRAX, x2);
} else {
GETEDH(x1, 0); // get edd changed addr, so cannot be called 2 times for same op...
CBZxw_MARK(xRDX);
MVNx_REG(x2, xRDX);
CBZxw_MARK(x2);
if(ed!=x1) {MOVxw_REG(x1, ed);}
if(ed!=x1) {MOVx_REG(x1, ed);}
CALL((void*)idiv64, -1);
B_NEXT_nocond;
MARK;
SDIVx(x2, xRAX, ed);
MSUBx(xRDX, x2, ed, xRAX);
MOVw_REG(xRAX, x2);
MOVx_REG(xRAX, x2);
SET_DFNONE(x2)
}
}
+237
View File
@@ -151,6 +151,39 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
break;
case 0xAF:
INST_NAME("IMUL Gd, Ed");
SETFLAGS(X_ALL, SF_PENDING);
nextop = F8;
grab_segdata(dyn, addr, ninst, x4, seg);
GETGD;
GETEDO(x4, 0);
if(rex.w) {
// 64bits imul
UFLAG_IF {
SMULH(x3, gd, ed);
MULx(gd, gd, ed);
UFLAG_OP1(x3);
UFLAG_RES(gd);
UFLAG_DF(x3, d_imul64);
} else {
MULxw(gd, gd, ed);
}
} else {
// 32bits imul
UFLAG_IF {
SMULL(gd, gd, ed);
UFLAG_RES(gd);
LSRx(x3, gd, 32);
UFLAG_OP1(x3);
UFLAG_DF(x3, d_imul32);
MOVw_REG(gd, gd);
} else {
MULxw(gd, gd, ed);
}
}
break;
default:
DEFAULT;
}
@@ -388,6 +421,210 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
break;
case 0xD1:
nextop = F8;
grab_segdata(dyn, addr, ninst, x6, seg);
switch((nextop>>3)&7) {
case 0:
INST_NAME("ROL Ed, 1");
SETFLAGS(X_OF|X_CF, SF_SUBSET);
GETEDO(x6, 0);
emit_rol32c(dyn, ninst, rex, ed, 1, x3, x4);
WBACKO(x6);
break;
case 1:
INST_NAME("ROR Ed, 1");
SETFLAGS(X_OF|X_CF, SF_SUBSET);
GETEDO(x6, 0);
emit_ror32c(dyn, ninst, rex, ed, 1, x3, x4);
WBACKO(x6);
break;
case 2:
INST_NAME("RCL Ed, 1");
MESSAGE(LOG_DUMP, "Need Optimization\n");
READFLAGS(X_CF);
SETFLAGS(X_OF|X_CF, SF_SET);
MOV32w(x2, 1);
GETEDO(x6, 0);
if(wback) {ADDx_REG(x6, x6, wback); wback=x6;}
if(ed!=x1) {MOVxw_REG(x1, ed);}
CALL_(rcl32, ed, x6);
WBACK;
break;
case 3:
INST_NAME("RCR Ed, 1");
MESSAGE(LOG_DUMP, "Need Optimization\n");
READFLAGS(X_CF);
SETFLAGS(X_OF|X_CF, SF_SET);
MOV32w(x2, 1);
GETEDO(x6, 0);
if(wback) {ADDx_REG(x6, x6, wback); wback=x6;}
if(ed!=x1) {MOVxw_REG(x1, ed);}
CALL_(rcr32, ed, x6);
WBACK;
break;
case 4:
case 6:
INST_NAME("SHL Ed, 1");
SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
GETEDO(x6, 0);
emit_shl32c(dyn, ninst, rex, ed, 1, x3, x4);
WBACKO(x6);
break;
case 5:
INST_NAME("SHR Ed, 1");
SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
GETEDO(x6, 0);
emit_shr32c(dyn, ninst, rex, ed, 1, x3, x4);
WBACKO(x6);
break;
case 7:
INST_NAME("SAR Ed, 1");
SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
GETEDO(x6, 0);
emit_sar32c(dyn, ninst, rex, ed, 1, x3, x4);
WBACKO(x6);
break;
}
break;
case 0xD3:
nextop = F8;
grab_segdata(dyn, addr, ninst, x6, seg);
switch((nextop>>3)&7) {
case 0:
INST_NAME("ROL Ed, CL");
SETFLAGS(X_OF|X_CF, SF_SUBSET);
if(rex.w) {
ANDSx_mask(x3, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f
} else {
ANDSw_mask(x3, xRCX, 0, 0b00100); //mask=0x00000001f
}
MOV64xw(x4, (rex.w?64:32));
SUBx_REG(x3, x4, x3);
GETEDO(x6, 0);
if(!rex.w && MODREG) {MOVw_REG(ed, ed);}
B_NEXT(cEQ);
RORxw_REG(ed, ed, x3);
WBACKO(x6);
UFLAG_IF { // calculate flags directly
CMPSw_U12(x3, rex.w?63:31);
B_MARK(cNE);
LSRxw(x4, ed, rex.w?63:31);
ADDxw_REG(x4, x4, ed);
BFIw(xFlags, x4, F_OF, 1);
MARK;
BFIw(xFlags, ed, F_CF, 1);
UFLAG_DF(x2, d_none);
}
break;
case 1:
INST_NAME("ROR Ed, CL");
SETFLAGS(X_OF|X_CF, SF_SUBSET);
if(rex.w) {
ANDSx_mask(x3, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f
} else {
ANDSw_mask(x3, xRCX, 0, 0b00100); //mask=0x00000001f
}
GETEDO(x6, 0);
if(!rex.w && MODREG) {MOVw_REG(ed, ed);}
B_NEXT(cEQ);
RORxw_REG(ed, ed, x3);
WBACKO(x6);
UFLAG_IF { // calculate flags directly
CMPSw_U12(x3, 1);
B_MARK(cNE);
LSRxw(x2, ed, rex.w?62:30); // x2 = d>>30
EORw_REG_LSR(x2, x2, x2, 1); // x2 = ((d>>30) ^ ((d>>30)>>1))
BFIw(xFlags, x2, F_OF, 1);
MARK;
LSRxw(x2, ed, rex.w?63:31);
BFIw(xFlags, x2, F_CF, 1);
UFLAG_DF(x2, d_none);
}
break;
case 2:
INST_NAME("RCL Ed, CL");
MESSAGE(LOG_DUMP, "Need Optimization\n");
READFLAGS(X_CF);
SETFLAGS(X_OF|X_CF, SF_SET);
if(rex.w) {
ANDSx_mask(x2, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f
} else {
ANDSw_mask(x2, xRCX, 0, 0b00100); //mask=0x00000001f
}
GETEDO(x6, 0);
if(wback) {ADDx_REG(x6, x6, wback); wback=x6;}
if(!rex.w && MODREG) {MOVw_REG(ed, ed);}
B_NEXT(cEQ);
CALL_(rex.w?((void*)rcl64):((void*)rcl32), ed, x6);
WBACK;
break;
case 3:
INST_NAME("RCR Ed, CL");
MESSAGE(LOG_DUMP, "Need Optimization\n");
READFLAGS(X_CF);
SETFLAGS(X_OF|X_CF, SF_SET);
if(rex.w) {
ANDSx_mask(x2, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f
} else {
ANDSw_mask(x2, xRCX, 0, 0b00100); //mask=0x00000001f
}
GETEDO(x6, 0);
if(wback) {ADDx_REG(x6, x6, wback); wback=x6;}
if(!rex.w && MODREG) {MOVw_REG(ed, ed);}
B_NEXT(cEQ);
CALL_(rex.w?((void*)rcr64):((void*)rcr32), ed, x6);
WBACK;
break;
case 4:
case 6:
INST_NAME("SHL Ed, CL");
SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
if(rex.w) {
ANDSx_mask(x3, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f
} else {
ANDSw_mask(x3, xRCX, 0, 0b00100); //mask=0x00000001f
}
GETEDO(x6, 0);
if(!rex.w && MODREG) {MOVw_REG(ed, ed);}
B_NEXT(cEQ);
emit_shl32(dyn, ninst, rex, ed, x3, x5, x4);
WBACKO(x6);
break;
case 5:
INST_NAME("SHR Ed, CL");
SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
if(rex.w) {
ANDSx_mask(x3, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f
} else {
ANDSw_mask(x3, xRCX, 0, 0b00100); //mask=0x00000001f
}
GETEDO(x6, 0);
if(!rex.w && MODREG) {MOVw_REG(ed, ed);}
B_NEXT(cEQ);
emit_shr32(dyn, ninst, rex, ed, x3, x5, x4);
WBACKO(x6);
break;
case 7:
INST_NAME("SAR Ed, CL");
SETFLAGS(X_ALL, SF_PENDING);
if(rex.w) {
ANDSx_mask(x3, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f
} else {
ANDSw_mask(x3, xRCX, 0, 0b00100); //mask=0x00000001f
}
GETEDO(x6, 0);
if(!rex.w && MODREG) {MOVw_REG(ed, ed);}
B_NEXT(cEQ);
UFLAG_OP12(ed, x3);
ASRxw_REG(ed, ed, x3);
WBACKO(x6);
UFLAG_RES(ed);
UFLAG_DF(x3, rex.w?d_sar64:d_sar32);
break;
}
break;
default:
DEFAULT;
}
+6
View File
@@ -458,6 +458,12 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("NOP");
break;
case 0x98:
INST_NAME("CBW");
SXTBw(x1, xRAX);
BFIw(xRAX, x1, 0, 16);
break;
case 0xA1:
INST_NAME("MOV EAX,Od");
u64 = F64;
+58 -9
View File
@@ -450,8 +450,9 @@ void retn_to_epilog(dynarec_arm_t* dyn, int ninst, int n)
BLR(x2); // save LR
}
void iret_to_epilog(dynarec_arm_t* dyn, int ninst)
void iret_to_epilog(dynarec_arm_t* dyn, int ninst, int is64bits)
{
#warning TODO: is64bits
MAYUSE(ninst);
MESSAGE(LOG_DUMP, "IRet to epilog\n");
// POP IP
@@ -480,7 +481,7 @@ void call_c(dynarec_arm_t* dyn, int ninst, void* fnc, int reg, int ret, int save
if(saveflags) {
STRx_U12(xFlags, xEmu, offsetof(x64emu_t, eflags));
}
fpu_pushcache(dyn, ninst, reg);
fpu_pushcache(dyn, ninst, reg, 0);
if(ret!=-2) {
STPx_S7_preindex(xEmu, savereg, xSP, -16); // ARM64 stack needs to be 16byte aligned
STPx_S7_offset(xRAX, xRCX, xEmu, offsetof(x64emu_t, regs[_AX])); // x9..x15, x16,x17,x18 those needs to be saved by caller
@@ -510,13 +511,59 @@ void call_c(dynarec_arm_t* dyn, int ninst, void* fnc, int reg, int ret, int save
GO(R8, R9);
#undef GO
}
fpu_popcache(dyn, ninst, reg);
fpu_popcache(dyn, ninst, reg, 0);
if(saveflags) {
LDRx_U12(xFlags, xEmu, offsetof(x64emu_t, eflags));
}
SET_NODF();
}
void call_n(dynarec_arm_t* dyn, int ninst, void* fnc, int w)
{
MAYUSE(fnc);
STRx_U12(xFlags, xEmu, offsetof(x64emu_t, eflags));
fpu_pushcache(dyn, ninst, x3, 1);
// x9..x15, x16,x17,x18 those needs to be saved by caller
// RDI, RSI, RDX, RCX, R8, R9 are used for function call
STPx_S7_preindex(xEmu, xRBX, xSP, -16); // ARM64 stack needs to be 16byte aligned
STPx_S7_offset(xRSP, xRBP, xEmu, offsetof(x64emu_t, regs[_SP]));
// float and double args
if(abs(w)>1) {
MESSAGE(LOG_DUMP, "Getting %d XMM args\n", abs(w)-1);
for(int i=0; i<abs(w)-1; ++i) {
sse_get_reg(dyn, ninst, x7, i);
}
}
if(w<0) {
MESSAGE(LOG_DUMP, "Return in XMM0\n");
sse_get_reg_empty(dyn, ninst, x7, 0);
}
// prepare regs for native call
MOVx_REG(0, xRDI);
MOVx_REG(x1, xRSI);
MOVx_REG(x2, xRDX);
MOVx_REG(x3, xRCX);
MOVx_REG(x4, xR8);
MOVx_REG(x5, xR9);
// native call
TABLE64(16, (uintptr_t)fnc); // using x16 as scratch regs for call address
BLR(16);
// put return value in x86 regs
if(w>0) {
MOVx_REG(xRAX, 0);
MOVx_REG(xRDX, x1);
}
// all done, restore all regs
LDPx_S7_postindex(xEmu, xRBX, xSP, 16);
#define GO(A, B) LDPx_S7_offset(x##A, x##B, xEmu, offsetof(x64emu_t, regs[_##A]))
GO(RSP, RBP);
#undef GO
fpu_popcache(dyn, ninst, x3, 1);
LDRx_U12(xFlags, xEmu, offsetof(x64emu_t, eflags));
SET_NODF();
}
void grab_segdata(dynarec_arm_t* dyn, uintptr_t addr, int ninst, int reg, int segment)
{
(void)addr;
@@ -1121,19 +1168,20 @@ static void sse_reflectcache(dynarec_arm_t* dyn, int ninst, int s1)
}
#endif
void fpu_pushcache(dynarec_arm_t* dyn, int ninst, int s1)
void fpu_pushcache(dynarec_arm_t* dyn, int ninst, int s1, int not07)
{
(void) ninst; (void)s1;
#if STEP > 1
int start = not07?8:0;
// only SSE regs needs to be push back to xEmu
int n=0;
for (int i=0; i<16; i++)
for (int i=start; i<16; i++)
if(dyn->ssecache[i]!=-1)
++n;
if(!n)
return;
MESSAGE(LOG_DUMP, "\tPush XMM Cache (%d)------\n", n);
for (int i=0; i<16; ++i)
for (int i=start; i<16; ++i)
if(dyn->ssecache[i]!=-1) {
VSTR128_U12(dyn->ssecache[i], xEmu, offsetof(x64emu_t, xmm[i]));
}
@@ -1143,19 +1191,20 @@ void fpu_pushcache(dynarec_arm_t* dyn, int ninst, int s1)
#endif
}
void fpu_popcache(dynarec_arm_t* dyn, int ninst, int s1)
void fpu_popcache(dynarec_arm_t* dyn, int ninst, int s1, int not07)
{
(void) ninst; (void)s1;
#if STEP > 1
int start = not07?8:0;
// only SSE regs needs to be pop back from xEmu
int n=0;
for (int i=0; i<16; i++)
for (int i=start; i<16; i++)
if(dyn->ssecache[i]!=-1)
++n;
if(!n)
return;
MESSAGE(LOG_DUMP, "\tPop XMM Cache (%d)------\n", n);
for (int i=0; i<16; ++i)
for (int i=start; i<16; ++i)
if(dyn->ssecache[i]!=-1) {
VLDR128_U12(dyn->ssecache[i], xEmu, offsetof(x64emu_t, xmm[i]));
}
+5 -3
View File
@@ -635,6 +635,7 @@ void* arm64_next(x64emu_t* emu, uintptr_t addr);
#define retn_to_epilog STEPNAME(retn_to_epilog)
#define iret_to_epilog STEPNAME(iret_to_epilog)
#define call_c STEPNAME(call_c)
#define call_n STEPNAME(call_n)
#define grab_segdata STEPNAME(grab_segdata)
#define emit_cmp8 STEPNAME(emit_cmp8)
#define emit_cmp16 STEPNAME(emit_cmp16)
@@ -751,8 +752,9 @@ void jump_to_epilog(dynarec_arm_t* dyn, uintptr_t ip, int reg, int ninst);
void jump_to_next(dynarec_arm_t* dyn, uintptr_t ip, int reg, int ninst);
void ret_to_epilog(dynarec_arm_t* dyn, int ninst);
void retn_to_epilog(dynarec_arm_t* dyn, int ninst, int n);
void iret_to_epilog(dynarec_arm_t* dyn, int ninst);
void iret_to_epilog(dynarec_arm_t* dyn, int ninst, int is64bits);
void call_c(dynarec_arm_t* dyn, int ninst, void* fnc, int reg, int ret, int saveflags, int save_reg);
void call_n(dynarec_arm_t* dyn, int ninst, void* fnc, int w);
void grab_segdata(dynarec_arm_t* dyn, uintptr_t addr, int ninst, int reg, int segment);
void emit_cmp8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5);
void emit_cmp16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5);
@@ -878,8 +880,8 @@ void x87_purgecache(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3);
#ifdef HAVE_TRACE
void fpu_reflectcache(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3);
#endif
void fpu_pushcache(dynarec_arm_t* dyn, int ninst, int s1);
void fpu_popcache(dynarec_arm_t* dyn, int ninst, int s1);
void fpu_pushcache(dynarec_arm_t* dyn, int ninst, int s1, int not07);
void fpu_popcache(dynarec_arm_t* dyn, int ninst, int s1, int not07);
uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
+4 -2
View File
@@ -235,6 +235,8 @@ int AllocElfMemory(box64context_t* context, elfheader_t* head, int mainbin)
}
} else {
// vaddr is 0, load everything has a One block
if(!offs && box64_wine)
offs = (uintptr_t)find47bitBlock(head->memsz); // limit to 47bits...
printf_log(LOG_DEBUG, "Allocating 0x%lx memory @%p for Elf \"%s\"\n", head->memsz, (void*)offs, head->name);
void* p = mmap((void*)offs, head->memsz
, PROT_READ | PROT_WRITE | PROT_EXEC
@@ -1532,7 +1534,7 @@ EXPORT void PltResolver(x64emu_t* emu)
GetGlobalSymbolStartEnd(my_context->maplib, symname, &offs, &end, h, -1, NULL);
if (!offs) {
printf_log(LOG_NONE, "Error: PltReolver: Symbol %s(ver %d: %s%s%s) not found, cannot apply R_X86_64_JUMP_SLOT %p (%p) in %s\n", symname, version, symname, vername?"@":"", vername?vername:"", p, *(void**)p, h->name);
printf_log(LOG_NONE, "Error: PltResolver: Symbol %s(ver %d: %s%s%s) not found, cannot apply R_X86_64_JUMP_SLOT %p (%p) in %s\n", symname, version, symname, vername?"@":"", vername?vername:"", p, *(void**)p, h->name);
emu->quit = 1;
return;
} else {
@@ -1540,7 +1542,7 @@ EXPORT void PltResolver(x64emu_t* emu)
printf_dump(LOG_DEBUG, " Apply %s R_X86_64_JUMP_SLOT %p with sym=%s(ver %d: %s%s%s) (%p -> %p / %s)\n", (bind==STB_LOCAL)?"Local":"Global", p, symname, version, symname, vername?"@":"", vername?vername:"",*(void**)p, (void*)offs, ElfName(FindElfAddress(my_context, offs)));
*p = offs;
} else {
printf_log(LOG_NONE, "PltReolver: Warning, Symbol %s(ver %d: %s%s%s) found, but Jump Slot Offset is NULL \n", symname, version, symname, vername?"@":"", vername?vername:"");
printf_log(LOG_NONE, "PltResolver: Warning, Symbol %s(ver %d: %s%s%s) found, but Jump Slot Offset is NULL \n", symname, version, symname, vername?"@":"", vername?vername:"");
}
}
+4 -3
View File
@@ -30,7 +30,8 @@ typedef struct x64emu_s {
reg64_t regs[16];
x64flags_t eflags;
reg64_t ip;
uintptr_t old_ip;
// sse
sse_regs_t xmm[16];
// fpu / mmx
mmx87_regs_t mmx87[8];
uint16_t cw,cw_mask_all;
@@ -42,8 +43,8 @@ typedef struct x64emu_s {
fpu_ld_t fpu_ld[8]; // for long double emulation / 80bits fld fst
fpu_ll_t fpu_ll[8]; // for 64bits fild / fist sequence
fpu_p_reg_t p_regs[8];
// sse
sse_regs_t xmm[16];
// old ip
uintptr_t old_ip;
// defered flags
int dummy1; // to align on 64bits with df
defered_flags_t df;
+8
View File
@@ -1051,6 +1051,14 @@ x64emurun:
if(emu->quit) goto fini;
break;
case 0xCF: /* IRET */
R_RIP = Pop(emu);
emu->segs[_CS] = Pop(emu);
emu->segs_serial[_CS] = 0;
emu->eflags.x64 = ((Pop(emu) & 0x3F7FD7)/* & (0xffff-40)*/ ) | 0x2; // mask off res2 and res3 and on res1
RESET_FLAGS(emu);
goto fini; // exit, to recompute CS if needed
break;
case 0xD0: /* GRP2 Eb,1 */
case 0xD2: /* GRP2 Eb,CL */
nextop = F8;
+52
View File
@@ -181,6 +181,16 @@ int Run64(x64emu_t *emu, rex_t rex, int seg)
}
break;
case 0xAF: /* IMUL Gd,Ed */
nextop = F8;
GETED_OFFS(0, tlsdata);
GETGD;
if(rex.w)
GD->q[0] = imul64(emu, GD->q[0], ED->q[0]);
else
GD->q[0] = imul32(emu, GD->dword[0], ED->dword[0]);
break;
default:
return 1;
}
@@ -354,6 +364,48 @@ int Run64(x64emu_t *emu, rex_t rex, int seg)
ED->dword[0] = F32;
break;
case 0xD1: /* GRP2 Ed,1 */
case 0xD3: /* GRP2 Ed,CL */
nextop = F8;
GETED_OFFS(0, tlsdata);
tmp8u = (opcode==0xD1)?1:R_CL;
if(rex.w) {
switch((nextop>>3)&7) {
case 0: ED->q[0] = rol64(emu, ED->q[0], tmp8u); break;
case 1: ED->q[0] = ror64(emu, ED->q[0], tmp8u); break;
case 2: ED->q[0] = rcl64(emu, ED->q[0], tmp8u); break;
case 3: ED->q[0] = rcr64(emu, ED->q[0], tmp8u); break;
case 4:
case 6: ED->q[0] = shl64(emu, ED->q[0], tmp8u); break;
case 5: ED->q[0] = shr64(emu, ED->q[0], tmp8u); break;
case 7: ED->q[0] = sar64(emu, ED->q[0], tmp8u); break;
}
} else {
if(MODREG)
switch((nextop>>3)&7) {
case 0: ED->q[0] = rol32(emu, ED->dword[0], tmp8u); break;
case 1: ED->q[0] = ror32(emu, ED->dword[0], tmp8u); break;
case 2: ED->q[0] = rcl32(emu, ED->dword[0], tmp8u); break;
case 3: ED->q[0] = rcr32(emu, ED->dword[0], tmp8u); break;
case 4:
case 6: ED->q[0] = shl32(emu, ED->dword[0], tmp8u); break;
case 5: ED->q[0] = shr32(emu, ED->dword[0], tmp8u); break;
case 7: ED->q[0] = sar32(emu, ED->dword[0], tmp8u); break;
}
else
switch((nextop>>3)&7) {
case 0: ED->dword[0] = rol32(emu, ED->dword[0], tmp8u); break;
case 1: ED->dword[0] = ror32(emu, ED->dword[0], tmp8u); break;
case 2: ED->dword[0] = rcl32(emu, ED->dword[0], tmp8u); break;
case 3: ED->dword[0] = rcr32(emu, ED->dword[0], tmp8u); break;
case 4:
case 6: ED->dword[0] = shl32(emu, ED->dword[0], tmp8u); break;
case 5: ED->dword[0] = shr32(emu, ED->dword[0], tmp8u); break;
case 7: ED->dword[0] = sar32(emu, ED->dword[0], tmp8u); break;
}
}
break;
default:
return 1;
}
+3
View File
@@ -42,6 +42,7 @@ void updateProtection(uintptr_t addr, size_t size, uint32_t prot);
void setProtection(uintptr_t addr, size_t size, uint32_t prot);
void freeProtection(uintptr_t addr, size_t size);
uint32_t getProtection(uintptr_t addr);
void loadProtectionFromMap();
#ifdef DYNAREC
void protectDB(uintptr_t addr, size_t size);
void protectDBnolock(uintptr_t addr, size_t size);
@@ -51,6 +52,8 @@ void unlockDB();
#endif
void* find32bitBlock(size_t size);
void* findBlockNearHint(void* hint, size_t size);
void* find47bitBlock(size_t size);
void* find47bitBlockNearHint(void* hint, size_t size);
// unlock mutex that are locked by current thread (for signal handling). Return a mask of unlock mutex
int unlockCustommemMutex();
+1
View File
@@ -24,6 +24,7 @@ extern char* trace_func;
#endif
extern int allow_missing_libs;
extern int box64_steam;
extern int box64_wine;
extern int box64_nopulse; // disabling the use of wrapped pulseaudio
extern int box64_nogtk; // disabling the use of wrapped gtk
extern int box64_novulkan; // disabling the use of wrapped vulkan
+1
View File
@@ -247,6 +247,7 @@ typedef union {
} mmx87_regs_t;
typedef union {
__uint128_t u128;
uint64_t q[2];
int64_t sq[2];
double d[2];
+17
View File
@@ -707,6 +707,17 @@ void my_box64signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
void* rsp = NULL;
#ifdef __aarch64__
void * pc = (void*)p->uc_mcontext.pc;
struct fpsimd_context *fpsimd = NULL;
// find fpsimd struct
{
struct _aarch64_ctx * ff = (struct _aarch64_ctx*)p->uc_mcontext.__reserved;
while (ff->magic && !fpsimd) {
if(ff->magic==FPSIMD_MAGIC)
fpsimd = (struct fpsimd_context*)ff;
else
ff = (struct _aarch64_ctx*)((uintptr_t)ff + ff->size);
}
}
#elif defined __x86_64__
void * pc = (void*)p->uc_mcontext.gregs[X64_RIP];
#elif defined __powerpc64__
@@ -747,6 +758,12 @@ void my_box64signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
ejb->emu->regs[_R13].q[0] = p->uc_mcontext.regs[23];
ejb->emu->regs[_R14].q[0] = p->uc_mcontext.regs[24];
ejb->emu->regs[_R15].q[0] = p->uc_mcontext.regs[25];
if(fpsimd) {
ejb->emu->xmm[0].u128 = fpsimd->vregs[0];
ejb->emu->xmm[1].u128 = fpsimd->vregs[1];
ejb->emu->xmm[2].u128 = fpsimd->vregs[2];
ejb->emu->xmm[3].u128 = fpsimd->vregs[3];
}
ejb->emu->ip.q[0] = getX64Address(db, (uintptr_t)pc);
ejb->emu->eflags.x64 = p->uc_mcontext.regs[26];
if(addr>=db->x64_addr && addr<(db->x64_addr+db->x64_size)) {
+15 -4
View File
@@ -8,6 +8,7 @@
#include <dirent.h>
#include <signal.h>
#include <sys/syscall.h>
#include <sys/mman.h>
#include "build_info.h"
#include "debug.h"
@@ -52,12 +53,13 @@ char* trace_func = NULL;
int box64_dynarec_trace = 0;
#endif
#endif
int box64_zoom = 0;
int x11threads = 0;
int x11glx = 1;
int allow_missing_libs = 0;
int fix_64bit_inodes = 0;
int box64_zoom = 0;
int box64_steam = 0;
int box64_wine = 0;
int box64_nopulse = 0;
int box64_nogtk = 0;
int box64_novulkan = 0;
@@ -731,7 +733,8 @@ int main(int argc, const char **argv, const char **env) {
if(!box64_nobanner)
PrintBox64Version();
// precheck, for win-preload
if(strstr(prog, "wine-preloader")==(prog+strlen(prog)-strlen("wine-preloader"))) {
if(strstr(prog, "wine-preloader")==(prog+strlen(prog)-strlen("wine-preloader"))
|| strstr(prog, "wine64-preloader")==(prog+strlen(prog)-strlen("wine64-preloader"))) {
// wine-preloader detecter, skipping it if next arg exist and is an x86 binary
int x64 = (nextarg<argc)?FileIsX64ELF(argv[nextarg]):0;
if(x64) {
@@ -741,9 +744,11 @@ int main(int argc, const char **argv, const char **env) {
}
}
// check if this is wine
if(!strcmp(prog, "wine") || (strlen(prog)>5 && !strcmp(prog+strlen(prog)-strlen("/wine"), "/wine"))) {
if(!strcmp(prog, "wine64")
|| !strcmp(prog, "wine64-development")
|| (strlen(prog)>5 && !strcmp(prog+strlen(prog)-strlen("/wine64"), "/wine64"))) {
const char* prereserve = getenv("WINEPRELOADRESERVE");
printf_log(LOG_INFO, "BOX64: Wine detected, WINEPRELOADRESERVE=\"%s\"\n", prereserve?prereserve:"");
printf_log(LOG_INFO, "BOX64: Wine64 detected, WINEPRELOADRESERVE=\"%s\"\n", prereserve?prereserve:"");
if(wine_preloaded)
wine_prereserve(prereserve);
// special case for winedbg, doesn't work anyway
@@ -751,6 +756,11 @@ int main(int argc, const char **argv, const char **env) {
printf_log(LOG_NONE, "winedbg detected, not launching it!\n");
exit(0); // exiting, it doesn't work anyway
}
box64_wine = 1;
}
// check if this is wineserver
if(!strcmp(prog, "wineserver") || !strcmp(prog, "wineserver64") || (strlen(prog)>9 && !strcmp(prog+strlen(prog)-strlen("/wineserver"), "/wineserver"))) {
box64_wine = 1;
}
// Create a new context
my_context = NewBox64Context(argc - nextarg);
@@ -1045,6 +1055,7 @@ int main(int argc, const char **argv, const char **env) {
#endif
atexit(endBox64);
loadProtectionFromMap();
// emulate!
printf_log(LOG_DEBUG, "Start x64emu on Main\n");
+4
View File
@@ -34,6 +34,7 @@
#() uFv
#() uFi
#() uFu
#() uFU
#() uFd
#() uFp
#() UFv
@@ -946,6 +947,7 @@
#() iFpppipp
#() iFpppuii
#() iFpppupu
#() iFpppLpp
#() iFppppii
#() iFppppip
#() iFppppup
@@ -1048,6 +1050,7 @@
#() iFpiiuuiu
#() iFpiuiipp
#() iFpiupiii
#() iFpippLpp
#() iFpippppp
#() iFpuuiuui
#() iFpuupppp
@@ -1130,6 +1133,7 @@
#() iFLLLLLLLL
#() iFpiiiiipi
#() iFpWCuWCuu
#() iFpuippLpp
#() iFpuuiiiii
#() iFpupppppp
#() iFppIIIppp
+157 -134
View File
@@ -68,6 +68,7 @@ typedef uint16_t (*WFp_t)(void*);
typedef uint64_t (*uFv_t)(void);
typedef uint64_t (*uFi_t)(int64_t);
typedef uint64_t (*uFu_t)(uint64_t);
typedef uint64_t (*uFU_t)(uint64_t);
typedef uint64_t (*uFd_t)(double);
typedef uint64_t (*uFp_t)(void*);
typedef uint64_t (*UFv_t)(void);
@@ -980,6 +981,7 @@ typedef int64_t (*iFpppipi_t)(void*, void*, void*, int64_t, void*, int64_t);
typedef int64_t (*iFpppipp_t)(void*, void*, void*, int64_t, void*, void*);
typedef int64_t (*iFpppuii_t)(void*, void*, void*, uint64_t, int64_t, int64_t);
typedef int64_t (*iFpppupu_t)(void*, void*, void*, uint64_t, void*, uint64_t);
typedef int64_t (*iFpppLpp_t)(void*, void*, void*, uintptr_t, void*, void*);
typedef int64_t (*iFppppii_t)(void*, void*, void*, void*, int64_t, int64_t);
typedef int64_t (*iFppppip_t)(void*, void*, void*, void*, int64_t, void*);
typedef int64_t (*iFppppup_t)(void*, void*, void*, void*, uint64_t, void*);
@@ -1082,6 +1084,7 @@ typedef int64_t (*iFpiiiLwp_t)(void*, int64_t, int64_t, int64_t, uintptr_t, int1
typedef int64_t (*iFpiiuuiu_t)(void*, int64_t, int64_t, uint64_t, uint64_t, int64_t, uint64_t);
typedef int64_t (*iFpiuiipp_t)(void*, int64_t, uint64_t, int64_t, int64_t, void*, void*);
typedef int64_t (*iFpiupiii_t)(void*, int64_t, uint64_t, void*, int64_t, int64_t, int64_t);
typedef int64_t (*iFpippLpp_t)(void*, int64_t, void*, void*, uintptr_t, void*, void*);
typedef int64_t (*iFpippppp_t)(void*, int64_t, void*, void*, void*, void*, void*);
typedef int64_t (*iFpuuiuui_t)(void*, uint64_t, uint64_t, int64_t, uint64_t, uint64_t, int64_t);
typedef int64_t (*iFpuupppp_t)(void*, uint64_t, uint64_t, void*, void*, void*, void*);
@@ -1164,6 +1167,7 @@ typedef int64_t (*iFuiifpppp_t)(uint64_t, int64_t, int64_t, float, void*, void*,
typedef int64_t (*iFLLLLLLLL_t)(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
typedef int64_t (*iFpiiiiipi_t)(void*, int64_t, int64_t, int64_t, int64_t, int64_t, void*, int64_t);
typedef int64_t (*iFpWCuWCuu_t)(void*, uint16_t, uint8_t, uint64_t, uint16_t, uint8_t, uint64_t, uint64_t);
typedef int64_t (*iFpuippLpp_t)(void*, uint64_t, int64_t, void*, void*, uintptr_t, void*, void*);
typedef int64_t (*iFpuuiiiii_t)(void*, uint64_t, uint64_t, int64_t, int64_t, int64_t, int64_t, int64_t);
typedef int64_t (*iFpupppppp_t)(void*, uint64_t, void*, void*, void*, void*, void*, void*);
typedef int64_t (*iFppIIIppp_t)(void*, void*, int64_t, int64_t, int64_t, void*, void*, void*);
@@ -1366,6 +1370,7 @@ void WFp(x64emu_t *emu, uintptr_t fcn) { WFp_t fn = (WFp_t)fcn; R_RAX=(unsigned
void uFv(x64emu_t *emu, uintptr_t fcn) { uFv_t fn = (uFv_t)fcn; R_RAX=(uint64_t)fn(); }
void uFi(x64emu_t *emu, uintptr_t fcn) { uFi_t fn = (uFi_t)fcn; R_RAX=(uint64_t)fn((int64_t)R_RDI); }
void uFu(x64emu_t *emu, uintptr_t fcn) { uFu_t fn = (uFu_t)fcn; R_RAX=(uint64_t)fn((uint64_t)R_RDI); }
void uFU(x64emu_t *emu, uintptr_t fcn) { uFU_t fn = (uFU_t)fcn; R_RAX=(uint64_t)fn((uint64_t)R_RDI); }
void uFd(x64emu_t *emu, uintptr_t fcn) { uFd_t fn = (uFd_t)fcn; R_RAX=(uint64_t)fn(emu->xmm[0].d[0]); }
void uFp(x64emu_t *emu, uintptr_t fcn) { uFp_t fn = (uFp_t)fcn; R_RAX=(uint64_t)fn((void*)R_RDI); }
void UFv(x64emu_t *emu, uintptr_t fcn) { UFv_t fn = (UFv_t)fcn; R_RAX=fn(); }
@@ -2278,6 +2283,7 @@ void iFpppipi(x64emu_t *emu, uintptr_t fcn) { iFpppipi_t fn = (iFpppipi_t)fcn; R
void iFpppipp(x64emu_t *emu, uintptr_t fcn) { iFpppipp_t fn = (iFpppipp_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (int64_t)R_RCX, (void*)R_R8, (void*)R_R9); }
void iFpppuii(x64emu_t *emu, uintptr_t fcn) { iFpppuii_t fn = (iFpppuii_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (uint64_t)R_RCX, (int64_t)R_R8, (int64_t)R_R9); }
void iFpppupu(x64emu_t *emu, uintptr_t fcn) { iFpppupu_t fn = (iFpppupu_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (uint64_t)R_RCX, (void*)R_R8, (uint64_t)R_R9); }
void iFpppLpp(x64emu_t *emu, uintptr_t fcn) { iFpppLpp_t fn = (iFpppLpp_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (uintptr_t)R_RCX, (void*)R_R8, (void*)R_R9); }
void iFppppii(x64emu_t *emu, uintptr_t fcn) { iFppppii_t fn = (iFppppii_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (int64_t)R_R8, (int64_t)R_R9); }
void iFppppip(x64emu_t *emu, uintptr_t fcn) { iFppppip_t fn = (iFppppip_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (int64_t)R_R8, (void*)R_R9); }
void iFppppup(x64emu_t *emu, uintptr_t fcn) { iFppppup_t fn = (iFppppup_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (uint64_t)R_R8, (void*)R_R9); }
@@ -2380,6 +2386,7 @@ void iFpiiiLwp(x64emu_t *emu, uintptr_t fcn) { iFpiiiLwp_t fn = (iFpiiiLwp_t)fcn
void iFpiiuuiu(x64emu_t *emu, uintptr_t fcn) { iFpiiuuiu_t fn = (iFpiiuuiu_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (int64_t)R_RSI, (int64_t)R_RDX, (uint64_t)R_RCX, (uint64_t)R_R8, (int64_t)R_R9, *(uint64_t*)(R_RSP + 8)); }
void iFpiuiipp(x64emu_t *emu, uintptr_t fcn) { iFpiuiipp_t fn = (iFpiuiipp_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (int64_t)R_RSI, (uint64_t)R_RDX, (int64_t)R_RCX, (int64_t)R_R8, (void*)R_R9, *(void**)(R_RSP + 8)); }
void iFpiupiii(x64emu_t *emu, uintptr_t fcn) { iFpiupiii_t fn = (iFpiupiii_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (int64_t)R_RSI, (uint64_t)R_RDX, (void*)R_RCX, (int64_t)R_R8, (int64_t)R_R9, *(int64_t*)(R_RSP + 8)); }
void iFpippLpp(x64emu_t *emu, uintptr_t fcn) { iFpippLpp_t fn = (iFpippLpp_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (int64_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (uintptr_t)R_R8, (void*)R_R9, *(void**)(R_RSP + 8)); }
void iFpippppp(x64emu_t *emu, uintptr_t fcn) { iFpippppp_t fn = (iFpippppp_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (int64_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8)); }
void iFpuuiuui(x64emu_t *emu, uintptr_t fcn) { iFpuuiuui_t fn = (iFpuuiuui_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (uint64_t)R_RSI, (uint64_t)R_RDX, (int64_t)R_RCX, (uint64_t)R_R8, (uint64_t)R_R9, *(int64_t*)(R_RSP + 8)); }
void iFpuupppp(x64emu_t *emu, uintptr_t fcn) { iFpuupppp_t fn = (iFpuupppp_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (uint64_t)R_RSI, (uint64_t)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8)); }
@@ -2462,6 +2469,7 @@ void iFuiifpppp(x64emu_t *emu, uintptr_t fcn) { iFuiifpppp_t fn = (iFuiifpppp_t)
void iFLLLLLLLL(x64emu_t *emu, uintptr_t fcn) { iFLLLLLLLL_t fn = (iFLLLLLLLL_t)fcn; R_RAX=(int64_t)fn((uintptr_t)R_RDI, (uintptr_t)R_RSI, (uintptr_t)R_RDX, (uintptr_t)R_RCX, (uintptr_t)R_R8, (uintptr_t)R_R9, *(uintptr_t*)(R_RSP + 8), *(uintptr_t*)(R_RSP + 16)); }
void iFpiiiiipi(x64emu_t *emu, uintptr_t fcn) { iFpiiiiipi_t fn = (iFpiiiiipi_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (int64_t)R_RSI, (int64_t)R_RDX, (int64_t)R_RCX, (int64_t)R_R8, (int64_t)R_R9, *(void**)(R_RSP + 8), *(int64_t*)(R_RSP + 16)); }
void iFpWCuWCuu(x64emu_t *emu, uintptr_t fcn) { iFpWCuWCuu_t fn = (iFpWCuWCuu_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (uint16_t)R_RSI, (uint8_t)R_RDX, (uint64_t)R_RCX, (uint16_t)R_R8, (uint8_t)R_R9, *(uint64_t*)(R_RSP + 8), *(uint64_t*)(R_RSP + 16)); }
void iFpuippLpp(x64emu_t *emu, uintptr_t fcn) { iFpuippLpp_t fn = (iFpuippLpp_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (uint64_t)R_RSI, (int64_t)R_RDX, (void*)R_RCX, (void*)R_R8, (uintptr_t)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16)); }
void iFpuuiiiii(x64emu_t *emu, uintptr_t fcn) { iFpuuiiiii_t fn = (iFpuuiiiii_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (uint64_t)R_RSI, (uint64_t)R_RDX, (int64_t)R_RCX, (int64_t)R_R8, (int64_t)R_R9, *(int64_t*)(R_RSP + 8), *(int64_t*)(R_RSP + 16)); }
void iFpupppppp(x64emu_t *emu, uintptr_t fcn) { iFpupppppp_t fn = (iFpupppppp_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (uint64_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16)); }
void iFppIIIppp(x64emu_t *emu, uintptr_t fcn) { iFppIIIppp_t fn = (iFppIIIppp_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (int64_t)R_RDX, (int64_t)R_RCX, (int64_t)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16)); }
@@ -2643,27 +2651,27 @@ int isSimpleWrapper(wrapper_t fun) {
if (fun == &vFv) return 1;
if (fun == &vFi) return 1;
if (fun == &vFu) return 1;
if (fun == &vFf) return 1;
if (fun == &vFd) return 1;
if (fun == &vFf) return 2;
if (fun == &vFd) return 2;
if (fun == &vFl) return 1;
if (fun == &vFL) return 1;
if (fun == &vFp) return 1;
if (fun == &cFv) return 1;
if (fun == &cFi) return 1;
if (fun == &cFu) return 1;
if (fun == &cFf) return 1;
if (fun == &cFf) return 2;
if (fun == &cFp) return 1;
if (fun == &wFp) return 1;
if (fun == &iFv) return 1;
if (fun == &iFw) return 1;
if (fun == &iFi) return 1;
if (fun == &iFu) return 1;
if (fun == &iFf) return 1;
if (fun == &iFd) return 1;
if (fun == &iFf) return 2;
if (fun == &iFd) return 2;
if (fun == &iFL) return 1;
if (fun == &iFp) return 1;
if (fun == &IFf) return 1;
if (fun == &IFd) return 1;
if (fun == &IFf) return 2;
if (fun == &IFd) return 2;
if (fun == &IFp) return 1;
if (fun == &CFp) return 1;
if (fun == &WFi) return 1;
@@ -2672,18 +2680,19 @@ int isSimpleWrapper(wrapper_t fun) {
if (fun == &uFv) return 1;
if (fun == &uFi) return 1;
if (fun == &uFu) return 1;
if (fun == &uFd) return 1;
if (fun == &uFU) return 1;
if (fun == &uFd) return 2;
if (fun == &uFp) return 1;
if (fun == &UFv) return 1;
if (fun == &UFp) return 1;
if (fun == &fFi) return 1;
if (fun == &fFf) return 1;
if (fun == &fFp) return 1;
if (fun == &dFv) return 1;
if (fun == &dFi) return 1;
if (fun == &dFu) return 1;
if (fun == &dFd) return 1;
if (fun == &dFp) return 1;
if (fun == &fFi) return -1;
if (fun == &fFf) return -2;
if (fun == &fFp) return -1;
if (fun == &dFv) return -1;
if (fun == &dFi) return -1;
if (fun == &dFu) return -1;
if (fun == &dFd) return -2;
if (fun == &dFp) return -1;
if (fun == &lFv) return 1;
if (fun == &lFi) return 1;
if (fun == &lFl) return 1;
@@ -2695,32 +2704,32 @@ int isSimpleWrapper(wrapper_t fun) {
if (fun == &pFi) return 1;
if (fun == &pFW) return 1;
if (fun == &pFu) return 1;
if (fun == &pFd) return 1;
if (fun == &pFd) return 2;
if (fun == &pFl) return 1;
if (fun == &pFL) return 1;
if (fun == &pFp) return 1;
if (fun == &vFii) return 1;
if (fun == &vFiu) return 1;
if (fun == &vFif) return 1;
if (fun == &vFid) return 1;
if (fun == &vFif) return 2;
if (fun == &vFid) return 2;
if (fun == &vFip) return 1;
if (fun == &vFWW) return 1;
if (fun == &vFWp) return 1;
if (fun == &vFui) return 1;
if (fun == &vFuu) return 1;
if (fun == &vFuf) return 1;
if (fun == &vFud) return 1;
if (fun == &vFuf) return 2;
if (fun == &vFud) return 2;
if (fun == &vFup) return 1;
if (fun == &vFfi) return 1;
if (fun == &vFff) return 1;
if (fun == &vFfp) return 1;
if (fun == &vFdd) return 1;
if (fun == &vFfi) return 2;
if (fun == &vFff) return 3;
if (fun == &vFfp) return 2;
if (fun == &vFdd) return 3;
if (fun == &vFlp) return 1;
if (fun == &vFLp) return 1;
if (fun == &vFpi) return 1;
if (fun == &vFpu) return 1;
if (fun == &vFpf) return 1;
if (fun == &vFpd) return 1;
if (fun == &vFpf) return 2;
if (fun == &vFpd) return 2;
if (fun == &vFpl) return 1;
if (fun == &vFpL) return 1;
if (fun == &vFpp) return 1;
@@ -2746,8 +2755,8 @@ int isSimpleWrapper(wrapper_t fun) {
if (fun == &iFpC) return 1;
if (fun == &iFpu) return 1;
if (fun == &iFpU) return 1;
if (fun == &iFpf) return 1;
if (fun == &iFpd) return 1;
if (fun == &iFpf) return 2;
if (fun == &iFpd) return 2;
if (fun == &iFpl) return 1;
if (fun == &iFpL) return 1;
if (fun == &iFpp) return 1;
@@ -2770,18 +2779,18 @@ int isSimpleWrapper(wrapper_t fun) {
if (fun == &UFii) return 1;
if (fun == &UFUp) return 1;
if (fun == &UFpp) return 1;
if (fun == &fFif) return 1;
if (fun == &fFfi) return 1;
if (fun == &fFff) return 1;
if (fun == &fFfp) return 1;
if (fun == &fFpp) return 1;
if (fun == &dFid) return 1;
if (fun == &dFdi) return 1;
if (fun == &dFdd) return 1;
if (fun == &dFdp) return 1;
if (fun == &dFLL) return 1;
if (fun == &dFpi) return 1;
if (fun == &dFpp) return 1;
if (fun == &fFif) return -2;
if (fun == &fFfi) return -2;
if (fun == &fFff) return -3;
if (fun == &fFfp) return -2;
if (fun == &fFpp) return -1;
if (fun == &dFid) return -2;
if (fun == &dFdi) return -2;
if (fun == &dFdd) return -3;
if (fun == &dFdp) return -2;
if (fun == &dFLL) return -1;
if (fun == &dFpi) return -1;
if (fun == &dFpp) return -1;
if (fun == &lFll) return 1;
if (fun == &lFpi) return 1;
if (fun == &lFpp) return 1;
@@ -2798,7 +2807,7 @@ int isSimpleWrapper(wrapper_t fun) {
if (fun == &pFui) return 1;
if (fun == &pFuu) return 1;
if (fun == &pFup) return 1;
if (fun == &pFdd) return 1;
if (fun == &pFdd) return 3;
if (fun == &pFlp) return 1;
if (fun == &pFLL) return 1;
if (fun == &pFpi) return 1;
@@ -2812,47 +2821,47 @@ int isSimpleWrapper(wrapper_t fun) {
if (fun == &vFiui) return 1;
if (fun == &vFiuu) return 1;
if (fun == &vFiup) return 1;
if (fun == &vFiff) return 1;
if (fun == &vFidd) return 1;
if (fun == &vFiff) return 3;
if (fun == &vFidd) return 3;
if (fun == &vFipi) return 1;
if (fun == &vFipu) return 1;
if (fun == &vFipp) return 1;
if (fun == &vFuii) return 1;
if (fun == &vFuiI) return 1;
if (fun == &vFuiu) return 1;
if (fun == &vFuif) return 1;
if (fun == &vFuid) return 1;
if (fun == &vFuif) return 2;
if (fun == &vFuid) return 2;
if (fun == &vFuip) return 1;
if (fun == &vFuui) return 1;
if (fun == &vFuuu) return 1;
if (fun == &vFuuf) return 1;
if (fun == &vFuud) return 1;
if (fun == &vFuuf) return 2;
if (fun == &vFuud) return 2;
if (fun == &vFuup) return 1;
if (fun == &vFuff) return 1;
if (fun == &vFudd) return 1;
if (fun == &vFuff) return 3;
if (fun == &vFudd) return 3;
if (fun == &vFull) return 1;
if (fun == &vFupu) return 1;
if (fun == &vFfff) return 1;
if (fun == &vFfpp) return 1;
if (fun == &vFddd) return 1;
if (fun == &vFdpp) return 1;
if (fun == &vFfff) return 4;
if (fun == &vFfpp) return 2;
if (fun == &vFddd) return 4;
if (fun == &vFdpp) return 2;
if (fun == &vFLpp) return 1;
if (fun == &vFpii) return 1;
if (fun == &vFpiu) return 1;
if (fun == &vFpif) return 1;
if (fun == &vFpid) return 1;
if (fun == &vFpif) return 2;
if (fun == &vFpid) return 2;
if (fun == &vFpip) return 1;
if (fun == &vFpui) return 1;
if (fun == &vFpuI) return 1;
if (fun == &vFpuu) return 1;
if (fun == &vFpup) return 1;
if (fun == &vFpdd) return 1;
if (fun == &vFpdd) return 3;
if (fun == &vFpll) return 1;
if (fun == &vFpLi) return 1;
if (fun == &vFpLL) return 1;
if (fun == &vFppi) return 1;
if (fun == &vFppu) return 1;
if (fun == &vFppd) return 1;
if (fun == &vFppd) return 2;
if (fun == &vFppL) return 1;
if (fun == &vFppp) return 1;
if (fun == &iFwww) return 1;
@@ -2870,9 +2879,9 @@ int isSimpleWrapper(wrapper_t fun) {
if (fun == &iFipp) return 1;
if (fun == &iFuuu) return 1;
if (fun == &iFuup) return 1;
if (fun == &iFuff) return 1;
if (fun == &iFuff) return 3;
if (fun == &iFuLL) return 1;
if (fun == &iFfff) return 1;
if (fun == &iFfff) return 4;
if (fun == &iFLwp) return 1;
if (fun == &iFLip) return 1;
if (fun == &iFLLp) return 1;
@@ -2890,9 +2899,9 @@ int isSimpleWrapper(wrapper_t fun) {
if (fun == &iFpup) return 1;
if (fun == &iFpUi) return 1;
if (fun == &iFpUU) return 1;
if (fun == &iFpfu) return 1;
if (fun == &iFpff) return 1;
if (fun == &iFpdd) return 1;
if (fun == &iFpfu) return 2;
if (fun == &iFpff) return 3;
if (fun == &iFpdd) return 3;
if (fun == &iFpli) return 1;
if (fun == &iFpll) return 1;
if (fun == &iFplp) return 1;
@@ -2904,7 +2913,7 @@ int isSimpleWrapper(wrapper_t fun) {
if (fun == &iFppC) return 1;
if (fun == &iFppW) return 1;
if (fun == &iFppu) return 1;
if (fun == &iFppd) return 1;
if (fun == &iFppd) return 2;
if (fun == &iFppl) return 1;
if (fun == &iFppL) return 1;
if (fun == &iFppp) return 1;
@@ -2924,14 +2933,14 @@ int isSimpleWrapper(wrapper_t fun) {
if (fun == &uFppu) return 1;
if (fun == &uFppp) return 1;
if (fun == &UFppi) return 1;
if (fun == &fFuii) return 1;
if (fun == &fFfff) return 1;
if (fun == &fFffp) return 1;
if (fun == &fFppL) return 1;
if (fun == &dFddd) return 1;
if (fun == &dFddp) return 1;
if (fun == &dFppi) return 1;
if (fun == &dFppp) return 1;
if (fun == &fFuii) return -1;
if (fun == &fFfff) return -4;
if (fun == &fFffp) return -3;
if (fun == &fFppL) return -1;
if (fun == &dFddd) return -4;
if (fun == &dFddp) return -3;
if (fun == &dFppi) return -1;
if (fun == &dFppp) return -1;
if (fun == &lFipi) return 1;
if (fun == &lFipL) return 1;
if (fun == &lFlll) return 1;
@@ -2960,7 +2969,7 @@ int isSimpleWrapper(wrapper_t fun) {
if (fun == &pFupi) return 1;
if (fun == &pFupL) return 1;
if (fun == &pFUpi) return 1;
if (fun == &pFddd) return 1;
if (fun == &pFddd) return 4;
if (fun == &pFpii) return 1;
if (fun == &pFpiu) return 1;
if (fun == &pFpil) return 1;
@@ -2979,7 +2988,7 @@ int isSimpleWrapper(wrapper_t fun) {
if (fun == &pFpLp) return 1;
if (fun == &pFppi) return 1;
if (fun == &pFppu) return 1;
if (fun == &pFppf) return 1;
if (fun == &pFppf) return 2;
if (fun == &pFppl) return 1;
if (fun == &pFppL) return 1;
if (fun == &pFppp) return 1;
@@ -2989,8 +2998,8 @@ int isSimpleWrapper(wrapper_t fun) {
if (fun == &vFiuuu) return 1;
if (fun == &vFiulp) return 1;
if (fun == &vFiupu) return 1;
if (fun == &vFifff) return 1;
if (fun == &vFiddd) return 1;
if (fun == &vFifff) return 4;
if (fun == &vFiddd) return 4;
if (fun == &vFipii) return 1;
if (fun == &vFipup) return 1;
if (fun == &vFippi) return 1;
@@ -3000,9 +3009,9 @@ int isSimpleWrapper(wrapper_t fun) {
if (fun == &vFuiui) return 1;
if (fun == &vFuiuu) return 1;
if (fun == &vFuiup) return 1;
if (fun == &vFuifi) return 1;
if (fun == &vFuiff) return 1;
if (fun == &vFuidd) return 1;
if (fun == &vFuifi) return 2;
if (fun == &vFuiff) return 3;
if (fun == &vFuidd) return 3;
if (fun == &vFuipi) return 1;
if (fun == &vFuipu) return 1;
if (fun == &vFuipp) return 1;
@@ -3011,18 +3020,18 @@ int isSimpleWrapper(wrapper_t fun) {
if (fun == &vFuuip) return 1;
if (fun == &vFuuui) return 1;
if (fun == &vFuuuu) return 1;
if (fun == &vFuuuf) return 1;
if (fun == &vFuuud) return 1;
if (fun == &vFuuuf) return 2;
if (fun == &vFuuud) return 2;
if (fun == &vFuuup) return 1;
if (fun == &vFuupi) return 1;
if (fun == &vFuupp) return 1;
if (fun == &vFufff) return 1;
if (fun == &vFuddd) return 1;
if (fun == &vFufff) return 4;
if (fun == &vFuddd) return 4;
if (fun == &vFupii) return 1;
if (fun == &vFuppi) return 1;
if (fun == &vFUUpi) return 1;
if (fun == &vFffff) return 1;
if (fun == &vFdddd) return 1;
if (fun == &vFffff) return 5;
if (fun == &vFdddd) return 5;
if (fun == &vFpiii) return 1;
if (fun == &vFpiip) return 1;
if (fun == &vFpiuL) return 1;
@@ -3030,18 +3039,18 @@ int isSimpleWrapper(wrapper_t fun) {
if (fun == &vFpipi) return 1;
if (fun == &vFpipp) return 1;
if (fun == &vFpuuu) return 1;
if (fun == &vFpudd) return 1;
if (fun == &vFpudd) return 3;
if (fun == &vFpupp) return 1;
if (fun == &vFpdii) return 1;
if (fun == &vFpddd) return 1;
if (fun == &vFpdii) return 2;
if (fun == &vFpddd) return 4;
if (fun == &vFpLLL) return 1;
if (fun == &vFppii) return 1;
if (fun == &vFppid) return 1;
if (fun == &vFppid) return 2;
if (fun == &vFppip) return 1;
if (fun == &vFppui) return 1;
if (fun == &vFppuu) return 1;
if (fun == &vFppup) return 1;
if (fun == &vFppdd) return 1;
if (fun == &vFppdd) return 3;
if (fun == &vFpppi) return 1;
if (fun == &vFpppu) return 1;
if (fun == &vFpppL) return 1;
@@ -3068,12 +3077,12 @@ int isSimpleWrapper(wrapper_t fun) {
if (fun == &iFippL) return 1;
if (fun == &iFippp) return 1;
if (fun == &iFuipp) return 1;
if (fun == &iFuuff) return 1;
if (fun == &iFuuff) return 3;
if (fun == &iFuppi) return 1;
if (fun == &iFuppp) return 1;
if (fun == &iFpiii) return 1;
if (fun == &iFpiiu) return 1;
if (fun == &iFpiid) return 1;
if (fun == &iFpiid) return 2;
if (fun == &iFpiiL) return 1;
if (fun == &iFpiip) return 1;
if (fun == &iFpiuL) return 1;
@@ -3115,7 +3124,7 @@ int isSimpleWrapper(wrapper_t fun) {
if (fun == &iFpppL) return 1;
if (fun == &iFpppp) return 1;
if (fun == &IFppip) return 1;
if (fun == &uFifff) return 1;
if (fun == &uFifff) return 4;
if (fun == &uFuuuu) return 1;
if (fun == &uFpipu) return 1;
if (fun == &uFpipp) return 1;
@@ -3126,7 +3135,7 @@ int isSimpleWrapper(wrapper_t fun) {
if (fun == &uFpppi) return 1;
if (fun == &uFpppp) return 1;
if (fun == &UFpipp) return 1;
if (fun == &dFppiL) return 1;
if (fun == &dFppiL) return -1;
if (fun == &lFiipL) return 1;
if (fun == &lFipiI) return 1;
if (fun == &lFipLi) return 1;
@@ -3151,8 +3160,8 @@ int isSimpleWrapper(wrapper_t fun) {
if (fun == &pFippL) return 1;
if (fun == &pFuiii) return 1;
if (fun == &pFulli) return 1;
if (fun == &pFdddd) return 1;
if (fun == &pFlfff) return 1;
if (fun == &pFdddd) return 5;
if (fun == &pFlfff) return 4;
if (fun == &pFpiii) return 1;
if (fun == &pFpiip) return 1;
if (fun == &pFpiuu) return 1;
@@ -3188,8 +3197,8 @@ int isSimpleWrapper(wrapper_t fun) {
if (fun == &vFiuipi) return 1;
if (fun == &vFiuuuu) return 1;
if (fun == &vFiulpp) return 1;
if (fun == &vFiffff) return 1;
if (fun == &vFidddd) return 1;
if (fun == &vFiffff) return 5;
if (fun == &vFidddd) return 5;
if (fun == &vFilill) return 1;
if (fun == &vFipipu) return 1;
if (fun == &vFipipp) return 1;
@@ -3198,7 +3207,7 @@ int isSimpleWrapper(wrapper_t fun) {
if (fun == &vFuiiiu) return 1;
if (fun == &vFuiiip) return 1;
if (fun == &vFuiiup) return 1;
if (fun == &vFuiifi) return 1;
if (fun == &vFuiifi) return 2;
if (fun == &vFuiIII) return 1;
if (fun == &vFuiuii) return 1;
if (fun == &vFuiuiu) return 1;
@@ -3207,8 +3216,8 @@ int isSimpleWrapper(wrapper_t fun) {
if (fun == &vFuiuup) return 1;
if (fun == &vFuiupi) return 1;
if (fun == &vFuiupu) return 1;
if (fun == &vFuifff) return 1;
if (fun == &vFuiddd) return 1;
if (fun == &vFuifff) return 4;
if (fun == &vFuiddd) return 4;
if (fun == &vFuipii) return 1;
if (fun == &vFuipip) return 1;
if (fun == &vFuipup) return 1;
@@ -3227,19 +3236,20 @@ int isSimpleWrapper(wrapper_t fun) {
if (fun == &vFuuuuu) return 1;
if (fun == &vFuuuup) return 1;
if (fun == &vFuupii) return 1;
if (fun == &vFuffff) return 1;
if (fun == &vFudddd) return 1;
if (fun == &vFuffff) return 5;
if (fun == &vFudddd) return 5;
if (fun == &vFupupi) return 1;
if (fun == &vFuppip) return 1;
if (fun == &vFupppp) return 1;
if (fun == &vFddddp) return 1;
if (fun == &vFfffff) return 6;
if (fun == &vFddddp) return 5;
if (fun == &vFpiiii) return 1;
if (fun == &vFpiipp) return 1;
if (fun == &vFpipii) return 1;
if (fun == &vFpuipp) return 1;
if (fun == &vFpuddd) return 1;
if (fun == &vFpddii) return 1;
if (fun == &vFpdddd) return 1;
if (fun == &vFpuddd) return 4;
if (fun == &vFpddii) return 3;
if (fun == &vFpdddd) return 5;
if (fun == &vFpliil) return 1;
if (fun == &vFppiii) return 1;
if (fun == &vFppiip) return 1;
@@ -3337,7 +3347,7 @@ int isSimpleWrapper(wrapper_t fun) {
if (fun == &pFpuuip) return 1;
if (fun == &pFpuuWW) return 1;
if (fun == &pFpuuup) return 1;
if (fun == &pFpdddd) return 1;
if (fun == &pFpdddd) return 5;
if (fun == &pFppiii) return 1;
if (fun == &pFppiip) return 1;
if (fun == &pFppipi) return 1;
@@ -3353,8 +3363,8 @@ int isSimpleWrapper(wrapper_t fun) {
if (fun == &vFiiiiii) return 1;
if (fun == &vFiiiuil) return 1;
if (fun == &vFiuippp) return 1;
if (fun == &vFiffiff) return 1;
if (fun == &vFiddidd) return 1;
if (fun == &vFiffiff) return 5;
if (fun == &vFiddidd) return 5;
if (fun == &vFuiiiii) return 1;
if (fun == &vFuiiiip) return 1;
if (fun == &vFuiiuii) return 1;
@@ -3366,8 +3376,8 @@ int isSimpleWrapper(wrapper_t fun) {
if (fun == &vFuiuuuu) return 1;
if (fun == &vFuiupii) return 1;
if (fun == &vFuiupiu) return 1;
if (fun == &vFuiffff) return 1;
if (fun == &vFuidddd) return 1;
if (fun == &vFuiffff) return 5;
if (fun == &vFuidddd) return 5;
if (fun == &vFuipiup) return 1;
if (fun == &vFuuiiii) return 1;
if (fun == &vFuuiuii) return 1;
@@ -3380,21 +3390,25 @@ int isSimpleWrapper(wrapper_t fun) {
if (fun == &vFuuuuii) return 1;
if (fun == &vFuuuuip) return 1;
if (fun == &vFuuuuuu) return 1;
if (fun == &vFuuuuff) return 1;
if (fun == &vFuuuuff) return 3;
if (fun == &vFuuuppi) return 1;
if (fun == &vFuuuppp) return 1;
if (fun == &vFuuffff) return 1;
if (fun == &vFuudddd) return 1;
if (fun == &vFuffiip) return 1;
if (fun == &vFuddiip) return 1;
if (fun == &vFuuffff) return 5;
if (fun == &vFuudddd) return 5;
if (fun == &vFuffiip) return 3;
if (fun == &vFufffff) return 6;
if (fun == &vFuddiip) return 3;
if (fun == &vFupupip) return 1;
if (fun == &vFuppppp) return 1;
if (fun == &vFffffff) return 7;
if (fun == &vFdddddd) return 7;
if (fun == &vFpiiiii) return 1;
if (fun == &vFpiiuuu) return 1;
if (fun == &vFpiippp) return 1;
if (fun == &vFpipppi) return 1;
if (fun == &vFpudddd) return 1;
if (fun == &vFpdddii) return 1;
if (fun == &vFpudddd) return 5;
if (fun == &vFpdddii) return 4;
if (fun == &vFpddddd) return 6;
if (fun == &vFppiiii) return 1;
if (fun == &vFppiiip) return 1;
if (fun == &vFppiipi) return 1;
@@ -3447,6 +3461,7 @@ int isSimpleWrapper(wrapper_t fun) {
if (fun == &iFpppipp) return 1;
if (fun == &iFpppuii) return 1;
if (fun == &iFpppupu) return 1;
if (fun == &iFpppLpp) return 1;
if (fun == &iFppppii) return 1;
if (fun == &iFppppip) return 1;
if (fun == &iFppppup) return 1;
@@ -3461,6 +3476,7 @@ int isSimpleWrapper(wrapper_t fun) {
if (fun == &LFpipipi) return 1;
if (fun == &pFiiiiii) return 1;
if (fun == &pFiCiiCi) return 1;
if (fun == &pFdddddd) return 7;
if (fun == &pFpiiiiu) return 1;
if (fun == &pFpiiCCC) return 1;
if (fun == &pFpippip) return 1;
@@ -3474,20 +3490,27 @@ int isSimpleWrapper(wrapper_t fun) {
if (fun == &pFppippp) return 1;
if (fun == &pFpppppu) return 1;
if (fun == &pFpppppp) return 1;
if (fun == &vFiiffffp) return 1;
if (fun == &vFuipffff) return 1;
if (fun == &vFuipdddd) return 1;
if (fun == &vFuuuufff) return 1;
if (fun == &vFuuuffff) return 1;
if (fun == &vFuuudddd) return 1;
if (fun == &vFuuffiip) return 1;
if (fun == &vFuuddiip) return 1;
if (fun == &vFpddiidd) return 1;
if (fun == &iFppppdpi) return 1;
if (fun == &pFifffppp) return 1;
if (fun == &vFuuuuufff) return 1;
if (fun == &iFdddpppppp) return 1;
if (fun == &vFuffiiffiip) return 1;
if (fun == &vFuddiiddiip) return 1;
if (fun == &vFiiffffp) return 5;
if (fun == &vFuipffff) return 5;
if (fun == &vFuipdddd) return 5;
if (fun == &vFuuuufff) return 4;
if (fun == &vFuuuffff) return 5;
if (fun == &vFuuudddd) return 5;
if (fun == &vFuuffiip) return 3;
if (fun == &vFuuddiip) return 3;
if (fun == &vFuffffff) return 7;
if (fun == &vFudddddd) return 7;
if (fun == &vFpddiidd) return 5;
if (fun == &vFpdddddd) return 7;
if (fun == &iFppppdpi) return 2;
if (fun == &pFifffppp) return 4;
if (fun == &vFuuuuufff) return 4;
if (fun == &vFffffffff) return 9;
if (fun == &vFuffffffff) return 9;
if (fun == &vFffuuuufff) return 6;
if (fun == &iFdddpppppp) return 4;
if (fun == &vFuffiiffiip) return 5;
if (fun == &vFuddiiddiip) return 5;
if (fun == &vFppdddddddd) return 9;
return 0;
}
+4
View File
@@ -64,6 +64,7 @@ void WFp(x64emu_t *emu, uintptr_t fnc);
void uFv(x64emu_t *emu, uintptr_t fnc);
void uFi(x64emu_t *emu, uintptr_t fnc);
void uFu(x64emu_t *emu, uintptr_t fnc);
void uFU(x64emu_t *emu, uintptr_t fnc);
void uFd(x64emu_t *emu, uintptr_t fnc);
void uFp(x64emu_t *emu, uintptr_t fnc);
void UFv(x64emu_t *emu, uintptr_t fnc);
@@ -976,6 +977,7 @@ void iFpppipi(x64emu_t *emu, uintptr_t fnc);
void iFpppipp(x64emu_t *emu, uintptr_t fnc);
void iFpppuii(x64emu_t *emu, uintptr_t fnc);
void iFpppupu(x64emu_t *emu, uintptr_t fnc);
void iFpppLpp(x64emu_t *emu, uintptr_t fnc);
void iFppppii(x64emu_t *emu, uintptr_t fnc);
void iFppppip(x64emu_t *emu, uintptr_t fnc);
void iFppppup(x64emu_t *emu, uintptr_t fnc);
@@ -1078,6 +1080,7 @@ void iFpiiiLwp(x64emu_t *emu, uintptr_t fnc);
void iFpiiuuiu(x64emu_t *emu, uintptr_t fnc);
void iFpiuiipp(x64emu_t *emu, uintptr_t fnc);
void iFpiupiii(x64emu_t *emu, uintptr_t fnc);
void iFpippLpp(x64emu_t *emu, uintptr_t fnc);
void iFpippppp(x64emu_t *emu, uintptr_t fnc);
void iFpuuiuui(x64emu_t *emu, uintptr_t fnc);
void iFpuupppp(x64emu_t *emu, uintptr_t fnc);
@@ -1160,6 +1163,7 @@ void iFuiifpppp(x64emu_t *emu, uintptr_t fnc);
void iFLLLLLLLL(x64emu_t *emu, uintptr_t fnc);
void iFpiiiiipi(x64emu_t *emu, uintptr_t fnc);
void iFpWCuWCuu(x64emu_t *emu, uintptr_t fnc);
void iFpuippLpp(x64emu_t *emu, uintptr_t fnc);
void iFpuuiiiii(x64emu_t *emu, uintptr_t fnc);
void iFpupppppp(x64emu_t *emu, uintptr_t fnc);
void iFppIIIppp(x64emu_t *emu, uintptr_t fnc);
+4 -1
View File
@@ -1958,7 +1958,7 @@ EXPORT void* my_mmap64(x64emu_t* emu, void *addr, unsigned long length, int prot
(void)emu;
if(prot&PROT_WRITE)
prot|=PROT_READ; // PROT_READ is implicit with PROT_WRITE on i386
if(box64_log<LOG_DEBUG) {dynarec_log(LOG_DEBUG, "mmap64(%p, %lu, 0x%x, 0x%x, %d, %ld) =>", addr, length, prot, flags, fd, offset);}
if(box64_log<LOG_DEBUG) {dynarec_log(LOG_DEBUG, "mmap64(%p, %lu, 0x%x, 0x%x, %d, %ld) => ", addr, length, prot, flags, fd, offset);}
#ifndef NOALIGN
if(flags&0x40) {
// 0x40 is MAP_32BIT, wich only exist on x86_64!
@@ -1967,6 +1967,9 @@ EXPORT void* my_mmap64(x64emu_t* emu, void *addr, unsigned long length, int prot
addr = find32bitBlock(length);
else
addr = findBlockNearHint(addr, length);
} else if (box64_wine) {
if(!addr)
addr = find47bitBlock(length);
}
#endif
void* ret = mmap64(addr, length, prot, flags, fd, offset);
+29 -29
View File
@@ -15,7 +15,7 @@ GO(accept, iFipp)
//GO(accept4,
GOW(access, iFpi)
//GO(acct,
//GOW(addmntent,
GOW(addmntent, iFpp)
//GOW(addseverity,
//GOW(adjtime,
//GO(__adjtimex,
@@ -153,7 +153,7 @@ GOW(close, iFi)
GOW(closedir, iFp)
GO(closelog, vFv)
//GO(__close_nocancel,
//GO(__cmsg_nxthdr,
GO(__cmsg_nxthdr, pFpp)
GO(confstr, LFipL)
//GO(__confstr_chk,
GOW(__connect, iFipu)
@@ -233,9 +233,9 @@ GOW(duplocale, pFp)
//GO(endaliasent,
//GO(endfsent,
//GO(endgrent,
//GO(endhostent,
//GO(__endmntent,
//GOW(endmntent,
GO(endhostent, vFv)
GO(__endmntent, iFp)
GOW(endmntent, iFp)
//GO(endnetent,
//GO(endnetgrent,
GO(endprotoent, vFv)
@@ -452,7 +452,7 @@ GO(fts_set, iFppi)
GOM(ftw, iFEppi)
GOM(ftw64, iFEppi)
GOW(funlockfile, vFp)
//GO(futimens,
GO(futimens, iFip)
//GOW(futimes,
//GO(futimesat,
//GO(fwide,
@@ -517,14 +517,14 @@ GO(getgrent, pFv)
//GO(getgrouplist,
GOW(getgroups, iFip)
//GO(__getgroups_chk,
//GO(gethostbyaddr,
//GO(gethostbyaddr_r,
GO(gethostbyaddr, pFpui)
GO(gethostbyaddr_r, iFpuippLpp)
GO(gethostbyname, pFp)
//GO(gethostbyname2,
//GO(gethostbyname2_r,
//GO(gethostbyname_r,
//GO(gethostent,
//GO(gethostent_r,
GO(gethostbyname2, pFpi)
GO(gethostbyname2_r, iFpippLpp)
GO(gethostbyname_r, iFpppLpp)
GO(gethostent, pFv)
GO(gethostent_r, iFppLpp)
//GO(gethostid,
GOW(gethostname, iFpL)
//GO(__gethostname_chk,
@@ -537,9 +537,9 @@ GOW(getline, iFppp)
GO(getlogin, pFv)
GOW(getlogin_r, iFpL)
//GO(__getlogin_r_chk,
//GO(getmntent,
//GO(__getmntent_r,
//GOW(getmntent_r,
GO(getmntent, pFp)
GO(__getmntent_r, pFpppi)
GOW(getmntent_r, pFpppi)
//GO(getmsg,
//GO(get_myaddress,
GO(getnameinfo, iFpupLpLi)
@@ -655,16 +655,16 @@ GOW(globfree64, vFp)
GO(gmtime, pFp)
GO(__gmtime_r, pFpp)
GOW(gmtime_r, pFpp)
//GOW(gnu_dev_major,
//GOW(gnu_dev_makedev,
//GOW(gnu_dev_minor,
//GOW(gnu_get_libc_release,
//GOW(gnu_get_libc_version,
GOW(gnu_dev_major, uFU)
GOW(gnu_dev_makedev, UFii)
GOW(gnu_dev_minor, uFU)
GOW(gnu_get_libc_release, pFv)
GOW(gnu_get_libc_version, pFv)
//GO(grantpt,
//GOW(group_member,
//GOW(gsignal,
//GO(gtty,
//GOW(hasmntopt,
GOW(hasmntopt, pFpp)
//GO(hcreate,
//GOW(hcreate_r,
//GOW(hdestroy,
@@ -672,7 +672,7 @@ GOW(gmtime_r, pFpp)
//DATA(h_errlist,
//DATAB(__h_errno,
//GO(__h_errno_location,
//GO(herror,
GO(herror, vFp)
//GO(host2netname,
//GO(hsearch,
//GOW(hsearch_r,
@@ -684,9 +684,9 @@ GO(iconv_close, iFL)
GO(iconv_open, LFpp)
//GO(__idna_from_dns_encoding,
//GO(__idna_to_dns_encoding,
//GOW(if_freenameindex,
GOW(if_freenameindex, vFp)
GOW(if_indextoname, pFup)
//GOW(if_nameindex,
GOW(if_nameindex, pFv)
GOW(if_nametoindex, uFp)
//GOW(imaxabs,
//GOW(imaxdiv,
@@ -1617,7 +1617,7 @@ GO(seteuid, iFu)
GOW(setgid, iFp)
//GO(setgrent,
//GO(setgroups,
//GO(sethostent,
GO(sethostent, vFi)
//GO(sethostid,
GO(sethostname, iFpL)
//GO(setipv4sourcefilter,
@@ -1628,8 +1628,8 @@ GO(setlinebuf, vFp)
GO(setlocale, pFip)
//GO(setlogin,
GO(setlogmask, iFi)
//GO(__setmntent,
//GOW(setmntent,
GO(__setmntent, pFpp)
GOW(setmntent, pFpp)
//GO(setnetent,
//GO(setnetgrent,
//GO(setns,
@@ -2035,7 +2035,7 @@ GOW(uselocale, pFp)
GO(usleep, iFu)
//GO(ustat,
GO(utime, iFpp)
//GO(utimensat,
GO(utimensat, iFippi)
GOW(utimes, iFpp)
//GOW(utmpname,
//GO(utmpxname,
+12
View File
@@ -0,0 +1,12 @@
div 1, 1 => 1 / 0
div 10, 5 => 2 / 0
div 10, 3 => 3 / 1
div 1, 18446744073709551615 => 0 / 1
div 10, 18446744073709551613 => 0 / 10
div 18446744073709551606, 18446744073709551613 => 0 / 18446744073709551606
idiv 1, 1 => 1 / 0
idiv 10, 5 => 2 / 0
idiv 10, 3 => 3 / 1
idiv 1, -1 => -1 / 0
idiv 10, -3 => -3 / 1
idiv -10, -3 => 3 / -1
Executable
BIN
View File
Binary file not shown.
+50
View File
@@ -0,0 +1,50 @@
#include <string.h>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdint.h>
#include <math.h>
#if defined(__x86_64__)
uint64_t _div_(uint64_t a, uint64_t b, uint64_t *r)
{
uint64_t ret, rem;
asm volatile (
"xor %%rdx, %%rdx\n"
"div %%rcx\n"
"mov %%rdx, %%rbx\n"
:"=a" (ret), "=b" (rem):"a" (a), "c" (b):"rdx","cc");
*r = rem;
return ret;
}
uint64_t _idiv_(uint64_t a, uint64_t b, uint64_t *r)
{
uint64_t ret, rem;
asm volatile (
"cqo\n"
"idiv %%rcx\n"
"mov %%rdx, %%rbx\n"
:"=a" (ret), "=b" (rem):"a" (a), "c" (b):"rdx","cc");
*r = rem;
return ret;
}
#else
#endif
int main(int argc, const char** argv)
{
uint64_t datas[][2] = {{1,1},{10,5},{10,3},{1, (uint64_t)-1}, {10, (uint64_t)-3}, {(uint64_t)-10, (uint64_t)-3}};
int sz = sizeof(datas)/sizeof(datas[0]);
for(int i=0; i<sz; ++i) {
uint64_t rem = 0;
uint64_t d = _div_(datas[i][0], datas[i][1], &rem);
printf("div %llu, %llu => %llu / %llu\n", datas[i][0], datas[i][1], d, rem);
}
for(int i=0; i<sz; ++i) {
uint64_t rem = 0;
uint64_t d = _idiv_(datas[i][0], datas[i][1], &rem);
printf("idiv %lld, %lld => %lld / %lld\n", datas[i][0], datas[i][1], d, rem);
}
return 0;
}