about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2023-02-20 21:30:22 +0100
committerptitSeb <sebastien.chev@gmail.com>2023-02-20 21:30:22 +0100
commitbfef8c9bbe8a16373742cb9c9e5691b93e994f58 (patch)
tree246b21e67025f3159006efd04f78fc6e4ec696bf /src
parent42b83789880c300711f08e3852784e17cafaf7ac (diff)
parent3fe2843bb3b95d8edd63d21c4f6acad7f652be91 (diff)
downloadbox64-bfef8c9bbe8a16373742cb9c9e5691b93e994f58.tar.gz
box64-bfef8c9bbe8a16373742cb9c9e5691b93e994f58.zip
Merge branch 'main' into steam_chrome
Diffstat (limited to 'src')
-rw-r--r--src/custommem.c47
-rwxr-xr-xsrc/dynarec/arm64/dynarec_arm64_f30f.c20
-rwxr-xr-xsrc/dynarec/arm64/dynarec_arm64_pass2.h12
-rwxr-xr-xsrc/dynarec/arm64/dynarec_arm64_pass3.h9
-rwxr-xr-xsrc/dynarec/arm64/dynarec_arm64_private.h1
-rwxr-xr-xsrc/dynarec/dynablock.c17
-rwxr-xr-xsrc/dynarec/dynarec_native.c25
-rwxr-xr-xsrc/include/debug.h1
-rwxr-xr-xsrc/include/dynarec_native.h3
-rwxr-xr-xsrc/libtools/signals.c5
-rwxr-xr-xsrc/main.c12
-rw-r--r--src/tools/rcfile.c8
-rw-r--r--src/wrapped/wrappedfaudio_private.h6
13 files changed, 94 insertions, 72 deletions
diff --git a/src/custommem.c b/src/custommem.c
index dfaca0c6..b9abcc3d 100644
--- a/src/custommem.c
+++ b/src/custommem.c
@@ -557,25 +557,29 @@ void FreeDynarecMap(uintptr_t addr)
     }
 }
 
-uintptr_t getSizeJmpDefault(uintptr_t addr, size_t maxsize)
+static uintptr_t getDBSize(uintptr_t addr, size_t maxsize, dynablock_t** db)
 {
-    uintptr_t idx3, idx2, idx1, idx0;
-    idx3 = (((uintptr_t)addr)>>48)&0xffff;
+    const uintptr_t idx3 = (addr>>48)&0xffff;
+    const uintptr_t idx2 = (addr>>32)&0xffff;
+    const uintptr_t idx1 = (addr>>16)&0xffff;
+    uintptr_t idx0 = addr&0xffff;
+    *db = *(dynablock_t**)(box64_jmptbl3[idx3][idx2][idx1][idx0]- sizeof(void*));
+    if(*db)
+        return 1;
     if(box64_jmptbl3[idx3] == box64_jmptbldefault2)
-        return ((addr&~((1LL<<48)-1))|0xffffffffffffLL)-addr + 1;
-    idx2 = (((uintptr_t)addr)>>32)&0xffff;
+        return (addr|0xffffffffffffLL)+1-addr;
     if(box64_jmptbl3[idx3][idx2] == box64_jmptbldefault1)
-        return ((addr&~((1LL<<32)-1))|0xffffffffLL)-addr + 1;
-    idx1 = (((uintptr_t)addr)>>16)&0xffff;
+        return (addr|0xffffffffLL)+1-addr;
     uintptr_t* block = box64_jmptbl3[idx3][idx2][idx1];
     if(block == box64_jmptbldefault0)
-        return ((addr&~((1LL<<16)-1))|0xffffLL)-addr + 1;
-    idx0 = addr&0xffff;
+        return (addr|0xffffLL)+1-addr;
     if (maxsize>0x10000)
         maxsize = 0x10000;
     while(idx0<maxsize && block[idx0]==(uintptr_t)native_next)
         ++idx0;
-    return idx0 - (addr&0xffff);
+    if(idx0<0x10000)
+        *db = *(dynablock_t**)(block[idx0]- sizeof(void*));
+    return idx0+1-(addr&0xffff);
 }
 
 // each dynmap is 64k of size
