about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2022-10-26 15:51:43 +0200
committerptitSeb <sebastien.chev@gmail.com>2022-10-26 15:51:43 +0200
commit31a6149b0f1e821f7b81dcb78e0bc8442291115f (patch)
tree685f9b86abe2a387102e1c38d91df26138fb6a93 /src
parent3d274fdfd93ea7a3d73c04c4dba9d2e71c2c7998 (diff)
downloadbox64-31a6149b0f1e821f7b81dcb78e0bc8442291115f.tar.gz
box64-31a6149b0f1e821f7b81dcb78e0bc8442291115f.zip
Actually fixed (this time) syscall 78
Diffstat (limited to 'src')
-rwxr-xr-xsrc/emu/x64syscall.c34
1 files changed, 22 insertions, 12 deletions
diff --git a/src/emu/x64syscall.c b/src/emu/x64syscall.c
index d0af2b60..45f4a079 100755
--- a/src/emu/x64syscall.c
+++ b/src/emu/x64syscall.c
@@ -244,19 +244,29 @@ ssize_t DirentFromDirent64(void* dest, void* source, ssize_t count)
 {
     nat_linux_dirent64_t *src = (nat_linux_dirent64_t*)source;
     x86_linux_dirent_t *dst = (x86_linux_dirent_t*)dest;
-    ssize_t ret = count;
+    x86_linux_dirent_t *old = NULL;
+    ssize_t ret = 0;
     while(count>0) {
-        dst->d_ino = src->d_ino;
-        dst->d_reclen = src->d_reclen+1;
-        strcpy(dst->d_name, src->d_name);
-        dst->d_off = src->d_off?(src->d_off+1):0;
-        *(uint8_t*)((uintptr_t)dst + dst->d_reclen -2) = 0;
-        *(uint8_t*)((uintptr_t)dst + dst->d_reclen -1) = src->d_type;
+        ssize_t sz = src->d_reclen+sizeof(x86_linux_dirent_t)-sizeof(nat_linux_dirent64_t)+2;
+        if(sz>=count) {
+            dst->d_ino = src->d_ino;
+            dst->d_reclen = sz;
+            ret+=sz;
+            strcpy(dst->d_name, src->d_name);
+            dst->d_off = src->d_off?(src->d_off+sizeof(x86_linux_dirent_t)-sizeof(nat_linux_dirent64_t)+2):0;
+            *(uint8_t*)((uintptr_t)dst + dst->d_reclen -2) = 0;
+            *(uint8_t*)((uintptr_t)dst + dst->d_reclen -1) = src->d_type;
 
-        count -= src->d_reclen;
-        ret += 1;
-        src = (nat_linux_dirent64_t*)(((uintptr_t)src) + src->d_reclen);
-        dst = (x86_linux_dirent_t*)(((uintptr_t)dst) + dst->d_reclen);
+            count -= src->d_reclen;
+            ret += 1;
+            old = dst;
+            src = (nat_linux_dirent64_t*)(((uintptr_t)src) + src->d_reclen);
+            dst = (x86_linux_dirent_t*)(((uintptr_t)dst) + dst->d_reclen);
+        } else {
+            if(old)
+                old->d_off = 0;
+            count = 0;
+        }
     }
     return ret;
 }
@@ -494,7 +504,7 @@ void EXPORT x64Syscall(x64emu_t *emu)
         case 78:
             {
                 size_t count = R_RDX;
-                nat_linux_dirent64_t d64[count];
+                nat_linux_dirent64_t *d64 = (nat_linux_dirent64_t*)alloca(count);
                 ssize_t ret = syscall(__NR_getdents64, R_EDI, d64, count);
                 ret = DirentFromDirent64((void*)R_RSI, d64, ret);
                 R_RAX = (uint64_t)ret;