Compare commits

...
26 Commits
Author SHA1 Message Date
ptitSeb e6e9fae178 Bumped to v0.1.6 2021-11-19 22:21:29 +01:00
ptitSeb 7042a1ae30 Try to use Github Actions 2021-11-19 21:52:10 +01:00
ptitSeb 7d277cc1ec Updated CHANGELOG 2021-11-19 21:43:49 +01:00
ptitSeb 1ac0465a03 Small change on unload of box64 2021-11-19 21:43:32 +01:00
ptitSeb 3533db97ff [DYNAREC] Reduce performance impact of StrongMem, and added old Strongmem method as BOX64_DYNAREC_STRONGMEM=2 2021-11-19 11:22:59 +01:00
ptitSeb 7888cae6c7 Merge pull request #166 from eerykitty/main
Minor changes to allow box64 to build and run on 64-bit PowerPC.
2021-11-19 07:48:02 +01:00
Joseph Allen b021beba6a Minor changes to allow box64 to build and run on ppc64le. 2021-11-18 17:48:52 -06:00
ptitSeb 684d67d12e Added wrapped __isoc99_scanf function (for #164) 2021-11-18 14:25:53 +01:00
ptitSeb 8d7683b851 Changed elfloader a bit to merge elf memory block if close enough (help load program on loongarch architecture) 2021-11-18 14:23:37 +01:00
ptitSeb e7290d78d5 [DYNAREC] Improved JIT handling, and added a HotPage detection to temporarily disable Dynarec when write occurs on the same page of some Dynablocks (help speedup some C#/Unity3D programs) 2021-11-18 14:21:16 +01:00
ptitSeb 4f0e98ade5 [DYNAREC] Added an option to simulate Strong Memory Model, and auto activate it when libmonobdgcw-2.0.so is detected (should help #110 and #158 at least) 2021-11-18 14:18:00 +01:00
ptitSeb 39dbfd9fd8 [DYNAREC] Removed special case for RimWorldLinux and generalized it for all program loading libmonodbwgc-2.0.so 2021-11-18 13:50:10 +01:00
ptitSeb 2d18558dc5 [TRACE] Fixed trace on function from a dlopen library not triggering preperly 2021-11-17 19:41:00 +01:00
ptitSeb 5fb9397521 [DYNAREC] Fixed a small issue with Segfault in Fillblock detection 2021-11-15 17:45:31 +01:00
ptitSeb f85e24dff8 [DYNAREC] Added some DMB to try help multi-tasked+JIT program (may help #110) 2021-11-14 21:43:02 +01:00
ptitSeb 2ea272fcd6 [DYNAREC] Added DMB emitter 2021-11-14 20:57:51 +01:00
ptitSeb d3e85b439b Added wrapped libxslt (from box86) (should help #161) 2021-11-14 15:19:25 +01:00
ptitSeb ea837908b6 Added wrapped libldap_r and liblber (helps wine) 2021-11-14 15:15:47 +01:00
ptitSeb a1573835dd Change ResolvePath behaviour in sync with box86 2021-11-14 10:44:55 +01:00
ptitSeb 34355d6b0c Added some data symbol to wrapped libxml2 (for #161 but it would probably be better to wrap libxslt directly) 2021-11-12 19:20:08 +01:00
ptitSeb 9557e4711f Added a few xcb symbols (for #161) 2021-11-12 12:19:50 +01:00
ptitSeb 6a1b9e050a [DYNAREC] Changed Dynarec a bit to try stabilise program using many threads and a JIT (help RimWorld Linux, but not enough to be 100% stable) 2021-11-11 20:47:10 +01:00
ptitSeb 6675b43dd0 [DYNAREC] Pass0 now alocate memory and do more stuff from pass1 2021-11-11 12:37:32 +01:00
ptitSeb 79d7e9f8eb Mark memprot as volatile to try help stability in heavily multithread programs 2021-11-11 12:37:01 +01:00
ptitSeb f5c9439f91 Improved CMPSS/CMPSD opcodes, improved test17 ([DYNAREC] too, and improved MINSS/MAXSS/MINSD/MAXSD too) 2021-11-07 15:06:55 +01:00
ptitSeb f73e4193f0 Chnaged memory protection tracking to reduce usage of lock, especially for [DYNAREC] reduced mutrex and chances of deadlock (help RimWorld) 2021-11-05 21:17:14 +01:00
65 changed files with 2492 additions and 498 deletions

No files matched your search

+83
View File
@@ -0,0 +1,83 @@
### Auto build Box64 and release its binary with Github Action
name: Build and Release Box64
on:
workflow_dispatch:
release:
push:
paths:
- "**/*.c"
- "**/*.h"
- "**/*.S"
- "**/*.py"
- "CMakeList.txt"
- "**/*.yml"
pull_request:
types: [assigned, opened, synchronize, reopened]
paths:
- "**/*.c"
- "**/*.h"
- "**/*.S"
- "**/*.py"
- "CMakeList.txt"
- "**/*.yml"
jobs:
build:
strategy:
fail-fast: false
matrix:
platform: [X64, OTHER_ARM, RPI4ARM64, RK3326, RK3399, RK3288, TEGRAX1, PHYTIUM, SD845]
type: [Release, Trace]
runs-on: ubuntu-latest
steps:
- name: "Checkout Box64 Repository"
uses: actions/checkout@v2
- name: "Environment preparation"
run: |
sudo apt-get update
if [[ ${{ matrix.platform }} != 'X64' && ${{ matrix.platform }} != 'OTHER_ARM' ]]; then
echo "BOX64_PLATFORM_MARCRO=-D${{ matrix.platform }}=1" >> $GITHUB_ENV
echo "BOX64_COMPILER=aarch64-linux-gnu-gcc" >> $GITHUB_ENV
sudo apt-get -y install git gcc-aarch64-linux-gnu cmake make python3
else
if [[ ${{ matrix.platform }} == 'X64' ]]; then
echo "BOX64_PLATFORM_MARCRO=-DLD80BITS=1 -DNOALIGN=1" >> $GITHUB_ENV
echo "BOX64_COMPILER=gcc" >> $GITHUB_ENV
sudo apt-get -y install git cmake make python3
ls /bin/*gcc*
else
echo BOX64_PLATFORM_MARCRO="-DARM_DYNAREC=ON" >> $GITHUB_ENV
echo "BOX64_COMPILER=aarch64-linux-gnu-gcc" >> $GITHUB_ENV
sudo apt-get -y install git gcc-aarch64-linux-gnu cmake make python3
fi
fi
if [[ ${{ matrix.type }} == 'Release' ]]; then
echo BOX64_BUILD_TYPE=Release >> $GITHUB_ENV
echo BOX64_HAVE_TRACE=0 >> $GITHUB_ENV
else
echo BOX64_BUILD_TYPE=RelWithDebInfo >> $GITHUB_ENV
echo BOX64_HAVE_TRACE=1 >> $GITHUB_ENV
fi
- name: "Display Build info"
run: |
echo "CMake Platform Macro: ${{ env.BOX64_PLATFORM_MARCRO }}"
echo "CMake C Compiler: ${{ env.BOX64_COMPILER }}"
echo "Build type: ${{ env.BOX64_BUILD_TYPE }}"
echo "Trace Enabled: ${{ env.BOX64_HAVE_TRACE }}"
- name: "Build Box64"
run: |
mkdir build
cd build
cmake .. -DCMAKE_C_COMPILER=${{ env.BOX64_COMPILER }} ${{ env.BOX64_PLATFORM_MARCRO }} -DCMAKE_BUILD_TYPE=${{ env.BOX64_BUILD_TYPE }} -DHAVE_TRACE=${{ env.BOX64_HAVE_TRACE }} -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON
make -j$(nproc) VERBOSE=1
- name: "Upload Artifact"
uses: actions/upload-artifact@v2
with:
name: box86-${{ matrix.platform }}-${{ matrix.type }}
path: build/box64
+3
View File
@@ -340,6 +340,9 @@ set(WRAPPEDS
"${BOX64_ROOT}/src/wrapped/wrappedxkbcommon.c"
"${BOX64_ROOT}/src/wrapped/wrappedxkbcommonx11.c"
"${BOX64_ROOT}/src/wrapped/wrappedxml2.c"
"${BOX64_ROOT}/src/wrapped/wrappedxslt.c"
"${BOX64_ROOT}/src/wrapped/wrappedldapr.c"
"${BOX64_ROOT}/src/wrapped/wrappedlber.c"
)
#set(WRAPPEDS_HEAD "${BOX64_ROOT}/src/wrapped/wrappedd3dadapter9_gen.h")
+4 -1
View File
@@ -1,5 +1,8 @@
Current Version
v0.1.6
======
* Introduce "HotPage", to temporarily disable Dynarec on a page were writing is also occuring (can help speed up C# code)
* Some work on Dynarec to limit the number of mutex use, and also allow smaller block to be built (for JIT'd programs)
* Introduce BOX64_DYNAREC_STRONGMEM for the (Arm) dynarec to emulate StrngMemory Model (needed by some games, like RimWorld)
* More functions wrapped
* Improve speed of the custom allocator used by dynarec and Hash (speedup loading)
* Added a workaround for streamwebhelper to not load it
+11
View File
@@ -115,6 +115,17 @@ Enables/Disables trace for generated code.
Forbid dynablock creation in the interval specified (helpfull for debugging behaviour difference between Dynarec and Interpretor)
* 0xXXXXXXXX-0xYYYYYYYY : define the interval where dynablock cannot start (inclusive-exclusive)
#### BOX64_DYNAREC_BIGBLOCK
Enables/Disables Box64's Dynarec building BigBlock.
* 0 : Don't try to build block as big as possible (can help program using lots of thread and a JIT, like C#/Unity) (Default when libmonobdwgc-2.0.so is loaded)
* 1 : Build Dynarec block as big as possible (Default.)
#### BOX64_DYNAREC_STRONGMEM
Enable/Disable simulation of Strong Memory model
* 0 : Don't try anything special (Default.)
* 1 : Enable some Memory Barrier when reading from memory (on some MOV opcode) to simulate Strong Memory Model while trying to limit performance impact (Default when libmonobdwgc-2.0.so is loaded)
* 2 : Enable some Memory Barrier when reading from memory (on some MOV opcode) to simulate Strong Memory Model
#### BOX64_LIBGL
* libXXXX set the name for libGL (defaults to libGL.so.1).
* /PATH/TO/libGLXXX : Sets the name and path for libGL
+7 -7
View File
@@ -270,6 +270,13 @@ void FreeBox64Context(box64context_t** context)
if(ctx->tlsdata)
free(ctx->tlsdata);
free_neededlib(&ctx->neededlibs);
if(ctx->emu_sig)
FreeX64Emu(&ctx->emu_sig);
finiAllHelpers(ctx);
pthread_mutex_destroy(&ctx->mutex_once);
pthread_mutex_destroy(&ctx->mutex_once2);
pthread_mutex_destroy(&ctx->mutex_trace);
@@ -282,13 +289,6 @@ void FreeBox64Context(box64context_t** context)
pthread_mutex_destroy(&ctx->mutex_thread);
pthread_mutex_destroy(&ctx->mutex_bridge);
free_neededlib(&ctx->neededlibs);
if(ctx->emu_sig)
FreeX64Emu(&ctx->emu_sig);
finiAllHelpers(ctx);
free(ctx);
}
+1 -1
View File
@@ -3,6 +3,6 @@
#define BOX64_MAJOR 0
#define BOX64_MINOR 1
#define BOX64_REVISION 5
#define BOX64_REVISION 6
#endif //__BOX64_VERSION_H_
+175 -182
View File
@@ -31,7 +31,6 @@
// init inside dynablocks.c
KHASH_MAP_INIT_INT64(dynablocks, dynablock_t*)
static dynablocklist_t*** dynmap123[1<<DYNAMAP_SHIFT]; // 64bits.. in 4x16bits array
static pthread_mutex_t mutex_mmap;
static mmaplist_t *mmaplist = NULL;
static size_t mmapsize = 0;
static size_t mmapcap = 0;
@@ -41,12 +40,12 @@ static uintptr_t** box64_jmptbldefault2[1<<JMPTABL_SHIFT];
static uintptr_t* box64_jmptbldefault1[1<<JMPTABL_SHIFT];
static uintptr_t box64_jmptbldefault0[1<<JMPTABL_SHIFT];
#endif
#define MEMPROT_SHIFT 12
#define MEMPROT_SHIFT2 (32-MEMPROT_SHIFT)
#define MEMPROT_SIZE (1<<(32-MEMPROT_SHIFT))
static pthread_mutex_t mutex_prot;
KHASH_MAP_INIT_INT(memprot, uint8_t*)
static kh_memprot_t *memprot;
#define MEMPROT_SHIFT 12
#define MEMPROT_SHIFT2 (16+12)
#define MEMPROT_SIZE (1<<16)
static uint8_t *volatile memprot[1<<20]; // x86_64 mem is 48bits, page is 12bits, so memory is tracked as [20][16][page protection]
static uint8_t memprot_default[MEMPROT_SIZE];
static int inited = 0;
typedef struct blocklist_s {
@@ -497,11 +496,9 @@ uintptr_t AllocDynarecMap(dynablock_t* db, size_t size)
if(!size)
return 0;
if(size>MMAPSIZE-2*sizeof(blockmark_t)) {
pthread_mutex_lock(&mutex_mmap);
#ifndef USE_MMAP
void *p = NULL;
if(posix_memalign(&p, box64_pagesize, size)) {
pthread_mutex_unlock(&mutex_mmap);
dynarec_log(LOG_INFO, "Cannot create dynamic map of %zu bytes\n", size);
return 0;
}
@@ -509,7 +506,6 @@ uintptr_t AllocDynarecMap(dynablock_t* db, size_t size)
#else
void* p = mmap(NULL, size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
if(p==(void*)-1) {
pthread_mutex_unlock(&mutex_mmap);
dynarec_log(LOG_INFO, "Cannot create dynamic map of %zu bytes\n", size);
return 0;
}
@@ -524,18 +520,14 @@ uintptr_t AllocDynarecMap(dynablock_t* db, size_t size)
int ret;
k = kh_put(dynablocks, blocks, (uintptr_t)p, &ret);
kh_value(blocks, k) = db;
pthread_mutex_unlock(&mutex_mmap);
return (uintptr_t)p;
}
pthread_mutex_lock(&mutex_mmap);
uintptr_t ret = FindFreeDynarecMap(db, size);
if(!ret)
ret = AddNewDynarecMap(db, size);
pthread_mutex_unlock(&mutex_mmap);
return ret;
}
@@ -544,7 +536,6 @@ void FreeDynarecMap(dynablock_t* db, uintptr_t addr, size_t size)
if(!addr || !size)
return;
if(size>MMAPSIZE-2*sizeof(blockmark_t)) {
pthread_mutex_lock(&mutex_mmap);
#ifndef USE_MMAP
free((void*)addr);
#else
@@ -556,12 +547,9 @@ void FreeDynarecMap(dynablock_t* db, uintptr_t addr, size_t size)
if(k!=kh_end(blocks))
kh_del(dynablocks, blocks, k);
}
pthread_mutex_unlock(&mutex_mmap);
return;
}
pthread_mutex_lock(&mutex_mmap);
ActuallyFreeDynarecMap(db, addr, size);
pthread_mutex_unlock(&mutex_mmap);
}
dynablocklist_t* getDB(uintptr_t idx)
@@ -760,44 +748,35 @@ uintptr_t getJumpTableAddress64(uintptr_t addr)
}
// Remove the Write flag from an adress range, so DB can be executed safely
void protectDBnolock(uintptr_t addr, uintptr_t size)
void protectDB(uintptr_t addr, uintptr_t size)
{
dynarec_log(LOG_DEBUG, "protectDB %p -> %p\n", (void*)addr, (void*)(addr+size-1));
uintptr_t idx = (addr>>MEMPROT_SHIFT);
uintptr_t end = ((addr+size-1LL)>>MEMPROT_SHIFT);
if(end>=(1LL<<(20+16)))
end = (1LL<<(20+16))-1;
if(end<idx) // memory addresses higher than 48bits are not tracked
return;
pthread_mutex_lock(&mutex_prot);
int ret;
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;
for (uintptr_t i=(idx>>16); i<=(end>>16); ++i)
if(memprot[i]==memprot_default) {
uint8_t* newblock = calloc(1<<16, sizeof(uint8_t));
/*if (arm64_lock_storeifref(&memprot[i], newblock, memprot_default) != newblock) {
free(newblock);
}*/
memprot[i] = newblock;
}
const uintptr_t ii = i&(MEMPROT_SIZE-1);
uint8_t prot = kh_value(memprot, k)[ii];
if(!(prot&PROT_DYNAREC)) {
if(!prot)
prot = PROT_READ | PROT_WRITE; // comes from malloc & co, so should not be able to execute
kh_value(memprot, k)[ii] = prot|PROT_DYNAREC;
mprotect((void*)(i<<MEMPROT_SHIFT), 1<<MEMPROT_SHIFT, prot&~(PROT_WRITE|PROT_CUSTOM));
for (uintptr_t i=idx; i<=end; ++i) {
uint32_t prot = memprot[i>>16][i&0xffff];
if(!prot)
prot = PROT_READ | PROT_WRITE | PROT_EXEC; // comes from malloc & co, so should not be able to execute
if((prot&PROT_WRITE)) {
prot&=~PROT_WRITE;
mprotect((void*)(i<<MEMPROT_SHIFT), 1<<MEMPROT_SHIFT, prot);
memprot[i>>16][i&0xffff] = prot|PROT_DYNAREC; // need to use atomic exchange?
}
}
}
void protectDB(uintptr_t addr, size_t size)
{
pthread_mutex_lock(&mutex_prot);
protectDBnolock(addr, size);
pthread_mutex_unlock(&mutex_prot);
}
void lockDB()
{
pthread_mutex_lock(&mutex_prot);
}
void unlockDB()
{
pthread_mutex_unlock(&mutex_prot);
}
@@ -807,90 +786,109 @@ void unprotectDB(uintptr_t addr, size_t size)
{
dynarec_log(LOG_DEBUG, "unprotectDB %p -> %p\n", (void*)addr, (void*)(addr+size-1));
uintptr_t idx = (addr>>MEMPROT_SHIFT);
uintptr_t end = ((addr+size-1LL)>>MEMPROT_SHIFT);
int ret;
uintptr_t end = ((addr+size-1)>>MEMPROT_SHIFT);
if(end>=(1LL<<(20+16)))
end = (1LL<<(20+16))-1;
if(end<idx) // memory addresses higher than 48bits are not tracked
return;
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;
for (uintptr_t i=(idx>>16); i<=(end>>16); ++i)
if(memprot[i]==memprot_default) {
uint8_t* newblock = calloc(1<<16, sizeof(uint8_t));
/*if (arm64_lock_storeifref(&memprot[i], newblock, memprot_default) != newblock) {
free(newblock);
}*/
memprot[i] = newblock;
}
const uintptr_t ii = i&(MEMPROT_SIZE-1);
uint8_t prot = kh_value(memprot, k)[ii];
for (uintptr_t i=idx; i<=end; ++i) {
uint32_t prot = memprot[i>>16][i&0xffff];
if(prot&PROT_DYNAREC) {
kh_value(memprot, k)[ii] = prot&~PROT_DYNAREC;
mprotect((void*)(i<<MEMPROT_SHIFT), 1<<MEMPROT_SHIFT, prot&~PROT_CUSTOM);
prot&=~PROT_DYNAREC;
prot|=PROT_WRITE;
cleanDBFromAddressRange((i<<MEMPROT_SHIFT), 1<<MEMPROT_SHIFT, 0);
mprotect((void*)(i<<MEMPROT_SHIFT), 1<<MEMPROT_SHIFT, prot);
memprot[i>>16][i&0xffff] = prot; // need to use atomic exchange?
}
}
pthread_mutex_unlock(&mutex_prot);
}
int isprotectedDB(uintptr_t addr, size_t size)
{
dynarec_log(LOG_DEBUG, "isprotectedDB %p -> %p => ", (void*)addr, (void*)(addr+size-1));
uintptr_t idx = (addr>>MEMPROT_SHIFT);
uintptr_t end = ((addr+size-1LL)>>MEMPROT_SHIFT);
if(end>=(1LL<<(20+16)))
end = (1LL<<(20+16))-1LL;
if(end<idx) { // memory addresses higher than 48bits are not tracked
dynarec_log(LOG_DEBUG, "00\n");
return 0;
}
for (uintptr_t i=idx; i<=end; ++i) {
uint32_t prot = memprot[i>>16][i&0xffff];
if((prot&PROT_WRITE)) {
dynarec_log(LOG_DEBUG, "0\n");
return 0;
}
}
dynarec_log(LOG_DEBUG, "1\n");
return 1;
}
#endif
void updateProtection(uintptr_t addr, size_t size, uint32_t prot)
{
dynarec_log(LOG_DEBUG, "updateProtection %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;
uintptr_t last = idx<<MEMPROT_SHIFT;
uint8_t oldprot = 0xff;
uintptr_t end = ((addr+size-1)>>MEMPROT_SHIFT);
if(end>=(1LL<<(20+16)))
end = (1LL<<(20+16))-1;
if(end<idx) // memory addresses higher than 48bits are not tracked
return;
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) {
uint32_t dyn = block[ii]&PROT_DYNAREC;
if(dyn && (prot&PROT_WRITE)) { // need to remove the write protection from this block
if(oldprot!=prot) {
if(oldprot!=0xff)
mprotect((void*)last, (i<<MEMPROT_SHIFT)-last, oldprot&~PROT_CUSTOM); // need to optimize
last = i<<MEMPROT_SHIFT;
oldprot = prot;
}
} else if(prot!=0xff) {
mprotect((void*)last, (i<<MEMPROT_SHIFT)-last, oldprot&~PROT_CUSTOM); // need to optimize
last = i << MEMPROT_SHIFT;
oldprot = 0xff;
for (uintptr_t i=(idx>>16); i<=(end>>16); ++i)
if(memprot[i]==memprot_default) {
uint8_t* newblock = calloc(1<<16, sizeof(uint8_t));
#if 0 //def ARM64 //disabled for now, not usefull with the mutex
if (arm64_lock_storeifref(&memprot[i], newblock, memprot_default) != newblock) {
free(newblock);
}
block[ii] = prot|dyn|PROT_ALLOC;
#else
memprot[i] = newblock;
#endif
}
i+=finish-start; // +1 from the "for" loop
for (uintptr_t i=idx; i<=end; ++i) {
uint32_t dyn=(memprot[i>>16][i&0xffff]&PROT_DYNAREC);
if(dyn && (prot&PROT_WRITE)) // need to remove the write protection from this block
mprotect((void*)(i<<MEMPROT_SHIFT), 1<<MEMPROT_SHIFT, prot&~PROT_WRITE);
memprot[i>>16][i&0xffff] = prot|dyn;
}
if(oldprot!=0xff)
mprotect((void*)last, (end<<MEMPROT_SHIFT)-last, oldprot&~PROT_CUSTOM); // need to optimize
pthread_mutex_unlock(&mutex_prot);
}
void setProtection(uintptr_t addr, size_t size, uint32_t prot)
{
dynarec_log(LOG_DEBUG, "setProtection %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;
uintptr_t end = ((addr+size-1)>>MEMPROT_SHIFT);
if(end>=(1LL<<(20+16)))
end = (1LL<<(20+16))-1;
if(end<idx) // memory addresses higher than 48bits are not tracked
return;
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;
for (uintptr_t i=(idx>>16); i<=(end>>16); ++i)
if(memprot[i]==memprot_default) {
uint8_t* newblock = calloc(MEMPROT_SIZE, sizeof(uint8_t));
#if 0 //def ARM64 //disabled for now, not usefull with the mutex
if (arm64_lock_storeifref(&memprot[i], newblock, memprot_default) != newblock) {
free(newblock);
}
#else
memprot[i] = newblock;
#endif
}
const uintptr_t start = i&(MEMPROT_SIZE-1);
const uintptr_t finish = (((i|(MEMPROT_SIZE-1))<end)?(MEMPROT_SIZE-1):end)&(MEMPROT_SIZE-1);
memset(kh_value(memprot, k)+start, prot|PROT_ALLOC, finish-start+1);
i+=finish-start; // +1 from the "for" loop
}
for (uintptr_t i=idx; i<=end; ++i)
memprot[i>>16][i&0xffff] = prot;
pthread_mutex_unlock(&mutex_prot);
}
@@ -899,18 +897,26 @@ 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;
if(end>=(1LL<<(20+16)))
end = (1LL<<(20+16))-1;
if(end<idx) // memory addresses higher than 48bits are not tracked
return;
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;
for (uintptr_t i=(idx>>16); i<=(end>>16); ++i)
if(memprot[i]==memprot_default) {
uint8_t* newblock = calloc(1<<16, sizeof(uint8_t));
#if 0 //def ARM64 //disabled for now, not usefull with the mutex
if (arm64_lock_storeifref(&memprot[i], newblock, memprot_default) != newblock) {
free(newblock);
}
#else
memprot[i] = newblock;
#endif
}
for (uintptr_t i=idx; i<=end; ++i) {
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);
uint8_t* block = memprot[i>>16];
for(uintptr_t ii = start; ii<=finish; ++ii) {
if(!block[ii])
block[ii] = prot;
@@ -933,7 +939,7 @@ void loadProtectionFromMap()
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);
allocProtection(s, e-s, prot|PROT_ALLOC);
}
}
fclose(f);
@@ -941,8 +947,9 @@ void loadProtectionFromMap()
static int blockempty(uint8_t* mem)
{
for (int i=0; i<(MEMPROT_SIZE); ++i)
if(mem[i])
uint32_t *p4 = (uint32_t*)mem;
for (int i=0; i<(MEMPROT_SIZE)/4; ++i, ++p4)
if(*p4)
return 0;
return 1;
}
@@ -952,19 +959,35 @@ void freeProtection(uintptr_t addr, size_t size)
dynarec_log(LOG_DEBUG, "freeProtection %p:%p\n", (void*)addr, (void*)(addr+size-1));
uintptr_t idx = (addr>>MEMPROT_SHIFT);
uintptr_t end = ((addr+size-1LL)>>MEMPROT_SHIFT);
if(end>=(1LL<<(20+16)))
end = (1LL<<(20+16))-1;
if(end<idx) // memory addresses higher than 48bits are not tracked
return;
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_get(memprot, memprot, key);
if(k!=kh_end(memprot)) {
const uint32_t key = (i>>16);
if(memprot[key]!=memprot_default) {
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);
uint8_t *block = memprot[key];
memset(block+start, 0, finish-start+1);
if(blockempty(block)) {
free(block);
kh_del(memprot, memprot, k);
#if 0 //def ARM64 //disabled for now, not usefull with the mutex
if (blockempty(block)) {
block = (void*)arm64_lock_xchg(&memprot[key], (uintptr_t)memprot_default);
if(!blockempty(block)) {
block = (void*)arm64_lock_xchg(&memprot[key], (uintptr_t)block);
for (int i = 0; i < 0x10000; ++i) {
memprot[key][i] |= block[i];
}
}
if (block != memprot_default) free(block);
}
#else
if(blockempty(block)) {
memprot[key] = memprot_default;
free(block);
}
#endif
i+=finish-start; // +1 from the "for" loop
}
}
@@ -973,65 +996,52 @@ void freeProtection(uintptr_t addr, size_t size)
uint32_t getProtection(uintptr_t addr)
{
const uint32_t key = (addr>>32)&0xffffffff;
pthread_mutex_lock(&mutex_prot);
khint_t k = kh_get(memprot, memprot, key);
if(k==kh_end(memprot)) {
pthread_mutex_unlock(&mutex_prot);
if(addr>=(1LL<<48))
return 0;
}
const uintptr_t idx = ((addr&0xffffffff)>>MEMPROT_SHIFT);
uint32_t ret = kh_val(memprot, k)[idx];
pthread_mutex_unlock(&mutex_prot);
const uintptr_t idx = (addr>>MEMPROT_SHIFT);
uint32_t ret = memprot[idx>>16][idx&0xffff];
return ret;
}
#define LOWEST (void*)0x20000
int availableBlock(uint8_t* p, size_t n)
{
for (size_t i=0; i<n; ++i, ++p)
if(*p)
return 0;
return 1;
}
static uintptr_t nextFree(uintptr_t addr)
{
if(addr>=(1LL<<48))
return 0;
do {
const uint32_t key = (addr>>32)&0xffffffff;
khint_t k = kh_get(memprot, memprot, key);
if(k==kh_end(memprot)) {
uintptr_t idx = (addr>>MEMPROT_SHIFT);
if(memprot[idx>>16]==memprot_default) {
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);
for (uintptr_t i=(idx&0xffff); i<MEMPROT_SIZE; ++i)
if(!memprot[idx>>16][i]) {
return ((idx>>16)<<(16+12))+(i<<MEMPROT_SHIFT);
}
addr += 0x100000000LL;
addr &= ~0xffffffffLL;
addr += (1LL<<(16+12));
addr &= ~((1LL<<(16+12)-1LL));
} while(1);
}
static uintptr_t maxFree(uintptr_t addr, uintptr_t sz)
{
if(addr>=(1LL<<48))
return 0;
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;
uintptr_t idx = (addr>>MEMPROT_SHIFT);
if(memprot[idx>>16]==memprot_default) {
mfree+=(1LL<<(16+12));
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;
for (uintptr_t i=(idx&0xffffLL); i<MEMPROT_SIZE; ++i)
if(!memprot[idx>>16][i]) {
mfree+=(1<<MEMPROT_SHIFT);
} else
return mfree;
}
addr += 0x100000000LL;
addr &= ~0xffffffffLL;
addr += (1LL<<(12+16));
addr &= ~((1LL<<(12+16))-1LL);
} while(1);
}
void* find32bitBlock(size_t size)
@@ -1042,12 +1052,10 @@ void* find47bitBlock(size_t size)
{
// slow iterative search... Would need something better one day
uintptr_t addr = 0x100000000LL;
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;
@@ -1058,12 +1066,10 @@ void* find47bitBlock(size_t size)
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;
}
@@ -1071,17 +1077,14 @@ 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;
}
@@ -1089,17 +1092,14 @@ void* findBlockNearHint(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<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;
}
@@ -1116,9 +1116,6 @@ int unlockCustommemMutex()
}
GO(mutex_blocks, 0)
GO(mutex_prot, 1)
#ifdef DYNAREC
GO(mutex_mmap, 2)
#endif
#undef GO
return ret;
}
@@ -1131,9 +1128,6 @@ void relockCustommemMutex(int locks)
GO(mutex_blocks, 0)
GO(mutex_prot, 1)
#ifdef DYNAREC
GO(mutex_mmap, 2)
#endif
#undef GO
}
@@ -1144,9 +1138,6 @@ static void init_mutexes(void)
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
pthread_mutex_init(&mutex_blocks, &attr);
pthread_mutex_init(&mutex_prot, &attr);
#ifdef DYNAREC
pthread_mutex_init(&mutex_mmap, &attr);
#endif
pthread_mutexattr_destroy(&attr);
}
@@ -1163,7 +1154,9 @@ void init_custommem_helper(box64context_t* ctx)
if(inited) // already initialized
return;
inited = 1;
memprot = kh_init(memprot);
memset(memprot_default, 0, sizeof(memprot_default));
for(int i=0; i<(1<<20); ++i)
memprot[i] = memprot_default;
init_mutexes();
#ifdef DYNAREC
#ifdef ARM64
@@ -1226,7 +1219,6 @@ void fini_custommem_helper(box64context_t *ctx)
}
free(mmaplist);
pthread_mutex_destroy(&mutex_mmap);
for (int i3=0; i3<(1<<DYNAMAP_SHIFT); ++i3)
if(box64_jmptbl3[i3]!=box64_jmptbldefault2) {
for (int i2=0; i2<(1<<DYNAMAP_SHIFT); ++i2)
@@ -1242,10 +1234,11 @@ void fini_custommem_helper(box64context_t *ctx)
}
#endif
uint8_t* m;
kh_foreach_value(memprot, m,
free(m);
);
kh_destroy(memprot, memprot);
for(int i=0; i<(1<<20); ++i) {
m = memprot[i];
if(m!=memprot_default)
free(m);
}
for(int i=0; i<n_blocks; ++i)
#ifdef USE_MMAP
+3
View File
@@ -351,6 +351,9 @@
#define PST_L1_STREAM_U12(Rn, imm12) EMIT(PRFM_imm(((imm12)>>3)&0xfff, Rn, 0b01001))
// Data Memory Barrier
#define DMB_gen(CRm) (0b1101010100<<22 | 0b011<<16 | 0b0011<<12 | (CRm)<<8 | 1<<7 | 0b01<<5 | 0b11111)
#define DMB_ISH() EMIT(DMB_gen(0b1011))
// BR and Branches
#define BR_gen(Z, op, A, M, Rn, Rm) (0b1101011<<25 | (Z)<<24 | (op)<<21 | 0b11111<<16 | (A)<<11 | (M)<<10 | (Rn)<<5 | (Rm))
+22 -3
View File
@@ -21,6 +21,7 @@
arm64_lock_read_b:
dmb ish
// address is x0, return is x0
ldaxrb w0, [x0]
ret
@@ -29,9 +30,11 @@ arm64_lock_write_b:
// address is x0, value is x1, return is x0
mov x2, x0
stlxrb w0, w1, [x2]
dmb ish
ret
arm64_lock_read_h:
dmb ish
// address is x0, return is x0
ldaxrh w0, [x0]
ret
@@ -40,9 +43,11 @@ arm64_lock_write_h:
// address is x0, value is x1, return is x0
mov x2, x0
stlxrh w0, w1, [x2]
dmb ish
ret
arm64_lock_read_d:
dmb ish
// address is x0, return is x0
ldaxr w0, [x0]
ret
@@ -51,9 +56,11 @@ arm64_lock_write_d:
// address is x0, value is w1, return is x0
mov x2, x0
stlxr w0, w1, [x2]
dmb ish
ret
arm64_lock_read_dd:
dmb ish
// address is x0, return is x0
ldaxr x0, [x0]
ret
@@ -62,9 +69,11 @@ arm64_lock_write_dd:
// address is x0, value is x1, return is x0
mov x2, x0
stlxr w0, x1, [x2]
dmb ish
ret
arm64_lock_read_dq:
dmb ish
// address is r2, return is r0, r1
ldaxp x4, x3, [x2]
str x4, [x0]
@@ -76,37 +85,47 @@ arm64_lock_write_dq:
// r0 needs to be aligned
stlxp w3, x0, x1, [x2]
mov w0, w3
dmb ish
ret
arm64_lock_xchg:
dmb ish
arm64_lock_xchg_0:
// address is x0, value is x1, return old value in x0
ldaxr x2, [x0]
stlxr w3, x1, [x0]
cbnz w3, arm64_lock_xchg
cbnz w3, arm64_lock_xchg_0
dmb ish
mov x0, x2
ret
arm64_lock_storeifnull:
dmb ish
arm64_lock_storeifnull_0:
// address is x0, value is x1, x1 store to x0 only if [x0] is 0. return new [x0] value (so x1 or old value)
ldaxr x2, [x0]
cbnz x2, arm64_lock_storeifnull_exit
mov x2, x1
stlxr w3, x2, [x0]
cbnz w3, arm64_lock_storeifnull
cbnz w3, arm64_lock_storeifnull_0
arm64_lock_storeifnull_exit:
dmb ish
mov x0, x2
ret
arm64_lock_storeifref:
dmb ish
arm64_lock_storeifref_0:
// address is x0, value is x1, x1 store to x0 only if [x0] is x3. return new [x0] value (so x1 or old value)
ldaxr x3, [x0]
cmp x2, x3
bne arm64_lock_storeifref_exit
stlxr w4, x1, [x0]
cbnz w4, arm64_lock_storeifref
cbnz w4, arm64_lock_storeifref_0
mov x0, x1
ret
arm64_lock_storeifref_exit:
dmb ish
mov x0, x3
ret
+156 -58
View File
@@ -48,6 +48,8 @@ dynablocklist_t* NewDynablockList(uintptr_t text, int textsz, int direct)
dynablocklist_t* ret = (dynablocklist_t*)calloc(1, sizeof(dynablocklist_t));
ret->text = text;
ret->textsz = textsz;
ret->minstart = text;
ret->maxend = text+textsz-1;
if(direct && textsz) {
ret->direct = (dynablock_t**)calloc(textsz, sizeof(dynablock_t*));
if(!ret->direct) {printf_log(LOG_NONE, "Warning, fail to create direct block for dynablock @%p\n", (void*)text);}
@@ -56,12 +58,14 @@ dynablocklist_t* NewDynablockList(uintptr_t text, int textsz, int direct)
return ret;
}
void FreeDynablock(dynablock_t* db)
void FreeDynablock(dynablock_t* db, int need_lock)
{
if(db) {
dynarec_log(LOG_DEBUG, "FreeDynablock(%p), db->block=%p x64=%p:%p parent=%p, father=%p, with %d son(s) already gone=%d\n", db, db->block, db->x64_addr, db->x64_addr+db->x64_size, db->parent, db->father, db->sons_size, db->gone);
if(db->gone)
return; // already in the process of deletion!
dynarec_log(LOG_DEBUG, "FreeDynablock(%p), db->block=%p x64=%p:%p parent=%p, father=%p, with %d son(s) already gone=%d\n", db, db->block, db->x64_addr, db->x64_addr+db->x64_size-1, db->parent, db->father, db->sons_size, db->gone);
if(need_lock)
pthread_mutex_lock(&my_context->mutex_dyndump);
db->done = 0;
db->gone = 1;
// remove from direct if there
@@ -77,16 +81,18 @@ void FreeDynablock(dynablock_t* db)
// remove and free the sons
for (int i=0; i<db->sons_size; ++i) {
dynablock_t *son = (dynablock_t*)arm64_lock_xchg(&db->sons[i], 0);
FreeDynablock(son);
FreeDynablock(son, 0);
}
// only the father free the DynarecMap
if(!db->father) {
dynarec_log(LOG_DEBUG, " -- FreeDyrecMap(%p, %d)\n", db->block, db->size);
FreeDynarecMap(db, (uintptr_t)db->block, db->size);
free(db->sons);
free(db->instsize);
}
free(db->sons);
free(db->instsize);
free(db);
if(need_lock)
pthread_mutex_unlock(&my_context->mutex_dyndump);
}
}
@@ -100,7 +106,7 @@ void FreeDynablockList(dynablocklist_t** dynablocks)
if((*dynablocks)->direct) {
for (int i=0; i<(*dynablocks)->textsz; ++i) {
if((*dynablocks)->direct[i] && !(*dynablocks)->direct[i]->father)
FreeDynablock((*dynablocks)->direct[i]);
FreeDynablock((*dynablocks)->direct[i], 1);
}
free((*dynablocks)->direct);
}
@@ -117,7 +123,8 @@ void MarkDynablock(dynablock_t* db)
db = db->father; // mark only father
if(db->need_test)
return; // already done
db->need_test = 1; // test only blocks that can be marked (and so deleted)
dynarec_log(LOG_DEBUG, "MarkDynablock %p with %d son(s) %p-%p\n", db, db->sons_size, db->x64_addr, db->x64_addr+db->x64_size-1);
db->need_test = 1;
setJumpTableDefault64(db->x64_addr);
for(int i=0; i<db->sons_size; ++i)
setJumpTableDefault64(db->sons[i]->x64_addr);
@@ -146,24 +153,19 @@ int IntervalIntersects(uintptr_t start1, uintptr_t end1, uintptr_t start2, uintp
void MarkDirectDynablock(dynablocklist_t* dynablocks, uintptr_t addr, uintptr_t size)
{
// Mark will try to find *any* blocks that intersect the range to mark
if(!dynablocks)
return;
if(!dynablocks->direct)
return;
uintptr_t startdb = dynablocks->text;
uintptr_t enddb = startdb + dynablocks->textsz -1;
uintptr_t start = addr;
uintptr_t end = addr+size-1;
if(start<startdb)
start = startdb;
if(end>enddb)
end = enddb;
uintptr_t sizedb = dynablocks->textsz;
dynablock_t *db;
if(end>startdb && start<enddb)
for(uintptr_t i = start; i<end; ++i)
if((db=dynablocks->direct[i-startdb]))
if(IntervalIntersects((uintptr_t)db->x64_addr, (uintptr_t)db->x64_addr+db->x64_size-1, addr, addr+size+1))
MarkDynablock(db);
dynarec_log(LOG_DEBUG, "MarkDirectDynablock %p-%p .. startdb=%p, sizedb=%p\n", (void*)addr, (void*)addr+size-1, (void*)startdb, (void*)sizedb);
for(uintptr_t i = 0; i<sizedb; ++i)
if((db=dynablocks->direct[i]))
if(IntervalIntersects((uintptr_t)db->x64_addr, (uintptr_t)db->x64_addr+db->x64_size-1, addr, addr+size+1))
MarkDynablock(db);
}
int FreeRangeDynablock(dynablocklist_t* dynablocks, uintptr_t addr, uintptr_t size)
@@ -199,7 +201,7 @@ int FreeRangeDynablock(dynablocklist_t* dynablocks, uintptr_t addr, uintptr_t si
}
// purge the list
kh_foreach_value(blocks, db,
FreeDynablock(db);
FreeDynablock(db, 1);
);
kh_destroy(dynablocks, blocks);
// check emptyness
@@ -214,13 +216,14 @@ void MarkRangeDynablock(dynablocklist_t* dynablocks, uintptr_t addr, uintptr_t s
{
if(!dynablocks)
return;
dynarec_log(LOG_DEBUG, "MarkRangeDynablock %p-%p\n", (void*)addr, (void*)addr+size-1);
if(dynablocks->direct) {
uintptr_t new_addr = addr - dynablocks->maxsz;
uintptr_t new_size = size + dynablocks->maxsz;
MarkDirectDynablock(dynablocks, new_addr, new_size);
uintptr_t new_addr = dynablocks->minstart;
uintptr_t new_size = dynablocks->maxend - new_addr + 1;
MarkDirectDynablock(dynablocks, addr, size);
// the blocks check before
for(unsigned idx=(new_addr)>>DYNAMAP_SHIFT; idx<(addr>>DYNAMAP_SHIFT); ++idx)
MarkDirectDynablock(getDB(idx), new_addr, new_size);
MarkDirectDynablock(getDB(idx), addr, size);
}
}
@@ -268,6 +271,7 @@ dynablock_t *AddNewDynablock(dynablocklist_t* dynablocks, uintptr_t addr, int* c
if (!*created)
return block;
pthread_mutex_lock(&my_context->mutex_dyndump);
if(!dynablocks->direct) {
dynablock_t** p = (dynablock_t**)calloc(dynablocks->textsz, sizeof(dynablock_t*));
if(arm64_lock_storeifnull(&dynablocks->direct, p)!=p)
@@ -282,12 +286,14 @@ dynablock_t *AddNewDynablock(dynablocklist_t* dynablocks, uintptr_t addr, int* c
dynablock_t* tmp = (dynablock_t*)arm64_lock_storeifnull(&dynablocks->direct[addr-dynablocks->text], block);
if(tmp != block) {
// a block appeard!
pthread_mutex_unlock(&my_context->mutex_dyndump);
free(block);
*created = 0;
return tmp;
}
*created = 1;
pthread_mutex_lock(&my_context->mutex_dyndump);
return block;
}
@@ -303,7 +309,7 @@ void cancelFillBlock()
return NULL if block is not found / cannot be created.
Don't create if create==0
*/
static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t filladdr, int create, dynablock_t* current)
static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t filladdr, int create, dynablock_t* current, int need_lock)
{
// try the quickest way first: get parent of current and check if ok!
dynablocklist_t *dynablocks = NULL;
@@ -332,19 +338,19 @@ static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t
if(!created)
return block; // existing block...
#if 0
if(box64_dynarec_dump)
pthread_mutex_lock(&my_context->mutex_dyndump);
#endif
// fill the block
block->x64_addr = (void*)addr;
pthread_mutex_lock(&my_context->mutex_dyndump);
if(need_lock)
pthread_mutex_lock(&my_context->mutex_dyndump);
if(sigsetjmp(&dynarec_jmpbuf, 1)) {
printf_log(LOG_INFO, "FillBlock at %p triggered a segfault, cancelling\n", (void*)addr);
if(need_lock)
pthread_mutex_unlock(&my_context->mutex_dyndump);
return NULL;
}
void* ret = FillBlock64(block, filladdr);
pthread_mutex_unlock(&my_context->mutex_dyndump);
if(need_lock)
pthread_mutex_unlock(&my_context->mutex_dyndump);
if(!ret) {
dynarec_log(LOG_DEBUG, "Fillblock of block %p for %p returned an error\n", block, (void*)addr);
void* old = (void*)arm64_lock_storeifref(&dynablocks->direct[addr-dynablocks->text], 0, block);
@@ -355,24 +361,20 @@ static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t
free(block);
block = NULL;
}
#if 0
if(box64_dynarec_dump)
pthread_mutex_unlock(&my_context->mutex_dyndump);
#endif
// check size
if(block && block->x64_size) {
if(dynablocks->minstart>addr)
dynablocks->minstart = addr;
int blocksz = block->x64_size;
if(dynablocks->maxsz<blocksz) {
dynablocks->maxsz = blocksz;
for(unsigned idx=(addr>>DYNAMAP_SHIFT)+1; idx<=((addr+blocksz)>>DYNAMAP_SHIFT); ++idx) {
if(dynablocks->maxend<addr+blocksz) {
dynablocks->maxend = addr+blocksz;
for(unsigned idx=(addr>>DYNAMAP_SHIFT)+1; idx<=((addr+blocksz-1)>>DYNAMAP_SHIFT); ++idx) {
dynablocklist_t* dblist;
if((dblist = getDB(idx)))
if(dblist->maxsz<blocksz)
dblist->maxsz = blocksz;
if(dblist->minstart>addr)
dblist->minstart = addr;
}
}
lockDB();
protectDBnolock((uintptr_t)block->x64_addr, block->x64_size);
// fill-in jumptable
addJumpTableIfDefault64(block->x64_addr, block->block);
for(int i=0; i<block->sons_size; ++i) {
@@ -380,39 +382,133 @@ static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t
block->sons[i]->done = 1;
}
block->done = 1;
unlockDB();
}
dynarec_log(LOG_DEBUG, " --- DynaRec Block %s @%p:%p (%p, 0x%x bytes, with %d son(s))\n", created?"created":"recycled", (void*)addr, (void*)(addr+((block)?block->x64_size:0)), (block)?block->block:0, (block)?block->size:0, (block)?block->sons_size:0);
dynarec_log(LOG_DEBUG, "%04d| --- DynaRec Block %s @%p:%p (%p, 0x%x bytes, with %d son(s))\n", GetTID(), created?"created":"recycled", (void*)addr, (void*)(addr+((block)?block->x64_size:1)-1), (block)?block->block:0, (block)?block->size:0, (block)?block->sons_size:0);
return block;
}
#define MAX_HOTPAGE 64
#define HOTPAGE_STEP 64
static int volatile hotpage_count[MAX_HOTPAGE] = {0};
static uintptr_t volatile hotpage[MAX_HOTPAGE] = {0};
static uintptr_t volatile hotpage_size[MAX_HOTPAGE] = {0};
static volatile int hotpages = 0;
int IsInHotPage(uintptr_t addr) {
if(!hotpages)
return 0;
for(int i=0; i<MAX_HOTPAGE; ++i) {
if((hotpage_count[i]>0) && (addr>=hotpage[i]) && (addr<hotpage[i]+0x1000*(hotpage_size[i]+1))) {
--hotpage_count[i];
if(!hotpage_count[i]) {
--hotpages;
hotpage_size[i] = 0;
dynarec_log(LOG_DEBUG, "End of Hotpage %p\n", (void*)hotpage[i]);
}
return 1;
}
}
return 0;
}
int AreaInHotPage(uintptr_t start, uintptr_t end) {
if(!hotpages)
return 0;
for(int i=0; i<MAX_HOTPAGE; ++i) {
if(hotpage_count[i]>0)
if(IntervalIntersects(start, end, hotpage[i], hotpage[i]+0x1000*(hotpage_size[i]+1)-1)) {
--hotpage_count[i];
if(!hotpage_count[i]) {
--hotpages;
hotpage_size[i] = 0;
dynarec_log(LOG_DEBUG, "End of Hotpage %p\n", (void*)hotpage[i]);
}
return 1;
}
}
return 0;
}
void AddHotPage(uintptr_t addr) {
addr&=~0xfff;
// look for same address
for(int i=0; i<MAX_HOTPAGE; ++i) {
if(addr>=hotpage[i] && addr<hotpage[i]+0x1000*(hotpage_size[i]+1)) {
if(!hotpage_count[i])
++hotpages;
hotpage_count[i] = HOTPAGE_STEP;
return;
}
if(addr==hotpage[i]+0x1000*(hotpage_size[i]+1)) {
++hotpage_size[i];
hotpage_count[i] = HOTPAGE_STEP;
return;
}
if(addr+0x1000==hotpage[i]) {
++hotpage_size[i];
hotpage[i] = addr;
hotpage_count[i] = HOTPAGE_STEP;
return;
}
}
// look for empty spot / minium
int mincnt = hotpage_count[0];
int minidx = 0;
for(int i=1; i<MAX_HOTPAGE; ++i)
if(hotpage_count[i]<mincnt) {
mincnt = hotpage_count[i];
minidx = i;
}
if(hotpage_count[minidx]) {
dynarec_log(LOG_NONE, "Warning, not enough Hotpage, replacing %p(%p/%d) with %p\n", (void*)hotpage[minidx], (void*)(0x1000*(hotpage_size[minidx]+1)), hotpage_count[minidx], (void*)addr);
hotpage_size[minidx] = 0;
} else
++hotpages;
hotpage[minidx] = addr;
hotpage_count[minidx] = HOTPAGE_STEP;
}
dynablock_t* DBGetBlock(x64emu_t* emu, uintptr_t addr, int create, dynablock_t** current)
{
dynablock_t *db = internalDBGetBlock(emu, addr, addr, create, *current);
dynablock_t *db = internalDBGetBlock(emu, addr, addr, create, *current, 1);
if(db && db->done && db->block && (db->need_test || (db->father && db->father->need_test))) {
if(pthread_mutex_trylock(&my_context->mutex_dyndump)) {
dynarec_log(LOG_DEBUG, "mutex_dyndump not available when trying to validate block %p from %p:%p (hash:%X) with %d son(s) for %p\n", db, db->x64_addr, db->x64_addr+db->x64_size-1, db->hash, db->sons_size, (void*)addr);
return NULL;
}
dynablock_t *father = db->father?db->father:db;
if(AreaInHotPage((uintptr_t)father->x64_addr, (uintptr_t)father->x64_addr + father->x64_size - 1)) {
dynarec_log(LOG_DEBUG, "Not running block %p from %p:%p with %d son(s) for %p because it's in a hotpage\n", father, father->x64_addr, father->x64_addr+father->x64_size-1, father->sons_size, (void*)addr);
pthread_mutex_unlock(&my_context->mutex_dyndump);
return NULL;
}
uint32_t hash = X31_hash_code(father->x64_addr, father->x64_size);
if(hash!=father->hash) {
dynarec_log(LOG_DEBUG, "Invalidating block %p from %p:%p (hash:%X/%X) with %d son(s) for %p\n", father, father->x64_addr, father->x64_addr+father->x64_size, hash, father->hash, father->sons_size, (void*)addr);
father->done = 0; // invalidating the block
dynarec_log(LOG_DEBUG, "Invalidating block %p from %p:%p (hash:%X/%X) with %d son(s) for %p\n", father, father->x64_addr, father->x64_addr+father->x64_size-1, hash, father->hash, father->sons_size, (void*)addr);
// no more current if it gets invalidated too
if(*current && father->x64_addr>=(*current)->x64_addr && (father->x64_addr+father->x64_size)<(*current)->x64_addr)
if(*current && IntervalIntersects(
(uintptr_t)father->x64_addr,
(uintptr_t)father->x64_addr+father->x64_size-1,
(uintptr_t)(*current)->x64_addr,
(uintptr_t)(*current)->x64_addr+(*current)->x64_size-1))
*current = NULL;
// Free father, it's now invalid!
FreeDynablock(father);
FreeDynablock(father, 0);
// start again... (will create a new block)
db = internalDBGetBlock(emu, addr, addr, create, *current);
db = internalDBGetBlock(emu, addr, addr, create, *current, 0);
} else {
father->need_test = 0;
lockDB();
protectDBnolock((uintptr_t)father->x64_addr, father->x64_size);
dynarec_log(LOG_DEBUG, "Validating block %p from %p:%p (hash:%X) with %d son(s) for %p\n", father, father->x64_addr, father->x64_addr+father->x64_size-1, father->hash, father->sons_size, (void*)addr);
protectDB((uintptr_t)father->x64_addr, father->x64_size);
// fill back jumptable
addJumpTableIfDefault64(father->x64_addr, father->block);
for(int i=0; i<father->sons_size; ++i)
addJumpTableIfDefault64(father->sons[i]->x64_addr, father->sons[i]->block);
unlockDB();
}
pthread_mutex_unlock(&my_context->mutex_dyndump);
}
return db;
}
@@ -421,26 +517,28 @@ dynablock_t* DBAlternateBlock(x64emu_t* emu, uintptr_t addr, uintptr_t filladdr)
{
dynarec_log(LOG_DEBUG, "Creating AlternateBlock at %p for %p\n", (void*)addr, (void*)filladdr);
int create = 1;
dynablock_t *db = internalDBGetBlock(emu, addr, filladdr, create, NULL);
dynablock_t *db = internalDBGetBlock(emu, addr, filladdr, create, NULL, 1);
if(db && db->done && db->block && (db->need_test || (db->father && db->father->need_test))) {
if(pthread_mutex_trylock(&my_context->mutex_dyndump))
return NULL;
dynablock_t *father = db->father?db->father:db;
uint32_t hash = X31_hash_code(father->x64_addr, father->x64_size);
if(hash!=father->hash) {
father->done = 0; // invalidating the block
dynarec_log(LOG_DEBUG, "Invalidating alt block %p from %p:%p (hash:%X/%X) with %d son(s) for %p\n", father, father->x64_addr, father->x64_addr+father->x64_size, hash, father->hash, father->sons_size, (void*)addr);
// Free father, it's now invalid!
FreeDynablock(father);
FreeDynablock(father, 0);
// start again... (will create a new block)
db = internalDBGetBlock(emu, addr, filladdr, create, NULL);
db = internalDBGetBlock(emu, addr, filladdr, create, NULL, 0);
} else {
father->need_test = 0;
lockDB();
protectDBnolock((uintptr_t)father->x64_addr, father->x64_size);
protectDB((uintptr_t)father->x64_addr, father->x64_size);
// fill back jumptable
addJumpTableIfDefault64(father->x64_addr, father->block);
for(int i=0; i<father->sons_size; ++i)
addJumpTableIfDefault64(father->sons[i]->x64_addr, father->sons[i]->block);
unlockDB();
}
pthread_mutex_unlock(&my_context->mutex_dyndump);
}
return db;
}
+2 -1
View File
@@ -29,7 +29,8 @@ typedef struct dynablock_s {
typedef struct dynablocklist_s {
uintptr_t text;
int textsz;
int maxsz; // maxblock size (for this block or previous block)
uintptr_t maxend; // max address end for anyblock on this blocklist
uintptr_t minstart; // min start address for block overlapping this blocklist
dynablock_t** direct; // direct mapping (waste of space, so the array is created at first write)
} dynablocklist_t;
+11 -7
View File
@@ -57,7 +57,7 @@ void* LinkNext(x64emu_t* emu, uintptr_t addr, void* x2, uintptr_t* x3)
if(!block) {
#ifdef HAVE_TRACE
dynablock_t* db = FindDynablockFromNativeAddress(x2-4);
printf_log(LOG_INFO, "Warning, jumping to a no-block address %p from %p (db=%p, x64addr=%p)\n", (void*)addr, x2-4, db, db?(void*)getX64Address(db, (uintptr_t)x2-4):NULL);
dynarec_log(LOG_INFO, "Warning, jumping to a no-block address %p from %p (db=%p, x64addr=%p)\n", (void*)addr, x2-4, db, db?(void*)getX64Address(db, (uintptr_t)x2-4):NULL);
#endif
//tableupdate(arm64_epilog, addr, table);
return arm64_epilog;
@@ -114,16 +114,17 @@ void DynaCall(x64emu_t* emu, uintptr_t addr)
PushExit(emu);
R_RIP = addr;
emu->df = d_none;
dynablock_t* block = NULL;
dynablock_t* current = NULL;
dynablock_t* block = DBGetBlock(emu, R_RIP, 1, &current);
current = block;
while(!emu->quit) {
block = DBGetBlock(emu, R_RIP, 1, &current);
current = block;
if(!block || !block->block || !block->done) {
// no block, of block doesn't have DynaRec content (yet, temp is not null)
// Use interpreter (should use single instruction step...)
dynarec_log(LOG_DEBUG, "%04d|Calling Interpretor @%p, emu=%p\n", GetTID(), (void*)R_RIP, emu);
Run(emu, 1);
block = DBGetBlock(emu, R_RIP, 1, &current);
current = block;
} else {
dynarec_log(LOG_DEBUG, "%04d|Calling DynaRec Block @%p (%p) of %d x64 instructions (father=%p) emu=%p\n", GetTID(), (void*)R_RIP, block->block, block->isize ,block->father, emu);
CHECK_FLAGS(emu);
@@ -131,6 +132,7 @@ void DynaCall(x64emu_t* emu, uintptr_t addr)
#ifdef ARM64
arm64_prolog(emu, block->block);
#endif
block = NULL;
}
if(emu->fork) {
int forktype = emu->fork;
@@ -194,22 +196,24 @@ int DynaRun(x64emu_t* emu)
return Run(emu, 0);
#ifdef DYNAREC
else {
dynablock_t* block = NULL;
dynablock_t* current = NULL;
dynablock_t* block = DBGetBlock(emu, R_RIP, 1, &current);;
current = block;
while(!emu->quit) {
block = DBGetBlock(emu, R_RIP, 1, &current);
current = block;
if(!block || !block->block || !block->done) {
// no block, of block doesn't have DynaRec content (yet, temp is not null)
// Use interpreter (should use single instruction step...)
dynarec_log(LOG_DEBUG, "%04d|Running Interpretor @%p, emu=%p\n", GetTID(), (void*)R_RIP, emu);
Run(emu, 1);
block = DBGetBlock(emu, R_RIP, 1, &current);
current = block;
} else {
dynarec_log(LOG_DEBUG, "%04d|Running DynaRec Block @%p (%p) of %d x64 insts (father=%p) emu=%p\n", GetTID(), (void*)R_RIP, block->block, block->isize, block->father, emu);
// block is here, let's run it!
#ifdef ARM64
arm64_prolog(emu, block->block);
#endif
block = NULL;
}
if(emu->fork) {
int forktype = emu->fork;
+66 -20
View File
@@ -58,13 +58,15 @@ void printf_x64_instruction(zydis_dec_t* dec, instruction_x64_t* inst, const cha
}
void add_next(dynarec_arm_t *dyn, uintptr_t addr) {
if(!box64_dynarec_bigblock)
return;
for(int i=0; i<dyn->next_sz; ++i)
if(dyn->next[i]==addr)
return;
if(dyn->next_sz == dyn->next_cap) {
dyn->next_cap += 16;
dyn->next = (uintptr_t*)realloc(dyn->next, dyn->next_cap*sizeof(uintptr_t));
}
for(int i=0; i<dyn->next_sz; ++i)
if(dyn->next[i]==addr)
return;
dyn->next[dyn->next_sz++] = addr;
}
uintptr_t get_closest_next(dynarec_arm_t *dyn, uintptr_t addr) {
@@ -333,28 +335,64 @@ uintptr_t arm_pass1(dynarec_arm_t* dyn, uintptr_t addr);
uintptr_t arm_pass2(dynarec_arm_t* dyn, uintptr_t addr);
uintptr_t arm_pass3(dynarec_arm_t* dyn, uintptr_t addr);
__thread void* current_helper = NULL;
void CancelBlock64()
{
dynarec_arm_t* helper = (dynarec_arm_t*)current_helper;
current_helper = NULL;
if(!helper)
return;
free(helper->next);
free(helper->insts);
free(helper->table64);
free(helper->sons_x64);
free(helper->sons_arm);
if(helper->dynablock && helper->dynablock->block)
FreeDynarecMap(helper->dynablock, (uintptr_t)helper->dynablock->block, helper->dynablock->size);
}
void* FillBlock64(dynablock_t* block, uintptr_t addr) {
if(IsInHotPage(addr)) {
dynarec_log(LOG_DEBUG, "Cancelling dynarec FillBlock on hotpage for %p\n", (void*)addr);
return NULL;
}
if(addr>=box64_nodynarec_start && addr<box64_nodynarec_end) {
block->done = 1;
return (void*)block;
}
// protect the 1st page
protectDB(addr, 1);
// init the helper
dynarec_arm_t helper = {0};
current_helper = &helper;
helper.dynablock = block;
helper.start = addr;
uintptr_t start = addr;
helper.cap = 64; // needs epilog handling
helper.insts = (instruction_arm64_t*)calloc(helper.cap, sizeof(instruction_arm64_t));
// pass 0, addresses, x86 jump addresses, overall size of the block
uintptr_t end = arm_pass0(&helper, addr);
// no need for next anymore
free(helper.next);
helper.next_sz = helper.next_cap = 0;
helper.next = NULL;
// basic checks
if(!helper.size) {
dynarec_log(LOG_DEBUG, "Warning, null-sized dynarec block (%p)\n", (void*)addr);
block->done = 1;
dynarec_log(LOG_INFO, "Warning, null-sized dynarec block (%p)\n", (void*)addr);
CancelBlock64();
return (void*)block;
}
helper.cap = helper.size+3; // needs epilog handling
helper.insts = (instruction_arm64_t*)calloc(helper.cap, sizeof(instruction_arm64_t));
// already protect the block and compute hash signature
protectDB(addr, end-addr); //end is 1byte after actual end
if(!isprotectedDB(addr, 1)) {
dynarec_log(LOG_INFO, "Warning, write on current page on pass0, aborting dynablock creation (%p)\n", (void*)addr);
CancelBlock64();
return NULL;
}
// protect the block of it goes over the 1st page
if((addr&~0xfff)!=(end&~0xfff)) // need to protect some other pages too
protectDB(addr, end-addr); //end is 1byte after actual end
// compute hash signature
uint32_t hash = X31_hash_code((void*)addr, end-addr);
// pass 1, addresses, x64 jump addresses, flags
arm_pass1(&helper, addr);
// calculate barriers
for(int i=0; i<helper.size; ++i)
if(helper.insts[i].x64.jmp) {
@@ -373,6 +411,8 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr) {
helper.insts[i].x64.jmp_insts = k;
}
}
// pass 1, flags
arm_pass1(&helper, addr);
for(int i=0; i<helper.size; ++i)
if(helper.insts[i].x64.set_flags && !helper.insts[i].x64.need_flags) {
helper.insts[i].x64.need_flags = needed_flags(&helper, i+1, helper.insts[i].x64.set_flags, 0);
@@ -386,10 +426,8 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr) {
size_t sz = helper.arm_size + helper.table64size*sizeof(uint64_t);
void* p = (void*)AllocDynarecMap(block, sz);
if(p==NULL) {
dynarec_log(LOG_DEBUG, "AllocDynarecMap(%p, %zu) failed, cancelling block\n", block, sz);
free(helper.insts);
free(helper.next);
free(helper.table64);
dynarec_log(LOG_INFO, "AllocDynarecMap(%p, %zu) failed, cancelling block\n", block, sz);
CancelBlock64();
return NULL;
}
helper.block = p;
@@ -443,8 +481,9 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr) {
}
// ok, free the helper now
free(helper.insts);
free(helper.next);
helper.insts = NULL;
free(helper.table64);
helper.table64 = NULL;
block->size = sz;
block->isize = helper.size;
block->block = p;
@@ -453,13 +492,17 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr) {
block->x64_size = end-start;
block->hash = X31_hash_code(block->x64_addr, block->x64_size);
// Check if something changed, to abbort if it as
if(block->hash != hash) {
if((block->hash != hash)) {
dynarec_log(LOG_INFO, "Warning, a block changed while beeing processed hash(%p:%ld)=%x/%x\n", block->x64_addr, block->x64_size, block->hash, hash);
free(helper.sons_x64);
free(helper.sons_arm);
FreeDynarecMap(block, (uintptr_t)p, sz);
CancelBlock64();
return NULL;
} // fill sons if any
if(!isprotectedDB(addr, end-addr)) {
dynarec_log(LOG_INFO, "Warning, block unprotected while beeing processed %p:%ld, cancelling\n", block->x64_addr, block->x64_size);
CancelBlock64();
return NULL;
//protectDB(addr, end-addr);
}
dynablock_t** sons = NULL;
int sons_size = 0;
if(helper.sons_size) {
@@ -488,7 +531,10 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr) {
free(sons);
}
free(helper.sons_x64);
helper.sons_x64 = NULL;
free(helper.sons_arm);
helper.sons_arm = NULL;
current_helper = NULL;
//block->done = 1;
return (void*)block;
}
+44 -44
View File
@@ -639,17 +639,15 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
BARRIER(2); \
JUMP(addr+i8);\
GETFLAGS; \
if(dyn->insts) { \
if(dyn->insts[ninst].x64.jmp_insts==-1) { \
/* out of the block */ \
i32 = dyn->insts[ninst+1].address-(dyn->arm_size); \
Bcond(NO, i32); \
jump_to_next(dyn, addr+i8, 0, ninst); \
} else { \
/* inside the block */ \
i32 = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address-(dyn->arm_size); \
Bcond(YES, i32); \
} \
if(dyn->insts[ninst].x64.jmp_insts==-1) { \
/* out of the block */ \
i32 = dyn->insts[ninst+1].address-(dyn->arm_size); \
Bcond(NO, i32); \
jump_to_next(dyn, addr+i8, 0, ninst); \
} else { \
/* inside the block */ \
i32 = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address-(dyn->arm_size); \
Bcond(YES, i32); \
}
GOCOND(0x70, "J", "ib");
@@ -846,6 +844,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
BFIx(gb1, x1, gb2*8, 8);
BFIx(eb1, x4, eb2*8, 8);
} else {
DMB_ISH();
GETGB(x4);
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0, rex, 0, 0);
MARKLOCK;
@@ -854,6 +853,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
// do the swap 14 -> strb(ed), 1 -> gd
STLXRB(x3, x4, ed);
CBNZx_MARKLOCK(x3);
DMB_ISH();
BFIx(gb1, x1, gb2*8, 8);
}
break;
@@ -869,6 +869,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
} else {
GETGD;
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0, rex, 0, 0);
DMB_ISH();
TSTx_mask(ed, 1, 0, 1+rex.w); // mask=3 or 7
B_MARK(cNE);
MARKLOCK;
@@ -880,6 +881,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
LDRxw_U12(x1, ed, 0);
STRxw_U12(gd, ed, 0);
MARK2;
DMB_ISH();
MOVxw_REG(gd, x1);
}
break;
@@ -953,6 +955,10 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
ed = wback;
}
} else {
if(box64_dynarec_strongmem &&
(dyn->insts[ninst].x64.barrier || !ninst || box64_dynarec_strongmem>1 || (ninst && dyn->insts[ninst-1].x64.barrier))) {
DMB_ISH();
}
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0xfff, 0, rex, 0, 0);
LDRB_U12(x4, wback, fixedaddress);
ed = x4;
@@ -963,9 +969,13 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("MOV Gd, Ed");
nextop=F8;
GETGD;
if(MODREG) { // reg <= reg
if(MODREG) {
MOVxw_REG(gd, xRAX+(nextop&7)+(rex.b<<3));
} else { // mem <= reg
} else {
if(box64_dynarec_strongmem &&
(dyn->insts[ninst].x64.barrier || !ninst || box64_dynarec_strongmem>1 || (ninst && dyn->insts[ninst-1].x64.barrier))) {
DMB_ISH();
}
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, 0, 0);
LDRxw_U12(gd, ed, fixedaddress);
}
@@ -1970,17 +1980,15 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
#define GO(Z) \
BARRIER(2); \
JUMP(addr+i8); \
if(dyn->insts) { \
if(dyn->insts[ninst].x64.jmp_insts==-1) { \
/* out of the block */ \
i32 = dyn->insts[ninst+1].address-(dyn->arm_size); \
if(Z) {CBNZx(xRCX, i32);} else {CBZx(xRCX, i32);}; \
jump_to_next(dyn, addr+i8, 0, ninst); \
} else { \
/* inside the block */ \
i32 = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address-(dyn->arm_size); \
if(Z) {CBZx(xRCX, i32);} else {CBNZx(xRCX, i32);}; \
} \
if(dyn->insts[ninst].x64.jmp_insts==-1) { \
/* out of the block */ \
i32 = dyn->insts[ninst+1].address-(dyn->arm_size); \
if(Z) {CBNZx(xRCX, i32);} else {CBZx(xRCX, i32);}; \
jump_to_next(dyn, addr+i8, 0, ninst); \
} else { \
/* inside the block */ \
i32 = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address-(dyn->arm_size); \
if(Z) {CBZx(xRCX, i32);} else {CBNZx(xRCX, i32);}; \
}
case 0xE0:
INST_NAME("LOOPNZ");
@@ -2019,12 +2027,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
printf_log(LOG_INFO, "Warning, CALL to 0x0 at %p (%p)\n", (void*)addr, (void*)(addr-1));
#endif
}
#if STEP == 0
if(isNativeCall(dyn, addr+i32, NULL, NULL))
tmp = 3;
else
tmp = 0;
#elif STEP < 2
#if STEP < 2
if(isNativeCall(dyn, addr+i32, &dyn->insts[ninst].natcall, &dyn->insts[ninst].retn))
tmp = dyn->insts[ninst].pass2choice = 3;
else
@@ -2042,7 +2045,7 @@ 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);
if(box64_log<2 && dyn->insts && (tmp=isSimpleWrapper(*(wrapper_t*)(dyn->insts[ninst].natcall+2)))) {
if(box64_log<2 && dyn->insts[ninst].natcall && (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
@@ -2104,18 +2107,16 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
i32 = F8S;
}
JUMP(addr+i32);
if(dyn->insts) {
PASS2IF(dyn->insts[ninst].x64.jmp_insts==-1, 1) {
// out of the block
jump_to_next(dyn, addr+i32, 0, ninst);
PASS2IF(dyn->insts[ninst].x64.jmp_insts==-1, 1) {
// out of the block
jump_to_next(dyn, addr+i32, 0, ninst);
} else {
// inside the block
tmp = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address-(dyn->arm_size);
if(tmp==4) {
NOP;
} else {
// inside the block
tmp = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address-(dyn->arm_size);
if(tmp==4) {
NOP;
} else {
B(tmp);
}
B(tmp);
}
}
*need_epilog = 0;
@@ -2384,8 +2385,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 2: // CALL Ed
INST_NAME("CALL Ed");
PASS2IF(dyn->insts &&
((ninst && dyn->insts[ninst-1].x64.set_flags)
PASS2IF(((ninst && dyn->insts[ninst-1].x64.set_flags)
|| ((ninst>1) && dyn->insts[ninst-2].x64.set_flags)), 1)
{
READFLAGS(X_PEND); // that's suspicious
+10 -12
View File
@@ -992,18 +992,16 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
BARRIER(2); \
JUMP(addr+i32_);\
GETFLAGS; \
if(dyn->insts) { \
if(dyn->insts[ninst].x64.jmp_insts==-1) { \
/* out of the block */ \
i32 = dyn->insts[ninst+1].address-(dyn->arm_size); \
Bcond(NO, i32); \
jump_to_next(dyn, addr+i32_, 0, ninst); \
} else { \
/* inside the block */ \
i32 = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address-(dyn->arm_size); \
Bcond(YES, i32); \
} \
}
if(dyn->insts[ninst].x64.jmp_insts==-1) { \
/* out of the block */ \
i32 = dyn->insts[ninst+1].address-(dyn->arm_size); \
Bcond(NO, i32); \
jump_to_next(dyn, addr+i32_, 0, ninst); \
} else { \
/* inside the block */ \
i32 = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address-(dyn->arm_size); \
Bcond(YES, i32); \
} \
GOCOND(0x80, "J", "Id");
#undef GO
+1 -2
View File
@@ -801,8 +801,7 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
break;
case 2: // CALL Ed
INST_NAME("CALL Ed");
PASS2IF(dyn->insts &&
((ninst && dyn->insts[ninst-1].x64.set_flags)
PASS2IF(((ninst && dyn->insts[ninst-1].x64.set_flags)
|| ((ninst>1) && dyn->insts[ninst-2].x64.set_flags)), 1)
{
READFLAGS(X_PEND); // that's suspicious
+9 -11
View File
@@ -227,17 +227,15 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
#define GO(NO, YES) \
BARRIER(2); \
JUMP(addr+i8);\
if(dyn->insts) { \
if(dyn->insts[ninst].x64.jmp_insts==-1) { \
/* out of the block */ \
i32 = dyn->insts[ninst+1].address-(dyn->arm_size); \
Bcond(NO, i32); \
jump_to_next(dyn, addr+i8, 0, ninst); \
} else { \
/* inside the block */ \
i32 = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address-(dyn->arm_size); \
Bcond(YES, i32); \
} \
if(dyn->insts[ninst].x64.jmp_insts==-1) { \
/* out of the block */ \
i32 = dyn->insts[ninst+1].address-(dyn->arm_size); \
Bcond(NO, i32); \
jump_to_next(dyn, addr+i8, 0, ninst); \
} else { \
/* inside the block */ \
i32 = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address-(dyn->arm_size); \
Bcond(YES, i32); \
}
case 0xE0:
INST_NAME("LOOPNZ (32bits)");
+26
View File
@@ -56,6 +56,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("LOCK ADD Eb, Gb");
SETFLAGS(X_ALL, SF_SET_PENDING);
nextop = F8;
DMB_ISH();
GETGB(x2);
if((nextop&0xC0)==0xC0) {
if(rex.rex) {
@@ -77,12 +78,14 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
STLXRB(x4, x1, wback);
CBNZx_MARKLOCK(x4);
}
DMB_ISH();
break;
case 0x01:
INST_NAME("LOCK ADD Ed, Gd");
SETFLAGS(X_ALL, SF_SET_PENDING);
nextop = F8;
GETGD;
DMB_ISH();
if((nextop&0xC0)==0xC0) {
ed = xRAX+(nextop&7)+(rex.b<<3);
emit_add32(dyn, ninst, rex, ed, gd, x3, x4);
@@ -94,6 +97,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
STLXRxw(x3, x1, wback);
CBNZx_MARKLOCK(x3);
}
DMB_ISH();
break;
case 0x09:
@@ -101,6 +105,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SETFLAGS(X_ALL, SF_SET_PENDING);
nextop = F8;
GETGD;
DMB_ISH();
if(MODREG) {
ed = xRAX+(nextop&7)+(rex.b<<3);
emit_or32(dyn, ninst, rex, ed, gd, x3, x4);
@@ -112,6 +117,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
STLXRxw(x3, x1, wback);
CBNZx_MARKLOCK(x3);
}
DMB_ISH();
break;
case 0x0F:
@@ -123,6 +129,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SETFLAGS(X_ALL, SF_SET_PENDING);
nextop = F8;
GETGD;
DMB_ISH();
if(MODREG) {
ed = xRAX+(nextop&7)+(rex.b<<3);
wback = 0;
@@ -163,6 +170,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
UFLAG_IF {emit_cmp32(dyn, ninst, rex, xRAX, x1, x3, x4, x5);}
MOVxw_REG(xRAX, x1); // upper par of RAX will be erase on 32bits, no mater what
}
DMB_ISH();
break;
case 0xC1:
@@ -170,6 +178,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SETFLAGS(X_ALL, SF_SET_PENDING);
nextop = F8;
GETGD;
DMB_ISH();
if(MODREG) {
ed = xRAX+(nextop&7)+(rex.b<<3);
MOVxw_REG(x1, ed);
@@ -201,6 +210,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
MOVxw_REG(gd, x1);
}
DMB_ISH();
break;
case 0xC7:
@@ -208,6 +218,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SETFLAGS(X_ZF, SF_SUBSET);
nextop = F8;
addr = geted(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, 0, 0, rex, 0, 0);
DMB_ISH();
MARKLOCK;
LDAXPxw(x2, x3, wback);
CMPSxw_REG(xRAX, x2);
@@ -223,6 +234,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MOVxw_REG(xRDX, x3);
MOV32w(x1, 0);
MARK3;
DMB_ISH();
BFIw(xFlags, x1, F_ZF, 1);
break;
@@ -236,6 +248,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SETFLAGS(X_ALL, SF_SET_PENDING);
nextop = F8;
GETGD;
DMB_ISH();
if(MODREG) {
ed = xRAX+(nextop&7)+(rex.b<<3);
emit_sub32(dyn, ninst, rex, ed, gd, x3, x4);
@@ -247,6 +260,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
STLXRxw(x3, x1, wback);
CBNZx_MARKLOCK(x3);
}
DMB_ISH();
break;
case 0x66:
@@ -255,6 +269,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 0x81:
case 0x83:
nextop = F8;
DMB_ISH();
switch((nextop>>3)&7) {
case 0: //ADD
if(opcode==0x81) {
@@ -448,6 +463,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
break;
}
DMB_ISH();
break;
default:
DEFAULT;
@@ -456,6 +472,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 0x80:
nextop = F8;
DMB_ISH();
switch((nextop>>3)&7) {
case 0: //ADD
INST_NAME("ADD Eb, Ib");
@@ -614,10 +631,12 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
default:
DEFAULT;
}
DMB_ISH();
break;
case 0x81:
case 0x83:
nextop = F8;
DMB_ISH();
switch((nextop>>3)&7) {
case 0: //ADD
if(opcode==0x81) {
@@ -794,6 +813,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
break;
}
DMB_ISH();
break;
case 0x87:
@@ -807,6 +827,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
MOVxw_REG(ed, x1);
} else {
GETGD;
DMB_ISH();
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0, rex, 0, 0);
TSTx_mask(ed, 1, 0, 1+rex.w); // mask=3 or 7
B_MARK(cNE);
@@ -819,6 +840,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
LDRxw_U12(x1, ed, 0);
STRxw_U12(gd, ed, 0);
MARK2;
DMB_ISH();
MOVxw_REG(gd, x1);
}
break;
@@ -830,6 +852,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 0: // INC Ed
INST_NAME("LOCK INC Ed");
SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
DMB_ISH();
if(MODREG) {
ed = xRAX+(nextop&7)+(rex.b<<3);
emit_inc32(dyn, ninst, rex, ed, x3, x4);
@@ -852,10 +875,12 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
CBNZw_MARK(x3);
STRxw_U12(x1, wback, 0);
}
DMB_ISH();
break;
case 1: //DEC Ed
INST_NAME("LOCK DEC Ed");
SETFLAGS(X_ALL&~X_CF, SF_SUBSET);
DMB_ISH();
if(MODREG) {
ed = xRAX+(nextop&7)+(rex.b<<3);
emit_dec32(dyn, ninst, rex, ed, x3, x4);
@@ -878,6 +903,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
CBNZw_MARK(x3);
STRxw_U12(x1, wback, 0);
}
DMB_ISH();
break;
default:
DEFAULT;
+19 -11
View File
@@ -49,7 +49,7 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
uint8_t gd, ed;
uint8_t wback;
uint8_t u8;
uint64_t u64;
uint64_t u64, j64;
int v0, v1;
int q0;
int d0, d1;
@@ -214,9 +214,15 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
v0 = sse_get_reg(dyn, ninst, x1, gd);
GETEX(v1, 0);
// MINSD: if any input is NaN, or Ex[0]<Gx[0], copy Ex[0] -> Gx[0]
#if 0
d0 = fpu_get_scratch(dyn);
FMINNMD(d0, v0, v1); // NaN handling may be slightly different, is that a problem?
VMOVeD(v0, 0, d0, 0); // to not erase uper part
#else
FCMPD(v0, v1);
B_NEXT(cLS); //Less than or equal
VMOVeD(v0, 0, v1, 0); // to not erase uper part
#endif
break;
case 0x5E:
INST_NAME("DIVSD Gx, Ex");
@@ -234,9 +240,15 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
v0 = sse_get_reg(dyn, ninst, x1, gd);
GETEX(v1, 0);
// MAXSD: if any input is NaN, or Ex[0]>Gx[0], copy Ex[0] -> Gx[0]
#if 0
d0 = fpu_get_scratch(dyn);
FMAXNMD(d0, v0, v1); // NaN handling may be slightly different, is that a problem?
VMOVeD(v0, 0, d0, 0); // to not erase uper part
#else
FCMPD(v0, v1);
B_NEXT(cGE); //Greater than or equal
VMOVeD(v0, 0, v1, 0); // to not erase uper part
#endif
break;
case 0x70:
@@ -282,19 +294,15 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
GETGX(v0);
GETEX(v1, 1);
u8 = F8;
if((u8&7)==6){
FCMPD(v1, v0);
} else {
FCMPD(v0, v1);
}
FCMPD(v0, v1);
switch(u8&7) {
case 0: CSETMx(x2, cEQ); CSELx(x2, xZR, x2, cVS); break; // Equal
case 1: CSETMx(x2, cMI); CSELx(x2, xZR, x2, cVS); break; // Less than
case 2: CSETMx(x2, cLE); CSELx(x2, xZR, x2, cVS); break; // Less or equal
case 0: CSETMx(x2, cEQ); break; // Equal
case 1: CSETMx(x2, cCC); break; // Less than
case 2: CSETMx(x2, cLS); break; // Less or equal
case 3: CSETMx(x2, cVS); break; // NaN
case 4: CSETMx(x2, cNE); break; // Not Equal
case 4: CSETMx(x2, cNE); break; // Not Equal or unordered
case 5: CSETMx(x2, cCS); break; // Greater or equal or unordered
case 6: CSETMx(x2, cLT); break; // Greater or unordered, test inverted, N!=V so unordered or less than (inverted)
case 6: CSETMx(x2, cHI); break; // Greater or unordered, test inverted, N!=V so unordered or less than (inverted)
case 7: CSETMx(x2, cVC); break; // not NaN
}
VMOVQDfrom(v0, 0, x2);
+18 -10
View File
@@ -259,9 +259,15 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
GETGX(v0);
GETEX(v1, 0);
// MINSS: if any input is NaN, or Ex[0]<Gx[0], copy Ex[0] -> Gx[0]
#if 0
d0 = fpu_get_scratch(dyn);
FMINNMS(d0, v0, v1); // NaN handling may be slightly different, is that a problem?
VMOVeS(v0, 0, d0, 0); // to not erase uper part
#else
FCMPS(v0, v1);
B_NEXT(cLS); //Less than or equal
VMOVeS(v0, 0, v1, 0); // to not erase uper part
#endif
break;
case 0x5E:
INST_NAME("DIVSS Gx, Ex");
@@ -278,9 +284,15 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
GETGX(v0);
GETEX(v1, 0);
// MAXSS: if any input is NaN, or Ex[0]>Gx[0], copy Ex[0] -> Gx[0]
#if 0
d0 = fpu_get_scratch(dyn);
FMAXNMS(d0, v0, v1); // NaN handling may be slightly different, is that a problem?
VMOVeS(v0, 0, d0, 0); // to not erase uper part
#else
FCMPS(v0, v1);
B_NEXT(cGE); //Greater than or equal
VMOVeS(v0, 0, v1, 0); // to not erase uper part
#endif
break;
case 0x6F:
@@ -384,19 +396,15 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
GETGX(v0);
GETEX(v1, 1);
u8 = F8;
if((u8&7)==6){
FCMPS(v1, v0);
} else {
FCMPS(v0, v1);
}
FCMPS(v0, v1);
switch(u8&7) {
case 0: CSETMw(x2, cEQ); CSELw(x2, xZR, x2, cVS); break; // Equal
case 1: CSETMw(x2, cMI); CSELw(x2, xZR, x2, cVS); break; // Less than
case 2: CSETMw(x2, cLE); CSELw(x2, xZR, x2, cVS); break; // Less or equal
case 0: CSETMw(x2, cEQ); break; // Equal
case 1: CSETMw(x2, cCC); break; // Less than
case 2: CSETMw(x2, cLS); break; // Less or equal
case 3: CSETMw(x2, cVS); break; // NaN
case 4: CSETMw(x2, cNE); break; // Not Equal
case 4: CSETMw(x2, cNE); break; // Not Equal or unordered
case 5: CSETMw(x2, cCS); break; // Greater or equal or unordered
case 6: CSETMw(x2, cLT); break; // Greater or unordered, test inverted, N!=V so unordered or less than (inverted)
case 6: CSETMw(x2, cHI); break; // Greater or unordered, test inverted, N!=V so unordered or less than (inverted)
case 7: CSETMw(x2, cVC); break; // not NaN
}
VMOVQSfrom(v0, 0, x2);
+23 -23
View File
@@ -312,18 +312,18 @@
// R0 will not be pushed/popd if ret is -2. Flags are not save/restored
#define CALL_S(F, ret) call_c(dyn, ninst, F, x7, ret, 0, 0)
#define MARK if(dyn->insts) {dyn->insts[ninst].mark = dyn->arm_size;}
#define GETMARK ((dyn->insts)?dyn->insts[ninst].mark:(dyn->arm_size+4))
#define MARK2 if(dyn->insts) {dyn->insts[ninst].mark2 = dyn->arm_size;}
#define GETMARK2 ((dyn->insts)?dyn->insts[ninst].mark2:(dyn->arm_size+4))
#define MARK3 if(dyn->insts) {dyn->insts[ninst].mark3 = dyn->arm_size;}
#define GETMARK3 ((dyn->insts)?dyn->insts[ninst].mark3:(dyn->arm_size+4))
#define MARKF if(dyn->insts) {dyn->insts[ninst].markf = dyn->arm_size;}
#define GETMARKF ((dyn->insts)?dyn->insts[ninst].markf:(dyn->arm_size+4))
#define MARKSEG if(dyn->insts) {dyn->insts[ninst].markseg = dyn->arm_size;}
#define GETMARKSEG ((dyn->insts)?dyn->insts[ninst].markseg:(dyn->arm_size+4))
#define MARKLOCK if(dyn->insts) {dyn->insts[ninst].marklock = dyn->arm_size;}
#define GETMARKLOCK ((dyn->insts)?dyn->insts[ninst].marklock:(dyn->arm_size+4))
#define MARK dyn->insts[ninst].mark = dyn->arm_size
#define GETMARK dyn->insts[ninst].mark
#define MARK2 dyn->insts[ninst].mark2 = dyn->arm_size
#define GETMARK2 dyn->insts[ninst].mark2
#define MARK3 dyn->insts[ninst].mark3 = dyn->arm_size
#define GETMARK3 dyn->insts[ninst].mark3
#define MARKF dyn->insts[ninst].markf = dyn->arm_size
#define GETMARKF dyn->insts[ninst].markf
#define MARKSEG dyn->insts[ninst].markseg = dyn->arm_size
#define GETMARKSEG dyn->insts[ninst].markseg
#define MARKLOCK dyn->insts[ninst].marklock = dyn->arm_size
#define GETMARKLOCK dyn->insts[ninst].marklock
// Branch to MARK if cond (use j64)
#define B_MARK(cond) \
@@ -430,11 +430,11 @@
j64 = GETMARKLOCK-(dyn->arm_size); \
CBNZx(reg, j64)
#define IFX(A) if(dyn->insts && (dyn->insts[ninst].x64.need_flags&(A)))
#define IFX_PENDOR0 if(dyn->insts && (dyn->insts[ninst].x64.need_flags&(X_PEND) || !dyn->insts[ninst].x64.need_flags))
#define IFXX(A) if(dyn->insts && (dyn->insts[ninst].x64.need_flags==(A)))
#define IFX2X(A, B) if(dyn->insts && (dyn->insts[ninst].x64.need_flags==(A) || dyn->insts[ninst].x64.need_flags==(B) || dyn->insts[ninst].x64.need_flags==((A)|(B))))
#define IFXN(A, B) if(dyn->insts && (dyn->insts[ninst].x64.need_flags&(A) && !(dyn->insts[ninst].x64.need_flags&(B))))
#define IFX(A) if((dyn->insts[ninst].x64.need_flags&(A)))
#define IFX_PENDOR0 if((dyn->insts[ninst].x64.need_flags&(X_PEND) || !dyn->insts[ninst].x64.need_flags))
#define IFXX(A) if((dyn->insts[ninst].x64.need_flags==(A)))
#define IFX2X(A, B) if((dyn->insts[ninst].x64.need_flags==(A) || dyn->insts[ninst].x64.need_flags==(B) || dyn->insts[ninst].x64.need_flags==((A)|(B))))
#define IFXN(A, B) if((dyn->insts[ninst].x64.need_flags&(A) && !(dyn->insts[ninst].x64.need_flags&(B))))
// Generate FCOM with s1 and s2 scratch regs (the VCMP is already done)
#define FCOM(s1, s2, s3) \
@@ -589,12 +589,12 @@
#ifndef BARRIER_NEXT
#define BARRIER_NEXT(A)
#endif
#define UFLAG_OP1(A) if(dyn->insts && dyn->insts[ninst].x64.need_flags) {STRxw_U12(A, xEmu, offsetof(x64emu_t, op1));}
#define UFLAG_OP2(A) if(dyn->insts && dyn->insts[ninst].x64.need_flags) {STRxw_U12(A, xEmu, offsetof(x64emu_t, op2));}
#define UFLAG_OP12(A1, A2) if(dyn->insts && dyn->insts[ninst].x64.need_flags) {STRxw_U12(A1, xEmu, offsetof(x64emu_t, op1));STRxw_U12(A2, 0, offsetof(x64emu_t, op2));}
#define UFLAG_RES(A) if(dyn->insts && dyn->insts[ninst].x64.need_flags) {STRxw_U12(A, xEmu, offsetof(x64emu_t, res));}
#define UFLAG_DF(r, A) if(dyn->insts && dyn->insts[ninst].x64.need_flags) {SET_DF(r, A)}
#define UFLAG_IF if(dyn->insts && dyn->insts[ninst].x64.need_flags)
#define UFLAG_OP1(A) if(dyn->insts[ninst].x64.need_flags) {STRxw_U12(A, xEmu, offsetof(x64emu_t, op1));}
#define UFLAG_OP2(A) if(dyn->insts[ninst].x64.need_flags) {STRxw_U12(A, xEmu, offsetof(x64emu_t, op2));}
#define UFLAG_OP12(A1, A2) if(dyn->insts[ninst].x64.need_flags) {STRxw_U12(A1, xEmu, offsetof(x64emu_t, op1));STRxw_U12(A2, 0, offsetof(x64emu_t, op2));}
#define UFLAG_RES(A) if(dyn->insts[ninst].x64.need_flags) {STRxw_U12(A, xEmu, offsetof(x64emu_t, res));}
#define UFLAG_DF(r, A) if(dyn->insts[ninst].x64.need_flags) {SET_DF(r, A)}
#define UFLAG_IF if(dyn->insts[ninst].x64.need_flags)
#ifndef DEFAULT
#define DEFAULT *ok = -1; BARRIER(2)
#endif
+8 -4
View File
@@ -3,6 +3,7 @@
#include <stddef.h>
#include <pthread.h>
#include <errno.h>
#include <string.h>
#include "debug.h"
#include "box64context.h"
@@ -14,6 +15,7 @@
#include "box64stack.h"
#include "emu/x64run_private.h"
#include "x64trace.h"
#include "dynablock.h"
#include "dynarec_arm64.h"
#include "dynarec_arm64_private.h"
#include "arm64_printer.h"
@@ -45,7 +47,7 @@ uintptr_t arm_pass(dynarec_arm_t* dyn, uintptr_t addr)
INIT;
while(ok) {
ip = addr;
if(dyn->insts && (dyn->insts[ninst].x64.barrier==1)) {
if((dyn->insts[ninst].x64.barrier==1)) {
dyn->last_ip = 0;
NEW_BARRIER_INST;
}
@@ -90,17 +92,18 @@ uintptr_t arm_pass(dynarec_arm_t* dyn, uintptr_t addr)
INST_EPILOG;
if(dyn->insts && dyn->insts[ninst+1].x64.barrier) {
if(dyn->insts[ninst+1].x64.barrier) {
fpu_purgecache(dyn, ninst, x1, x2, x3);
if(dyn->insts[ninst+1].x64.barrier!=2) {
dyn->state_flags = 0;
dyn->dfnone = 0;
}
}
if(!ok && !need_epilog && dyn->insts && (addr < (dyn->start+dyn->isize))) {
if(!ok && !need_epilog && (addr < (dyn->start+dyn->isize))) {
ok = 1;
}
if(!ok && !need_epilog && !dyn->insts && getProtection(addr+3)&~PROT_CUSTOM)
#if STEP == 0
if(!ok && !need_epilog && box64_dynarec_bigblock && getProtection(addr+3)&~PROT_CUSTOM && !IsInHotPage(addr+3))
if(*(uint32_t*)addr!=0) { // check if need to continue (but is next 4 bytes are 0, stop)
uintptr_t next = get_closest_next(dyn, addr);
if(next && (
@@ -113,6 +116,7 @@ uintptr_t arm_pass(dynarec_arm_t* dyn, uintptr_t addr)
dynarec_log(LOG_DEBUG, "Cannot extend block %p -> %p (%02X %02X %02X %02X %02X %02X %02X %02x)\n", (void*)addr, (void*)next, PK(0), PK(1), PK(2), PK(3), PK(4), PK(5), PK(6), PK(7));
}
}
#endif
if(ok<0) {ok = 0; need_epilog=1;}
++ninst;
#if STEP == 0
+10 -2
View File
@@ -5,8 +5,16 @@
#define SETFLAGS(A, B)
#define READFLAGS(A)
#define EMIT(A)
#define JUMP(A) add_next(dyn, (uintptr_t)A)
#define NEW_INST ++dyn->size
#define JUMP(A) add_next(dyn, (uintptr_t)A); dyn->insts[ninst].x64.jmp = A
#define BARRIER(A) dyn->insts[ninst].x64.barrier = A
#define BARRIER_NEXT(A) if(ninst<dyn->size) dyn->insts[ninst+1].x64.barrier = A
#define NEW_INST \
if(dyn->size+3>=dyn->cap) { \
dyn->insts = (instruction_arm64_t*)realloc(dyn->insts, sizeof(instruction_arm64_t)*dyn->cap*2); \
memset(&dyn->insts[dyn->cap], 0, sizeof(instruction_arm64_t)*dyn->cap); \
dyn->cap *= 2; \
} \
++dyn->size
#define INST_EPILOG
#define INST_NAME(name)
#define DEFAULT \
+1 -4
View File
@@ -6,12 +6,9 @@
#define EMIT(A)
#define READFLAGS(A) dyn->insts[ninst].x64.use_flags = A
#define SETFLAGS(A,B) {dyn->insts[ninst].x64.set_flags = A; dyn->insts[ninst].x64.state_flags = B;}
#define JUMP(A) dyn->insts[ninst].x64.jmp = A
#define BARRIER(A) dyn->insts[ninst].x64.barrier = A
#define BARRIER_NEXT(A) if(ninst<dyn->size) dyn->insts[ninst+1].x64.barrier = A
#define NEW_INST \
dyn->insts[ninst].x64.addr = ip; \
if(ninst) dyn->insts[ninst-1].x64.size = dyn->insts[ninst].x64.addr - dyn->insts[ninst-1].x64.addr;
#define INST_EPILOG
#define INST_EPILOG
#define INST_NAME(name)
+3 -1
View File
@@ -4,8 +4,9 @@
#include "dynarec_private.h"
typedef struct x64emu_s x64emu_t;
typedef struct dynablock_s dynablock_t;
typedef struct instruction_arm_s {
typedef struct instruction_arm64_s {
instruction_x64_t x64;
uintptr_t address; // (start) address of the arm emited instruction
uintptr_t epilog; // epilog of current instruction (can be start of next, of barrier stuff)
@@ -50,6 +51,7 @@ typedef struct dynarec_arm_s {
uintptr_t* sons_x64; // the x64 address of potential dynablock sons
void** sons_arm; // the arm address of potential dynablock sons
int sons_size; // number of potential dynablock sons
dynablock_t* dynablock;
} dynarec_arm_t;
void add_next(dynarec_arm_t *dyn, uintptr_t addr);
+1 -1
View File
@@ -185,7 +185,7 @@ int AllocElfMemory(box64context_t* context, elfheader_t* head, int mainbin)
uintptr_t end = head->multiblock_offs[j] + head->multiblock_size[j];
start &= ~balign;
if( (head->e_type == ET_DYN) ||
(((bstart>=start) && (bstart<=end)) || ((bend>=start) && (bend<=end)) || ((bstart<start) && (bend>end))))
(((bstart>=start) && (bstart<=end+0x1000)) || ((bend>=start) && (bend<=end)) || ((bstart<start) && (bend>end))))
{
// merge
ok = 1;
+3 -3
View File
@@ -218,10 +218,10 @@ int RunF20F(x64emu_t *emu, rex_t rex)
tmp8s = 0;
switch(tmp8u&7) {
case 0: tmp8s=(GX->d[0] == EX->d[0]); break;
case 1: tmp8s=isless(GX->d[0], EX->d[0]); break;
case 2: tmp8s=islessequal(GX->d[0], EX->d[0]); break;
case 1: tmp8s=isless(GX->d[0], EX->d[0]) && !(isnan(GX->d[0]) || isnan(EX->d[0])); break;
case 2: tmp8s=islessequal(GX->d[0], EX->d[0]) && !(isnan(GX->d[0]) || isnan(EX->d[0])); break;
case 3: tmp8s=isnan(GX->d[0]) || isnan(EX->d[0]); break;
case 4: tmp8s=(GX->d[0] != EX->d[0]); break;
case 4: tmp8s=isnan(GX->d[0]) || isnan(EX->d[0]) || (GX->d[0] != EX->d[0]); break;
case 5: tmp8s=isnan(GX->d[0]) || isnan(EX->d[0]) || isgreaterequal(GX->d[0], EX->d[0]); break;
case 6: tmp8s=isnan(GX->d[0]) || isnan(EX->d[0]) || isgreater(GX->d[0], EX->d[0]); break;
case 7: tmp8s=!isnan(GX->d[0]) && !isnan(EX->d[0]); break;
+3 -3
View File
@@ -318,10 +318,10 @@ int RunF30F(x64emu_t *emu, rex_t rex)
tmp8s = 0;
switch(tmp8u&7) {
case 0: tmp8s=(GX->f[0] == EX->f[0]); break;
case 1: tmp8s=isless(GX->f[0], EX->f[0]); break;
case 2: tmp8s=islessequal(GX->f[0], EX->f[0]); break;
case 1: tmp8s=isless(GX->f[0], EX->f[0]) && !(isnan(GX->f[0]) || isnan(EX->f[0])); break;
case 2: tmp8s=islessequal(GX->f[0], EX->f[0]) && !(isnan(GX->f[0]) || isnan(EX->f[0])); break;
case 3: tmp8s=isnan(GX->f[0]) || isnan(EX->f[0]); break;
case 4: tmp8s=(GX->f[0] != EX->f[0]); break;
case 4: tmp8s=isnan(GX->f[0]) || isnan(EX->f[0]) || (GX->f[0] != EX->f[0]); break;
case 5: tmp8s=isnan(GX->f[0]) || isnan(EX->f[0]) || isgreaterequal(GX->f[0], EX->f[0]); break;
case 6: tmp8s=isnan(GX->f[0]) || isnan(EX->f[0]) || isgreater(GX->f[0], EX->f[0]); break;
case 7: tmp8s=!isnan(GX->f[0]) && !isnan(EX->f[0]); break;
+1 -3
View File
@@ -45,10 +45,8 @@ 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);
void unprotectDB(uintptr_t addr, size_t size);
void lockDB();
void unlockDB();
int isprotectedDB(uintptr_t addr, size_t size);
#endif
void* find32bitBlock(size_t size);
void* findBlockNearHint(void* hint, size_t size);
+2
View File
@@ -13,6 +13,8 @@ extern int box64_dynarec_dump;
extern int box64_dynarec_trace;
extern int box64_dynarec_forced;
extern uintptr_t box64_nodynarec_start, box64_nodynarec_end;
extern int box64_dynarec_bigblock;
extern int box64_dynarec_strongmem;
#ifdef ARM64
extern int arm64_asimd;
extern int arm64_aes;
+3 -1
View File
@@ -9,7 +9,7 @@ typedef struct kh_dynablocks_s kh_dynablocks_t;
uint32_t X31_hash_code(void* addr, int len);
dynablocklist_t* NewDynablockList(uintptr_t text, int textsz, int direct);
void FreeDynablockList(dynablocklist_t** dynablocks);
void FreeDynablock(dynablock_t* db);
void FreeDynablock(dynablock_t* db, int need_lock);
void MarkDynablock(dynablock_t* db);
//return 1 if Dynareblock is empty
int FreeRangeDynablock(dynablocklist_t* dynablocks, uintptr_t addr, uintptr_t size);
@@ -31,5 +31,7 @@ dynablock_t *AddNewDynablock(dynablocklist_t* dynablocks, uintptr_t addr, int* c
// for use in signal handler
void cancelFillBlock();
int IsInHotPage(uintptr_t addr);
void AddHotPage(uintptr_t addr);
#endif //__DYNABLOCK_H_
+1
View File
@@ -4,6 +4,7 @@
typedef struct dynablock_s dynablock_t;
typedef struct x64emu_s x64emu_t;
void CancelBlock64();
void* FillBlock64(dynablock_t* block, uintptr_t addr);
#endif //__DYNAREC_ARM_H_
+1 -11
View File
@@ -90,17 +90,7 @@ typedef struct va_list {
memcpy(&p[6], emu->xmm, 8*16); \
}
#elif defined(__powerpc64__)
// TODO, is this correct?
#define CREATE_SYSV_VALIST(A) \
va_list sysv_varargs; \
sysv_varargs->gpr=8; \
sysv_varargs->fpr=8; \
sysv_varargs->overflow_arg_area=A;
#define CONVERT_VALIST(A) \
#error TODO!
#elif defined(__loongarch64)
#elif defined(__loongarch64) || defined(__powerpc64__)
#define CREATE_SYSV_VALIST(A) \
va_list sysv_varargs = (va_list)A
// not creating CONVERT_VALIST(A) on purpose
+8 -1
View File
@@ -262,6 +262,13 @@ static int loadEmulatedLib(const char* libname, library_t *lib, box64context_t*
lib->priv.n.localsymbols = kh_init(mapsymbols);
printf_log(LOG_INFO, "Using emulated %s\n", libname);
#ifdef DYNAREC
if(libname && strstr(libname, "libmonobdwgc-2.0.so")) {
printf_log(LOG_INFO, "MonoBleedingEdge detected, disable Dynarec BigBlock and enable Dynarec StrongMem\n");
box64_dynarec_bigblock = 0;
box64_dynarec_strongmem = 1;
}
#endif
return 1;
}
return 0;
@@ -376,7 +383,7 @@ int FinalizeLibrary(library_t* lib, lib_t* local_maplib, int bindnow, x64emu_t*
}
#ifdef HAVE_TRACE
if(trace_func) {
if (GetGlobalSymbolStartEnd(my_context->maplib, trace_func, &trace_start, &trace_end, elf_header, -1, NULL)) {
if (GetGlobalSymbolStartEnd(local_maplib, trace_func, &trace_start, &trace_end, elf_header, -1, NULL)) {
SetTraceEmu(trace_start, trace_end);
printf_log(LOG_INFO, "TRACE on %s only (%p-%p)\n", trace_func, (void*)trace_start, (void*)trace_end);
free(trace_func);
+3 -3
View File
@@ -154,9 +154,9 @@ GO("libcups.so.2", libcups)
//GO("libvulkan.so", vulkan)
//GO("libwayland-client.so.0", waylandclient)
GO("libxml2.so.2", xml2)
//GO("libxslt.so.1", xslt)
//GO("libldap_r-2.4.so.2", ldapr)
//GO("liblber-2.4.so.2", lber)
GO("libxslt.so.1", xslt)
GO("libldap_r-2.4.so.2", ldapr)
GO("liblber-2.4.so.2", lber)
//GO("libnsl.so.1", nsl)
//GO("liblcms2.so.2", lcms2)
GO("libkrb5.so.3", krb5)
+47 -9
View File
@@ -310,8 +310,8 @@ uint64_t RunFunctionHandler(int* exit, x64_ucontext_t* sigcontext, uintptr_t fnc
int oldquitonlongjmp = emu->quitonlongjmp;
emu->quitonlongjmp = 2;
//EmuCall(emu, fnc); // avoid DynaCall for now
DynaCall(emu, fnc);
EmuCall(emu, fnc); // avoid DynaCall for now
//DynaCall(emu, fnc);
if(nargs>6)
R_RSP+=((nargs-6)*sizeof(void*));
@@ -705,6 +705,11 @@ void my_sigactionhandler_oldcode(int32_t sig, int simple, siginfo_t* info, void
relockMutex(Locks);
}
extern __thread void* current_helper;
#ifdef DYNAREC
static pthread_mutex_t mutex_dynarec_prot;
#endif
void my_box64signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
{
// sig==SIGSEGV || sig==SIGBUS || sig==SIGILL here!
@@ -728,7 +733,7 @@ void my_box64signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
#elif defined __x86_64__
void * pc = (void*)p->uc_mcontext.gregs[X64_RIP];
#elif defined __powerpc64__
void * pc = (void*)p->uc_mcontext.uc_regs->gregs[PT_NIP];
void * pc = (void*)p->uc_mcontext.gp_regs[PT_NIP];
#else
void * pc = NULL; // unknow arch...
#warning Unhandled architecture
@@ -736,17 +741,30 @@ void my_box64signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
int Locks = unlockMutex();
uint32_t prot = getProtection((uintptr_t)addr);
#ifdef DYNAREC
if((Locks & (1<<8)) && (sig==SIGSEGV)) //1<<8 is mutex_dyndump
cancelFillBlock(); // Segfault inside a Fillblock, just cancel it's creation, don't relock mutex
if((Locks & (1<<8)) && (sig==SIGSEGV) && current_helper) {//1<<8 is mutex_dyndump
relockMutex(Locks);
cancelFillBlock(); // Segfault inside a Fillblock, cancel it's creation...
}
dynablock_t* db = NULL;
int db_searched = 0;
if ((sig==SIGSEGV) && (addr) && (info->si_code == SEGV_ACCERR) && (prot&PROT_DYNAREC)) {
// access error, unprotect the block (and mark them dirty)
unprotectDB((uintptr_t)addr, 1); // unprotect 1 byte... But then, the whole page will be unprotected
pthread_mutex_lock(&mutex_dynarec_prot);
// check if SMC inside block
db = FindDynablockFromNativeAddress(pc);
db_searched = 1;
dynarec_log(LOG_DEBUG, "SIGSEGV with Access error on %p for %p , db=%p(%p), prot=0x%x\n", pc, addr, db, db?((void*)db->x64_addr):NULL, prot);
static uintptr_t repeated_page = 0;
dynarec_log(LOG_DEBUG, "SIGSEGV with Access error on %p for %p , db=%p(%p), prot=0x%x (old page=%p)\n", pc, addr, db, db?((void*)db->x64_addr):NULL, prot, (void*)repeated_page);
static int repeated_count = 0;
if(repeated_page == ((uintptr_t)addr&~0xfff)) {
++repeated_count; // Access eoor multiple time on same page, disable dynarec on this page a few time...
dynarec_log(LOG_DEBUG, "Detecting a Hotpage at %p (%d)\n", (void*)repeated_page, repeated_count);
AddHotPage(repeated_page);
} else {
repeated_page = (uintptr_t)addr&~0xfff;
repeated_count = 0;
}
// access error, unprotect the block (and mark them dirty)
unprotectDB((uintptr_t)addr, 1); // unprotect 1 byte... But then, the whole page will be unprotected
if(db && ((addr>=db->x64_addr && addr<(db->x64_addr+db->x64_size)) || db->need_test)) {
// dynablock got auto-dirty! need to get out of it!!!
emu_jmpbuf_t* ejb = GetJmpBuf();
@@ -781,17 +799,21 @@ void my_box64signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
dynarec_log(LOG_INFO, "Dynablock unprotected, getting out!\n");
}
relockMutex(Locks);
pthread_mutex_unlock(&mutex_dynarec_prot);
siglongjmp(ejb->jmpbuf, 2);
}
dynarec_log(LOG_INFO, "Warning, Auto-SMC (%p for db %p/%p) detected, but jmpbuffer not ready!\n", (void*)addr, db, (void*)db->x64_addr);
}
// done
if(prot&PROT_WRITE) {
if((prot&PROT_WRITE) || (prot&PROT_DYNAREC)) {
pthread_mutex_unlock(&mutex_dynarec_prot);
// if there is no write permission, don't return and continue to program signal handling
relockMutex(Locks);
return;
}
pthread_mutex_unlock(&mutex_dynarec_prot);
} else if ((sig==SIGSEGV) && (addr) && (info->si_code == SEGV_ACCERR) && (prot&(PROT_READ|PROT_WRITE))) {
pthread_mutex_lock(&mutex_dynarec_prot);
db = FindDynablockFromNativeAddress(pc);
db_searched = 1;
if(db && db->x64_addr>= addr && (db->x64_addr+db->x64_size)<addr) {
@@ -808,6 +830,7 @@ void my_box64signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
glitch_addr = addr;
glitch_prot = prot;
relockMutex(Locks);
pthread_mutex_unlock(&mutex_dynarec_prot);
return; // try again
}
dynarec_log(/*LOG_DEBUG*/LOG_INFO, "Repeated SIGSEGV with Access error on %p for %p, db=%p, prot=0x%x\n", pc, addr, db, prot);
@@ -815,6 +838,7 @@ dynarec_log(/*LOG_DEBUG*/LOG_INFO, "Repeated SIGSEGV with Access error on %p for
glitch_addr = NULL;
glitch_prot = 0;
}
pthread_mutex_unlock(&mutex_dynarec_prot);
}
#else
void* db = NULL;
@@ -1277,7 +1301,17 @@ EXPORT int my_swapcontext(x64emu_t* emu, void* ucp1, void* ucp2)
my_setcontext(emu, ucp2);
return 0;
}
#ifdef DYNAREC
static void atfork_child_dynarec_prot(void)
{
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
pthread_mutex_init(&mutex_dynarec_prot, &attr);
pthread_mutexattr_destroy(&attr);
}
#endif
void init_signal_helper(box64context_t* context)
{
// setup signal handling
@@ -1296,6 +1330,10 @@ void init_signal_helper(box64context_t* context)
sigaction(SIGILL, &action, NULL);
pthread_once(&sigstack_key_once, sigstack_key_alloc);
#ifdef DYNAREC
atfork_child_dynarec_prot();
pthread_atfork(NULL, NULL, atfork_child_dynarec_prot);
#endif
}
void fini_signal_helper()
+22 -8
View File
@@ -42,6 +42,8 @@ int box64_pagesize;
int box64_dynarec = 1;
int box64_dynarec_dump = 0;
int box64_dynarec_forced = 0;
int box64_dynarec_bigblock = 1;
int box64_dynarec_strongmem = 0;
uintptr_t box64_nodynarec_start = 0;
uintptr_t box64_nodynarec_end = 0;
#ifdef ARM64
@@ -262,6 +264,24 @@ void LoadLogEnv()
if(box64_dynarec_forced)
printf_log(LOG_INFO, "Dynarec is Forced on all addresses\n");
}
p = getenv("BOX64_DYNAREC_BIGBLOCK");
if(p) {
if(strlen(p)==1) {
if(p[0]>='0' && p[0]<='1')
box64_dynarec_bigblock = p[0]-'0';
}
if(!box64_dynarec_bigblock)
printf_log(LOG_INFO, "Dynarec will not try to make big block\n");
}
p = getenv("BOX64_DYNAREC_STRONGMEM");
if(p) {
if(strlen(p)==1) {
if(p[0]>='0' && p[0]<='2')
box64_dynarec_strongmem = p[0]-'0';
}
if(box64_dynarec_strongmem)
printf_log(LOG_INFO, "Dynarec will try to emulate a strong memory model%s\n", (box64_dynarec_strongmem==1)?" with limited performace loss":"");
}
p = getenv("BOX64_NODYNAREC");
if(p) {
if (strchr(p,'-')) {
@@ -838,10 +858,7 @@ int main(int argc, const char **argv, const char **env) {
// check BOX64_LD_LIBRARY_PATH and load it
LoadEnvVars(my_context);
if(argv[0][0]=='/')
my_context->box64path = strdup(argv[0]);
else
my_context->box64path = ResolveFile(argv[0], &my_context->box64_path);
my_context->box64path = ResolveFile(argv[0], &my_context->box64_path);
// prepare all other env. var
my_context->envc = CountEnv(environ?environ:env);
printf_log(LOG_INFO, "Counted %d Env var\n", my_context->envc);
@@ -883,10 +900,7 @@ int main(int argc, const char **argv, const char **env) {
}
// lets build argc/argv stuff
printf_log(LOG_INFO, "Looking for %s\n", prog);
if(strchr(prog, '/'))
my_context->argv[0] = strdup(prog);
else
my_context->argv[0] = ResolveFile(prog, &my_context->box64_path);
my_context->argv[0] = ResolveFile(prog, &my_context->box64_path);
// check if box86 is present
{
my_context->box86path = strdup(my_context->box64path);
+1 -1
View File
@@ -60,7 +60,7 @@ char* ResolveFile(const char* filename, path_collection_t* paths)
return realpath(p, NULL);
}
return NULL;
return strdup(filename); //NULL;
}
int FileIsX64ELF(const char* filename)
+20
View File
@@ -452,6 +452,7 @@
#() LFpLp
#() LFppi
#() LFppL
#() LFppp
#() LFSpL
#() pFEip
#() pFEiV
@@ -724,6 +725,7 @@
#() iFppui
#() iFppuu
#() iFppup
#() iFppdp
#() iFppll
#() iFpplp
#() iFppLi
@@ -1490,6 +1492,7 @@
#() iFpppippp
#() iFpppuiii
#() iFppppiii
#() iFppppipp
#() iFppppdpi
#() iFpppppip
#() iFpppppup
@@ -1604,7 +1607,9 @@
#() iFpppipipi
#() iFpppipppp
#() iFppppiipi
#() iFppppippp
#() iFppppppii
#() iFpppppppi
#() iFpppppppp
#() uFEipipppp
#() uFEpiupppp
@@ -1631,6 +1636,7 @@
#() pFpWWiCpup
#() pFpuuWWCuu
#() pFpuuuupup
#() pFpuuupwwp
#() pFpdwwWWui
#() pFplpppppp
#() pFppiiiiii
@@ -1673,6 +1679,7 @@
#() iFEpiiiiipi
#() iFEpppipppp
#() iFEppplPPPP
#() iFEpppppupp
#() iFEppPPPPPP
#() iFiiiiiiiip
#() iFiiiipiiip
@@ -1783,6 +1790,7 @@
#() iFEpppipppppp
#() iFEppppiiiiuu
#() iFiiiiiiiiiip
#() iFppippipppip
#() iFppppiiuuiiL
#() uFEpLiupppLuV
#() uFEpLippppLup
@@ -1856,12 +1864,14 @@
#() vFppuiiiiipuiiiiiiii
#() vFpppipppppppppppppp
#() iFpppppppppppppppppp
#() LFpppppppppppppppppp
#() pFippppppppppppppppp
#() vFpiiiiiiiiiiiiiiiiii
#() pFiiiippppppppppppppp
#() pFpippppppppppppppppp
#() iFpppppppppppppppppppppp
#() pFipppppppppppppppppppppp
#() iFpppppppppppppppppppppppppppppppppp
#defined(HAVE_LD80BITS) DFD
#defined(HAVE_LD80BITS) vFppippDDC
#!defined(HAVE_LD80BITS) KFK
@@ -2372,6 +2382,10 @@ wrappedgtkx112:
wrappedkrb5:
- iFppppppipp:
- krb5_get_init_creds_password
wrappedlber:
wrappedldapr:
- iFpppppupp:
- ldap_sasl_interactive_bind_s
wrappedldlinux:
- pFp:
- __tls_get_addr
@@ -2439,6 +2453,7 @@ wrappedlibc:
- sigaltstack
- swapcontext
- iFpV:
- __isoc99_scanf
- execl
- execlp
- printf
@@ -3448,3 +3463,8 @@ wrappedxml2:
- xmlHashUpdateEntry3
- pFpppppi:
- xmlCreateIOParserCtxt
wrappedxslt:
- vFp:
- xsltSetLoaderFunc
- iFppp:
- xsltRegisterExtModuleFunction
+8
View File
@@ -0,0 +1,8 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedlberDEFS_H_
#define __wrappedlberDEFS_H_
#endif // __wrappedlberDEFS_H_
+17
View File
@@ -0,0 +1,17 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedlberTYPES_H_
#define __wrappedlberTYPES_H_
#ifndef LIBNAME
#error You should only #include this file inside a wrapped*.c file
#endif
#ifndef ADDED_FUNCTIONS
#define ADDED_FUNCTIONS()
#endif
#define SUPER() ADDED_FUNCTIONS()
#endif // __wrappedlberTYPES_H_
@@ -0,0 +1,8 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedlberUNDEFS_H_
#define __wrappedlberUNDEFS_H_
#endif // __wrappedlberUNDEFS_H_
+8
View File
@@ -0,0 +1,8 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedldaprDEFS_H_
#define __wrappedldaprDEFS_H_
#endif // __wrappedldaprDEFS_H_
+19
View File
@@ -0,0 +1,19 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedldaprTYPES_H_
#define __wrappedldaprTYPES_H_
#ifndef LIBNAME
#error You should only #include this file inside a wrapped*.c file
#endif
#ifndef ADDED_FUNCTIONS
#define ADDED_FUNCTIONS()
#endif
typedef int64_t (*iFpppppupp_t)(void*, void*, void*, void*, void*, uint64_t, void*, void*);
#define SUPER() ADDED_FUNCTIONS() \
GO(ldap_sasl_interactive_bind_s, iFpppppupp_t)
#endif // __wrappedldaprTYPES_H_
@@ -0,0 +1,8 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedldaprUNDEFS_H_
#define __wrappedldaprUNDEFS_H_
#endif // __wrappedldaprUNDEFS_H_
+1
View File
@@ -110,6 +110,7 @@ typedef int64_t (*iFpippppp_t)(void*, int64_t, void*, void*, void*, void*, void*
GO(execvp, iFpp_t) \
GO(sigaltstack, iFpp_t) \
GO(swapcontext, iFpp_t) \
GO(__isoc99_scanf, iFpV_t) \
GO(execl, iFpV_t) \
GO(execlp, iFpV_t) \
GO(printf, iFpV_t) \
+8
View File
@@ -0,0 +1,8 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedxsltDEFS_H_
#define __wrappedxsltDEFS_H_
#endif // __wrappedxsltDEFS_H_
+21
View File
@@ -0,0 +1,21 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedxsltTYPES_H_
#define __wrappedxsltTYPES_H_
#ifndef LIBNAME
#error You should only #include this file inside a wrapped*.c file
#endif
#ifndef ADDED_FUNCTIONS
#define ADDED_FUNCTIONS()
#endif
typedef void (*vFp_t)(void*);
typedef int64_t (*iFppp_t)(void*, void*, void*);
#define SUPER() ADDED_FUNCTIONS() \
GO(xsltSetLoaderFunc, vFp_t) \
GO(xsltRegisterExtModuleFunction, iFppp_t)
#endif // __wrappedxsltTYPES_H_
@@ -0,0 +1,8 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedxsltUNDEFS_H_
#define __wrappedxsltUNDEFS_H_
#endif // __wrappedxsltUNDEFS_H_
+22
View File
@@ -486,6 +486,7 @@ typedef uintptr_t (*LFpLi_t)(void*, uintptr_t, int64_t);
typedef uintptr_t (*LFpLp_t)(void*, uintptr_t, void*);
typedef uintptr_t (*LFppi_t)(void*, void*, int64_t);
typedef uintptr_t (*LFppL_t)(void*, void*, uintptr_t);
typedef uintptr_t (*LFppp_t)(void*, void*, void*);
typedef uintptr_t (*LFSpL_t)(void*, void*, uintptr_t);
typedef void* (*pFEip_t)(x64emu_t*, int64_t, void*);
typedef void* (*pFEiV_t)(x64emu_t*, int64_t, void*);
@@ -758,6 +759,7 @@ typedef int64_t (*iFppuw_t)(void*, void*, uint64_t, int16_t);
typedef int64_t (*iFppui_t)(void*, void*, uint64_t, int64_t);
typedef int64_t (*iFppuu_t)(void*, void*, uint64_t, uint64_t);
typedef int64_t (*iFppup_t)(void*, void*, uint64_t, void*);
typedef int64_t (*iFppdp_t)(void*, void*, double, void*);
typedef int64_t (*iFppll_t)(void*, void*, intptr_t, intptr_t);
typedef int64_t (*iFpplp_t)(void*, void*, intptr_t, void*);
typedef int64_t (*iFppLi_t)(void*, void*, uintptr_t, int64_t);
@@ -1524,6 +1526,7 @@ typedef int64_t (*iFpppippi_t)(void*, void*, void*, int64_t, void*, void*, int64
typedef int64_t (*iFpppippp_t)(void*, void*, void*, int64_t, void*, void*, void*);
typedef int64_t (*iFpppuiii_t)(void*, void*, void*, uint64_t, int64_t, int64_t, int64_t);
typedef int64_t (*iFppppiii_t)(void*, void*, void*, void*, int64_t, int64_t, int64_t);
typedef int64_t (*iFppppipp_t)(void*, void*, void*, void*, int64_t, void*, void*);
typedef int64_t (*iFppppdpi_t)(void*, void*, void*, void*, double, void*, int64_t);
typedef int64_t (*iFpppppip_t)(void*, void*, void*, void*, void*, int64_t, void*);
typedef int64_t (*iFpppppup_t)(void*, void*, void*, void*, void*, uint64_t, void*);
@@ -1638,7 +1641,9 @@ typedef int64_t (*iFpppiippp_t)(void*, void*, void*, int64_t, int64_t, void*, vo
typedef int64_t (*iFpppipipi_t)(void*, void*, void*, int64_t, void*, int64_t, void*, int64_t);
typedef int64_t (*iFpppipppp_t)(void*, void*, void*, int64_t, void*, void*, void*, void*);
typedef int64_t (*iFppppiipi_t)(void*, void*, void*, void*, int64_t, int64_t, void*, int64_t);
typedef int64_t (*iFppppippp_t)(void*, void*, void*, void*, int64_t, void*, void*, void*);
typedef int64_t (*iFppppppii_t)(void*, void*, void*, void*, void*, void*, int64_t, int64_t);
typedef int64_t (*iFpppppppi_t)(void*, void*, void*, void*, void*, void*, void*, int64_t);
typedef int64_t (*iFpppppppp_t)(void*, void*, void*, void*, void*, void*, void*, void*);
typedef uint64_t (*uFEipipppp_t)(x64emu_t*, int64_t, void*, int64_t, void*, void*, void*, void*);
typedef uint64_t (*uFEpiupppp_t)(x64emu_t*, void*, int64_t, uint64_t, void*, void*, void*, void*);
@@ -1665,6 +1670,7 @@ typedef void* (*pFpCuuuCup_t)(void*, uint8_t, uint64_t, uint64_t, uint64_t, uint
typedef void* (*pFpWWiCpup_t)(void*, uint16_t, uint16_t, int64_t, uint8_t, void*, uint64_t, void*);
typedef void* (*pFpuuWWCuu_t)(void*, uint64_t, uint64_t, uint16_t, uint16_t, uint8_t, uint64_t, uint64_t);
typedef void* (*pFpuuuupup_t)(void*, uint64_t, uint64_t, uint64_t, uint64_t, void*, uint64_t, void*);
typedef void* (*pFpuuupwwp_t)(void*, uint64_t, uint64_t, uint64_t, void*, int16_t, int16_t, void*);
typedef void* (*pFpdwwWWui_t)(void*, double, int16_t, int16_t, uint16_t, uint16_t, uint64_t, int64_t);
typedef void* (*pFplpppppp_t)(void*, intptr_t, void*, void*, void*, void*, void*, void*);
typedef void* (*pFppiiiiii_t)(void*, void*, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t);
@@ -1707,6 +1713,7 @@ typedef void (*vFpppppippp_t)(void*, void*, void*, void*, void*, int64_t, void*,
typedef int64_t (*iFEpiiiiipi_t)(x64emu_t*, void*, int64_t, int64_t, int64_t, int64_t, int64_t, void*, int64_t);
typedef int64_t (*iFEpppipppp_t)(x64emu_t*, void*, void*, void*, int64_t, void*, void*, void*, void*);
typedef int64_t (*iFEppplPPPP_t)(x64emu_t*, void*, void*, void*, intptr_t, void*, void*, void*, void*);
typedef int64_t (*iFEpppppupp_t)(x64emu_t*, void*, void*, void*, void*, void*, uint64_t, void*, void*);
typedef int64_t (*iFEppPPPPPP_t)(x64emu_t*, void*, void*, void*, void*, void*, void*, void*, void*);
typedef int64_t (*iFiiiiiiiip_t)(int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, void*);
typedef int64_t (*iFiiiipiiip_t)(int64_t, int64_t, int64_t, int64_t, void*, int64_t, int64_t, int64_t, void*);
@@ -1817,6 +1824,7 @@ typedef void (*vFppppppppppp_t)(void*, void*, void*, void*, void*, void*, void*,
typedef int64_t (*iFEpppipppppp_t)(x64emu_t*, void*, void*, void*, int64_t, void*, void*, void*, void*, void*, void*);
typedef int64_t (*iFEppppiiiiuu_t)(x64emu_t*, void*, void*, void*, void*, int64_t, int64_t, int64_t, int64_t, uint64_t, uint64_t);
typedef int64_t (*iFiiiiiiiiiip_t)(int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, void*);
typedef int64_t (*iFppippipppip_t)(void*, void*, int64_t, void*, void*, int64_t, void*, void*, void*, int64_t, void*);
typedef int64_t (*iFppppiiuuiiL_t)(void*, void*, void*, void*, int64_t, int64_t, uint64_t, uint64_t, int64_t, int64_t, uintptr_t);
typedef uint64_t (*uFEpLiupppLuV_t)(x64emu_t*, void*, uintptr_t, int64_t, uint64_t, void*, void*, void*, uintptr_t, uint64_t, void*);
typedef uint64_t (*uFEpLippppLup_t)(x64emu_t*, void*, uintptr_t, int64_t, void*, void*, void*, void*, uintptr_t, uint64_t, void*);
@@ -1890,12 +1898,14 @@ typedef void* (*pFppippipipipipipip_t)(void*, void*, int64_t, void*, void*, int6
typedef void (*vFppuiiiiipuiiiiiiii_t)(void*, void*, uint64_t, int64_t, int64_t, int64_t, int64_t, int64_t, void*, uint64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t);
typedef void (*vFpppipppppppppppppp_t)(void*, void*, void*, int64_t, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
typedef int64_t (*iFpppppppppppppppppp_t)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
typedef uintptr_t (*LFpppppppppppppppppp_t)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
typedef void* (*pFippppppppppppppppp_t)(int64_t, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
typedef void (*vFpiiiiiiiiiiiiiiiiii_t)(void*, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t);
typedef void* (*pFiiiippppppppppppppp_t)(int64_t, int64_t, int64_t, int64_t, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
typedef void* (*pFpippppppppppppppppp_t)(void*, int64_t, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
typedef int64_t (*iFpppppppppppppppppppppp_t)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
typedef void* (*pFipppppppppppppppppppppp_t)(int64_t, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
typedef int64_t (*iFpppppppppppppppppppppppppppppppppp_t)(void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*);
#if defined(HAVE_LD80BITS)
typedef long double (*DFD_t)(long double);
@@ -2375,6 +2385,7 @@ void LFpLi(x64emu_t *emu, uintptr_t fcn) { LFpLi_t fn = (LFpLi_t)fcn; R_RAX=(uin
void LFpLp(x64emu_t *emu, uintptr_t fcn) { LFpLp_t fn = (LFpLp_t)fcn; R_RAX=(uintptr_t)fn((void*)R_RDI, (uintptr_t)R_RSI, (void*)R_RDX); }
void LFppi(x64emu_t *emu, uintptr_t fcn) { LFppi_t fn = (LFppi_t)fcn; R_RAX=(uintptr_t)fn((void*)R_RDI, (void*)R_RSI, (int64_t)R_RDX); }
void LFppL(x64emu_t *emu, uintptr_t fcn) { LFppL_t fn = (LFppL_t)fcn; R_RAX=(uintptr_t)fn((void*)R_RDI, (void*)R_RSI, (uintptr_t)R_RDX); }
void LFppp(x64emu_t *emu, uintptr_t fcn) { LFppp_t fn = (LFppp_t)fcn; R_RAX=(uintptr_t)fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX); }
void LFSpL(x64emu_t *emu, uintptr_t fcn) { LFSpL_t fn = (LFSpL_t)fcn; R_RAX=(uintptr_t)fn(io_convert((void*)R_RDI), (void*)R_RSI, (uintptr_t)R_RDX); }
void pFEip(x64emu_t *emu, uintptr_t fcn) { pFEip_t fn = (pFEip_t)fcn; R_RAX=(uintptr_t)fn(emu, (int64_t)R_RDI, (void*)R_RSI); }
void pFEiV(x64emu_t *emu, uintptr_t fcn) { pFEiV_t fn = (pFEiV_t)fcn; R_RAX=(uintptr_t)fn(emu, (int64_t)R_RDI, (void*)(R_RSP + 8)); }
@@ -2647,6 +2658,7 @@ void iFppuw(x64emu_t *emu, uintptr_t fcn) { iFppuw_t fn = (iFppuw_t)fcn; R_RAX=(
void iFppui(x64emu_t *emu, uintptr_t fcn) { iFppui_t fn = (iFppui_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (uint64_t)R_RDX, (int64_t)R_RCX); }
void iFppuu(x64emu_t *emu, uintptr_t fcn) { iFppuu_t fn = (iFppuu_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (uint64_t)R_RDX, (uint64_t)R_RCX); }
void iFppup(x64emu_t *emu, uintptr_t fcn) { iFppup_t fn = (iFppup_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (uint64_t)R_RDX, (void*)R_RCX); }
void iFppdp(x64emu_t *emu, uintptr_t fcn) { iFppdp_t fn = (iFppdp_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, emu->xmm[0].d[0], (void*)R_RDX); }
void iFppll(x64emu_t *emu, uintptr_t fcn) { iFppll_t fn = (iFppll_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (intptr_t)R_RDX, (intptr_t)R_RCX); }
void iFpplp(x64emu_t *emu, uintptr_t fcn) { iFpplp_t fn = (iFpplp_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (intptr_t)R_RDX, (void*)R_RCX); }
void iFppLi(x64emu_t *emu, uintptr_t fcn) { iFppLi_t fn = (iFppLi_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (uintptr_t)R_RDX, (int64_t)R_RCX); }
@@ -3413,6 +3425,7 @@ void iFpppippi(x64emu_t *emu, uintptr_t fcn) { iFpppippi_t fn = (iFpppippi_t)fcn
void iFpppippp(x64emu_t *emu, uintptr_t fcn) { iFpppippp_t fn = (iFpppippp_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**)(R_RSP + 8)); }
void iFpppuiii(x64emu_t *emu, uintptr_t fcn) { iFpppuiii_t fn = (iFpppuiii_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, *(int64_t*)(R_RSP + 8)); }
void iFppppiii(x64emu_t *emu, uintptr_t fcn) { iFppppiii_t fn = (iFppppiii_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, *(int64_t*)(R_RSP + 8)); }
void iFppppipp(x64emu_t *emu, uintptr_t fcn) { iFppppipp_t fn = (iFppppipp_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**)(R_RSP + 8)); }
void iFppppdpi(x64emu_t *emu, uintptr_t fcn) { iFppppdpi_t fn = (iFppppdpi_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, emu->xmm[0].d[0], (void*)R_R8, (int64_t)R_R9); }
void iFpppppip(x64emu_t *emu, uintptr_t fcn) { iFpppppip_t fn = (iFpppppip_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (int64_t)R_R9, *(void**)(R_RSP + 8)); }
void iFpppppup(x64emu_t *emu, uintptr_t fcn) { iFpppppup_t fn = (iFpppppup_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (uint64_t)R_R9, *(void**)(R_RSP + 8)); }
@@ -3527,7 +3540,9 @@ void iFpppiippp(x64emu_t *emu, uintptr_t fcn) { iFpppiippp_t fn = (iFpppiippp_t)
void iFpppipipi(x64emu_t *emu, uintptr_t fcn) { iFpppipipi_t fn = (iFpppipipi_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (int64_t)R_RCX, (void*)R_R8, (int64_t)R_R9, *(void**)(R_RSP + 8), *(int64_t*)(R_RSP + 16)); }
void iFpppipppp(x64emu_t *emu, uintptr_t fcn) { iFpppipppp_t fn = (iFpppipppp_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**)(R_RSP + 8), *(void**)(R_RSP + 16)); }
void iFppppiipi(x64emu_t *emu, uintptr_t fcn) { iFppppiipi_t fn = (iFppppiipi_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**)(R_RSP + 8), *(int64_t*)(R_RSP + 16)); }
void iFppppippp(x64emu_t *emu, uintptr_t fcn) { iFppppippp_t fn = (iFppppippp_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**)(R_RSP + 8), *(void**)(R_RSP + 16)); }
void iFppppppii(x64emu_t *emu, uintptr_t fcn) { iFppppppii_t fn = (iFppppppii_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(int64_t*)(R_RSP + 8), *(int64_t*)(R_RSP + 16)); }
void iFpppppppi(x64emu_t *emu, uintptr_t fcn) { iFpppppppi_t fn = (iFpppppppi_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(int64_t*)(R_RSP + 16)); }
void iFpppppppp(x64emu_t *emu, uintptr_t fcn) { iFpppppppp_t fn = (iFpppppppp_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16)); }
void uFEipipppp(x64emu_t *emu, uintptr_t fcn) { uFEipipppp_t fn = (uFEipipppp_t)fcn; R_RAX=(uint64_t)fn(emu, (int64_t)R_RDI, (void*)R_RSI, (int64_t)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8)); }
void uFEpiupppp(x64emu_t *emu, uintptr_t fcn) { uFEpiupppp_t fn = (uFEpiupppp_t)fcn; R_RAX=(uint64_t)fn(emu, (void*)R_RDI, (int64_t)R_RSI, (uint64_t)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8)); }
@@ -3554,6 +3569,7 @@ void pFpCuuuCup(x64emu_t *emu, uintptr_t fcn) { pFpCuuuCup_t fn = (pFpCuuuCup_t)
void pFpWWiCpup(x64emu_t *emu, uintptr_t fcn) { pFpWWiCpup_t fn = (pFpWWiCpup_t)fcn; R_RAX=(uintptr_t)fn((void*)R_RDI, (uint16_t)R_RSI, (uint16_t)R_RDX, (int64_t)R_RCX, (uint8_t)R_R8, (void*)R_R9, *(uint64_t*)(R_RSP + 8), *(void**)(R_RSP + 16)); }
void pFpuuWWCuu(x64emu_t *emu, uintptr_t fcn) { pFpuuWWCuu_t fn = (pFpuuWWCuu_t)fcn; R_RAX=(uintptr_t)fn((void*)R_RDI, (uint64_t)R_RSI, (uint64_t)R_RDX, (uint16_t)R_RCX, (uint16_t)R_R8, (uint8_t)R_R9, *(uint64_t*)(R_RSP + 8), *(uint64_t*)(R_RSP + 16)); }
void pFpuuuupup(x64emu_t *emu, uintptr_t fcn) { pFpuuuupup_t fn = (pFpuuuupup_t)fcn; R_RAX=(uintptr_t)fn((void*)R_RDI, (uint64_t)R_RSI, (uint64_t)R_RDX, (uint64_t)R_RCX, (uint64_t)R_R8, (void*)R_R9, *(uint64_t*)(R_RSP + 8), *(void**)(R_RSP + 16)); }
void pFpuuupwwp(x64emu_t *emu, uintptr_t fcn) { pFpuuupwwp_t fn = (pFpuuupwwp_t)fcn; R_RAX=(uintptr_t)fn((void*)R_RDI, (uint64_t)R_RSI, (uint64_t)R_RDX, (uint64_t)R_RCX, (void*)R_R8, (int16_t)R_R9, *(int16_t*)(R_RSP + 8), *(void**)(R_RSP + 16)); }
void pFpdwwWWui(x64emu_t *emu, uintptr_t fcn) { pFpdwwWWui_t fn = (pFpdwwWWui_t)fcn; R_RAX=(uintptr_t)fn((void*)R_RDI, emu->xmm[0].d[0], (int16_t)R_RSI, (int16_t)R_RDX, (uint16_t)R_RCX, (uint16_t)R_R8, (uint64_t)R_R9, *(int64_t*)(R_RSP + 8)); }
void pFplpppppp(x64emu_t *emu, uintptr_t fcn) { pFplpppppp_t fn = (pFplpppppp_t)fcn; R_RAX=(uintptr_t)fn((void*)R_RDI, (intptr_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16)); }
void pFppiiiiii(x64emu_t *emu, uintptr_t fcn) { pFppiiiiii_t fn = (pFppiiiiii_t)fcn; R_RAX=(uintptr_t)fn((void*)R_RDI, (void*)R_RSI, (int64_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)); }
@@ -3596,6 +3612,7 @@ void vFpppppippp(x64emu_t *emu, uintptr_t fcn) { vFpppppippp_t fn = (vFpppppippp
void iFEpiiiiipi(x64emu_t *emu, uintptr_t fcn) { iFEpiiiiipi_t fn = (iFEpiiiiipi_t)fcn; R_RAX=(int64_t)fn(emu, (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 iFEpppipppp(x64emu_t *emu, uintptr_t fcn) { iFEpppipppp_t fn = (iFEpppipppp_t)fcn; R_RAX=(int64_t)fn(emu, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (int64_t)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16)); }
void iFEppplPPPP(x64emu_t *emu, uintptr_t fcn) { iFEppplPPPP_t fn = (iFEppplPPPP_t)fcn; R_RAX=(int64_t)fn(emu, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (intptr_t)R_RCX, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24), *(void**)(R_RSP + 32)); }
void iFEpppppupp(x64emu_t *emu, uintptr_t fcn) { iFEpppppupp_t fn = (iFEpppppupp_t)fcn; R_RAX=(int64_t)fn(emu, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (uint64_t)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16)); }
void iFEppPPPPPP(x64emu_t *emu, uintptr_t fcn) { iFEppPPPPPP_t fn = (iFEppPPPPPP_t)fcn; R_RAX=(int64_t)fn(emu, (void*)R_RDI, (void*)R_RSI, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24), *(void**)(R_RSP + 32), *(void**)(R_RSP + 40), *(void**)(R_RSP + 48)); }
void iFiiiiiiiip(x64emu_t *emu, uintptr_t fcn) { iFiiiiiiiip_t fn = (iFiiiiiiiip_t)fcn; R_RAX=(int64_t)fn((int64_t)R_RDI, (int64_t)R_RSI, (int64_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**)(R_RSP + 24)); }
void iFiiiipiiip(x64emu_t *emu, uintptr_t fcn) { iFiiiipiiip_t fn = (iFiiiipiiip_t)fcn; R_RAX=(int64_t)fn((int64_t)R_RDI, (int64_t)R_RSI, (int64_t)R_RDX, (int64_t)R_RCX, (void*)R_R8, (int64_t)R_R9, *(int64_t*)(R_RSP + 8), *(int64_t*)(R_RSP + 16), *(void**)(R_RSP + 24)); }
@@ -3706,6 +3723,7 @@ void vFppppppppppp(x64emu_t *emu, uintptr_t fcn) { vFppppppppppp_t fn = (vFppppp
void iFEpppipppppp(x64emu_t *emu, uintptr_t fcn) { iFEpppipppppp_t fn = (iFEpppipppppp_t)fcn; R_RAX=(int64_t)fn(emu, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (int64_t)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24), *(void**)(R_RSP + 32)); }
void iFEppppiiiiuu(x64emu_t *emu, uintptr_t fcn) { iFEppppiiiiuu_t fn = (iFEppppiiiiuu_t)fcn; R_RAX=(int64_t)fn(emu, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (int64_t)R_R8, (int64_t)R_R9, *(int64_t*)(R_RSP + 8), *(int64_t*)(R_RSP + 16), *(uint64_t*)(R_RSP + 24), *(uint64_t*)(R_RSP + 32)); }
void iFiiiiiiiiiip(x64emu_t *emu, uintptr_t fcn) { iFiiiiiiiiiip_t fn = (iFiiiiiiiiiip_t)fcn; R_RAX=(int64_t)fn((int64_t)R_RDI, (int64_t)R_RSI, (int64_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), *(int64_t*)(R_RSP + 24), *(int64_t*)(R_RSP + 32), *(void**)(R_RSP + 40)); }
void iFppippipppip(x64emu_t *emu, uintptr_t fcn) { iFppippipppip_t fn = (iFppippipppip_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (int64_t)R_RDX, (void*)R_RCX, (void*)R_R8, (int64_t)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24), *(int64_t*)(R_RSP + 32), *(void**)(R_RSP + 40)); }
void iFppppiiuuiiL(x64emu_t *emu, uintptr_t fcn) { iFppppiiuuiiL_t fn = (iFppppiiuuiiL_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, *(uint64_t*)(R_RSP + 8), *(uint64_t*)(R_RSP + 16), *(int64_t*)(R_RSP + 24), *(int64_t*)(R_RSP + 32), *(uintptr_t*)(R_RSP + 40)); }
void uFEpLiupppLuV(x64emu_t *emu, uintptr_t fcn) { uFEpLiupppLuV_t fn = (uFEpLiupppLuV_t)fcn; R_RAX=(uint64_t)fn(emu, (void*)R_RDI, (uintptr_t)R_RSI, (int64_t)R_RDX, (uint64_t)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(uintptr_t*)(R_RSP + 16), *(uint64_t*)(R_RSP + 24), (void*)(R_RSP + 32)); }
void uFEpLippppLup(x64emu_t *emu, uintptr_t fcn) { uFEpLippppLup_t fn = (uFEpLippppLup_t)fcn; R_RAX=(uint64_t)fn(emu, (void*)R_RDI, (uintptr_t)R_RSI, (int64_t)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(uintptr_t*)(R_RSP + 16), *(uint64_t*)(R_RSP + 24), *(void**)(R_RSP + 32)); }
@@ -3779,12 +3797,14 @@ void pFppippipipipipipip(x64emu_t *emu, uintptr_t fcn) { pFppippipipipipipip_t f
void vFppuiiiiipuiiiiiiii(x64emu_t *emu, uintptr_t fcn) { vFppuiiiiipuiiiiiiii_t fn = (vFppuiiiiipuiiiiiiii_t)fcn; fn((void*)R_RDI, (void*)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**)(R_RSP + 24), *(uint64_t*)(R_RSP + 32), *(int64_t*)(R_RSP + 40), *(int64_t*)(R_RSP + 48), *(int64_t*)(R_RSP + 56), *(int64_t*)(R_RSP + 64), *(int64_t*)(R_RSP + 72), *(int64_t*)(R_RSP + 80), *(int64_t*)(R_RSP + 88), *(int64_t*)(R_RSP + 96)); }
void vFpppipppppppppppppp(x64emu_t *emu, uintptr_t fcn) { vFpppipppppppppppppp_t fn = (vFpppipppppppppppppp_t)fcn; fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (int64_t)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24), *(void**)(R_RSP + 32), *(void**)(R_RSP + 40), *(void**)(R_RSP + 48), *(void**)(R_RSP + 56), *(void**)(R_RSP + 64), *(void**)(R_RSP + 72), *(void**)(R_RSP + 80), *(void**)(R_RSP + 88), *(void**)(R_RSP + 96)); }
void iFpppppppppppppppppp(x64emu_t *emu, uintptr_t fcn) { iFpppppppppppppppppp_t fn = (iFpppppppppppppppppp_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24), *(void**)(R_RSP + 32), *(void**)(R_RSP + 40), *(void**)(R_RSP + 48), *(void**)(R_RSP + 56), *(void**)(R_RSP + 64), *(void**)(R_RSP + 72), *(void**)(R_RSP + 80), *(void**)(R_RSP + 88), *(void**)(R_RSP + 96)); }
void LFpppppppppppppppppp(x64emu_t *emu, uintptr_t fcn) { LFpppppppppppppppppp_t fn = (LFpppppppppppppppppp_t)fcn; R_RAX=(uintptr_t)fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24), *(void**)(R_RSP + 32), *(void**)(R_RSP + 40), *(void**)(R_RSP + 48), *(void**)(R_RSP + 56), *(void**)(R_RSP + 64), *(void**)(R_RSP + 72), *(void**)(R_RSP + 80), *(void**)(R_RSP + 88), *(void**)(R_RSP + 96)); }
void pFippppppppppppppppp(x64emu_t *emu, uintptr_t fcn) { pFippppppppppppppppp_t fn = (pFippppppppppppppppp_t)fcn; R_RAX=(uintptr_t)fn((int64_t)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24), *(void**)(R_RSP + 32), *(void**)(R_RSP + 40), *(void**)(R_RSP + 48), *(void**)(R_RSP + 56), *(void**)(R_RSP + 64), *(void**)(R_RSP + 72), *(void**)(R_RSP + 80), *(void**)(R_RSP + 88), *(void**)(R_RSP + 96)); }
void vFpiiiiiiiiiiiiiiiiii(x64emu_t *emu, uintptr_t fcn) { vFpiiiiiiiiiiiiiiiiii_t fn = (vFpiiiiiiiiiiiiiiiiii_t)fcn; fn((void*)R_RDI, (int64_t)R_RSI, (int64_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), *(int64_t*)(R_RSP + 24), *(int64_t*)(R_RSP + 32), *(int64_t*)(R_RSP + 40), *(int64_t*)(R_RSP + 48), *(int64_t*)(R_RSP + 56), *(int64_t*)(R_RSP + 64), *(int64_t*)(R_RSP + 72), *(int64_t*)(R_RSP + 80), *(int64_t*)(R_RSP + 88), *(int64_t*)(R_RSP + 96), *(int64_t*)(R_RSP + 104)); }
void pFiiiippppppppppppppp(x64emu_t *emu, uintptr_t fcn) { pFiiiippppppppppppppp_t fn = (pFiiiippppppppppppppp_t)fcn; R_RAX=(uintptr_t)fn((int64_t)R_RDI, (int64_t)R_RSI, (int64_t)R_RDX, (int64_t)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24), *(void**)(R_RSP + 32), *(void**)(R_RSP + 40), *(void**)(R_RSP + 48), *(void**)(R_RSP + 56), *(void**)(R_RSP + 64), *(void**)(R_RSP + 72), *(void**)(R_RSP + 80), *(void**)(R_RSP + 88), *(void**)(R_RSP + 96), *(void**)(R_RSP + 104)); }
void pFpippppppppppppppppp(x64emu_t *emu, uintptr_t fcn) { pFpippppppppppppppppp_t fn = (pFpippppppppppppppppp_t)fcn; R_RAX=(uintptr_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**)(R_RSP + 16), *(void**)(R_RSP + 24), *(void**)(R_RSP + 32), *(void**)(R_RSP + 40), *(void**)(R_RSP + 48), *(void**)(R_RSP + 56), *(void**)(R_RSP + 64), *(void**)(R_RSP + 72), *(void**)(R_RSP + 80), *(void**)(R_RSP + 88), *(void**)(R_RSP + 96), *(void**)(R_RSP + 104)); }
void iFpppppppppppppppppppppp(x64emu_t *emu, uintptr_t fcn) { iFpppppppppppppppppppppp_t fn = (iFpppppppppppppppppppppp_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24), *(void**)(R_RSP + 32), *(void**)(R_RSP + 40), *(void**)(R_RSP + 48), *(void**)(R_RSP + 56), *(void**)(R_RSP + 64), *(void**)(R_RSP + 72), *(void**)(R_RSP + 80), *(void**)(R_RSP + 88), *(void**)(R_RSP + 96), *(void**)(R_RSP + 104), *(void**)(R_RSP + 112), *(void**)(R_RSP + 120), *(void**)(R_RSP + 128)); }
void pFipppppppppppppppppppppp(x64emu_t *emu, uintptr_t fcn) { pFipppppppppppppppppppppp_t fn = (pFipppppppppppppppppppppp_t)fcn; R_RAX=(uintptr_t)fn((int64_t)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24), *(void**)(R_RSP + 32), *(void**)(R_RSP + 40), *(void**)(R_RSP + 48), *(void**)(R_RSP + 56), *(void**)(R_RSP + 64), *(void**)(R_RSP + 72), *(void**)(R_RSP + 80), *(void**)(R_RSP + 88), *(void**)(R_RSP + 96), *(void**)(R_RSP + 104), *(void**)(R_RSP + 112), *(void**)(R_RSP + 120), *(void**)(R_RSP + 128), *(void**)(R_RSP + 136)); }
void iFpppppppppppppppppppppppppppppppppp(x64emu_t *emu, uintptr_t fcn) { iFpppppppppppppppppppppppppppppppppp_t fn = (iFpppppppppppppppppppppppppppppppppp_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16), *(void**)(R_RSP + 24), *(void**)(R_RSP + 32), *(void**)(R_RSP + 40), *(void**)(R_RSP + 48), *(void**)(R_RSP + 56), *(void**)(R_RSP + 64), *(void**)(R_RSP + 72), *(void**)(R_RSP + 80), *(void**)(R_RSP + 88), *(void**)(R_RSP + 96), *(void**)(R_RSP + 104), *(void**)(R_RSP + 112), *(void**)(R_RSP + 120), *(void**)(R_RSP + 128), *(void**)(R_RSP + 136), *(void**)(R_RSP + 144), *(void**)(R_RSP + 152), *(void**)(R_RSP + 160), *(void**)(R_RSP + 168), *(void**)(R_RSP + 176), *(void**)(R_RSP + 184), *(void**)(R_RSP + 192), *(void**)(R_RSP + 200), *(void**)(R_RSP + 208), *(void**)(R_RSP + 216), *(void**)(R_RSP + 224)); }
#if defined(HAVE_LD80BITS)
void DFD(x64emu_t *emu, uintptr_t fcn) { DFD_t fn = (DFD_t)fcn; long double ld=fn(LD2localLD((void*)(R_RSP + 8))); fpu_do_push(emu); ST0val = ld; }
@@ -4212,6 +4232,7 @@ int isSimpleWrapper(wrapper_t fun) {
if (fun == &LFpLp) return 1;
if (fun == &LFppi) return 1;
if (fun == &LFppL) return 1;
if (fun == &LFppp) return 1;
if (fun == &pFiii) return 1;
if (fun == &pFiiu) return 1;
if (fun == &pFiip) return 1;
@@ -4438,6 +4459,7 @@ int isSimpleWrapper(wrapper_t fun) {
if (fun == &iFppui) return 1;
if (fun == &iFppuu) return 1;
if (fun == &iFppup) return 1;
if (fun == &iFppdp) return 2;
if (fun == &iFppll) return 1;
if (fun == &iFpplp) return 1;
if (fun == &iFppLi) return 1;
+10
View File
@@ -485,6 +485,7 @@ void LFpLi(x64emu_t *emu, uintptr_t fnc);
void LFpLp(x64emu_t *emu, uintptr_t fnc);
void LFppi(x64emu_t *emu, uintptr_t fnc);
void LFppL(x64emu_t *emu, uintptr_t fnc);
void LFppp(x64emu_t *emu, uintptr_t fnc);
void LFSpL(x64emu_t *emu, uintptr_t fnc);
void pFEip(x64emu_t *emu, uintptr_t fnc);
void pFEiV(x64emu_t *emu, uintptr_t fnc);
@@ -757,6 +758,7 @@ void iFppuw(x64emu_t *emu, uintptr_t fnc);
void iFppui(x64emu_t *emu, uintptr_t fnc);
void iFppuu(x64emu_t *emu, uintptr_t fnc);
void iFppup(x64emu_t *emu, uintptr_t fnc);
void iFppdp(x64emu_t *emu, uintptr_t fnc);
void iFppll(x64emu_t *emu, uintptr_t fnc);
void iFpplp(x64emu_t *emu, uintptr_t fnc);
void iFppLi(x64emu_t *emu, uintptr_t fnc);
@@ -1523,6 +1525,7 @@ void iFpppippi(x64emu_t *emu, uintptr_t fnc);
void iFpppippp(x64emu_t *emu, uintptr_t fnc);
void iFpppuiii(x64emu_t *emu, uintptr_t fnc);
void iFppppiii(x64emu_t *emu, uintptr_t fnc);
void iFppppipp(x64emu_t *emu, uintptr_t fnc);
void iFppppdpi(x64emu_t *emu, uintptr_t fnc);
void iFpppppip(x64emu_t *emu, uintptr_t fnc);
void iFpppppup(x64emu_t *emu, uintptr_t fnc);
@@ -1637,7 +1640,9 @@ void iFpppiippp(x64emu_t *emu, uintptr_t fnc);
void iFpppipipi(x64emu_t *emu, uintptr_t fnc);
void iFpppipppp(x64emu_t *emu, uintptr_t fnc);
void iFppppiipi(x64emu_t *emu, uintptr_t fnc);
void iFppppippp(x64emu_t *emu, uintptr_t fnc);
void iFppppppii(x64emu_t *emu, uintptr_t fnc);
void iFpppppppi(x64emu_t *emu, uintptr_t fnc);
void iFpppppppp(x64emu_t *emu, uintptr_t fnc);
void uFEipipppp(x64emu_t *emu, uintptr_t fnc);
void uFEpiupppp(x64emu_t *emu, uintptr_t fnc);
@@ -1664,6 +1669,7 @@ void pFpCuuuCup(x64emu_t *emu, uintptr_t fnc);
void pFpWWiCpup(x64emu_t *emu, uintptr_t fnc);
void pFpuuWWCuu(x64emu_t *emu, uintptr_t fnc);
void pFpuuuupup(x64emu_t *emu, uintptr_t fnc);
void pFpuuupwwp(x64emu_t *emu, uintptr_t fnc);
void pFpdwwWWui(x64emu_t *emu, uintptr_t fnc);
void pFplpppppp(x64emu_t *emu, uintptr_t fnc);
void pFppiiiiii(x64emu_t *emu, uintptr_t fnc);
@@ -1706,6 +1712,7 @@ void vFpppppippp(x64emu_t *emu, uintptr_t fnc);
void iFEpiiiiipi(x64emu_t *emu, uintptr_t fnc);
void iFEpppipppp(x64emu_t *emu, uintptr_t fnc);
void iFEppplPPPP(x64emu_t *emu, uintptr_t fnc);
void iFEpppppupp(x64emu_t *emu, uintptr_t fnc);
void iFEppPPPPPP(x64emu_t *emu, uintptr_t fnc);
void iFiiiiiiiip(x64emu_t *emu, uintptr_t fnc);
void iFiiiipiiip(x64emu_t *emu, uintptr_t fnc);
@@ -1816,6 +1823,7 @@ void vFppppppppppp(x64emu_t *emu, uintptr_t fnc);
void iFEpppipppppp(x64emu_t *emu, uintptr_t fnc);
void iFEppppiiiiuu(x64emu_t *emu, uintptr_t fnc);
void iFiiiiiiiiiip(x64emu_t *emu, uintptr_t fnc);
void iFppippipppip(x64emu_t *emu, uintptr_t fnc);
void iFppppiiuuiiL(x64emu_t *emu, uintptr_t fnc);
void uFEpLiupppLuV(x64emu_t *emu, uintptr_t fnc);
void uFEpLippppLup(x64emu_t *emu, uintptr_t fnc);
@@ -1889,12 +1897,14 @@ void pFppippipipipipipip(x64emu_t *emu, uintptr_t fnc);
void vFppuiiiiipuiiiiiiii(x64emu_t *emu, uintptr_t fnc);
void vFpppipppppppppppppp(x64emu_t *emu, uintptr_t fnc);
void iFpppppppppppppppppp(x64emu_t *emu, uintptr_t fnc);
void LFpppppppppppppppppp(x64emu_t *emu, uintptr_t fnc);
void pFippppppppppppppppp(x64emu_t *emu, uintptr_t fnc);
void vFpiiiiiiiiiiiiiiiiii(x64emu_t *emu, uintptr_t fnc);
void pFiiiippppppppppppppp(x64emu_t *emu, uintptr_t fnc);
void pFpippppppppppppppppp(x64emu_t *emu, uintptr_t fnc);
void iFpppppppppppppppppppppp(x64emu_t *emu, uintptr_t fnc);
void pFipppppppppppppppppppppp(x64emu_t *emu, uintptr_t fnc);
void iFpppppppppppppppppppppppppppppppppp(x64emu_t *emu, uintptr_t fnc);
#if defined(HAVE_LD80BITS)
void DFD(x64emu_t *emu, uintptr_t fnc);
+24
View File
@@ -0,0 +1,24 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <dlfcn.h>
#include "wrappedlibs.h"
#include "wrapper.h"
#include "bridge.h"
#include "librarian/library_private.h"
#include "x64emu.h"
const char* lberName =
#ifdef ANDROID
"liblber-2.4.so"
#else
"liblber-2.4.so.2"
#endif
;
#define LIBNAME lber
#include "wrappedlib_init.h"
+140
View File
@@ -0,0 +1,140 @@
#if !(defined(GO) && defined(GOM) && defined(GO2) && defined(DATA))
#error Meh....
#endif
//GO(ber_alloc,
GO(ber_alloc_t, pFi)
//GO(ber_bprint,
GO(ber_bvarray_add, vFpp)
//GO(ber_bvarray_add_x,
//GO(ber_bvarray_dup_x,
GO(ber_bvarray_free, vFp)
//GO(ber_bvarray_free_x,
GO(ber_bvdup, pFp)
GO(ber_bvecadd, vFpp)
//GO(ber_bvecadd_x,
GO(ber_bvecfree, vFp)
//GO(ber_bvecfree_x,
GO(ber_bvfree, vFp)
//GO(ber_bvfree_x,
//GO(ber_bvreplace,
//GO(ber_bvreplace_x,
GO(ber_bvstr, pFp)
GO(ber_bvstrdup, pFp)
//GO(ber_decode_oid,
//GO(ber_dump,
//GO(ber_dup,
GO(ber_dupbv, pFpp)
//GO(ber_dupbv_x,
//GO(ber_encode_oid,
//GO(ber_errno_addr,
//GO(ber_error_print,
GO(ber_first_element, LFppp)
GO(ber_flatten, iFpp)
//GO(ber_flatten2,
GO(ber_flush, iFppi)
GO(ber_flush2, iFppi)
GO(ber_free, vFpi)
//GO(ber_free_buf,
GO(ber_get_bitstringa, LFppp)
GO(ber_get_boolean, LFpp)
GO(ber_get_enum, iFpp)
GO(ber_get_int, iFpp)
GO(ber_get_next, LFppp)
GO(ber_get_null, LFp)
//GO(ber_get_option,
GO(ber_get_stringa, LFpp)
GO(ber_get_stringal, LFpp)
//GO(ber_get_stringa_null,
GO(ber_get_stringb, LFppp)
GO(ber_get_stringbv, LFppi)
//GO(ber_get_stringbv_null,
//GO(ber_get_tag,
GO(ber_init, pFp)
GO(ber_init2, vFppi)
//GO(ber_init_w_nullc,
//DATAB(ber_int_errno_fn,
//DATAB(ber_int_log_proc,
//DATAB(ber_int_memory_fns,
//DATAB(ber_int_options,
//GO(ber_int_sb_close,
//GO(ber_int_sb_destroy,
//GO(ber_int_sb_init,
//GO(ber_int_sb_read,
//GO(ber_int_sb_write,
//GO(ber_len,
//GO(ber_log_bprint,
//GO(ber_log_dump,
//GO(ber_log_sos_dump,
//GO(ber_mem2bv,
//GO(ber_mem2bv_x,
//GO(ber_memalloc,
//GO(ber_memalloc_x,
//GO(ber_memcalloc,
//GO(ber_memcalloc_x,
//GO(ber_memfree,
//GO(ber_memfree_x,
//GO(ber_memrealloc,
//GO(ber_memrealloc_x,
//GO(ber_memvfree,
//GO(ber_memvfree_x,
GO(ber_next_element, LFppp)
//GO(ber_peek_element,
GO(ber_peek_tag, LFpp)
GO(ber_printf, iFpppppppppppppppppppppppppppppppppp) //VAArg. May need some wrapping...
//GO(ber_ptrlen,
//GO(ber_put_berval,
GO(ber_put_bitstring, iFppLL)
GO(ber_put_boolean, iFpiL)
GO(ber_put_enum, iFpiL)
GO(ber_put_int, iFpiL)
GO(ber_put_null, iFpL)
GO(ber_put_ostring, iFppLL)
GO(ber_put_seq, iFp)
GO(ber_put_set, iFp)
GO(ber_put_string, iFppL)
//DATAB(ber_pvt_err_file,
//GO(ber_pvt_log_output,
//DATA(ber_pvt_log_print,
//GO(ber_pvt_log_printf,
//DATAB(ber_pvt_opt_on,
//GO(ber_pvt_sb_buf_destroy,
//GO(ber_pvt_sb_buf_init,
//GO(ber_pvt_sb_copy_out,
//GO(ber_pvt_sb_do_write,
//GO(ber_pvt_sb_grow_buffer,
//GO(ber_pvt_socket_set_nonblock,
//GO(ber_read,
//GO(ber_realloc,
//GO(ber_remaining,
//GO(ber_reset,
//GO(ber_rewind,
GO(ber_scanf, LFpppppppppppppppppp) // VAArg
//GO(ber_set_option,
//GO(ber_skip_data,
//GO(ber_skip_element,
GO(ber_skip_tag, LFpp)
//GO(ber_sockbuf_add_io,
//GO(ber_sockbuf_alloc,
//GO(ber_sockbuf_ctrl,
//GO(ber_sockbuf_free,
//DATA(ber_sockbuf_io_debug,
//DATA(ber_sockbuf_io_fd,
//DATA(ber_sockbuf_io_readahead,
//DATA(ber_sockbuf_io_tcp,
//GO(ber_sockbuf_remove_io,
//GO(ber_sos_dump,
//GO(ber_start,
GO(ber_start_seq, iFpL)
GO(ber_start_set, iFpL)
GO(ber_str2bv, pFpLip)
//GO(ber_str2bv_x,
//GO(ber_strdup,
//GO(ber_strdup_x,
//GO(ber_strndup,
//GO(ber_strndup_x,
//GO(ber_strnlen,
//GO(ber_write,
//GO(der_alloc,
//GO(lutil_debug,
//GO(lutil_debug_file,
+113
View File
@@ -0,0 +1,113 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <dlfcn.h>
#include "wrappedlibs.h"
#include "debug.h"
#include "wrapper.h"
#include "bridge.h"
#include "librarian/library_private.h"
#include "x64emu.h"
#include "emu/x64emu_private.h"
#include "box64context.h"
#include "librarian.h"
#include "callback.h"
const char* ldaprName =
#ifdef ANDROID
"libldap_r-2.4.so"
#else
"libldap_r-2.4.so.2"
#endif
;
#define LIBNAME ldapr
static library_t *my_lib = NULL;
typedef int (*iFpppppupp_t) (void*, void*, void*, void* , void*, unsigned, void*, void*);
#define SUPER() \
GO(ldap_sasl_interactive_bind_s, iFpppppupp_t) \
typedef struct ldapr_my_s {
// functions
#define GO(A, B) B A;
SUPER()
#undef GO
} ldapr_my_t;
void* getLdaprMy(library_t* lib)
{
ldapr_my_t* my = (ldapr_my_t*)calloc(1, sizeof(ldapr_my_t));
#define GO(A, W) my->A = (W)dlsym(lib->priv.w.lib, #A);
SUPER()
#undef GO
return my;
}
#undef SUPER
void freeLdaprMy(void* lib)
{
//ldapr_my_t *my = (ldapr_my_t *)lib;
}
#define SUPER() \
GO(0) \
GO(1) \
GO(2) \
GO(3) \
GO(4)
// LDAP_SASL_INTERACT_PROC ...
#define GO(A) \
static uintptr_t my_LDAP_SASL_INTERACT_PROC_fct_##A = 0; \
static int my_LDAP_SASL_INTERACT_PROC_##A(void* a, unsigned b, void* c, void* d) \
{ \
return RunFunction(my_context, my_LDAP_SASL_INTERACT_PROC_fct_##A, 4, a, b, c, d); \
}
SUPER()
#undef GO
static void* find_LDAP_SASL_INTERACT_PROC_Fct(void* fct)
{
if(!fct) return fct;
if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
#define GO(A) if(my_LDAP_SASL_INTERACT_PROC_fct_##A == (uintptr_t)fct) return my_LDAP_SASL_INTERACT_PROC_##A;
SUPER()
#undef GO
#define GO(A) if(my_LDAP_SASL_INTERACT_PROC_fct_##A == 0) {my_LDAP_SASL_INTERACT_PROC_fct_##A = (uintptr_t)fct; return my_LDAP_SASL_INTERACT_PROC_##A; }
SUPER()
#undef GO
printf_log(LOG_NONE, "Warning, no more slot for libldap_r LDAP_SASL_INTERACT_PROC callback\n");
return NULL;
}
#undef SUPER
EXPORT int my_ldap_sasl_interactive_bind_s(x64emu_t* emu, void* ld, void* dn, void* mechs, void* sctrls, void* cctrls, unsigned flags, void* f, void* defaults)
{
ldapr_my_t* my = (ldapr_my_t*)my_lib->priv.w.p2;
return my->ldap_sasl_interactive_bind_s(ld, dn, mechs, sctrls, cctrls, flags, find_LDAP_SASL_INTERACT_PROC_Fct(f), defaults);
}
#ifdef ANDROID
#define NEEDED_LIB "liblber-2.4.so"
#else
#define NEEDED_LIB "liblber-2.4.so.2"
#endif
#define CUSTOM_INIT \
lib->priv.w.p2 = getLdaprMy(lib); \
lib->priv.w.needed = 1; \
lib->priv.w.neededlibs = (char**)calloc(lib->priv.w.needed, sizeof(char*)); \
lib->priv.w.neededlibs[0] = strdup(NEEDED_LIB); \
my_lib = lib;
#define CUSTOM_FINI \
freeLdaprMy(lib->priv.w.p2); \
free(lib->priv.w.p2); \
my_lib = NULL;
#include "wrappedlib_init.h"
+510
View File
@@ -0,0 +1,510 @@
#if !(defined(GO) && defined(GOM) && defined(GO2) && defined(DATA))
#error Meh....
#endif
GO(ldap_abandon, iFpi)
GO(ldap_abandon_ext, iFpipp)
//GO(ldap_add,
GO(ldap_add_ext, iFpppppp)
GO(ldap_add_ext_s, iFppppp)
//GO(ldap_add_result_entry,
//GO(ldap_add_s,
//GO(ldap_alloc_ber_with_options,
//GO(ldap_append_referral,
//GO(ldap_attributetype2bv,
//GO(ldap_attributetype2name,
//GO(ldap_attributetype2str,
//GO(ldap_attributetype_free,
GO(ldap_bind, iFpppi)
GO(ldap_bind_s, iFpppi)
//GO(ldap_build_add_req,
//GO(ldap_build_bind_req,
//GO(ldap_build_compare_req,
//GO(ldap_build_delete_req,
//GO(ldap_build_extended_req,
//GO(ldap_build_moddn_req,
//GO(ldap_build_modify_req,
//GO(ldap_build_search_req,
//GO(ldap_bv2dn,
//GO(ldap_bv2dn_x,
//GO(ldap_bv2escaped_filter_value,
//GO(ldap_bv2escaped_filter_value_len,
//GO(ldap_bv2escaped_filter_value_x,
//GO(ldap_bv2rdn,
//GO(ldap_bv2rdn_x,
//GO(ldap_cancel,
//GO(ldap_cancel_s,
//GO(ldap_charray2str,
//GO(ldap_charray_add,
//GO(ldap_charray_dup,
//GO(ldap_charray_free,
//GO(ldap_charray_inlist,
//GO(ldap_charray_merge,
//GO(ldap_chase_referrals,
//GO(ldap_chase_v3referrals,
//GO(ldap_clear_select_write,
//GO(ldap_compare,
GO(ldap_compare_ext, iFppppppp)
GO(ldap_compare_ext_s, iFpppppp)
//GO(ldap_compare_s,
//GO(ldap_connect_to_host,
//GO(ldap_connect_to_path,
//GO(ldap_contentrule2bv,
//GO(ldap_contentrule2name,
//GO(ldap_contentrule2str,
//GO(ldap_contentrule_free,
GO(ldap_control_create, iFpipip)
GO(ldap_control_dup, pFp)
GO(ldap_control_find, pFppp)
GO(ldap_control_free, vFp)
GO(ldap_controls_dup, pFp)
GO(ldap_controls_free, vFp)
GO(ldap_count_entries, iFpp)
//GO(ldap_count_messages,
GO(ldap_count_references, iFpp)
GO(ldap_count_values, iFp)
GO(ldap_count_values_len, iFp)
//GO(ldap_create,
//GO(ldap_create_assertion_control,
//GO(ldap_create_assertion_control_value,
//GO(ldap_create_control,
//GO(ldap_create_deref_control,
//GO(ldap_create_deref_control_value,
//GO(ldap_create_page_control,
//GO(ldap_create_page_control_value,
//GO(ldap_create_passwordpolicy_control,
//GO(ldap_create_session_tracking_control,
//GO(ldap_create_session_tracking_value,
GO(ldap_create_sort_control, iFppip)
//GO(ldap_create_sort_control_value,
//GO(ldap_create_sort_keylist,
GO(ldap_create_vlv_control, iFppp)
//GO(ldap_create_vlv_control_value,
GO(ldap_dcedn2dn, pFp)
GO(ldap_delete, iFpp)
GO(ldap_delete_ext, iFppppp)
GO(ldap_delete_ext_s, iFpppp)
//GO(ldap_delete_result_entry,
GO(ldap_delete_s, iFpp)
//GO(ldap_derefresponse_free,
//GO(ldap_destroy,
GO(ldap_dn2ad_canonical, pFp)
//GO(ldap_dn2bv,
//GO(ldap_dn2bv_x,
GO(ldap_dn2dcedn, pFp)
//GO(ldap_dn2domain,
GO(ldap_dn2str, iFppu)
GO(ldap_dn2ufn, pFp)
//GO(ldap_dnfree,
//GO(ldap_dnfree_x,
//GO(ldap_dn_normalize,
//GO(ldap_domain2dn,
//GO(ldap_domain2hostlist,
//GO(ldap_dump_connection,
//GO(ldap_dump_requests_and_responses,
//GO(ldap_dup,
//GO(ldap_err2string,
GO(ldap_explode_dn, pFpi)
GO(ldap_explode_rdn, pFpi)
GO(ldap_extended_operation, iFpppppp)
GO(ldap_extended_operation_s, iFppppppp)
//GO(ldap_find_control,
//GO(ldap_find_request_by_msgid,
GO(ldap_first_attribute, pFppp)
GO(ldap_first_entry, pFpp)
//GO(ldap_first_message,
GO(ldap_first_reference, pFpp)
//GO(ldap_free_connection,
//GO(ldap_free_request,
//GO(ldap_free_select_info,
//GO(ldap_free_sort_keylist,
//GO(ldap_free_urldesc,
//GO(ldap_free_urllist,
//GO(ldap_get_attribute_ber,
GO(ldap_get_dn, pFpp)
//GO(ldap_get_dn_ber,
//GO(ldap_get_entry_controls,
//GO(ldap_get_message_ber,
GO(ldap_get_option, iFpip)
GO(ldap_get_values, pFppp)
GO(ldap_get_values_len, pFppp)
//GO(ldap_gssapi_bind,
//GO(ldap_gssapi_bind_s,
//GO(ldap_host_connected_to,
GO(ldap_init, pFpi)
GO(ldap_init_fd, iFuipp)
GO(ldap_initialize, iFpp)
GO(ldap_install_tls, iFp)
//GO(ldap_int_bisect_delete,
//GO(ldap_int_bisect_find,
//GO(ldap_int_bisect_insert,
//GO(ldap_int_check_async_open,
//GO(ldap_int_client_controls,
//GO(ldap_int_connect_cbs,
//GO(ldap_int_error_init,
//GO(ldap_int_flush_request,
//DATA(ldap_int_global_options,
//DATAB(ldap_int_gmtime_mutex,
//DATAB(ldap_int_hostname,
//DATAB(ldap_int_hostname_mutex,
//DATAB(ldap_int_inet4or6,
//GO(ldap_int_initialize,
//GO(ldap_int_initialize_global_options,
//GO(ldap_int_msgtype2str,
//GO(ldap_int_open_connection,
//GO(ldap_int_parse_numericoid,
//GO(ldap_int_parse_ruleid,
//GO(ldap_int_poll,
//GO(ldap_int_put_controls,
//DATAB(ldap_int_resolv_mutex,
//GO(ldap_int_sasl_bind,
//GO(ldap_int_sasl_close,
//GO(ldap_int_sasl_config,
//GO(ldap_int_sasl_external,
//GO(ldap_int_sasl_get_option,
//GO(ldap_int_sasl_init,
//GO(ldap_int_sasl_open,
//GO(ldap_int_sasl_set_option,
//GO(ldap_int_select,
//GO(ldap_int_thread_destroy,
//GO(ldap_int_thread_initialize,
//GO(ldap_int_thread_pool_shutdown,
//GO(ldap_int_thread_pool_startup,
//GO(ldap_int_timeval_dup,
//GO(ldap_int_tls_config,
//GO(ldap_int_tls_destroy,
//DATA(ldap_int_tls_impl,
//GO(ldap_int_tls_start,
//GO(ldap_int_utils_init,
//GO(ldap_is_ldapi_url,
//GO(ldap_is_ldaps_url,
//GO(ldap_is_ldap_url,
//GO(ldap_is_read_ready,
//GO(ldap_is_write_ready,
//GO(ldap_ld_free,
//GO(ldap_log_printf,
//GO(ldap_mark_select_clear,
//GO(ldap_mark_select_read,
//GO(ldap_mark_select_write,
//GO(ldap_matchingrule2bv,
//GO(ldap_matchingrule2name,
//GO(ldap_matchingrule2str,
//GO(ldap_matchingrule_free,
//GO(ldap_matchingruleuse2bv,
//GO(ldap_matchingruleuse2name,
//GO(ldap_matchingruleuse2str,
//GO(ldap_matchingruleuse_free,
GO(ldap_memalloc, pFL)
GO(ldap_memcalloc, pFLL)
GO(ldap_memfree, vFp)
GO(ldap_memrealloc, pFpL)
GO(ldap_memvfree, vFp)
//GO(ldap_modify,
GO(ldap_modify_ext, iFpppppp)
GO(ldap_modify_ext_s, iFppppp)
//GO(ldap_modify_s,
//GO(ldap_modrdn,
//GO(ldap_modrdn2,
//GO(ldap_modrdn2_s,
//GO(ldap_modrdn_s,
GO(ldap_mods_free, vFpp)
//GO(ldap_msgdelete,
GO(ldap_msgfree, iFp)
GO(ldap_msgid, iFp)
GO(ldap_msgtype, iFp)
//GO(ldap_nameform2bv,
//GO(ldap_nameform2name,
//GO(ldap_nameform2str,
//GO(ldap_nameform_free,
//GO(ldap_new_connection,
//GO(ldap_new_select_info,
GO(ldap_next_attribute, pFppp)
GO(ldap_next_entry, pFpp)
//GO(ldap_next_message,
GO(ldap_next_reference, pFpp)
//GO(ldap_ntlm_bind,
//GO(ldap_objectclass2bv,
//GO(ldap_objectclass2name,
//GO(ldap_objectclass2str,
//GO(ldap_objectclass_free,
GO(ldap_open, pFpi)
//GO(ldap_open_defconn,
//GO(ldap_open_internal_connection,
//GO(ldap_parse_deref_control,
//GO(ldap_parse_derefresponse_control,
GO(ldap_parse_extended_result, iFppppi)
//GO(ldap_parse_intermediate,
//GO(ldap_parse_ntlm_bind_result,
//GO(ldap_parse_page_control,
//GO(ldap_parse_pageresponse_control,
//GO(ldap_parse_passwd,
//GO(ldap_parse_passwordpolicy_control,
GO(ldap_parse_reference, iFppppi)
//GO(ldap_parse_refresh,
GO(ldap_parse_result, iFpppppppi)
GO(ldap_parse_sasl_bind_result, iFpppi)
//GO(ldap_parse_session_tracking_control,
GO(ldap_parse_sortresponse_control, iFpppp)
GO(ldap_parse_vlvresponse_control, iFpppppp)
//GO(ldap_parse_whoami,
//GO(ldap_passwd,
//GO(ldap_passwd_s,
//GO(ldap_passwordpolicy_err2txt,
//GO(ldap_perror,
//GO(ldap_put_vrFilter,
//GO(ldap_pvt_bv2scope,
//GO(ldap_pvt_csnstr,
//GO(ldap_pvt_ctime,
//GO(ldap_pvt_discard,
//GO(ldap_pvt_filter_value_unescape,
//GO(ldap_pvt_find_wildcard,
//GO(ldap_pvt_get_controls,
//GO(ldap_pvt_get_fqdn,
//GO(ldap_pvt_get_hname,
//GO(ldap_pvt_gethostbyaddr_a,
//GO(ldap_pvt_gethostbyname_a,
//GO(ldap_pvt_gettime,
//GO(ldap_pvt_hex_unescape,
//GO(ldap_pvt_put_control,
//GO(ldap_pvt_put_filter,
//GO(ldap_pvt_runqueue_find,
//GO(ldap_pvt_runqueue_insert,
//GO(ldap_pvt_runqueue_isrunning,
//GO(ldap_pvt_runqueue_next_sched,
//GO(ldap_pvt_runqueue_persistent_backload,
//GO(ldap_pvt_runqueue_remove,
//GO(ldap_pvt_runqueue_resched,
//GO(ldap_pvt_runqueue_runtask,
//GO(ldap_pvt_runqueue_stoptask,
//GO(ldap_pvt_sasl_generic_install,
//GO(ldap_pvt_sasl_generic_remove,
//GO(ldap_pvt_sasl_getmechs,
//GO(ldap_pvt_sasl_install,
//GO(ldap_pvt_sasl_mutex_dispose,
//GO(ldap_pvt_sasl_mutex_lock,
//GO(ldap_pvt_sasl_mutex_new,
//GO(ldap_pvt_sasl_mutex_unlock,
//GO(ldap_pvt_sasl_remove,
//GO(ldap_pvt_sasl_secprops,
//GO(ldap_pvt_sasl_secprops_unparse,
//GO(ldap_pvt_scope2bv,
//GO(ldap_pvt_scope2str,
//GO(ldap_pvt_search,
//GO(ldap_pvt_search_s,
//DATA(ldap_pvt_sockbuf_io_sasl_generic,
//GO(ldap_pvt_str2lower,
//GO(ldap_pvt_str2lowerbv,
//GO(ldap_pvt_str2scope,
//GO(ldap_pvt_str2upper,
//GO(ldap_pvt_str2upperbv,
//GO(ldap_pvt_strtok,
//GO(ldap_pvt_thread_cond_broadcast,
//GO(ldap_pvt_thread_cond_destroy,
//GO(ldap_pvt_thread_cond_init,
//GO(ldap_pvt_thread_cond_signal,
//GO(ldap_pvt_thread_cond_wait,
//GO(ldap_pvt_thread_create,
//GO(ldap_pvt_thread_destroy,
//GO(ldap_pvt_thread_exit,
//GO(ldap_pvt_thread_get_concurrency,
//GO(ldap_pvt_thread_initialize,
//GO(ldap_pvt_thread_join,
//GO(ldap_pvt_thread_key_create,
//GO(ldap_pvt_thread_key_destroy,
//GO(ldap_pvt_thread_key_getdata,
//GO(ldap_pvt_thread_key_setdata,
//GO(ldap_pvt_thread_kill,
//GO(ldap_pvt_thread_mutex_destroy,
//GO(ldap_pvt_thread_mutex_init,
//GO(ldap_pvt_thread_mutex_lock,
//GO(ldap_pvt_thread_mutex_trylock,
//GO(ldap_pvt_thread_mutex_unlock,
//GO(ldap_pvt_thread_pool_backload,
//GO(ldap_pvt_thread_pool_context,
//GO(ldap_pvt_thread_pool_context_reset,
//GO(ldap_pvt_thread_pool_destroy,
//GO(ldap_pvt_thread_pool_getkey,
//GO(ldap_pvt_thread_pool_idle,
//GO(ldap_pvt_thread_pool_init,
//GO(ldap_pvt_thread_pool_maxthreads,
//GO(ldap_pvt_thread_pool_pause,
//GO(ldap_pvt_thread_pool_pausecheck,
//GO(ldap_pvt_thread_pool_pausing,
//GO(ldap_pvt_thread_pool_purgekey,
//GO(ldap_pvt_thread_pool_query,
//GO(ldap_pvt_thread_pool_resume,
//GO(ldap_pvt_thread_pool_retract,
//GO(ldap_pvt_thread_pool_setkey,
//GO(ldap_pvt_thread_pool_submit,
//GO(ldap_pvt_thread_pool_tid,
//GO(ldap_pvt_thread_pool_unidle,
//GO(ldap_pvt_thread_rdwr_destroy,
//GO(ldap_pvt_thread_rdwr_init,
//GO(ldap_pvt_thread_rdwr_rlock,
//GO(ldap_pvt_thread_rdwr_rtrylock,
//GO(ldap_pvt_thread_rdwr_runlock,
//GO(ldap_pvt_thread_rdwr_wlock,
//GO(ldap_pvt_thread_rdwr_wtrylock,
//GO(ldap_pvt_thread_rdwr_wunlock,
//GO(ldap_pvt_thread_rmutex_destroy,
//GO(ldap_pvt_thread_rmutex_init,
//GO(ldap_pvt_thread_rmutex_lock,
//GO(ldap_pvt_thread_rmutex_trylock,
//GO(ldap_pvt_thread_rmutex_unlock,
//GO(ldap_pvt_thread_self,
//GO(ldap_pvt_thread_set_concurrency,
//GO(ldap_pvt_thread_sleep,
//GO(ldap_pvt_thread_yield,
//GO(ldap_pvt_tls_accept,
//GO(ldap_pvt_tls_check_hostname,
//GO(ldap_pvt_tls_ctx_free,
//GO(ldap_pvt_tls_destroy,
//GO(ldap_pvt_tls_get_my_dn,
//GO(ldap_pvt_tls_get_option,
//GO(ldap_pvt_tls_get_peer_dn,
//GO(ldap_pvt_tls_get_strength,
//GO(ldap_pvt_tls_init,
//GO(ldap_pvt_tls_init_def_ctx,
//GO(ldap_pvt_tls_inplace,
//GO(ldap_pvt_tls_sb_ctx,
//GO(ldap_pvt_tls_set_option,
//GO(ldap_pvt_url_scheme2proto,
//GO(ldap_pvt_url_scheme2tls,
//GO(ldap_pvt_url_scheme_port,
//GO(ldap_rdn2bv,
//GO(ldap_rdn2bv_x,
//GO(ldap_rdn2str,
//GO(ldap_rdnfree,
//GO(ldap_rdnfree_x,
//GO(ldap_refresh,
//GO(ldap_refresh_s,
GO(ldap_rename, iFppppippp)
//GO(ldap_rename2,
//GO(ldap_rename2_s,
GO(ldap_rename_s, iFppppipp)
GO(ldap_result, iFppipp)
//GO(ldap_result2error,
//GO(ldap_return_request,
GO(ldap_sasl_bind, iFppppppp)
GO(ldap_sasl_bind_s, iFppppppp)
//GO(ldap_sasl_interactive_bind,
GOM(ldap_sasl_interactive_bind_s, iFEpppppupp)
//GO(ldap_scherr2str,
//GO(ldap_search,
GO(ldap_search_ext, iFppippipppip)
GO(ldap_search_ext_s, iFppippipppip)
//GO(ldap_search_s,
//GO(ldap_search_st,
//GO(ldap_send_initial_request,
//GO(ldap_send_server_request,
//GO(ldap_send_unbind,
//GO(ldap_set_ber_options,
//GO(ldap_set_nextref_proc,
GO(ldap_set_option, iFpip)
//GOM(ldap_set_rebind_proc, iFEpBp)
//GO(ldap_set_urllist_proc,
GO(ldap_simple_bind, iFppp)
GO(ldap_simple_bind_s, iFppp)
//GO(ldap_sort_entries,
//GO(ldap_sort_strcasecmp,
//GO(ldap_sort_values,
GO(ldap_start_tls, iFp)
GO(ldap_start_tls_s, iFppp)
//GO(ldap_str2attributetype,
//GO(ldap_str2charray,
//GO(ldap_str2contentrule,
GO(ldap_str2dn, iFppu)
//GO(ldap_str2matchingrule,
//GO(ldap_str2matchingruleuse,
//GO(ldap_str2nameform,
//GO(ldap_str2objectclass,
//GO(ldap_str2rdn,
//GO(ldap_str2structurerule,
//GO(ldap_str2syntax,
GO(ldap_strdup, pFp)
//GO(ldap_structurerule2bv,
//GO(ldap_structurerule2name,
//GO(ldap_structurerule2str,
//GO(ldap_structurerule_free,
//GO(ldap_sync_destroy,
//GO(ldap_sync_init,
//GO(ldap_sync_initialize,
//GO(ldap_sync_init_refresh_and_persist,
//GO(ldap_sync_init_refresh_only,
//GO(ldap_sync_poll,
//GO(ldap_syntax2bv,
//GO(ldap_syntax2name,
//GO(ldap_syntax2str,
//GO(ldap_syntax_free,
GO(ldap_tls_inplace, iFp)
//GO(ldap_turn,
//GO(ldap_turn_s,
//GO(ldap_ucs_to_utf8s,
GO(ldap_unbind, iFp)
GO(ldap_unbind_ext, iFppp)
GO(ldap_unbind_ext_s, iFppp)
GO(ldap_unbind_s, iFp)
//GO(ldap_url_desc2str,
//GO(ldap_url_dup,
//GO(ldap_url_duplist,
//GO(ldap_url_list2hosts,
//GO(ldap_url_list2urls,
//GO(ldap_url_parse,
//GO(ldap_url_parse_ext,
//GO(ldap_url_parsehosts,
//GO(ldap_url_parselist,
//GO(ldap_url_parselist_ext,
//GO(ldap_utf8_bytes,
//GO(ldap_utf8_charlen,
//GO(ldap_utf8_charlen2,
//GO(ldap_utf8_chars,
//GO(ldap_utf8_copy,
//GO(ldap_utf8_isalnum,
//GO(ldap_utf8_isalpha,
//GO(ldap_utf8_isascii,
//GO(ldap_utf8_isdigit,
//GO(ldap_utf8_islower,
//GO(ldap_utf8_isspace,
//GO(ldap_utf8_isupper,
//GO(ldap_utf8_isxdigit,
//GO(ldap_utf8_next,
//GO(ldap_utf8_offset,
//GO(ldap_utf8_prev,
//GO(ldap_utf8_strchr,
//GO(ldap_utf8_strcspn,
//GO(ldap_utf8_strpbrk,
//GO(ldap_utf8_strspn,
//GO(ldap_utf8_strtok,
//GO(ldap_value_dup,
GO(ldap_value_free, vFp)
GO(ldap_value_free_len, vFp)
//GO(ldap_whoami,
//GO(ldap_whoami_s,
//GO(ldap_X509dn2bv,
//GO(ldap_x_mbs_to_utf8s,
//GO(ldap_x_mb_to_utf8,
//GO(ldap_x_ucs4_to_utf8,
//GO(ldap_x_utf8s_to_mbs,
//GO(ldap_x_utf8s_to_wcs,
//GO(ldap_x_utf8_to_mb,
//GO(ldap_x_utf8_to_ucs4,
//GO(ldap_x_utf8_to_wc,
//GO(ldap_x_wcs_to_utf8s,
//GO(ldap_x_wc_to_utf8,
//GO(ldif_close,
//GO(ldif_countlines,
//DATAB(ldif_debug,
//GO(ldif_fetch_url,
//GO(ldif_getline,
//GO(ldif_is_not_printable,
//GO(ldif_must_b64_encode_register,
//GO(ldif_must_b64_encode_release,
//GO(ldif_open,
//GO(ldif_open_url,
//GO(ldif_parse_line,
//GO(ldif_parse_line2,
//GO(ldif_put,
//GO(ldif_put_wrap,
//GO(ldif_read_record,
//GO(ldif_sput,
//GO(ldif_sput_wrap,
+8 -4
View File
@@ -763,6 +763,14 @@ EXPORT int my___isoc99_fscanf(x64emu_t* emu, void* stream, void* fmt, uint64_t*
}
EXPORT int my_fscanf(x64emu_t* emu, void* stream, void* fmt, uint64_t* b) __attribute__((alias("my___isoc99_fscanf")));
EXPORT int my___isoc99_scanf(x64emu_t* emu, void* fmt, uint64_t* b)
{
myStackAlignScanf(emu, (const char*)fmt, b, emu->scratch, 1);
PREPARE_VALIST;
return vscanf(fmt, VARARGS);
}
EXPORT int my___isoc99_sscanf(x64emu_t* emu, void* stream, void* fmt, uint64_t* b)
{
myStackAlignScanf(emu, (const char*)fmt, b, emu->scratch, 2);
@@ -1653,8 +1661,6 @@ EXPORT int32_t my_execvp(x64emu_t* emu, const char* path, char* const argv[])
{
// need to use BOX64_PATH / PATH here...
char* fullpath = ResolveFile(path, &my_context->box64_path);
if(!fullpath)
fullpath = strdup(path);
// use fullpath...
int self = isProcSelf(fullpath, "exe");
int x64 = FileIsX64ELF(fullpath);
@@ -1705,8 +1711,6 @@ EXPORT int32_t my_execlp(x64emu_t* emu, const char* path)
{
// need to use BOX64_PATH / PATH here...
char* fullpath = ResolveFile(path, &my_context->box64_path);
if(!fullpath)
fullpath = strdup(path);
// use fullpath...
int self = isProcSelf(fullpath, "exe");
int x64 = FileIsX64ELF(fullpath);
+1 -1
View File
@@ -920,7 +920,7 @@ GO(__isnanl, iFD)
GOW(isnanl, iFD)
GOM(__isoc99_fscanf, iFEppV)
//GO(__isoc99_fwscanf, iFppV)
//GO(__isoc99_scanf, iFpV)
GOM(__isoc99_scanf, iFEpV)
GOM(__isoc99_sscanf, iFEppV)
//GO(__isoc99_swscanf, iFppV)
GOM(__isoc99_vfscanf, iFEppp)
+1 -1
View File
@@ -64,7 +64,7 @@ void* my_dlopen(x64emu_t* emu, void *filename, int flag)
CLEARERR
if(filename) {
char* rfilename = (char*)filename;
if(box64_zoom && strstr(rfilename, "/libturbojpeg.so")) {
if(box64_zoom && rfilename && strstr(rfilename, "/libturbojpeg.so")) {
void* sys = my_dlopen(emu, "libturbojpeg.so.0", flag);
if(sys)
return sys;
+5 -5
View File
@@ -2,8 +2,8 @@
#error meh!
#endif
//GO(xcb_shape_combine,
//GO(xcb_shape_combine_checked,
GO(xcb_shape_combine, pFpuuupwwp)
GO(xcb_shape_combine_checked, pFpuuupwwp)
//GO(xcb_shape_get_rectangles,
//GO(xcb_shape_get_rectangles_rectangles,
//GO(xcb_shape_get_rectangles_rectangles_iterator,
@@ -26,9 +26,9 @@ GO(xcb_shape_mask_checked, pFpuuuwwu)
//GO(xcb_shape_query_extents,
//GO(xcb_shape_query_extents_reply,
//GO(xcb_shape_query_extents_unchecked,
//GO(xcb_shape_query_version,
//GO(xcb_shape_query_version_reply,
//GO(xcb_shape_query_version_unchecked,
GO(xcb_shape_query_version, pFp)
GO(xcb_shape_query_version_reply, pFppp)
GO(xcb_shape_query_version_unchecked, pFp)
//GO(xcb_shape_rectangles,
//GO(xcb_shape_rectangles_checked,
//GO(xcb_shape_rectangles_rectangles,
+7
View File
@@ -1606,3 +1606,10 @@ DATAM(xmlFree, sizeof(void*))
DATAM(xmlMalloc, sizeof(void*))
DATAM(xmlRealloc, sizeof(void*))
DATAM(xmlMemStrdup, sizeof(void*))
DATA(xmlIsDigitGroup, 2*sizeof(void*)+2*sizeof(int))
DATA(xmlStringText, sizeof(void*))
DATA(xmlStringTextNoenc, sizeof(void*))
DATA(xmlIsCombiningGroup, 2*sizeof(void*)+2*sizeof(int))
DATA(xmlIsExtenderGroup, 2*sizeof(void*)+2*sizeof(int))
DATA(xmlIsBaseCharGroup, 2*sizeof(void*)+2*sizeof(int))
+135
View File
@@ -0,0 +1,135 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <dlfcn.h>
#include "wrappedlibs.h"
#include "debug.h"
#include "wrapper.h"
#include "bridge.h"
#include "librarian/library_private.h"
#include "x64emu.h"
#include "emu/x64emu_private.h"
#include "box64context.h"
#include "librarian.h"
#include "callback.h"
const char *xsltName =
#ifdef ANDROID
"libxslt.so"
#else
"libxslt.so.1"
#endif
;
#define LIBNAME xslt
static library_t *my_lib = NULL;
typedef void (*vFp_t) (void*);
typedef int (*iFppp_t) (void*, void*, void*);
#define SUPER() \
GO(xsltRegisterExtModuleFunction, iFppp_t) \
GO(xsltSetLoaderFunc, vFp_t) \
typedef struct xslt_my_s {
// functions
#define GO(A, B) B A;
SUPER()
#undef GO
} xslt_my_t;
void* getXsltMy(library_t* lib)
{
xslt_my_t* my = (xslt_my_t*)calloc(1, sizeof(xslt_my_t));
#define GO(A, W) my->A = (W)dlsym(lib->priv.w.lib, #A);
SUPER()
#undef GO
return my;
}
#undef SUPER
void freeXsltMy(void* lib)
{
//xslt_my_t *my = (xslt_my_t *)lib;
}
#define SUPER() \
GO(0) \
GO(1) \
GO(2) \
GO(3) \
GO(4)
// xmlXPathFunction ...
#define GO(A) \
static uintptr_t my_xmlXPathFunction_fct_##A = 0; \
static void my_xmlXPathFunction_##A(void* a, int b) \
{ \
RunFunction(my_context, my_xmlXPathFunction_fct_##A, 2, a, b); \
}
SUPER()
#undef GO
static void* find_xmlXPathFunction_Fct(void* fct)
{
if(!fct) return fct;
if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
#define GO(A) if(my_xmlXPathFunction_fct_##A == (uintptr_t)fct) return my_xmlXPathFunction_##A;
SUPER()
#undef GO
#define GO(A) if(my_xmlXPathFunction_fct_##A == 0) {my_xmlXPathFunction_fct_##A = (uintptr_t)fct; return my_xmlXPathFunction_##A; }
SUPER()
#undef GO
printf_log(LOG_NONE, "Warning, no more slot for libxslt xmlXPathFunction callback\n");
return NULL;
}
// xsltDocLoaderFunc ...
#define GO(A) \
static uintptr_t my_xsltDocLoaderFunc_fct_##A = 0; \
static void* my_xsltDocLoaderFunc_##A(void* a, void* b, int c, void* d, int e) \
{ \
return (void*)RunFunction(my_context, my_xsltDocLoaderFunc_fct_##A, 5, a, b, c, d, e); \
}
SUPER()
#undef GO
static void* find_xsltDocLoaderFunc_Fct(void* fct)
{
if(!fct) return fct;
if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
#define GO(A) if(my_xsltDocLoaderFunc_fct_##A == (uintptr_t)fct) return my_xsltDocLoaderFunc_##A;
SUPER()
#undef GO
#define GO(A) if(my_xsltDocLoaderFunc_fct_##A == 0) {my_xsltDocLoaderFunc_fct_##A = (uintptr_t)fct; return my_xsltDocLoaderFunc_##A; }
SUPER()
#undef GO
printf_log(LOG_NONE, "Warning, no more slot for libxslt xsltDocLoaderFunc callback\n");
return NULL;
}
#undef SUPER
EXPORT int my_xsltRegisterExtModuleFunction(x64emu_t* emu, void* name, void* URI, void* f)
{
xslt_my_t* my = (xslt_my_t*)my_lib->priv.w.p2;
return my->xsltRegisterExtModuleFunction(name, URI, find_xmlXPathFunction_Fct(f));
}
EXPORT void my_xsltSetLoaderFunc(x64emu_t* emu, void* f)
{
xslt_my_t* my = (xslt_my_t*)my_lib->priv.w.p2;
my->xsltSetLoaderFunc(find_xsltDocLoaderFunc_Fct(f));
}
#define CUSTOM_INIT \
lib->priv.w.p2 = getXsltMy(lib); \
my_lib = lib;
#define CUSTOM_FINI \
freeXsltMy(lib->priv.w.p2); \
free(lib->priv.w.p2); \
my_lib = NULL;
#include "wrappedlib_init.h"
+247
View File
@@ -0,0 +1,247 @@
#if !(defined(GO) && defined(GOM) && defined(GO2) && defined(DATA))
#error meh!
#endif
GO(xslAddCall, iFpp)
GO(xslDropCall, vFv)
GO(xslHandleDebugger, vFpppp)
//GO(xsltAddKey,
GO(xsltAddStackElemList, iFpp)
//GO(xsltAddTemplate,
GO(xsltAllocateExtra, iFp)
GO(xsltAllocateExtraCtxt, iFp)
//GO(xsltApplyAttributeSet,
GO(xsltApplyImports, vFpppp)
GO(xsltApplyOneTemplate, vFppppp)
GO(xsltApplyStripSpaces, vFpp)
GO(xsltApplyStylesheet, pFppp)
GO(xsltApplyStylesheetUser, pFpppppp)
GO(xsltApplyTemplates, vFpppp)
GO(xsltAttribute, vFpppp)
//GO(xsltAttrListTemplateProcess,
//GO(xsltAttrTemplateProcess,
//GO(xsltAttrTemplateValueProcess,
//GO(xsltAttrTemplateValueProcessNode,
GO(xsltCalibrateAdjust, vFl)
GO(xsltCallTemplate, vFpppp)
GO(xsltCheckExtPrefix, iFpp)
GO(xsltCheckExtURI, iFpp)
GO(xsltCheckRead, iFppp)
GO(xsltCheckWrite, iFppp)
GO(xsltChoose, vFpppp)
GO(xsltCleanupGlobals, vFv)
//GO(xsltCleanupTemplates,
GO(xsltComment, vFpppp)
GO(xsltCompileAttr, vFpp)
//GO(xsltCompilePattern,
GO(xsltComputeSortResult, pFpp)
GO(xsltCopy, vFpppp)
//GO(xsltCopyNamespace,
//GO(xsltCopyNamespaceList,
GO(xsltCopyOf, vFpppp)
GO(xsltCopyTextString, pFpppi)
//GO(xsltCopyTree,
GO(xsltCreateRVT, pFp)
GO(xsltDebug, vFpppp)
GO(xsltDebugDumpExtensions, vFp)
GO(xsltDebugGetDefaultTrace, iFv)
GO(xsltDebugSetDefaultTrace, vFi)
GO(xsltDecimalFormatGetByName, pFpp)
GO(xsltDecimalFormatGetByQName, pFppp)
GO(xsltDefaultSortFunction, vFppi)
//GO(xsltDocumentComp,
GO(xsltDocumentElem, vFpppp)
//GO(xsltDocumentFunction,
GO(xsltDocumentSortFunction, vFp)
GO(xsltDoSortFunction, vFppi)
GO(xsltElement, vFpppp)
//GO(xsltElementAvailableFunction,
//GO(xsltEvalAttrValueTemplate,
GO(xsltEvalAVT, pFppp)
GO(xsltEvalGlobalVariables, iFp)
GO(xsltEvalOneUserParam, iFppp)
//GO(xsltEvalStaticAttrValueTemplate,
//GO(xsltEvalTemplateString,
GO(xsltEvalUserParams, iFpp)
//GO(xsltEvalXPathPredicate,
//GO(xsltEvalXPathString,
//GO(xsltEvalXPathStringNs,
//GOM(xsltExtElementLookup, BFEppp)
GO(xsltExtensionInstructionResultFinalize, iFp)
GO(xsltExtensionInstructionResultRegister, iFpp)
//GOM(xsltExtModuleElementLookup, BFEpp)
//GOM(xsltExtModuleElementPreComputeLookup, BFEpp)
//GOM(xsltExtModuleFunctionLookup, BFEpp)
//GOM(xsltExtModuleTopLevelLookup, BFEpp)
GO(xsltFindDocument, pFpp)
GO(xsltFindElemSpaceHandling, iFpp)
GO(xsltFindTemplate, pFppp)
GO(xsltFlagRVTs, iFppp)
GO(xsltForEach, vFpppp)
GO(xsltFormatNumberConversion, iFppdp)
//GO(xsltFormatNumberFunction,
//GO(xsltFreeAttributeSetsHashes,
GO(xsltFreeAVTList, vFp)
//GO(xsltFreeCompMatchList,
GO(xsltFreeCtxtExts, vFp)
//GO(xsltFreeDocumentKeys,
GO(xsltFreeDocuments, vFp)
GO(xsltFreeExts, vFp)
GO(xsltFreeGlobalVariables, vFp)
//GO(xsltFreeKeys,
//GO(xsltFreeLocale,
//GO(xsltFreeNamespaceAliasHashes,
GO(xsltFreeRVTs, vFp)
GO(xsltFreeSecurityPrefs, vFp)
GO(xsltFreeStackElemList, vFp)
GO(xsltFreeStyleDocuments, vFp)
//GO(xsltFreeStylePreComps,
GO(xsltFreeStylesheet, vFp)
//GO(xsltFreeTemplateHashes,
GO(xsltFreeTransformContext, vFp)
//GO(xsltFunctionAvailableFunction,
GO(xsltFunctionNodeSet, vFpi)
//GO(xsltGenerateIdFunction,
GO(xsltGetCNsProp, pFpppp)
GO(xsltGetDebuggerStatus, iFv)
//GO(xsltGetDefaultSecurityPrefs,
GO(xsltGetExtData, pFpp)
GO(xsltGetExtInfo, pFpp)
//GO(xsltGetKey,
//GO(xsltGetNamespace,
GO(xsltGetNsProp, pFppp)
//GO(xsltGetPlainNamespace,
GO(xsltGetProfileInformation, pFp)
GO(xsltGetQNameURI, pFpp)
GO(xsltGetQNameURI2, pFppp)
GO(xsltGetSecurityPrefs, pFpi)
//GO(xsltGetSpecialNamespace,
//GO(xsltGetTemplate,
GO(xsltGetUTF8Char, iFpp)
GO(xsltGetXIncludeDefault, iFv)
GO(xsltIf, vFpppp)
GO(xsltInit, vFv)
GO(xsltInitAllDocKeys, iFp)
GO(xsltInitCtxtExts, iFp)
//GO(xsltInitCtxtKey,
//GO(xsltInitCtxtKeys,
//GOM(xsltInitElemPreComp, vFEpppBB)
GO(xsltInitGlobals, vFv)
GO(xsltIsBlank, iFp)
//GO(xsltKeyFunction,
GO(xsltLoadDocument, pFpp)
GO(xsltLoadStyleDocument, pFpp)
GO(xsltLoadStylesheetPI, pFp)
//GO(xsltLocaleStrcmp,
GO(xsltLocalVariablePop, vFpii)
GO(xsltLocalVariablePush, iFppi)
GO(xsltMessage, vFppp)
//GO(xsltNamespaceAlias,
GO(xsltNeedElemSpaceHandling, iFp)
GO(xsltNewDocument, pFpp)
//GOM(xsltNewElemPreComp, pFEppB)
//GO(xsltNewLocale,
GO(xsltNewSecurityPrefs, pFv)
GO(xsltNewStyleDocument, pFpp)
GO(xsltNewStylesheet, pFv)
GO(xsltNewTransformContext, pFpp)
GO(xsltNextImport, pFp)
//GO(xsltNormalizeCompSteps,
GO(xsltNumber, vFpppp)
GO(xsltNumberFormat, vFppp)
GO(xsltParseAnyXSLTElem, iFpp)
GO(xsltParseGlobalParam, vFpp)
GO(xsltParseGlobalVariable, vFpp)
GO(xsltParseSequenceConstructor, vFpp)
//GO(xsltParseStylesheetAttributeSet,
GO(xsltParseStylesheetCallerParam, pFpp)
GO(xsltParseStylesheetDoc, pFp)
GO(xsltParseStylesheetFile, pFp)
GO(xsltParseStylesheetImport, iFpp)
GO(xsltParseStylesheetImportedDoc, pFpp)
GO(xsltParseStylesheetInclude, iFpp)
GO(xsltParseStylesheetOutput, vFpp)
GO(xsltParseStylesheetParam, vFpp)
GO(xsltParseStylesheetProcess, pFpp)
GO(xsltParseStylesheetVariable, vFpp)
//GO(xsltParseTemplateContent,
GO(xsltPointerListAddSize, iFppi)
GO(xsltPointerListClear, vFp)
GO(xsltPointerListCreate, pFi)
GO(xsltPointerListFree, vFp)
GO(xsltPreComputeExtModuleElement, pFpp)
GO(xsltPrintErrorContext, vFppp)
GO(xsltProcessingInstruction, vFpppp)
GO(xsltProcessOneNode, vFppp)
GO(xsltProfileStylesheet, pFpppp)
GO(xsltQuoteOneUserParam, iFppp)
GO(xsltQuoteUserParams, iFpp)
GO(xsltRegisterAllElement, vFp)
GO(xsltRegisterAllExtras, vFv)
//GO(xsltRegisterAllFunctions,
//GOM(xsltRegisterExtElement, iFEpppB)
//GOM(xsltRegisterExtFunction, iFEpppB)
//GOM(xsltRegisterExtModule, iFEpBB)
//GOM(xsltRegisterExtModuleElement, iFEppBB)
//GOM(xsltRegisterExtModuleFull, iFEpBBBB)
GOM(xsltRegisterExtModuleFunction, iFEppp)
//GOM(xsltRegisterExtModuleTopLevel, iFEppB)
GO(xsltRegisterExtPrefix, iFppp)
GO(xsltRegisterExtras, vFp)
GO(xsltRegisterLocalRVT, iFpp)
GO(xsltRegisterPersistRVT, iFpp)
GO(xsltRegisterTestModule, vFv)
GO(xsltRegisterTmpRVT, iFpp)
GO(xsltReleaseRVT, vFpp)
//GO(xsltResolveStylesheetAttributeSet,
GO(xsltRestoreDocumentNamespaces, iFpp)
GO(xsltRunStylesheet, iFpppppp)
GO(xsltRunStylesheetUser, iFpppppppp)
GO(xsltSaveProfiling, vFpp)
GO(xsltSaveResultTo, iFppp)
GO(xsltSaveResultToFd, iFipp)
GO(xsltSaveResultToFile, iFppp)
GO(xsltSaveResultToFilename, iFpppi)
GO(xsltSaveResultToString, iFpppp)
GO(xsltSecurityAllow, iFppp)
GO(xsltSecurityForbid, iFppp)
GO(xsltSetCtxtParseOptions, iFpi)
GO(xsltSetCtxtSecurityPrefs, iFpp)
//GOM(xsltSetCtxtSortFunc, vFEpB)
//GOM(xsltSetDebuggerCallbacks, iFip)
GO(xsltSetDebuggerStatus, vFi)
GO(xsltSetDefaultSecurityPrefs, vFp)
//GOM(xsltSetGenericDebugFunc, vFEpB)
//GOM(xsltSetGenericErrorFunc, vFEpB)
GOM(xsltSetLoaderFunc, vFEp)
//GOM(xsltSetSecurityPrefs, iFEppB)
//GOM(xsltSetSortFunc, vFEp)
//GO(MxsltSetTransformErrorFunc, vFEppB)
GO(xsltSetXIncludeDefault, vFi)
GO(xsltShutdownCtxtExts, vFp)
GO(xsltShutdownExts, vFp)
GO(xsltSort, vFpppp)
GO(xsltSplitQName, pFppp)
//GO(xsltStrxfrm,
GO(xsltStyleGetExtData, pFpp)
//GO(xsltStylePreCompute,
GO(xsltStyleStylesheetLevelGetExtData, pFpp)
//GO(xsltSystemPropertyFunction,
//GO(xsltTemplateProcess,
//GO(xsltTestCompMatchList,
GO(xsltText, vFpppp)
GO(xsltTimestamp, lFv)
GO(xsltTransformError, vFpppppppppppppppp) //vaarg
GO(xsltUninit, vFv)
//GO(xsltUnparsedEntityURIFunction,
GO(xsltUnregisterExtModule, iFp)
GO(xsltUnregisterExtModuleElement, iFpp)
GO(xsltUnregisterExtModuleFunction, iFpp)
GO(xsltUnregisterExtModuleTopLevel, iFpp)
GO(xsltValueOf, vFpppp)
GO(xsltVariableLookup, pFppp)
GO(xsltXPathCompile, pFpp)
GO(xsltXPathCompileFlags, pFppi)
GO(xsltXPathFunctionLookup, pFppp)
GO(xsltXPathGetTransformContext, pFp)
//GO(xsltXPathVariableLookup,
+154 -12
View File
@@ -1,12 +1,154 @@
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
ucomiss 1.000000, 2.000000 => 0x202
ucomiss 2.000000, 1.000000 => 0x203
ucomiss 1.000000, inf => 0x202
ucomiss inf, 1.000000 => 0x203
ucomiss 1.000000, -inf => 0x203
ucomiss -inf, 1.000000 => 0x202
ucomiss 1.000000, nan => 0x247
ucomiss nan, 1.000000 => 0x247
ucomiss 1.000000, 1.000000 => 0x242
ucomiss 1.000000, 1.000000 => 0x242
ucomiss inf, inf => 0x242
ucomiss -inf, inf => 0x202
ucomiss inf, -inf => 0x203
ucomiss nan, nan => 0x247
minss 1, 2 => 1
minss 2, 1 => 1
minss -inf, 2 => -inf
minss 2, -inf => -inf
minss inf, 2 => 2
minss 2, inf => 2
minss nan, 2 => 2
minss 2, nan => nan
minss nan, 3.40282e+38 => 3.40282e+38
minss 3.40282e+38, nan => nan
minss -inf, 3.40282e+38 => -inf
minss 3.40282e+38, -inf => -inf
minss inf, 3.40282e+38 => 3.40282e+38
minss 3.40282e+38, inf => 3.40282e+38
maxss 1, 2 => 2
maxss 2, 1 => 2
maxss -inf, 2 => 2
maxss 2, -inf => 2
maxss inf, 2 => inf
maxss 2, inf => inf
maxss nan, 2 => 2
maxss 2, nan => nan
maxss nan, 3.40282e+38 => 3.40282e+38
maxss 3.40282e+38, nan => nan
maxss -inf, 3.40282e+38 => 3.40282e+38
maxss 3.40282e+38, -inf => 3.40282e+38
maxss inf, 3.40282e+38 => inf
maxss 3.40282e+38, inf => inf
cmpss 0 1.000000, 2.000000 => 0x0
cmpss 0 2.000000, 1.000000 => 0x0
cmpss 0 1.000000, inf => 0x0
cmpss 0 inf, 1.000000 => 0x0
cmpss 0 1.000000, -inf => 0x0
cmpss 0 -inf, 1.000000 => 0x0
cmpss 0 1.000000, nan => 0x0
cmpss 0 nan, 1.000000 => 0x0
cmpss 0 1.000000, 1.000000 => 0xffffffff
cmpss 0 1.000000, 1.000000 => 0xffffffff
cmpss 0 inf, inf => 0xffffffff
cmpss 0 -inf, inf => 0x0
cmpss 0 inf, -inf => 0x0
cmpss 0 nan, nan => 0x0
cmpss 1 1.000000, 2.000000 => 0xffffffff
cmpss 1 2.000000, 1.000000 => 0x0
cmpss 1 1.000000, inf => 0xffffffff
cmpss 1 inf, 1.000000 => 0x0
cmpss 1 1.000000, -inf => 0x0
cmpss 1 -inf, 1.000000 => 0xffffffff
cmpss 1 1.000000, nan => 0x0
cmpss 1 nan, 1.000000 => 0x0
cmpss 1 1.000000, 1.000000 => 0x0
cmpss 1 1.000000, 1.000000 => 0x0
cmpss 1 inf, inf => 0x0
cmpss 1 -inf, inf => 0xffffffff
cmpss 1 inf, -inf => 0x0
cmpss 1 nan, nan => 0x0
cmpss 2 1.000000, 2.000000 => 0xffffffff
cmpss 2 2.000000, 1.000000 => 0x0
cmpss 2 1.000000, inf => 0xffffffff
cmpss 2 inf, 1.000000 => 0x0
cmpss 2 1.000000, -inf => 0x0
cmpss 2 -inf, 1.000000 => 0xffffffff
cmpss 2 1.000000, nan => 0x0
cmpss 2 nan, 1.000000 => 0x0
cmpss 2 1.000000, 1.000000 => 0xffffffff
cmpss 2 1.000000, 1.000000 => 0xffffffff
cmpss 2 inf, inf => 0xffffffff
cmpss 2 -inf, inf => 0xffffffff
cmpss 2 inf, -inf => 0x0
cmpss 2 nan, nan => 0x0
cmpss 3 1.000000, 2.000000 => 0x0
cmpss 3 2.000000, 1.000000 => 0x0
cmpss 3 1.000000, inf => 0x0
cmpss 3 inf, 1.000000 => 0x0
cmpss 3 1.000000, -inf => 0x0
cmpss 3 -inf, 1.000000 => 0x0
cmpss 3 1.000000, nan => 0xffffffff
cmpss 3 nan, 1.000000 => 0xffffffff
cmpss 3 1.000000, 1.000000 => 0x0
cmpss 3 1.000000, 1.000000 => 0x0
cmpss 3 inf, inf => 0x0
cmpss 3 -inf, inf => 0x0
cmpss 3 inf, -inf => 0x0
cmpss 3 nan, nan => 0xffffffff
cmpss 4 1.000000, 2.000000 => 0xffffffff
cmpss 4 2.000000, 1.000000 => 0xffffffff
cmpss 4 1.000000, inf => 0xffffffff
cmpss 4 inf, 1.000000 => 0xffffffff
cmpss 4 1.000000, -inf => 0xffffffff
cmpss 4 -inf, 1.000000 => 0xffffffff
cmpss 4 1.000000, nan => 0xffffffff
cmpss 4 nan, 1.000000 => 0xffffffff
cmpss 4 1.000000, 1.000000 => 0x0
cmpss 4 1.000000, 1.000000 => 0x0
cmpss 4 inf, inf => 0x0
cmpss 4 -inf, inf => 0xffffffff
cmpss 4 inf, -inf => 0xffffffff
cmpss 4 nan, nan => 0xffffffff
cmpss 5 1.000000, 2.000000 => 0x0
cmpss 5 2.000000, 1.000000 => 0xffffffff
cmpss 5 1.000000, inf => 0x0
cmpss 5 inf, 1.000000 => 0xffffffff
cmpss 5 1.000000, -inf => 0xffffffff
cmpss 5 -inf, 1.000000 => 0x0
cmpss 5 1.000000, nan => 0xffffffff
cmpss 5 nan, 1.000000 => 0xffffffff
cmpss 5 1.000000, 1.000000 => 0xffffffff
cmpss 5 1.000000, 1.000000 => 0xffffffff
cmpss 5 inf, inf => 0xffffffff
cmpss 5 -inf, inf => 0x0
cmpss 5 inf, -inf => 0xffffffff
cmpss 5 nan, nan => 0xffffffff
cmpss 6 1.000000, 2.000000 => 0x0
cmpss 6 2.000000, 1.000000 => 0xffffffff
cmpss 6 1.000000, inf => 0x0
cmpss 6 inf, 1.000000 => 0xffffffff
cmpss 6 1.000000, -inf => 0xffffffff
cmpss 6 -inf, 1.000000 => 0x0
cmpss 6 1.000000, nan => 0xffffffff
cmpss 6 nan, 1.000000 => 0xffffffff
cmpss 6 1.000000, 1.000000 => 0x0
cmpss 6 1.000000, 1.000000 => 0x0
cmpss 6 inf, inf => 0x0
cmpss 6 -inf, inf => 0x0
cmpss 6 inf, -inf => 0xffffffff
cmpss 6 nan, nan => 0xffffffff
cmpss 7 1.000000, 2.000000 => 0xffffffff
cmpss 7 2.000000, 1.000000 => 0xffffffff
cmpss 7 1.000000, inf => 0xffffffff
cmpss 7 inf, 1.000000 => 0xffffffff
cmpss 7 1.000000, -inf => 0xffffffff
cmpss 7 -inf, 1.000000 => 0xffffffff
cmpss 7 1.000000, nan => 0x0
cmpss 7 nan, 1.000000 => 0x0
cmpss 7 1.000000, 1.000000 => 0xffffffff
cmpss 7 1.000000, 1.000000 => 0xffffffff
cmpss 7 inf, inf => 0xffffffff
cmpss 7 -inf, inf => 0xffffffff
cmpss 7 inf, -inf => 0xffffffff
cmpss 7 nan, nan => 0x0
BIN
View File
Binary file not shown.
+177 -27
View File
@@ -6,45 +6,195 @@
#include <math.h>
#if defined(__x86_64__)
uint64_t _div_(uint64_t a, uint64_t b, uint64_t *r)
uint64_t _ucomiss_(float a, float b)
{
uint64_t ret, rem;
uint64_t ret;
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;
"ucomiss %%xmm0, %%xmm1\n"
"pushf\n"
"pop %%rax"
:"=a" (ret)::"xmm0","xmm1","cc");
return ret;
}
uint64_t _idiv_(uint64_t a, uint64_t b, uint64_t *r)
uint64_t _minss_(float a, float b)
{
uint64_t ret, rem;
uint64_t ret;
asm volatile (
"cqo\n"
"idiv %%rcx\n"
"mov %%rdx, %%rbx\n"
:"=a" (ret), "=b" (rem):"a" (a), "c" (b):"rdx","cc");
*r = rem;
"minss %%xmm1, %%xmm0\n"
"movd %%xmm0, %%eax"
:"=a" (ret)::"xmm0","xmm1","cc");
return ret;
}
uint64_t _maxss_(float a, float b)
{
uint64_t ret;
asm volatile (
"maxss %%xmm1, %%xmm0\n"
"movd %%xmm0, %%eax"
:"=a" (ret)::"xmm0","xmm1","cc");
return ret;
}
#define CMPSS(A) \
uint64_t _cmpss_##A(float a, float b) \
{ \
uint64_t ret; \
asm volatile ( \
"cmpss $" #A ", %%xmm1, %%xmm0\n" \
"movd %%xmm0, %%eax" \
:"=a" (ret)::"xmm0","xmm1","cc"); \
return ret; \
}
#else
uint64_t _ucomiss_(float a, float b)
{
uint32_t ret;
asm volatile (
"movss %1, %%xmm0\n"
"movss %2, %%xmm1\n"
"ucomiss %%xmm0, %%xmm1\n"
"pushf\n"
"pop %%eax"
:"=a" (ret):"m"(a), "m"(b):"xmm0", "xmm1", "cc");
return ret;
}
uint64_t _minss_(float a, float b)
{
uint32_t ret;
asm volatile (
"movss %1, %%xmm0\n"
"movss %2, %%xmm1\n"
"minss %%xmm1, %%xmm0\n"
"movd %%xmm0, %%eax"
:"=a" (ret):"m"(a), "m"(b):"xmm0", "xmm1", "cc");
return ret;
}
uint64_t _maxss_(float a, float b)
{
uint32_t ret;
asm volatile (
"movss %1, %%xmm0\n"
"movss %2, %%xmm1\n"
"maxss %%xmm1, %%xmm0\n"
"movd %%xmm0, %%eax"
:"=a" (ret):"m"(a), "m"(b):"xmm0", "xmm1", "cc");
return ret;
}
#define CMPSS(A) \
uint64_t _cmpss_##A(float a, float b) \
{ \
uint32_t ret; \
asm volatile ( \
"movss %1, %%xmm0\n" \
"movss %2, %%xmm1\n" \
"cmpss $" #A ", %%xmm1, %%xmm0\n" \
"movd %%xmm0, %%eax" \
:"=a" (ret):"m"(a), "m"(b):"xmm0", "xmm1", "cc"); \
return ret; \
}
#endif
CMPSS(0)
CMPSS(1)
CMPSS(2)
CMPSS(3)
CMPSS(4)
CMPSS(5)
CMPSS(6)
CMPSS(7)
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}};
float a, b;
uint64_t flags;
uint32_t maxf = 0x7f7fffff;
uint32_t minf = 0xff7fffff;
uint32_t r;
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;
#define GO1(A, N) \
a = 1.0f; b = 2.0f; \
flags = A(a, b); \
printf(N " %f, %f => 0x%lx\n", a, b, flags); \
flags = A(b, a); \
printf(N " %f, %f => 0x%lx\n", b, a, flags); \
b = INFINITY; \
flags = A(a, b); \
printf(N " %f, %f => 0x%lx\n", a, b, flags); \
flags = A(b, a); \
printf(N " %f, %f => 0x%lx\n", b, a, flags); \
b = -INFINITY; \
flags = A(a, b); \
printf(N " %f, %f => 0x%lx\n", a, b, flags); \
flags = A(b, a); \
printf(N " %f, %f => 0x%lx\n", b, a, flags); \
b = NAN; \
flags = A(a, b); \
printf(N " %f, %f => 0x%lx\n", a, b, flags); \
flags = A(b, a); \
printf(N " %f, %f => 0x%lx\n", b, a, flags); \
b = a; \
flags = A(a, b); \
printf(N " %f, %f => 0x%lx\n", a, b, flags); \
flags = A(b, a); \
printf(N " %f, %f => 0x%lx\n", b, a, flags); \
a = b = INFINITY; \
flags = A(a, b); \
printf(N " %f, %f => 0x%lx\n", a, b, flags); \
a = -INFINITY; \
flags = A(a, b); \
printf(N " %f, %f => 0x%lx\n", a, b, flags); \
flags = A(b, a); \
printf(N " %f, %f => 0x%lx\n", b, a, flags); \
a = b = NAN; \
flags = A(a, b); \
printf(N " %f, %f => 0x%lx\n", a, b, flags);
#define GO2(A, N) \
a = 1.0f; b = 2.0f; \
r = A(a, b); \
printf(N " %g, %g => %g\n", a, b, *(float*)&r); \
r = A(b, a); \
printf(N " %g, %g => %g\n", b, a, *(float*)&r); \
a = -INFINITY; \
r = A(a, b); \
printf(N " %g, %g => %g\n", a, b, *(float*)&r); \
r = A(b, a); \
printf(N " %g, %g => %g\n", b, a, *(float*)&r); \
a = +INFINITY; \
r = A(a, b); \
printf(N " %g, %g => %g\n", a, b, *(float*)&r); \
r = A(b, a); \
printf(N " %g, %g => %g\n", b, a, *(float*)&r); \
a = NAN; \
r = A(a, b); \
printf(N " %g, %g => %g\n", a, b, *(float*)&r); \
r = A(b, a); \
printf(N " %g, %g => %g\n", b, a, *(float*)&r); \
b = *(float*)&maxf; \
r = A(a, b); \
printf(N " %g, %g => %g\n", a, b, *(float*)&r); \
r = A(b, a); \
printf(N " %g, %g => %g\n", b, a, *(float*)&r); \
a = -INFINITY; \
r = A(a, b); \
printf(N " %g, %g => %g\n", a, b, *(float*)&r); \
r = A(b, a); \
printf(N " %g, %g => %g\n", b, a, *(float*)&r); \
a = +INFINITY; \
r = A(a, b); \
printf(N " %g, %g => %g\n", a, b, *(float*)&r); \
r = A(b, a); \
printf(N " %g, %g => %g\n", b, a, *(float*)&r);
GO1(_ucomiss_, "ucomiss")
GO2(_minss_, "minss")
GO2(_maxss_, "maxss")
GO1(_cmpss_0, "cmpss 0")
GO1(_cmpss_1, "cmpss 1")
GO1(_cmpss_2, "cmpss 2")
GO1(_cmpss_3, "cmpss 3")
GO1(_cmpss_4, "cmpss 4")
GO1(_cmpss_5, "cmpss 5")
GO1(_cmpss_6, "cmpss 6")
GO1(_cmpss_7, "cmpss 7")
return 0;
}