From 9705d5e38bdf4ec72daf480de0830dfde6e33a70 Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Sat, 18 Feb 2023 15:06:40 +0100 Subject: Preliminary work to get steamwebhelper working --- src/include/custommem.h | 6 +++++- src/include/debug.h | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'src/include') diff --git a/src/include/custommem.h b/src/include/custommem.h index 42f75a89..590fd561 100644 --- a/src/include/custommem.h +++ b/src/include/custommem.h @@ -38,13 +38,17 @@ uintptr_t getJumpAddress64(uintptr_t addr); #define PROT_DYNAREC 0x80 #define PROT_DYNAREC_R 0x40 -#define PROT_CUSTOM (PROT_DYNAREC | PROT_DYNAREC_R) +#define PROT_MMAP 0x20 +#define PROT_DYN (PROT_DYNAREC | PROT_DYNAREC_R) +#define PROT_CUSTOM (PROT_DYNAREC | PROT_DYNAREC_R | PROT_MMAP) void updateProtection(uintptr_t addr, size_t size, uint32_t prot); void setProtection(uintptr_t addr, size_t size, uint32_t prot); +void setProtection_mmap(uintptr_t addr, size_t size, uint32_t prot); void freeProtection(uintptr_t addr, size_t size); void refreshProtection(uintptr_t addr); uint32_t getProtection(uintptr_t addr); +int getMmapped(uintptr_t addr); void loadProtectionFromMap(); #ifdef DYNAREC void protectDB(uintptr_t addr, size_t size); diff --git a/src/include/debug.h b/src/include/debug.h index 7251c728..0a6f722e 100755 --- a/src/include/debug.h +++ b/src/include/debug.h @@ -45,6 +45,7 @@ extern char* box64_trace; extern uint64_t start_cnt; #endif extern int box64_nosandbox; +extern int box64_malloc_hack; extern int box64_dummy_crashhandler; extern int box64_sse_flushto0; extern int allow_missing_libs; -- cgit 1.4.1 From 5d42d9212fde49278e0ad0167edd77755a2fbcd9 Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Sun, 19 Feb 2023 14:50:01 +0100 Subject: Improved convertion to/from 80bits double, and added BOX64_X87_NO80BITS to not handle them --- docs/USAGE.md | 10 ++++++++++ src/dynarec/arm64/dynarec_arm64_db.c | 30 +++++++++++++++++++++--------- src/emu/x87emu_private.c | 30 +++++++++++++++++++++++++++++- src/include/debug.h | 1 + src/main.c | 7 +++++++ src/tools/rcfile.c | 1 + 6 files changed, 69 insertions(+), 10 deletions(-) (limited to 'src/include') diff --git a/docs/USAGE.md b/docs/USAGE.md index e961ebb2..fa908e46 100755 --- a/docs/USAGE.md +++ b/docs/USAGE.md @@ -187,6 +187,16 @@ Behavior with FillBlock is not availble (FillBlock build Dynarec blocks and is n * 0 : Dynarec will not wait for FillBlock to ready and use Interpreter instead (might speedup a bit massive multithread or JIT programs) * 1 : Dynarec will wait for FillBlock to be ready (Default) +#### BOX64_SSE_FLUSHTO0 * +Handling of SSE Flush to 0 flags +* 0 : Just track the flag (Default) +* 1 : Direct apply of SSE Flush to 0 flag + +#### BOX64_X87_NO80BITS * +Handling of x87 80bits long double +* 0 : Try to handle 80bits long double as precise as possible (Default) +* 1 : Handle them as double + #### BOX64_LIBGL * * libXXXX set the name for libGL (defaults to libGL.so.1). * /PATH/TO/libGLXXX : Sets the name and path for libGL diff --git a/src/dynarec/arm64/dynarec_arm64_db.c b/src/dynarec/arm64/dynarec_arm64_db.c index b9d71080..e40cc71d 100644 --- a/src/dynarec/arm64/dynarec_arm64_db.c +++ b/src/dynarec/arm64/dynarec_arm64_db.c @@ -295,21 +295,33 @@ uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin STRx_U12(x5, ed, 0); STRH_U12(x6, ed, 8); } else { - if(ed!=x1) { - MOVx_REG(x1, ed); + if(box64_x87_no80bits) { + v1 = x87_do_push(dyn, ninst, x1, NEON_CACHE_ST_D); + addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0xfff<<3, 7, rex, NULL, 0, 0); + VLDR64_U12(v1, ed, fixedaddress); + } else { + if(ed!=x1) { + MOVx_REG(x1, ed); + } + x87_do_push_empty(dyn, ninst, x3); + CALL(arm_fld, -1); } - x87_do_push_empty(dyn, ninst, x3); - CALL(arm_fld, -1); } break; case 7: INST_NAME("FSTP tbyte"); - x87_forget(dyn, ninst, x1, x3, 0); - addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0, 0, rex, NULL, 0, 0); - if(ed!=x1) { - MOVx_REG(x1, ed); + if(box64_x87_no80bits) { + v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D); + addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0xfff<<3, 7, rex, NULL, 0, 0); + VSTR64_U12(v1, wback, fixedaddress); + } else { + x87_forget(dyn, ninst, x1, x3, 0); + addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0, 0, rex, NULL, 0, 0); + if(ed!=x1) { + MOVx_REG(x1, ed); + } + CALL(arm_fstp, -1); } - CALL(arm_fstp, -1); x87_do_pop(dyn, ninst, x3); break; default: diff --git a/src/emu/x87emu_private.c b/src/emu/x87emu_private.c index 2114c00d..9f4b8af6 100755 --- a/src/emu/x87emu_private.c +++ b/src/emu/x87emu_private.c @@ -83,6 +83,10 @@ void fpu_fbld(x64emu_t* emu, uint8_t* s) { // long double (80bits) -> double (64bits) void LD2D(void* ld, void* d) { + if(box64_x87_no80bits) { + *(uint64_t*)d = *(uint64_t*)ld; + return; + } FPU_t result; #pragma pack(push, 1) struct { @@ -122,7 +126,7 @@ void LD2D(void* ld, void* d) *(uint64_t*)d = result.q; return; } - if(((uint32_t)(val.b&0x7fff)==0) || (exp64<=0)) { + if(((uint32_t)(val.b&0x7fff)==0) || (exp64<-1074)) { //if(val.f.q==0) // zero //if(val.f.q!=0) @@ -134,6 +138,18 @@ void LD2D(void* ld, void* d) return; } + if(exp64<=0 && val.f.q) { + // try to see if it can be a denormal + int one = -exp64-1022; + uint64_t r = 0; + if(val.b&0x8000) + r |= 0x8000000000000000L; + r |= val.f.q>>one; + *(uint64_t*)d = r; + return; + + } + if(exp64>=0x7ff) { // to big value... result.d = HUGE_VAL; @@ -154,6 +170,10 @@ void LD2D(void* ld, void* d) // double (64bits) -> long double (80bits) void D2LD(void* d, void* ld) { + if(box64_x87_no80bits) { + *(uint64_t*)ld = *(uint64_t*)d; + return; + } #pragma pack(push, 1) struct { FPU_t f; @@ -190,6 +210,12 @@ void D2LD(void* d, void* ld) if(exp80!=0){ mant80final |= 0x8000000000000000L; exp80final += (BIAS80 - BIAS64); + } else if(mant80final!=0) { + // denormals -> normal + exp80final = BIAS80-1023; + int one = __builtin_clz(mant80final) + 1; + exp80final -= one; + mant80final<<=one; } } val.b = ((int16_t)(sign80)<<15)| (int16_t)(exp80final); @@ -201,6 +227,8 @@ void D2LD(void* d, void* ld) double FromLD(void* ld) { + if(box64_x87_no80bits) + return *(double*)ld; double ret; // cannot add = 0; it break factorio (issue when calling fmodl) LD2D(ld, &ret); return ret; diff --git a/src/include/debug.h b/src/include/debug.h index 0a6f722e..024805a1 100755 --- a/src/include/debug.h +++ b/src/include/debug.h @@ -48,6 +48,7 @@ extern int box64_nosandbox; extern int box64_malloc_hack; extern int box64_dummy_crashhandler; extern int box64_sse_flushto0; +extern int box64_x87_no80bits; extern int allow_missing_libs; extern int box64_mapclean; extern int box64_prefer_wrapped; diff --git a/src/main.c b/src/main.c index 4c0af6cd..ea809e54 100755 --- a/src/main.c +++ b/src/main.c @@ -93,6 +93,7 @@ int allow_missing_libs = 0; int box64_prefer_emulated = 0; int box64_prefer_wrapped = 0; int box64_sse_flushto0 = 0; +int box64_x87_no80bits = 0; int fix_64bit_inodes = 0; int box64_dummy_crashhandler = 1; int box64_mapclean = 0; @@ -965,6 +966,12 @@ void LoadEnvVars(box64context_t *context) printf_log(LOG_INFO, "BOX64: Direct apply of SSE Flush to 0 flag\n"); } } + if(getenv("BOX64_X87_NO80BITS")) { + if (strcmp(getenv("BOX64_X87_NO80BITS"), "1")==0) { + box64_x87_no80bits = 1; + printf_log(LOG_INFO, "BOX64: all 80bits x87 long double will be handle as double\n"); + } + } if(getenv("BOX64_PREFER_WRAPPED")) { if (strcmp(getenv("BOX64_PREFER_WRAPPED"), "1")==0) { box64_prefer_wrapped = 1; diff --git a/src/tools/rcfile.c b/src/tools/rcfile.c index 8a2ac920..75df7137 100644 --- a/src/tools/rcfile.c +++ b/src/tools/rcfile.c @@ -64,6 +64,7 @@ ENTRYBOOL(BOX64_X11THREADS, box64_x11threads) \ ENTRYBOOL(BOX64_X11GLX, box64_x11glx) \ ENTRYDSTRING(BOX64_LIBGL, box64_libGL) \ ENTRYBOOL(BOX64_SSE_FLUSHTO0, box64_sse_flushto0) \ +ENTRYBOOL(BOX64_X87_NO80BITS, box64_x87_no80bits) \ ENTRYSTRING_(BOX64_EMULATED_LIBS, emulated_libs) \ ENTRYBOOL(BOX64_ALLOWMISSINGLIBS, allow_missing_libs) \ ENTRYBOOL(BOX64_PREFER_WRAPPED, box64_prefer_wrapped) \ -- cgit 1.4.1 From c4b57774f0b4794ad22e3e8c9fb4be760431b64e Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Thu, 2 Mar 2023 19:38:23 +0100 Subject: [DYNAREC] Finetuned the jump table memory allocation --- src/custommem.c | 229 ++++++++++++++++++------------- src/dynarec/arm64/dynarec_arm64_helper.c | 24 ++-- src/include/box64context.h | 1 - src/include/custommem.h | 13 ++ 4 files changed, 160 insertions(+), 107 deletions(-) (limited to 'src/include') diff --git a/src/custommem.c b/src/custommem.c index e261b62f..f0936b73 100644 --- a/src/custommem.c +++ b/src/custommem.c @@ -33,10 +33,11 @@ // init inside dynablocks.c static mmaplist_t *mmaplist = NULL; -static uintptr_t*** box64_jmptbl3[1<chunks[i].block = p; list->chunks[i].first = p; @@ -607,110 +623,112 @@ void cleanDBFromAddressRange(uintptr_t addr, size_t size, int destroy) } } -int addJumpTableIfDefault64(void* addr, void* jmp) +static uintptr_t *create_jmptbl(uintptr_t idx0, uintptr_t idx1, uintptr_t idx2, uintptr_t idx3) { - uintptr_t idx3, idx2, idx1, idx0; - idx3 = (((uintptr_t)addr)>>48)&0xffff; - idx2 = (((uintptr_t)addr)>>32)&0xffff; - idx1 = (((uintptr_t)addr)>>16)&0xffff; - idx0 = (((uintptr_t)addr) )&0xffff; if(box64_jmptbl3[idx3] == box64_jmptbldefault2) { - uintptr_t*** tbl = (uintptr_t***)box_malloc((1<>JMPTABL_START3)&JMPTABLE_MASK3; + idx2 = (((uintptr_t)addr)>>JMPTABL_START2)&JMPTABLE_MASK2; + idx1 = (((uintptr_t)addr)>>JMPTABL_START1)&JMPTABLE_MASK1; + idx0 = (((uintptr_t)addr) )&JMPTABLE_MASK0; - return (native_lock_storeifref(&box64_jmptbl3[idx3][idx2][idx1][idx0], jmp, native_next)==jmp)?1:0; + return (native_lock_storeifref(create_jmptbl(idx0, idx1, idx2, idx3), jmp, native_next)==jmp)?1:0; } void setJumpTableDefault64(void* addr) { uintptr_t idx3, idx2, idx1, idx0; - idx3 = (((uintptr_t)addr)>>48)&0xffff; + idx3 = (((uintptr_t)addr)>>JMPTABL_START3)&JMPTABLE_MASK3; if(box64_jmptbl3[idx3] == box64_jmptbldefault2) return; - idx2 = (((uintptr_t)addr)>>32)&0xffff; + idx2 = (((uintptr_t)addr)>>JMPTABL_START2)&JMPTABLE_MASK2; if(box64_jmptbl3[idx3][idx2] == box64_jmptbldefault1) return; - idx1 = (((uintptr_t)addr)>>16)&0xffff; + idx1 = (((uintptr_t)addr)>>JMPTABL_START1)&JMPTABLE_MASK1; if(box64_jmptbl3[idx3][idx2][idx1] == box64_jmptbldefault0) return; - idx0 = (((uintptr_t)addr) )&0xffff; + idx0 = (((uintptr_t)addr) )&JMPTABLE_MASK0; box64_jmptbl3[idx3][idx2][idx1][idx0] = (uintptr_t)native_next; } void setJumpTableDefaultRef64(void* addr, void* jmp) { uintptr_t idx3, idx2, idx1, idx0; - idx3 = (((uintptr_t)addr)>>48)&0xffff; + idx3 = (((uintptr_t)addr)>>JMPTABL_START3)&JMPTABLE_MASK3; if(box64_jmptbl3[idx3] == box64_jmptbldefault2) return; - idx2 = (((uintptr_t)addr)>>32)&0xffff; + idx2 = (((uintptr_t)addr)>>JMPTABL_START2)&JMPTABLE_MASK2; if(box64_jmptbl3[idx3][idx2] == box64_jmptbldefault1) return; - idx1 = (((uintptr_t)addr)>>16)&0xffff; + idx1 = (((uintptr_t)addr)>>JMPTABL_START1)&JMPTABLE_MASK1; if(box64_jmptbl3[idx3][idx2][idx1] == box64_jmptbldefault0) return; - idx0 = (((uintptr_t)addr) )&0xffff; + idx0 = (((uintptr_t)addr) )&JMPTABLE_MASK0; native_lock_storeifref(&box64_jmptbl3[idx3][idx2][idx1][idx0], native_next, jmp); } int setJumpTableIfRef64(void* addr, void* jmp, void* ref) { uintptr_t idx3, idx2, idx1, idx0; - idx3 = (((uintptr_t)addr)>>48)&0xffff; - idx2 = (((uintptr_t)addr)>>32)&0xffff; - idx1 = (((uintptr_t)addr)>>16)&0xffff; - idx0 = (((uintptr_t)addr) )&0xffff; - if(box64_jmptbl3[idx3] == box64_jmptbldefault2) { - uintptr_t*** tbl = (uintptr_t***)box_malloc((1<>JMPTABL_START3)&JMPTABLE_MASK3; + idx2 = (((uintptr_t)addr)>>JMPTABL_START2)&JMPTABLE_MASK2; + idx1 = (((uintptr_t)addr)>>JMPTABL_START1)&JMPTABLE_MASK1; + idx0 = (((uintptr_t)addr) )&JMPTABLE_MASK0; + return (native_lock_storeifref(create_jmptbl(idx0, idx1, idx2, idx3), jmp, ref)==jmp)?1:0; } int isJumpTableDefault64(void* addr) { uintptr_t idx3, idx2, idx1, idx0; - idx3 = (((uintptr_t)addr)>>48)&0xffff; + idx3 = (((uintptr_t)addr)>>JMPTABL_START3)&JMPTABLE_MASK3; if(box64_jmptbl3[idx3] == box64_jmptbldefault2) return 1; - idx2 = (((uintptr_t)addr)>>32)&0xffff; + idx2 = (((uintptr_t)addr)>>JMPTABL_START2)&JMPTABLE_MASK2; if(box64_jmptbl3[idx3][idx2] == box64_jmptbldefault1) return 1; - idx1 = (((uintptr_t)addr)>>16)&0xffff; + idx1 = (((uintptr_t)addr)>>JMPTABL_START1)&JMPTABLE_MASK1; if(box64_jmptbl3[idx3][idx2][idx1] == box64_jmptbldefault0) return 1; - idx0 = (((uintptr_t)addr) )&0xffff; + idx0 = (((uintptr_t)addr) )&JMPTABLE_MASK0; return (box64_jmptbl3[idx3][idx2][idx1][idx0]==(uintptr_t)native_next)?1:0; } uintptr_t getJumpTable64() @@ -721,42 +739,20 @@ uintptr_t getJumpTable64() uintptr_t getJumpTableAddress64(uintptr_t addr) { uintptr_t idx3, idx2, idx1, idx0; - idx3 = ((addr)>>48)&0xffff; - idx2 = ((addr)>>32)&0xffff; - idx1 = ((addr)>>16)&0xffff; - idx0 = ((addr) )&0xffff; - if(box64_jmptbl3[idx3] == box64_jmptbldefault2) { - uintptr_t*** tbl = (uintptr_t***)box_malloc((1<>JMPTABL_START3)&JMPTABLE_MASK3; + idx2 = ((addr)>>JMPTABL_START2)&JMPTABLE_MASK2; + idx1 = ((addr)>>JMPTABL_START1)&JMPTABLE_MASK1; + idx0 = ((addr) )&JMPTABLE_MASK0; + return (uintptr_t)create_jmptbl(idx0, idx1, idx2, idx3); } dynablock_t* getDB(uintptr_t addr) { uintptr_t idx3, idx2, idx1, idx0; - idx3 = ((addr)>>48)&0xffff; - idx2 = ((addr)>>32)&0xffff; - idx1 = ((addr)>>16)&0xffff; - idx0 = ((addr) )&0xffff; + idx3 = ((addr)>>JMPTABL_START3)&JMPTABLE_MASK3; + idx2 = ((addr)>>JMPTABL_START2)&JMPTABLE_MASK2; + idx1 = ((addr)>>JMPTABL_START1)&JMPTABLE_MASK1; + idx0 = ((addr) )&JMPTABLE_MASK0; /*if(box64_jmptbl3[idx3] == box64_jmptbldefault2) { return NULL; } @@ -788,6 +784,10 @@ void protectDB(uintptr_t addr, uintptr_t size) if(memprot[i].prot==memprot_default) { uint8_t* newblock = box_calloc(1<<16, sizeof(uint8_t)); memprot[i].prot = newblock; +#ifdef TRACE_MEMSTAT + memprot_allocated += (1<<16) * sizeof(uint8_t); + if (memprot_allocated > memprot_max_allocated) memprot_max_allocated = memprot_allocated; +#endif } for (uintptr_t i=idx; i<=end; ++i) { uint32_t prot = memprot[i>>16].prot[i&0xffff]; @@ -966,6 +966,10 @@ void updateProtection(uintptr_t addr, size_t size, uint32_t prot) if(memprot[i].prot==memprot_default) { uint8_t* newblock = box_calloc(1<<16, sizeof(uint8_t)); memprot[i].prot = newblock; +#ifdef TRACE_MEMSTAT + memprot_allocated += (1<<16) * sizeof(uint8_t); + if (memprot_allocated > memprot_max_allocated) memprot_max_allocated = memprot_allocated; +#endif } for (uintptr_t i=idx; i<=end; ++i) { uint32_t old_prot = memprot[i>>16].prot[i&0xffff]; @@ -994,6 +998,10 @@ void setProtection(uintptr_t addr, size_t size, uint32_t prot) if(memprot[i].prot==memprot_default && prot) { uint8_t* newblock = box_calloc(MEMPROT_SIZE, sizeof(uint8_t)); memprot[i].prot = newblock; +#ifdef TRACE_MEMSTAT + memprot_allocated += (1<<16) * sizeof(uint8_t); + if (memprot_allocated > memprot_max_allocated) memprot_max_allocated = memprot_allocated; +#endif } if(prot || memprot[i].prot!=memprot_default) { uintptr_t bstart = ((i<<16) memprot_max_allocated) memprot_max_allocated = memprot_allocated; +#endif } } native_lock_storeb(&memprot[idx].hot[base], box64_dynarec_hotpage); @@ -1157,6 +1170,9 @@ void freeProtection(uintptr_t addr, size_t size) if(start==0 && finish==MEMPROT_SIZE-1) { memprot[key].prot = memprot_default; box_free(block); +#ifdef TRACE_MEMSTAT + memprot_allocated -= (1<<16) * sizeof(uint8_t); +#endif } else { memset(block+start, 0, (finish-start+1)*sizeof(uint8_t)); // blockempty is quite slow, so disable the free of blocks for now @@ -1170,6 +1186,9 @@ void freeProtection(uintptr_t addr, size_t size) uint8_t *hot = memprot[key].hot; memprot[key].hot = NULL; box_free(hot); +#ifdef TRACE_MEMSTAT + memprot_allocated -= (1<<16) * sizeof(uint8_t); +#endif } i+=finish-start; // +1 from the "for" loop } @@ -1323,12 +1342,14 @@ void init_custommem_helper(box64context_t* ctx) init_mutexes(); #ifdef DYNAREC if(box64_dynarec) - for(int i=0; i<(1< njmps_in_lv1_max) njmps_in_lv1_max = njmps_in_cur_lv1; + } + } + } + printf_log(LOG_INFO, "Allocation:\n- dynarec: %lld kio\n- customMalloc: %lld kio\n- memprot: %lld kio (peak at %lld kio)\n- jump table: %lld kio (%lld level 3, %lld level 2, %lld level 1 table allocated, for %lld jumps, with at most %lld per level 1)\n", dynarec_allocated / 1024, customMalloc_allocated / 1024, memprot_allocated / 1024, memprot_max_allocated / 1024, jmptbl_allocated / 1024, jmptbl_allocated3, jmptbl_allocated2, jmptbl_allocated1, njmps, njmps_in_lv1_max); +#endif if(!inited) return; inited = 0; @@ -1370,11 +1411,11 @@ void fini_custommem_helper(box64context_t *ctx) } box_free(mmaplist); - for (int i3=0; i3<(1< Date: Fri, 3 Mar 2023 10:53:07 +0100 Subject: Better way to use CREATE_VALIST_FROM_VAARG macro --- src/include/myalign.h | 4 +++- src/wrapped/wrappedlibc.c | 8 ++++---- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'src/include') diff --git a/src/include/myalign.h b/src/include/myalign.h index 4a705afa..cc4922bd 100755 --- a/src/include/myalign.h +++ b/src/include/myalign.h @@ -50,7 +50,7 @@ typedef struct { memcpy(&p[6], emu->xmm, 8*16); \ } - +#define PREFER_CONVERT_VAARG #elif defined(__aarch64__) // aarch64: 8 64bits general regs and 8 128bits float regs @@ -92,6 +92,8 @@ typedef struct va_list { memcpy(&p[6], emu->xmm, 8*16); \ } +#define PREFER_CONVERT_VAARG + #elif defined(__sw_64__) /* or Alpha */ /* typdef struct { diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c index 39c905ec..0f9ae4a5 100755 --- a/src/wrapped/wrappedlibc.c +++ b/src/wrapped/wrappedlibc.c @@ -763,7 +763,7 @@ EXPORT void *my_div(void *result, int numerator, int denominator) { #endif EXPORT int my_snprintf(x64emu_t* emu, void* buff, size_t s, void * fmt, uint64_t * b) { - #ifdef CREATE_VALIST_FROM_VAARG + #ifdef PREFER_CONVERT_VAARG CREATE_VALIST_FROM_VAARG(b, emu->scratch, 3); #else myStackAlign(emu, (const char*)fmt, b, emu->scratch, R_EAX, 3); @@ -776,7 +776,7 @@ EXPORT int my___snprintf(x64emu_t* emu, void* buff, size_t s, void * fmt, uint64 EXPORT int my___snprintf_chk(x64emu_t* emu, void* buff, size_t s, int flags, size_t maxlen, void * fmt, uint64_t * b) { (void)flags; (void)maxlen; - #ifdef CREATE_VALIST_FROM_VAARG + #ifdef PREFER_CONVERT_VAARG CREATE_VALIST_FROM_VAARG(b, emu->scratch, 5); #else myStackAlign(emu, (const char*)fmt, b, emu->scratch, R_EAX, 5); @@ -787,7 +787,7 @@ EXPORT int my___snprintf_chk(x64emu_t* emu, void* buff, size_t s, int flags, siz } EXPORT int my_sprintf(x64emu_t* emu, void* buff, void * fmt, void * b) { - #ifdef CREATE_VALIST_FROM_VAARG + #ifdef PREFER_CONVERT_VAARG CREATE_VALIST_FROM_VAARG(b, emu->scratch, 2); #else myStackAlign(emu, (const char*)fmt, b, emu->scratch, R_EAX, 2); @@ -797,7 +797,7 @@ EXPORT int my_sprintf(x64emu_t* emu, void* buff, void * fmt, void * b) { } EXPORT int my___sprintf_chk(x64emu_t* emu, void* buff, int flag, size_t l, void * fmt, void * b) { (void)flag; (void)l; - #ifdef CREATE_VALIST_FROM_VAARG + #ifdef PREFER_CONVERT_VAARG CREATE_VALIST_FROM_VAARG(b, emu->scratch, 4); #else myStackAlign(emu, (const char*)fmt, b, emu->scratch, R_EAX, 4); -- cgit 1.4.1 From 219ac40a7dffe17a3417dd94910bedf6ea06fe45 Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Sun, 5 Mar 2023 09:59:26 +0100 Subject: [DYNAREC] Fixed (again) and improved new jmptable memory manager --- src/custommem.c | 24 +++++++++++++----------- src/include/custommem.h | 6 +++--- 2 files changed, 16 insertions(+), 14 deletions(-) (limited to 'src/include') diff --git a/src/custommem.c b/src/custommem.c index 6cb011c1..633e15fe 100644 --- a/src/custommem.c +++ b/src/custommem.c @@ -581,21 +581,23 @@ static uintptr_t getDBSize(uintptr_t addr, size_t maxsize, dynablock_t** db) uintptr_t idx0 = addr&JMPTABLE_MASK0; *db = *(dynablock_t**)(box64_jmptbl3[idx3][idx2][idx1][idx0]- sizeof(void*)); if(*db) - return 1; + return addr+1; if(box64_jmptbl3[idx3] == box64_jmptbldefault2) - return (addr|((1LL<>JMPTABL_START2)+1)<JMPTABLE_MASK0+1) - maxsize = JMPTABLE_MASK0+1; - while(idx0>JMPTABL_START1)+1)<JMPTABLE_MASK0) + maxsize = JMPTABLE_MASK0; + while(block[idx0]==(uintptr_t)native_next) { ++idx0; - if(idx0maxsize) + return (addr&~JMPTABLE_MASK0)+idx0; + } + *db = *(dynablock_t**)(block[idx0]- sizeof(void*)); + return (addr&~JMPTABLE_MASK0)+idx0+1; } // each dynmap is 64k of size @@ -613,7 +615,7 @@ void cleanDBFromAddressRange(uintptr_t addr, size_t size, int destroy) dynablock_t* db = NULL; uintptr_t end = addr+size; while (start_addr Date: Sun, 5 Mar 2023 11:48:48 +0100 Subject: Added automatic detection of libcef (will help zoon #510, #451, #302 and probably other too) --- docs/USAGE.md | 5 +++++ src/include/debug.h | 1 + src/librarian/library.c | 4 ++++ src/main.c | 10 ++++++++++ src/tools/rcfile.c | 1 + 5 files changed, 21 insertions(+) (limited to 'src/include') diff --git a/docs/USAGE.md b/docs/USAGE.md index 9000da1a..cc95735d 100755 --- a/docs/USAGE.md +++ b/docs/USAGE.md @@ -202,6 +202,11 @@ Handling of x87 80bits long double * 0 : Try to handle 80bits long double as precise as possible (Default) * 1 : Handle them as double +#### BOX64_LIBCEF * +Detect libcef and apply malloc_hack settings +* 0 : Don't detect libcef +* 1 : Detect libcef, and apply MALLOC_HACK=2 if detected (Default) + #### BOX64_LIBGL * * libXXXX set the name for libGL (defaults to libGL.so.1). * /PATH/TO/libGLXXX : Sets the name and path for libGL diff --git a/src/include/debug.h b/src/include/debug.h index f4461243..e2e75ee1 100755 --- a/src/include/debug.h +++ b/src/include/debug.h @@ -33,6 +33,7 @@ extern int arm64_crc32; extern int arm64_atomics; #endif #endif +extern int box64_libcef; extern int dlsym_error; // log dlsym error extern int cycle_log; // if using rolling logs #ifdef HAVE_TRACE diff --git a/src/librarian/library.c b/src/librarian/library.c index 3cfb2bee..48919220 100755 --- a/src/librarian/library.c +++ b/src/librarian/library.c @@ -306,6 +306,10 @@ static int loadEmulatedLib(const char* libname, library_t *lib, box64context_t* box64_dynarec_strongmem = 1; } #endif + if(libname && box64_libcef && strstr(libname, "libcef.so")) { + printf_log(LOG_INFO, "libcef detected, using malloc_hack_2\n"); + box64_malloc_hack = 2; + } return 1; } return 0; diff --git a/src/main.c b/src/main.c index e6c29568..20e5bd35 100755 --- a/src/main.c +++ b/src/main.c @@ -73,6 +73,7 @@ int arm64_atomics = 0; #else //DYNAREC int box64_dynarec = 0; #endif +int box64_libcef = 1; int dlsym_error = 0; int cycle_log = 0; #ifdef HAVE_TRACE @@ -627,6 +628,15 @@ void LoadLogEnv() #endif #endif // Other BOX64 env. var. + p = getenv("BOX64_LIBCEF"); + if(p) { + if(strlen(p)==1) { + if(p[0]>='0' && p[0]<='1') + box64_libcef = p[0]-'0'; + } + if(!box64_libcef) + printf_log(LOG_INFO, "Dynarec will not detect libcef\n"); + } p = getenv("BOX64_LOAD_ADDR"); if(p) { if(sscanf(p, "0x%zx", &box64_load_addr)!=1) diff --git a/src/tools/rcfile.c b/src/tools/rcfile.c index b21b6e9d..ff4eb754 100644 --- a/src/tools/rcfile.c +++ b/src/tools/rcfile.c @@ -79,6 +79,7 @@ ENTRYSTRING_(BOX64_BASH, bash) \ ENTRYINT(BOX64_JITGDB, jit_gdb, 0, 2, 2) \ ENTRYBOOL(BOX64_NOSANDBOX, box64_nosandbox) \ ENTRYBOOL(BOX64_EXIT, want_exit) \ +ENTRYBOOL(BOX64_LIBCEF, box64_libcef) \ ENTRYINT(BOX64_MALLOC_HACK, box64_malloc_hack, 0, 2, 2) \ #ifdef HAVE_TRACE -- cgit 1.4.1 From f9bc94bfb8529c6b10c989ad3a355498a72d7f85 Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Sun, 5 Mar 2023 15:09:11 +0100 Subject: Refactored OpenGL symbol fetching and managment --- src/box64context.c | 2 + src/include/box64context.h | 5 +- src/include/gltools.h | 12 ++ src/include/library.h | 4 - src/wrapped/wrappedlibegl.c | 65 +------- src/wrapped/wrappedlibgl.c | 395 ++++++++++++++++++++++++++++++-------------- src/wrapped/wrappedsdl1.c | 48 +----- src/wrapped/wrappedsdl2.c | 63 +------ 8 files changed, 296 insertions(+), 298 deletions(-) create mode 100644 src/include/gltools.h (limited to 'src/include') diff --git a/src/box64context.c b/src/box64context.c index 67f7f584..95b4a5bd 100755 --- a/src/box64context.c +++ b/src/box64context.c @@ -20,6 +20,7 @@ #include "x64emu.h" #include "signals.h" #include "rcfile.h" +#include "gltools.h" EXPORTDYN void initAllHelpers(box64context_t* context) @@ -233,6 +234,7 @@ box64context_t *NewBox64Context(int argc) return context; } +void freeALProcWrapper(box64context_t* context); EXPORTDYN void FreeBox64Context(box64context_t** context) { diff --git a/src/include/box64context.h b/src/include/box64context.h index 3e55ff44..010521e8 100755 --- a/src/include/box64context.h +++ b/src/include/box64context.h @@ -34,7 +34,7 @@ typedef struct kh_dynablocks_s kh_dynablocks_t; #endif #define DYNAMAP_SHIFT 16 -typedef void* (*procaddess_t)(const char* name); +typedef void* (*procaddress_t)(const char* name); typedef void* (*vkprocaddess_t)(void* instance, const char* name); #define MAX_SIGNAL 64 @@ -114,9 +114,6 @@ typedef struct box64context_s { uintptr_t vsyscall; // vsyscall bridge value uintptr_t vsyscalls[3]; // the 3 x86 VSyscall pseudo bridges (mapped at 0xffffffffff600000+) dlprivate_t *dlprivate; // dlopen library map - kh_symbolmap_t *glwrappers; // the map of wrapper for glProcs (for GLX or SDL1/2) - kh_symbolmap_t *glmymap; // link to the mysymbolmap of libGL - procaddess_t glxprocaddress; kh_symbolmap_t *alwrappers; // the map of wrapper for alGetProcAddress kh_symbolmap_t *almymap; // link to the mysymbolmap if libOpenAL kh_symbolmap_t *vkwrappers; // the map of wrapper for VulkanProcs (TODO: check SDL2) diff --git a/src/include/gltools.h b/src/include/gltools.h new file mode 100644 index 00000000..07bd74f7 --- /dev/null +++ b/src/include/gltools.h @@ -0,0 +1,12 @@ +#ifndef __GL_TOOLS_H__ +#define __GL_TOOLS_H__ + +typedef struct box64context_s box64context_t; + +typedef void* (*glprocaddress_t)(const char* name); + +void freeGLProcWrapper(box64context_t* context); + +void* getGLProcAddress(x64emu_t* emu, glprocaddress_t procaddr, const char* rname); + +#endif //__GL_TOOLS_H__ \ No newline at end of file diff --git a/src/include/library.h b/src/include/library.h index 48200a9e..afe108e7 100755 --- a/src/include/library.h +++ b/src/include/library.h @@ -28,10 +28,6 @@ int IsSameLib(library_t* lib, const char* path); // check if lib is same (pat int GetLibGlobalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int* weak, int version, const char* vername, int local); int GetLibWeakSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int* weak, int version, const char* vername, int local); int GetLibLocalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int* weak, int version, const char* vername, int local); -void fillGLProcWrapper(box64context_t* context); -void freeGLProcWrapper(box64context_t* context); -void fillALProcWrapper(box64context_t* context); -void freeALProcWrapper(box64context_t* context); char** GetNeededLibsNames(library_t* lib); int GetNeededLibsN(library_t* lib); library_t* GetNeededLib(library_t* lib, int idx); diff --git a/src/wrapped/wrappedlibegl.c b/src/wrapped/wrappedlibegl.c index 7f8e7cb9..2a19ed94 100755 --- a/src/wrapped/wrappedlibegl.c +++ b/src/wrapped/wrappedlibegl.c @@ -15,6 +15,7 @@ #include "box64context.h" #include "librarian.h" #include "callback.h" +#include "gltools.h" const char* libeglName = "libEGL.so.1"; #define LIBNAME libegl @@ -23,75 +24,15 @@ const char* libeglName = "libEGL.so.1"; #include "wrappercallback.h" -// FIXME: old wrapped* type of file, cannot use generated/wrappedlibgltypes.h - -void fillGLProcWrapper(box64context_t*); -void freeProcWrapper(kh_symbolmap_t** symbolmap); - EXPORT void* my_eglGetProcAddress(x64emu_t* emu, void* name) { khint_t k; const char* rname = (const char*)name; - if(dlsym_error && box64_log ", rname); - if(!emu->context->glwrappers) - fillGLProcWrapper(emu->context); - // check if glxprocaddress is filled, and search for lib and fill it if needed - // get proc adress using actual glXGetProcAddress - k = kh_get(symbolmap, emu->context->glmymap, rname); - int is_my = (k==kh_end(emu->context->glmymap))?0:1; - void* symbol; - if(is_my) { - // try again, by using custom "my_" now... - char tmp[200]; - strcpy(tmp, "my_"); - strcat(tmp, rname); - symbol = dlsym(emu->context->box64lib, tmp); - } else - symbol = my->eglGetProcAddress((void*)rname); - if(!symbol) { - if(dlsym_error && box64_logcontext->system, symbol); - if(ret) { - if(dlsym_error && box64_logcontext->glwrappers, rname); - if(k==kh_end(emu->context->glwrappers) && strstr(rname, "ARB")==NULL) { - // try again, adding ARB at the end if not present - char tmp[200]; - strcpy(tmp, rname); - strcat(tmp, "ARB"); - k = kh_get(symbolmap, emu->context->glwrappers, tmp); - } - if(k==kh_end(emu->context->glwrappers) && strstr(rname, "EXT")==NULL) { - // try again, adding EXT at the end if not present - char tmp[200]; - strcpy(tmp, rname); - strcat(tmp, "EXT"); - k = kh_get(symbolmap, emu->context->glwrappers, tmp); - } - if(k==kh_end(emu->context->glwrappers)) { - if(dlsym_error && box64_logcontext->glwrappers, k); - AddOffsetSymbol(emu->context->maplib, symbol, rname); - ret = AddBridge(emu->context->system, kh_value(emu->context->glwrappers, k), symbol, 0, constname); - if(dlsym_error && box64_logeglGetProcAddress, name); } - #define CUSTOM_INIT \ - getMy(lib); \ - if (!box64->glxprocaddress) \ - box64->glxprocaddress = (procaddess_t)my->eglGetProcAddress; + getMy(lib); #define CUSTOM_FINI \ freeMy(); diff --git a/src/wrapped/wrappedlibgl.c b/src/wrapped/wrappedlibgl.c index 9875847c..020f0f41 100755 --- a/src/wrapped/wrappedlibgl.c +++ b/src/wrapped/wrappedlibgl.c @@ -15,72 +15,19 @@ #include "box64context.h" #include "librarian.h" #include "callback.h" +#include "gltools.h" const char* libglName = "libGL.so.1"; #define LIBNAME libgl +static library_t* my_lib = NULL; // FIXME: old wrapped* type of file, cannot use generated/wrappedlibgltypes.h -void fillGLProcWrapper(box64context_t*); -void freeProcWrapper(kh_symbolmap_t** symbolmap); - EXPORT void* my_glXGetProcAddress(x64emu_t* emu, void* name) { khint_t k; const char* rname = (const char*)name; - printf_dlsym(LOG_DEBUG, "Calling glXGetProcAddress(\"%s\") => ", rname); - if(!emu->context->glwrappers) - fillGLProcWrapper(emu->context); - // check if glxprocaddress is filled, and search for lib and fill it if needed - // get proc adress using actual glXGetProcAddress - k = kh_get(symbolmap, emu->context->glmymap, rname); - int is_my = (k==kh_end(emu->context->glmymap))?0:1; - void* symbol; - if(is_my) { - // try again, by using custom "my_" now... - char tmp[200]; - strcpy(tmp, "my_"); - strcat(tmp, rname); - symbol = dlsym(emu->context->box64lib, tmp); - } else - symbol = emu->context->glxprocaddress(rname); - if(!symbol) { - printf_dlsym(LOG_DEBUG, "%p\n", NULL); - return NULL; // easy - } - // check if alread bridged - uintptr_t ret = CheckBridged(emu->context->system, symbol); - if(ret) { - printf_dlsym(LOG_DEBUG, "%p\n", (void*)ret); - return (void*)ret; // already bridged - } - // get wrapper - k = kh_get(symbolmap, emu->context->glwrappers, rname); - if(k==kh_end(emu->context->glwrappers) && strstr(rname, "ARB")==NULL) { - // try again, adding ARB at the end if not present - char tmp[200]; - strcpy(tmp, rname); - strcat(tmp, "ARB"); - k = kh_get(symbolmap, emu->context->glwrappers, tmp); - } - if(k==kh_end(emu->context->glwrappers) && strstr(rname, "EXT")==NULL) { - // try again, adding EXT at the end if not present - char tmp[200]; - strcpy(tmp, rname); - strcat(tmp, "EXT"); - k = kh_get(symbolmap, emu->context->glwrappers, tmp); - } - if(k==kh_end(emu->context->glwrappers)) { - printf_dlsym(LOG_DEBUG, "%p\n", NULL); - printf_dlsym(LOG_INFO, "Warning, no wrapper for %s\n", rname); - return NULL; - } - const char* constname = kh_key(emu->context->glwrappers, k); - AddOffsetSymbol(emu->context->maplib, symbol, rname); - ret = AddBridge(emu->context->system, kh_value(emu->context->glwrappers, k), symbol, 0, constname); - printf_dlsym(LOG_DEBUG, "%p\n", (void*)ret); - return (void*)ret; - + return getGLProcAddress(emu, my_lib->w.priv, rname); } EXPORT void* my_glXGetProcAddressARB(x64emu_t* emu, void* name) __attribute__((alias("my_glXGetProcAddress"))); @@ -89,6 +36,16 @@ typedef void (*vFpp_t)(void*, void*); typedef void*(*pFp_t)(void*); typedef void (*debugProc_t)(int32_t, int32_t, uint32_t, int32_t, int32_t, void*, void*); +typedef struct gl_wrappers_s { + glprocaddress_t procaddress; + kh_symbolmap_t *glwrappers; // the map of wrapper for glProcs (for GLX or SDL1/2) + kh_symbolmap_t *glmymap; // link to the mysymbolmap of libGL +} gl_wrappers_t; + +KHASH_MAP_INIT_INT64(gl_wrappers, gl_wrappers_t*) + +static kh_gl_wrappers_t *gl_wrappers = NULL; + #define SUPER() \ GO(0) \ GO(1) \ @@ -140,106 +97,302 @@ static void* find_program_callback_Fct(void* fct) printf_log(LOG_NONE, "Warning, no more slot for libGL program_callback callback\n"); return NULL; } -#undef SUPER -EXPORT void my_glDebugMessageCallback(x64emu_t* emu, void* prod, void* param) +// glDebugMessageCallback ... +#define GO(A) \ +static vFpp_t my_glDebugMessageCallback_fct_##A = NULL; \ +static void my_glDebugMessageCallback_##A(x64emu_t* emu, void* prod, void* param) \ +{ \ + if(!my_glDebugMessageCallback_fct_##A) \ + return; \ + my_glDebugMessageCallback_fct_##A(find_debug_callback_Fct(prod), param); \ +} +SUPER() +#undef GO +static void* find_glDebugMessageCallback_Fct(void* fct) { - static vFpp_t DebugMessageCallback = NULL; - static int init = 1; - if(init) { - DebugMessageCallback = emu->context->glxprocaddress("glDebugMessageCallback"); - init = 0; - } - if(!DebugMessageCallback) - return; - DebugMessageCallback(find_debug_callback_Fct(prod), param); + if(!fct) return fct; + #define GO(A) if(my_glDebugMessageCallback_fct_##A == (vFpp_t)fct) return my_glDebugMessageCallback_##A; + SUPER() + #undef GO + #define GO(A) if(my_glDebugMessageCallback_fct_##A == 0) {my_glDebugMessageCallback_fct_##A = (vFpp_t)fct; return my_glDebugMessageCallback_##A; } + SUPER() + #undef GO + printf_log(LOG_NONE, "Warning, no more slot for libGL glDebugMessageCallback callback\n"); + return NULL; } -EXPORT void my_glDebugMessageCallbackARB(x64emu_t* emu, void* prod, void* param) __attribute__((alias("my_glDebugMessageCallback"))); -EXPORT void my_glDebugMessageCallbackAMD(x64emu_t* emu, void* prod, void* param) __attribute__((alias("my_glDebugMessageCallback"))); -EXPORT void my_glDebugMessageCallbackKHR(x64emu_t* emu, void* prod, void* param) __attribute__((alias("my_glDebugMessageCallback"))); - -EXPORT int my_glXSwapIntervalMESA(int interval) +// glDebugMessageCallbackARB ... +#define GO(A) \ +static vFpp_t my_glDebugMessageCallbackARB_fct_##A = NULL; \ +static void my_glDebugMessageCallbackARB_##A(x64emu_t* emu, void* prod, void* param) \ +{ \ + if(!my_glDebugMessageCallbackARB_fct_##A) \ + return; \ + my_glDebugMessageCallbackARB_fct_##A(find_debug_callback_Fct(prod), param); \ +} +SUPER() +#undef GO +static void* find_glDebugMessageCallbackARB_Fct(void* fct) { - static iFi_t SwapIntervalMESA = NULL; - static int init = 1; - if(init) { - SwapIntervalMESA = my_context->glxprocaddress("glXSwapIntervalMESA"); - init = 0; - } - if(!SwapIntervalMESA) - return 0; - return SwapIntervalMESA(interval); + if(!fct) return fct; + #define GO(A) if(my_glDebugMessageCallbackARB_fct_##A == (vFpp_t)fct) return my_glDebugMessageCallbackARB_##A; + SUPER() + #undef GO + #define GO(A) if(my_glDebugMessageCallbackARB_fct_##A == 0) {my_glDebugMessageCallbackARB_fct_##A = (vFpp_t)fct; return my_glDebugMessageCallbackARB_##A; } + SUPER() + #undef GO + printf_log(LOG_NONE, "Warning, no more slot for libGL glDebugMessageCallbackARB callback\n"); + return NULL; } - -EXPORT void my_glProgramCallbackMESA(x64emu_t* emu, void* f, void* data) +// glDebugMessageCallbackAMD ... +#define GO(A) \ +static vFpp_t my_glDebugMessageCallbackAMD_fct_##A = NULL; \ +static void my_glDebugMessageCallbackAMD_##A(x64emu_t* emu, void* prod, void* param) \ +{ \ + if(!my_glDebugMessageCallbackAMD_fct_##A) \ + return; \ + my_glDebugMessageCallbackAMD_fct_##A(find_debug_callback_Fct(prod), param); \ +} +SUPER() +#undef GO +static void* find_glDebugMessageCallbackAMD_Fct(void* fct) { - static vFpp_t ProgramCallbackMESA = NULL; - static int init = 1; - if(init) { - ProgramCallbackMESA = my_context->glxprocaddress("glProgramCallbackMESA"); - init = 0; - } - if(!ProgramCallbackMESA) - return; - ProgramCallbackMESA(find_program_callback_Fct(f), data); + if(!fct) return fct; + #define GO(A) if(my_glDebugMessageCallbackAMD_fct_##A == (vFpp_t)fct) return my_glDebugMessageCallbackAMD_##A; + SUPER() + #undef GO + #define GO(A) if(my_glDebugMessageCallbackAMD_fct_##A == 0) {my_glDebugMessageCallbackAMD_fct_##A = (vFpp_t)fct; return my_glDebugMessageCallbackAMD_##A; } + SUPER() + #undef GO + printf_log(LOG_NONE, "Warning, no more slot for libGL glDebugMessageCallbackAMD callback\n"); + return NULL; +} +// glDebugMessageCallbackKHR ... +#define GO(A) \ +static vFpp_t my_glDebugMessageCallbackKHR_fct_##A = NULL; \ +static void my_glDebugMessageCallbackKHR_##A(x64emu_t* emu, void* prod, void* param) \ +{ \ + if(!my_glDebugMessageCallbackKHR_fct_##A) \ + return; \ + my_glDebugMessageCallbackKHR_fct_##A(find_debug_callback_Fct(prod), param); \ +} +SUPER() +#undef GO +static void* find_glDebugMessageCallbackKHR_Fct(void* fct) +{ + if(!fct) return fct; + #define GO(A) if(my_glDebugMessageCallbackKHR_fct_##A == (vFpp_t)fct) return my_glDebugMessageCallbackKHR_##A; + SUPER() + #undef GO + #define GO(A) if(my_glDebugMessageCallbackKHR_fct_##A == 0) {my_glDebugMessageCallbackKHR_fct_##A = (vFpp_t)fct; return my_glDebugMessageCallbackKHR_##A; } + SUPER() + #undef GO + printf_log(LOG_NONE, "Warning, no more slot for libGL glDebugMessageCallbackKHR callback\n"); + return NULL; +} +// glXSwapIntervalMESA ... +#define GO(A) \ +static iFi_t my_glXSwapIntervalMESA_fct_##A = NULL; \ +static int my_glXSwapIntervalMESA_##A(int interval) \ +{ \ + if(!my_glXSwapIntervalMESA_fct_##A) \ + return 0; \ + return my_glXSwapIntervalMESA_fct_##A(interval); \ +} +SUPER() +#undef GO +static void* find_glXSwapIntervalMESA_Fct(void* fct) +{ + if(!fct) return fct; + #define GO(A) if(my_glXSwapIntervalMESA_fct_##A == (iFi_t)fct) return my_glXSwapIntervalMESA_##A; + SUPER() + #undef GO + #define GO(A) if(my_glXSwapIntervalMESA_fct_##A == 0) {my_glXSwapIntervalMESA_fct_##A = (iFi_t)fct; return my_glXSwapIntervalMESA_##A; } + SUPER() + #undef GO + printf_log(LOG_NONE, "Warning, no more slot for libGL glXSwapIntervalMESA callback\n"); + return NULL; +} +// glProgramCallbackMESA ... +#define GO(A) \ +static vFpp_t my_glProgramCallbackMESA_fct_##A = NULL; \ +static void my_glProgramCallbackMESA_##A(x64emu_t* emu, void* f, void* data)\ +{ \ + if(!my_glProgramCallbackMESA_fct_##A) \ + return; \ + my_glProgramCallbackMESA_fct_##A(find_program_callback_Fct(f), data); \ +} +SUPER() +#undef GO +static void* find_glProgramCallbackMESA_Fct(void* fct) +{ + if(!fct) return fct; + #define GO(A) if(my_glProgramCallbackMESA_fct_##A == (vFpp_t)fct) return my_glProgramCallbackMESA_##A; + SUPER() + #undef GO + #define GO(A) if(my_glProgramCallbackMESA_fct_##A == 0) {my_glProgramCallbackMESA_fct_##A = (vFpp_t)fct; return my_glProgramCallbackMESA_##A; } + SUPER() + #undef GO + printf_log(LOG_NONE, "Warning, no more slot for libGL glProgramCallbackMESA callback\n"); + return NULL; } - void* my_GetVkProcAddr(x64emu_t* emu, void* name, void*(*getaddr)(void*)); // defined in wrappedvulkan.c -EXPORT void* my_glGetVkProcAddrNV(x64emu_t* emu, void* name) +// glGetVkProcAddrNV ... +#define GO(A) \ +static pFp_t my_glGetVkProcAddrNV_fct_##A = NULL; \ +static void* my_glGetVkProcAddrNV_##A(x64emu_t* emu, void* name) \ +{ \ + if(!my_glGetVkProcAddrNV_fct_##A) \ + return NULL; \ + return my_GetVkProcAddr(emu, name, my_glGetVkProcAddrNV_fct_##A); \ +} +SUPER() +#undef GO +static void* find_glGetVkProcAddrNV_Fct(void* fct) { - static pFp_t GetVkProcAddrNV = NULL; - static int init = 1; - if(init) { - GetVkProcAddrNV = my_context->glxprocaddress("glGetVkProcAddrNV"); - init = 0; - } - return my_GetVkProcAddr(emu, name, GetVkProcAddrNV); + if(!fct) return fct; + #define GO(A) if(my_glGetVkProcAddrNV_fct_##A == (pFp_t)fct) return my_glGetVkProcAddrNV_##A; + SUPER() + #undef GO + #define GO(A) if(my_glGetVkProcAddrNV_fct_##A == 0) {my_glGetVkProcAddrNV_fct_##A = (pFp_t)fct; return my_glGetVkProcAddrNV_##A; } + SUPER() + #undef GO + printf_log(LOG_NONE, "Warning, no more slot for libGL glGetVkProcAddrNV callback\n"); + return NULL; } +#undef SUPER #define PRE_INIT if(box64_libGL) {lib->w.lib = dlopen(box64_libGL, RTLD_LAZY | RTLD_GLOBAL); lib->path = strdup(box64_libGL);} else #define CUSTOM_INIT \ + my_lib = lib; \ lib->w.priv = dlsym(lib->w.lib, "glXGetProcAddress"); \ - if (!box64->glxprocaddress) \ - box64->glxprocaddress = lib->w.priv; - #include "wrappedlib_init.h" -void fillGLProcWrapper(box64context_t* context) +#define SUPER() \ + GO(vFpp_t, glDebugMessageCallback) \ + GO(vFpp_t, glDebugMessageCallbackARB) \ + GO(vFpp_t, glDebugMessageCallbackAMD) \ + GO(vFpp_t, glDebugMessageCallbackKHR) \ + GO(iFi_t, glXSwapIntervalMESA) \ + GO(vFpp_t, glProgramCallbackMESA) \ + GO(pFp_t, glGetVkProcAddrNV) \ + + +gl_wrappers_t* getGLProcWrapper(box64context_t* context, glprocaddress_t procaddress) { int cnt, ret; khint_t k; - kh_symbolmap_t * symbolmap = kh_init(symbolmap); + if(!gl_wrappers) { + gl_wrappers = kh_init(gl_wrappers); + } + k = kh_put(gl_wrappers, gl_wrappers, (uintptr_t)procaddress, &ret); + if(!ret) + return kh_value(gl_wrappers, k); + gl_wrappers_t* wrappers = kh_value(gl_wrappers, k) = (gl_wrappers_t*)calloc(1, sizeof(gl_wrappers_t)); + + wrappers->procaddress = procaddress; + wrappers->glwrappers = kh_init(symbolmap); // populates maps... cnt = sizeof(libglsymbolmap)/sizeof(map_onesymbol_t); for (int i=0; iglwrappers, libglsymbolmap[i].name, &ret); + kh_value(wrappers->glwrappers, k) = libglsymbolmap[i].w; } // and the my_ symbols map cnt = sizeof(MAPNAME(mysymbolmap))/sizeof(map_onesymbol_t); for (int i=0; iglwrappers, libglmysymbolmap[i].name, &ret); + kh_value(wrappers->glwrappers, k) = libglmysymbolmap[i].w; } - context->glwrappers = symbolmap; // my_* map - symbolmap = kh_init(symbolmap); + wrappers->glmymap = kh_init(symbolmap); cnt = sizeof(MAPNAME(mysymbolmap))/sizeof(map_onesymbol_t); for (int i=0; iglmymap, libglmysymbolmap[i].name, &ret); + kh_value(wrappers->glmymap, k) = libglmysymbolmap[i].w; } - context->glmymap = symbolmap; + return wrappers; } void freeGLProcWrapper(box64context_t* context) { if(!context) return; - if(context->glwrappers) - kh_destroy(symbolmap, context->glwrappers); - if(context->glmymap) - kh_destroy(symbolmap, context->glmymap); - context->glwrappers = NULL; - context->glmymap = NULL; + if(!gl_wrappers) + return; + gl_wrappers_t* wrappers; + kh_foreach_value(gl_wrappers, wrappers, + if(wrappers->glwrappers) + kh_destroy(symbolmap, wrappers->glwrappers); + if(wrappers->glmymap) + kh_destroy(symbolmap, wrappers->glmymap); + wrappers->glwrappers = NULL; + wrappers->glmymap = NULL; + ); + kh_destroy(gl_wrappers, gl_wrappers); + gl_wrappers = NULL; } + +void* getGLProcAddress(x64emu_t* emu, glprocaddress_t procaddr, const char* rname) +{ + khint_t k; + printf_dlsym(LOG_DEBUG, "Calling getGLProcAddress[%p](\"%s\") => ", procaddr, rname); + gl_wrappers_t* wrappers = getGLProcWrapper(emu->context, procaddr); + // check if glxprocaddress is filled, and search for lib and fill it if needed + // get proc adress using actual glXGetProcAddress + k = kh_get(symbolmap, wrappers->glmymap, rname); + int is_my = (k==kh_end(wrappers->glmymap))?0:1; + void* symbol; + if(is_my) { + // try again, by using custom "my_" now... + #define GO(A, B) else if(!strcmp(rname, #B)) symbol = find_##B##_Fct(procaddr(rname)); + if(0) {} + SUPER() + else { + printf_log(LOG_NONE, "Warning, %s defined as GOM, but find_%s_Fct not defined\n", rname, rname); + char tmp[200]; + strcpy(tmp, "my_"); + strcat(tmp, rname); + symbol = dlsym(emu->context->box64lib, tmp); + } + #undef GO + #undef SUPER + } else + symbol = procaddr(rname); + if(!symbol) { + printf_dlsym(LOG_DEBUG, "%p\n", NULL); + return NULL; // easy + } + // check if alread bridged + uintptr_t ret = CheckBridged(emu->context->system, symbol); + if(ret) { + printf_dlsym(LOG_DEBUG, "%p\n", (void*)ret); + return (void*)ret; // already bridged + } + // get wrapper + k = kh_get(symbolmap, wrappers->glwrappers, rname); + if(k==kh_end(wrappers->glwrappers) && strstr(rname, "ARB")==NULL) { + // try again, adding ARB at the end if not present + char tmp[200]; + strcpy(tmp, rname); + strcat(tmp, "ARB"); + k = kh_get(symbolmap, wrappers->glwrappers, tmp); + } + if(k==kh_end(wrappers->glwrappers) && strstr(rname, "EXT")==NULL) { + // try again, adding EXT at the end if not present + char tmp[200]; + strcpy(tmp, rname); + strcat(tmp, "EXT"); + k = kh_get(symbolmap, wrappers->glwrappers, tmp); + } + if(k==kh_end(wrappers->glwrappers)) { + printf_dlsym(LOG_DEBUG, "%p\n", NULL); + printf_dlsym(LOG_INFO, "Warning, no wrapper for %s\n", rname); + return NULL; + } + const char* constname = kh_key(wrappers->glwrappers, k); + AddOffsetSymbol(emu->context->maplib, symbol, rname); + ret = AddBridge(emu->context->system, kh_value(wrappers->glwrappers, k), symbol, 0, constname); + printf_dlsym(LOG_DEBUG, "%p\n", (void*)ret); + return (void*)ret; +} \ No newline at end of file diff --git a/src/wrapped/wrappedsdl1.c b/src/wrapped/wrappedsdl1.c index 97353568..4ebfb31e 100755 --- a/src/wrapped/wrappedsdl1.c +++ b/src/wrapped/wrappedsdl1.c @@ -16,6 +16,7 @@ #include "emu/x64emu_private.h" #include "box64context.h" #include "sdl1rwops.h" +#include "gltools.h" #include "x64trace.h" #include "threads.h" @@ -349,56 +350,11 @@ EXPORT void my_SDL_KillThread(x64emu_t* emu, void* p) my->SDL_KillThread(p); } -void fillGLProcWrapper(box64context_t* context); EXPORT void* my_SDL_GL_GetProcAddress(x64emu_t* emu, void* name) { khint_t k; const char* rname = (const char*)name; - printf_log(LOG_DEBUG, "Calling SDL_GL_GetProcAddress(%s)\n", rname); - // check if glxprocaddress is filled, and search for lib and fill it if needed - if(!emu->context->glwrappers) - fillGLProcWrapper(emu->context); - // get proc adress using actual glXGetProcAddress - k = kh_get(symbolmap, emu->context->glmymap, rname); - int is_my = (k==kh_end(emu->context->glmymap))?0:1; - void* symbol; - if(is_my) { - // try again, by using custom "my_" now... - char tmp[200]; - strcpy(tmp, "my_"); - strcat(tmp, rname); - symbol = dlsym(emu->context->box64lib, tmp); - } else - symbol = my->SDL_GL_GetProcAddress(name); - if(!symbol) - return NULL; // easy - // check if alread bridged - uintptr_t ret = CheckBridged(emu->context->system, symbol); - if(ret) - return (void*)ret; // already bridged - // get wrapper - k = kh_get(symbolmap, emu->context->glwrappers, rname); - if(k==kh_end(emu->context->glwrappers) && strstr(rname, "ARB")==NULL) { - // try again, adding ARB at the end if not present - char tmp[200]; - strcpy(tmp, rname); - strcat(tmp, "ARB"); - k = kh_get(symbolmap, emu->context->glwrappers, tmp); - } - if(k==kh_end(emu->context->glwrappers) && strstr(rname, "EXT")==NULL) { - // try again, adding EXT at the end if not present - char tmp[200]; - strcpy(tmp, rname); - strcat(tmp, "EXT"); - k = kh_get(symbolmap, emu->context->glwrappers, tmp); - } - if(k==kh_end(emu->context->glwrappers)) { - printf_log(LOG_INFO, "Warning, no wrapper for %s\n", rname); - return NULL; - } - AddOffsetSymbol(emu->context->maplib, symbol, rname); - const char* constname = kh_key(emu->context->glwrappers, k); - return (void*)AddBridge(emu->context->system, kh_value(emu->context->glwrappers, k), symbol, 0, constname); + return getGLProcAddress(emu, (glprocaddress_t)my->SDL_GL_GetProcAddress, rname); } // DL functions from wrappedlibdl.c diff --git a/src/wrapped/wrappedsdl2.c b/src/wrapped/wrappedsdl2.c index d68ca1a9..40b39edf 100755 --- a/src/wrapped/wrappedsdl2.c +++ b/src/wrapped/wrappedsdl2.c @@ -18,6 +18,7 @@ #include "sdl2rwops.h" #include "myalign.h" #include "threads.h" +#include "gltools.h" #include "generated/wrappedsdl2defs.h" @@ -645,71 +646,11 @@ EXPORT void my2_SDL_Log(x64emu_t* emu, void* fmt, void *b) { my->SDL_LogMessageV(0, 3, fmt, VARARGS); } -void fillGLProcWrapper(box64context_t*); EXPORT void* my2_SDL_GL_GetProcAddress(x64emu_t* emu, void* name) { khint_t k; const char* rname = (const char*)name; - printf_dlsym(LOG_DEBUG, "Calling SDL_GL_GetProcAddress(%s) => ", rname); - // check if glxprocaddress is filled, and search for lib and fill it if needed - if(!emu->context->glxprocaddress) - emu->context->glxprocaddress = (procaddess_t)my->SDL_GL_GetProcAddress; - if(!emu->context->glwrappers) { - fillGLProcWrapper(emu->context); - // check if libGL is loaded, load it if not (helps DeadCells) - if(!my_glhandle && !GetLibInternal(box64_libGL?box64_libGL:"libGL.so.1")) { - // use a my_dlopen to actually open that lib, like SDL2 is doing... - my_glhandle = my_dlopen(emu, box64_libGL?box64_libGL:"libGL.so.1", RTLD_LAZY|RTLD_GLOBAL); - } - } - // get proc adress using actual glXGetProcAddress - k = kh_get(symbolmap, emu->context->glmymap, rname); - int is_my = (k==kh_end(emu->context->glmymap))?0:1; - void* symbol; - if(is_my) { - // try again, by using custom "my_" now... - char tmp[200]; - strcpy(tmp, "my_"); - strcat(tmp, rname); - symbol = dlsym(emu->context->box64lib, tmp); - } else - symbol = my->SDL_GL_GetProcAddress(name); - if(!symbol) { - printf_dlsym(LOG_DEBUG, "%p\n", NULL); - return NULL; // easy - } - // check if alread bridged - uintptr_t ret = CheckBridged(emu->context->system, symbol); - if(ret) { - printf_dlsym(LOG_DEBUG, "%p\n", (void*)ret); - return (void*)ret; // already bridged - } - // get wrapper - k = kh_get(symbolmap, emu->context->glwrappers, rname); - if(k==kh_end(emu->context->glwrappers) && strstr(rname, "ARB")==NULL) { - // try again, adding ARB at the end if not present - char tmp[200]; - strcpy(tmp, rname); - strcat(tmp, "ARB"); - k = kh_get(symbolmap, emu->context->glwrappers, tmp); - } - if(k==kh_end(emu->context->glwrappers) && strstr(rname, "EXT")==NULL) { - // try again, adding EXT at the end if not present - char tmp[200]; - strcpy(tmp, rname); - strcat(tmp, "EXT"); - k = kh_get(symbolmap, emu->context->glwrappers, tmp); - } - if(k==kh_end(emu->context->glwrappers)) { - printf_dlsym(LOG_DEBUG, "%p\n", NULL); - printf_log(LOG_INFO, "Warning, no wrapper for %s\n", rname); - return NULL; - } - AddOffsetSymbol(emu->context->maplib, symbol, rname); - const char* constname = kh_key(emu->context->glwrappers, k); - ret = AddBridge(emu->context->system, kh_value(emu->context->glwrappers, k), symbol, 0, constname); - printf_dlsym(LOG_DEBUG, "%p\n", (void*)ret); - return (void*)ret; + return getGLProcAddress(emu, (glprocaddress_t)my->SDL_GL_GetProcAddress, rname); } #define nb_once 16 -- cgit 1.4.1