@@ -590,17 +594,15 @@ void cleanDBFromAddressRange(uintptr_t addr, size_t size, int destroy)
 {
     uintptr_t start_addr = my_context?((addr<my_context->max_db_size)?0:(addr-my_context->max_db_size)):addr;
     dynarec_log(LOG_DEBUG, "cleanDBFromAddressRange %p/%p -> %p %s\n", (void*)addr, (void*)start_addr, (void*)(addr+size-1), destroy?"destroy":"mark");
-    for (uintptr_t i=start_addr; i<addr+size; ++i) {
-        dynablock_t* db = getDB(i);
+    dynablock_t* db = NULL;
+    uintptr_t end = addr+size;
+    while (start_addr<end) {
+        start_addr += getDBSize(start_addr, end-start_addr, &db);
         if(db) {
             if(destroy)
                 FreeRangeDynablock(db, addr, size);
             else
                 MarkRangeDynablock(db, addr, size);
-        } else {
-            uintptr_t next = getSizeJmpDefault(i, size-i);
-            if(next)
-                i+=next-1;
         }
     }
 }
@@ -785,9 +787,6 @@ void protectDB(uintptr_t addr, uintptr_t size)
     for (uintptr_t i=(idx>>16); i<=(end>>16); ++i)
         if(memprot[i].prot==memprot_default) {
             uint8_t* newblock = box_calloc(1<<16, sizeof(uint8_t));
-            /*if (native_lock_storeifref(&memprot[i], newblock, memprot_default) != newblock) {
-                box_free(newblock);
-            }*/
             memprot[i].prot = newblock;
         }
     for (uintptr_t i=idx; i<=end; ++i) {
@@ -1052,17 +1051,17 @@ void allocProtection(uintptr_t addr, size_t size, uint32_t prot)
 
 #ifdef DYNAREC
 int IsInHotPage(uintptr_t addr) {
-    if(addr<=(1LL<<48))
+    if(addr>=(1LL<<48))
         return 0;
     int idx = (addr>>MEMPROT_SHIFT)>>16;
-    uint8_t *block = memprot[idx].hot;
-    if(!block)
+    uint8_t *hot = memprot[idx].hot;
+    if(!hot)
         return 0;
     int base = (addr>>MEMPROT_SHIFT)&0xffff;
-    if(!block[base])
+    if(!hot[base])
         return 0;
     // decrement hot
-    native_lock_decifnot0b(&block[base]);
+    native_lock_decifnot0b(&hot[base]);
     return 1;
 }
 
diff --git a/src/dynarec/arm64/dynarec_arm64_f30f.c b/src/dynarec/arm64/dynarec_arm64_f30f.c
index 1f60b843..2d0b8c6b 100755
--- a/src/dynarec/arm64/dynarec_arm64_f30f.c
+++ b/src/dynarec/arm64/dynarec_arm64_f30f.c
@@ -367,13 +367,13 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             GETED(0);

             GETGD;

             TSTxw_REG(ed, ed);

-            CSETw(x1, cEQ);

-            BFIw(xFlags, x1, F_CF, 1);  // CF = is source 0?

-            RBITxw(x1, ed);   // reverse

-            CLZxw(gd, x1);    // x2 gets leading 0 == TZCNT

+            CSETw(x3, cEQ);

+            BFIw(xFlags, x3, F_CF, 1);  // CF = is source 0?

+            RBITxw(x3, ed);   // reverse

+            CLZxw(gd, x3);    // x2 gets leading 0 == TZCNT

             TSTxw_REG(gd, gd);

-            CSETw(x1, cEQ);

-            BFIw(xFlags, x1, F_ZF, 1);  // ZF = is dest 0?

+            CSETw(x3, cEQ);

+            BFIw(xFlags, x3, F_ZF, 1);  // ZF = is dest 0?

             break;

         case 0xBD:

             INST_NAME("LZCNT Gd, Ed");

@@ -383,12 +383,12 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             GETED(0);

             GETGD;

             TSTxw_REG(ed, ed);

-            CSETw(x1, cEQ);

-            BFIw(xFlags, x1, F_CF, 1);  // CF = is source 0?

+            CSETw(x3, cEQ);

+            BFIw(xFlags, x3, F_CF, 1);  // CF = is source 0?

             CLZxw(gd, ed);    // x2 gets leading 0 == LZCNT

             TSTxw_REG(gd, gd);

-            CSETw(x1, cEQ);

-            BFIw(xFlags, x1, F_ZF, 1);  // ZF = is dest 0?

+            CSETw(x3, cEQ);

+            BFIw(xFlags, x3, F_ZF, 1);  // ZF = is dest 0?

             break;

 

         case 0xC2:

diff --git a/src/dynarec/arm64/dynarec_arm64_pass2.h b/src/dynarec/arm64/dynarec_arm64_pass2.h
index 29d5f01a..edc43ae5 100755
--- a/src/dynarec/arm64/dynarec_arm64_pass2.h
+++ b/src/dynarec/arm64/dynarec_arm64_pass2.h
@@ -1,14 +1,18 @@
 #define INIT        dyn->native_size = 0
-#define FINI        if(ninst) {dyn->insts[ninst].address = (dyn->insts[ninst-1].address+dyn->insts[ninst-1].size);}
+#define FINI                                                                                            \
+        if(ninst) {                                                                                     \
+                dyn->insts[ninst].address = (dyn->insts[ninst-1].address+dyn->insts[ninst-1].size);     \
+                dyn->insts_size += 1+((dyn->insts[ninst].x64.size>dyn->insts[ninst].size)?dyn->insts[ninst].x64.size:dyn->insts[ninst].size)/15; \
+        }
 
 #define MESSAGE(A, ...)  
 #define EMIT(A)     dyn->insts[ninst].size+=4; dyn->native_size+=4
 #define NEW_INST                                                                                        \
         if(ninst) {                                                                                     \
                 dyn->insts[ninst].address = (dyn->insts[ninst-1].address+dyn->insts[ninst-1].size);     \
-                if(ninst && isInstClean(dyn, ninst)) {                                                  \
-                        if(dyn->last_ip!=ip) dyn->last_ip = 0;                                          \
-                }                                                                                       \
+                if(isInstClean(dyn, ninst) && dyn->last_ip!=ip)                                         \
+                        dyn->last_ip = 0;                                                               \
+                dyn->insts_size += 1+((dyn->insts[ninst-1].x64.size>dyn->insts[ninst-1].size)?dyn->insts[ninst-1].x64.size:dyn->insts[ninst-1].size)/15; \
         }
 #define INST_EPILOG dyn->insts[ninst].epilog = dyn->native_size; 
 #define INST_NAME(name) 
diff --git a/src/dynarec/arm64/dynarec_arm64_pass3.h b/src/dynarec/arm64/dynarec_arm64_pass3.h
index 13b2b323..ae79c11f 100755
--- a/src/dynarec/arm64/dynarec_arm64_pass3.h
+++ b/src/dynarec/arm64/dynarec_arm64_pass3.h
@@ -1,5 +1,8 @@
 #define INIT    
-#define FINI
+#define FINI        \
+    if(ninst)       \
+        addInst(dyn->instsize, &dyn->insts_size, dyn->insts[ninst].x64.size, dyn->insts[ninst].size/4); \
+    addInst(dyn->instsize, &dyn->insts_size, 0, 0);
 #define EMIT(A)     \
     if(box64_dynarec_dump) {dynarec_log(LOG_NONE, "\t%08x\t%s\n", (uint32_t)(A), arm64_print(A, (uintptr_t)dyn->block));} \
     *(uint32_t*)(dyn->block) = (uint32_t)(A);       \
@@ -10,7 +13,9 @@
 #define NEW_INST        \
     if(ninst && isInstClean(dyn, ninst)) {                      \
         if(dyn->last_ip!=ip) dyn->last_ip = 0;                  \
-    }
+    }                                                           \
+    if(ninst)                                                   \
+        addInst(dyn->instsize, &dyn->insts_size, dyn->insts[ninst-1].x64.size, dyn->insts[ninst-1].size/4);
 #define INST_EPILOG     
 #define INST_NAME(name) \
     if(box64_dynarec_dump) {\
diff --git a/src/dynarec/arm64/dynarec_arm64_private.h b/src/dynarec/arm64/dynarec_arm64_private.h
index 6abdf829..1b194e97 100755
--- a/src/dynarec/arm64/dynarec_arm64_private.h
+++ b/src/dynarec/arm64/dynarec_arm64_private.h
@@ -103,6 +103,7 @@ typedef struct dynarec_arm_s {
     int*                predecessor;// single array of all predecessor
     dynablock_t*        dynablock;
     instsize_t*         instsize;
+    size_t              insts_size; // size of the instruction size array (calculated)
     uint8_t             smread;    // for strongmem model emulation
     uint8_t             smwrite;    // for strongmem model emulation
 } dynarec_arm_t;
diff --git a/src/dynarec/dynablock.c b/src/dynarec/dynablock.c
index 6ff5e53c..59530aed 100755
--- a/src/dynarec/dynablock.c
+++ b/src/dynarec/dynablock.c
@@ -68,7 +68,7 @@ void MarkDynablock(dynablock_t* db)
     }
 }
 
-int IntervalIntersects(uintptr_t start1, uintptr_t end1, uintptr_t start2, uintptr_t end2)
+static int IntervalIntersects(uintptr_t start1, uintptr_t end1, uintptr_t start2, uintptr_t end2)
 {
     if(start1 > end2 || start2 > end1)
         return 0;
@@ -205,8 +205,19 @@ dynablock_t* DBGetBlock(x64emu_t* emu, uintptr_t addr, int create)
     dynablock_t *db = internalDBGetBlock(emu, addr, addr, create, 1);
     if(db && db->done && db->block && db->need_test) {
         if(AreaInHotPage((uintptr_t)db->x64_addr, (uintptr_t)db->x64_addr + db->x64_size - 1)) {
-            dynarec_log(LOG_INFO, "Not running block %p from %p:%p with for %p because it's in a hotpage\n", db, db->x64_addr, db->x64_addr+db->x64_size-1, (void*)addr);
-            return NULL;
+            if(box64_dynarec_fastpage) {
+                uint32_t hash = X31_hash_code(db->x64_addr, db->x64_size);
+                if(hash==db->hash)  // seems ok, run it without reprotecting it
+                    return db;
+                db->done = 0;   // invalidating the block, it's already not good
+                dynarec_log(LOG_DEBUG, "Invalidating block %p from %p:%p (hash:%X/%X) for %p\n", db, db->x64_addr, db->x64_addr+db->x64_size-1, hash, db->hash, (void*)addr);
+                // Free db, it's now invalid!
+                FreeDynablock(db, 1);
+                return NULL;    // not building a new one, it's still a hotpage
+            } else {
+                dynarec_log(LOG_INFO, "Not running block %p from %p:%p with for %p because it's in a hotpage\n", db, db->x64_addr, db->x64_addr+db->x64_size-1, (void*)addr);
+                return NULL;
+            }
         }
         uint32_t hash = X31_hash_code(db->x64_addr, db->x64_size);
         if(mutex_trylock(&my_context->mutex_dyndump)) {
diff --git a/src/dynarec/dynarec_native.c b/src/dynarec/dynarec_native.c
index f8d29b61..c3f01ff2 100755
--- a/src/dynarec/dynarec_native.c
+++ b/src/dynarec/dynarec_native.c
@@ -240,7 +240,7 @@ int is_instructions(dynarec_native_t *dyn, uintptr_t addr, int n)
     return (i==n)?1:0;
 }
 
-instsize_t* addInst(instsize_t* insts, size_t* size, size_t* cap, int x64_size, int native_size)
+void addInst(instsize_t* insts, size_t* size, int x64_size, int native_size)
 {
     // x64 instruction is <16 bytes
     int toadd;
@@ -248,10 +248,6 @@ instsize_t* addInst(instsize_t* insts, size_t* size, size_t* cap, int x64_size,
         toadd = 1 + x64_size/15;
     else
         toadd = 1 + native_size/15;
-    if((*size)+toadd>(*cap)) {
-        *cap = (*size)+toadd;
-        insts = (instsize_t*)customRealloc(insts, (*cap)*sizeof(instsize_t));
-    }
     while(toadd) {
         if(x64_size>15)
             insts[*size].x64 = 15;    
@@ -266,7 +262,6 @@ instsize_t* addInst(instsize_t* insts, size_t* size, size_t* cap, int x64_size,
         ++(*size);
         --toadd;
     }
-    return insts;
 }
 
 // add a value to table64 (if needed) and gives back the imm19 to use in LDR_literal
@@ -391,7 +386,6 @@ void CancelBlock64(int need_lock)
     }
     customFree(helper->next);
     customFree(helper->insts);
-    customFree(helper->instsize);
     customFree(helper->predecessor);
     customFree(helper->table64);
     if(helper->dynablock && helper->dynablock->actual_block)
@@ -522,18 +516,7 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr) {
     // pass 2, instruction size
     native_pass2(&helper, addr);
     // keep size of instructions for signal handling
-    size_t insts_rsize = 0;
-    {
-        size_t insts_size = 0;
-        size_t cap = 1;
-        for(int i=0; i<helper.size; ++i)
-            cap += 1 + ((helper.insts[i].x64.size>helper.insts[i].size)?helper.insts[i].x64.size:helper.insts[i].size)/15;
-        helper.instsize = (instsize_t*)customCalloc(cap, sizeof(instsize_t));
-        for(int i=0; i<helper.size; ++i)
-            helper.instsize = addInst(helper.instsize, &insts_size, &cap, helper.insts[i].x64.size, helper.insts[i].size/4);
-        helper.instsize = addInst(helper.instsize, &insts_size, &cap, 0, 0);    // add a "end of block" mark, just in case
-        insts_rsize = insts_size*sizeof(instsize_t);
-    }
+    size_t insts_rsize = (helper.insts_size+2)*sizeof(instsize_t);
     insts_rsize = (insts_rsize+7)&~7;   // round the size...
     // ok, now allocate mapped memory, with executable flag on
     size_t sz = sizeof(void*) + helper.native_size + helper.table64size*sizeof(uint64_t) + 4*sizeof(void*) + insts_rsize;
@@ -550,6 +533,8 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr) {
     helper.block = p;
     helper.native_start = (uintptr_t)p;
     helper.tablestart = helper.native_start + helper.native_size;
+    helper.insts_size = 0;  // reset
+    helper.instsize = (instsize_t*)instsize;
     *(dynablock_t**)actual_p = block;
     // pass 3, emit (log emit native opcode)
     if(box64_dynarec_dump) {
@@ -581,14 +566,12 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr) {
         memcpy((void*)helper.tablestart, helper.table64, helper.table64size*8);
     }
     // keep size of instructions for signal handling
-    memcpy(instsize, helper.instsize, insts_rsize);
     block->instsize = instsize;
     // ok, free the helper now
     customFree(helper.insts);
     helper.insts = NULL;
     customFree(helper.table64);
     helper.table64 = NULL;
-    customFree(helper.instsize);
     helper.instsize = NULL;
     customFree(helper.predecessor);
     helper.predecessor = NULL;
diff --git a/src/include/debug.h b/src/include/debug.h
index 024805a1..f4461243 100755
--- a/src/include/debug.h
+++ b/src/include/debug.h
@@ -23,6 +23,7 @@ extern int box64_dynarec_safeflags;
 extern int box64_dynarec_callret;
 extern int box64_dynarec_bleeding_edge;
 extern int box64_dynarec_hotpage;
+extern int box64_dynarec_fastpage;
 extern int box64_dynarec_wait;
 #ifdef ARM64
 extern int arm64_asimd;
diff --git a/src/include/dynarec_native.h b/src/include/dynarec_native.h
index 9fe26323..eff5a6bf 100755
--- a/src/include/dynarec_native.h
+++ b/src/include/dynarec_native.h
@@ -3,6 +3,9 @@
 
 typedef struct dynablock_s dynablock_t;
 typedef struct x64emu_s x64emu_t;
+typedef struct instsize_s instsize_t;
+
+void addInst(instsize_t* insts, size_t* size, int x64_size, int native_size);
 
 void CancelBlock64(int need_lock);
 void* FillBlock64(dynablock_t* block, uintptr_t addr);
diff --git a/src/libtools/signals.c b/src/libtools/signals.c
index ffe36ea6..92ab59ef 100755
--- a/src/libtools/signals.c
+++ b/src/libtools/signals.c
@@ -855,7 +855,7 @@ void my_box64signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
     }
     dynablock_t* db = NULL;
     int db_searched = 0;
-    if ((sig==SIGSEGV) && (addr) && (info->si_code == SEGV_ACCERR) && (prot&PROT_DYN)) {
+    if ((sig==SIGSEGV) && (addr) && (info->si_code == SEGV_ACCERR) && (prot&PROT_DYNAREC)) {
         mutex_lock(&mutex_dynarec_prot);
         // check if SMC inside block
         db = FindDynablockFromNativeAddress(pc);
@@ -966,6 +966,9 @@ dynarec_log(/*LOG_DEBUG*/LOG_INFO, "Repeated SIGSEGV with Access error on %p for
             glitch2_prot = 0;
         }
         mutex_unlock(&mutex_dynarec_prot);
+    } else if ((sig==SIGSEGV) && (addr) && (info->si_code == SEGV_ACCERR) && (prot&PROT_DYNAREC_R)) {
+        // unprotect and continue to signal handler, because Write is not there on purpose
+        unprotectDB((uintptr_t)addr, 1, 1);    // unprotect 1 byte... But then, the whole page will be unprotected
     }
     if(!db_searched)
         db = FindDynablockFromNativeAddress(pc);
diff --git a/src/main.c b/src/main.c
index ea809e54..e6c29568 100755
--- a/src/main.c
+++ b/src/main.c
@@ -57,7 +57,8 @@ int box64_dynarec_fastnan = 1;
 int box64_dynarec_fastround = 1;
 int box64_dynarec_safeflags = 1;
 int box64_dynarec_callret = 0;
-int box64_dynarec_hotpage = 16;
+int box64_dynarec_hotpage = 4;
+int box64_dynarec_fastpage = 0;
 int box64_dynarec_bleeding_edge = 1;
 int box64_dynarec_wait = 1;
 uintptr_t box64_nodynarec_start = 0;
@@ -564,6 +565,15 @@ void LoadLogEnv()
         else
             printf_log(LOG_INFO, "Dynarec will not tag HotPage\n");
     }
+    p = getenv("BOX64_DYNAREC_FASTPAGE");
+    if(p) {
+        if(strlen(p)==1) {
+            if(p[0]>='0' && p[0]<='1')
+                box64_dynarec_fastpage = p[0]-'0';
+        }
+        if(box64_dynarec_fastpage)
+            printf_log(LOG_INFO, "Dynarec will use Fast HotPage\n");
+    }
     p = getenv("BOX64_NODYNAREC");
     if(p) {
         if (strchr(p,'-')) {
diff --git a/src/tools/rcfile.c b/src/tools/rcfile.c
index 75df7137..04451175 100644
--- a/src/tools/rcfile.c
+++ b/src/tools/rcfile.c
@@ -113,7 +113,8 @@ ENTRYINT(BOX64_DYNAREC_SAFEFLAGS, box64_dynarec_safeflags, 0, 2, 2) \
 ENTRYBOOL(BOX64_DYNAREC_CALLRET, box64_dynarec_callret)             \
 ENTRYBOOL(BOX64_DYNAREC_BLEEDING_EDGE, box64_dynarec_bleeding_edge) \
 ENTRYINT(BOX64_DYNAREC_HOTPAGE, box64_dynarec_hotpage, 0, 255, 8)   \
-ENTRYBOOL(box64_dynarec_wait, box64_dynarec_wait)                   \
+ENTRYBOOL(BOX64_DYNAREC_FASTPAGE, box64_dynarec_fastpage)           \
+ENTRYBOOL(BOX64_DYNAREC_WAIT, box64_dynarec_wait)                   \
 ENTRYSTRING_(BOX64_NODYNAREC, box64_nodynarec)                      \
 
 #else
@@ -130,7 +131,8 @@ IGNORE(BOX64_DYNAREC_SAFEFLAGS)                                     \
 IGNORE(BOX64_DYNAREC_CALLRET)                                       \
 IGNORE(BOX64_DYNAREC_BLEEDING_EDGE)                                 \
 IGNORE(BOX64_DYNAREC_HOTPAGE)                                       \
-IGNORE(BOX64_DYNAREC_wait)                                          \
+IGNORE(BOX64_DYNAREC_FASTPAGE)                                      \
+IGNORE(BOX64_DYNAREC_WAIT)                                          \
 IGNORE(BOX64_NODYNAREC)                                             \
 
 #endif
@@ -355,7 +357,7 @@ void LoadRCFile(const char* filename)
             if(0) ;
             SUPER()
             else if(len && current_name) {
-                printf_log(LOG_INFO, "Warning, unsupported %s=%s for [%s] in %s", key, val, current_name, filename);
+                printf_log(LOG_INFO, "Warning, unsupported %s=%s for [%s] in %s\n", key, val, current_name, filename);
             }
             #undef ENTRYBOOL
             #undef CENTRYBOOL
diff --git a/src/wrapped/wrappedfaudio_private.h b/src/wrapped/wrappedfaudio_private.h
index 3c145ea7..bec2d849 100644
--- a/src/wrapped/wrappedfaudio_private.h
+++ b/src/wrapped/wrappedfaudio_private.h
@@ -106,13 +106,13 @@ GO(FACTWave_SetMatrixCoefficients, uFpuup)
 GO(FACTWave_SetPitch, uFpw)
 GO(FACTWave_SetVolume, uFpf)
 GO(FACTWave_Stop, uFpu)
-//GO(FAPOBase_AddRef, 
+GO(FAPOBase_AddRef, iFp)
 //GO(FAPOBase_BeginProcess, 
 //GO(FAPOBase_CalcInputFrames, 
 //GO(FAPOBase_CalcOutputFrames, 
 //GO(FAPOBase_EndProcess, 
 //GO(FAPOBase_GetParameters, 
-//GO(FAPOBase_GetRegistrationProperties, 
+GO(FAPOBase_GetRegistrationProperties, uFpp)
 //GO(FAPOBase_Initialize, 
 //GO(FAPOBase_IsInputFormatSupported, 
 //GO(FAPOBase_IsOutputFormatSupported, 
@@ -120,7 +120,7 @@ GO(FACTWave_Stop, uFpu)
 //GO(FAPOBase_OnSetParameters, 
 //GO(FAPOBase_ParametersChanged, 
 //GO(FAPOBase_ProcessThru, 
-//GO(FAPOBase_Release, 
+GO(FAPOBase_Release, iFp)
 //GO(FAPOBase_Reset, 
 //GO(FAPOBase_SetParameters, 
 //GO(FAPOBase_UnlockForProcess,