about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-10-04 12:28:11 +0200
committerptitSeb <sebastien.chev@gmail.com>2024-10-04 12:28:11 +0200
commit9f4eb36c99723f20e203bda0db07005284ae2eba (patch)
treec4b1de9a09ef69c3ba597a82ead6c8017d9ecaaf /src
parentcbbafafb46b39b5ccb6f4c08d085317bcf09fba0 (diff)
downloadbox64-9f4eb36c99723f20e203bda0db07005284ae2eba.tar.gz
box64-9f4eb36c99723f20e203bda0db07005284ae2eba.zip
[BOX32][WRAPPER] More wrapped function to libc, and many fixes some existing ones
Diffstat (limited to 'src')
-rwxr-xr-xsrc/emu/x86int3.c6
-rw-r--r--src/emu/x86syscall_32.c19
-rwxr-xr-xsrc/include/myalign32.h12
-rw-r--r--src/libtools/libc_net32.c33
-rwxr-xr-xsrc/libtools/myalign32.c113
-rw-r--r--src/wrapped32/generated/functions_list.txt1
-rw-r--r--src/wrapped32/generated/wrappedlibctypes32.h1
-rwxr-xr-xsrc/wrapped32/wrappedlibc_private.h2
8 files changed, 150 insertions, 37 deletions
diff --git a/src/emu/x86int3.c b/src/emu/x86int3.c
index 7e54b0da..3455eda1 100755
--- a/src/emu/x86int3.c
+++ b/src/emu/x86int3.c
@@ -259,11 +259,11 @@ void x86Int3(x64emu_t* emu, uintptr_t* addr)
                     pu32 = (uint32_t*)from_ptr(*(ptr_t*)from_ptr(R_ESP+4));
                     post = 3;
                 } else  if(strstr(s, "__snprintf_chk")==s) {
-                    snprintf(buff, 255, "%04d|%p: Calling %s(%p, %zu, %d, %d, \"%s\", %p)", tid, from_ptrv(*(ptr_t*)from_ptr(R_ESP)), (char *)s, from_ptrv(*(ptr_t*)from_ptr(R_ESP+4)), *(size_t*)from_ptr(R_ESP+8), *(int*)from_ptr(R_ESP+12), *(int*)from_ptr(R_ESP+16), (char*)from_ptrv(*(ptr_t*)from_ptr(R_ESP+20)), *(void**)from_ptr(R_ESP+24));
+                    snprintf(buff, 255, "%04d|%p: Calling %s(%p, %zu, %d, %d, \"%s\", %p)", tid, from_ptrv(*(ptr_t*)from_ptr(R_ESP)), (char *)s, from_ptrv(*(ptr_t*)from_ptr(R_ESP+4)), from_ptri(ulong_t, R_ESP+8), *(int*)from_ptr(R_ESP+12), *(int*)from_ptr(R_ESP+16), (char*)from_ptrv(*(ptr_t*)from_ptr(R_ESP+20)), *(void**)from_ptr(R_ESP+24));
                     pu32 = (uint32_t*)from_ptr(*(ptr_t*)from_ptr(R_ESP+4));
                     post = 3;
                 } else  if(strstr(s, "snprintf")==s) {
-                    snprintf(buff, 255, "%04d|%p: Calling %s(%p, %zu, \"%s\", ...)", tid, from_ptrv(*(ptr_t*)from_ptr(R_ESP)), (char *)s, from_ptrv(*(ptr_t*)from_ptr(R_ESP+4)), *(size_t*)from_ptr(R_ESP+8), (char*)from_ptrv(*(ptr_t*)from_ptr(R_ESP+12)));
+                    snprintf(buff, 255, "%04d|%p: Calling %s(%p, %zu, \"%s\", ...)", tid, from_ptrv(*(ptr_t*)from_ptr(R_ESP)), (char *)s, from_ptrv(*(ptr_t*)from_ptr(R_ESP+4)), from_ptri(ulong_t, R_ESP+8), (char*)from_ptrv(*(ptr_t*)from_ptr(R_ESP+12)));
                     pu32 = (uint32_t*)from_ptr(*(ptr_t*)from_ptr(R_ESP+4));
                     post = 3;
                 } else  if(strstr(s, "sprintf")==s) {
@@ -320,6 +320,8 @@ void x86Int3(x64emu_t* emu, uintptr_t* addr)
                     snprintf(buff, 255, "%04d|%p: Calling %s(\"%s\")", tid, from_ptrv(*(ptr_t*)from_ptr(R_ESP)), (char *)s, (char*)from_ptrv(*(ptr_t*)from_ptr(R_ESP+4)));
                 } else if (!strcmp(s, "glTexImage2D")) {
                     snprintf(buff, 256, "%04d|%p: Calling %s(0x%x, %d, 0x%x, %d, %d, %d, 0x%x, 0x%x, %p)", tid, from_ptrv(*(ptr_t*)from_ptrv(R_ESP)), (char *)s, *(uint32_t*)from_ptrv(R_ESP+4), *(int*)from_ptrv(R_ESP+8), *(int*)from_ptrv(R_ESP+12), *(int*)from_ptrv(R_ESP+16), *(int*)from_ptrv(R_ESP+20), *(int*)from_ptrv(R_ESP+24), *(uint32_t*)from_ptrv(R_ESP+28), *(uint32_t*)from_ptrv(R_ESP+32), from_ptrv(*(ptr_t*)from_ptrv(R_ESP+36)));
+                } else  if(strstr(s, "fscanf")==s) {
+                    snprintf(buff, 255, "%04d|%p: Calling %s(%p, \"%s\", ...)", tid, from_ptrv(*(ptr_t*)from_ptr(R_ESP)), (char *)s, from_ptrv(*(ptr_t*)from_ptr(R_ESP+4)), (char *)from_ptrv(*(ptr_t*)from_ptr(R_ESP+8)));
                 } else  if(strstr(s, "sscanf")==s) {
                     snprintf(buff, 255, "%04d|%p: Calling %s(\"%s\", \"%s\", ...)", tid, from_ptrv(*(ptr_t*)from_ptr(R_ESP)), (char *)s, (char *)from_ptrv(*(ptr_t*)from_ptr(R_ESP+4)), (char *)from_ptrv(*(ptr_t*)from_ptr(R_ESP+8)));
                 } else  if(!strcmp(s, "vsscanf")) {
diff --git a/src/emu/x86syscall_32.c b/src/emu/x86syscall_32.c
index 0b363ff1..7b2c25d0 100644
--- a/src/emu/x86syscall_32.c
+++ b/src/emu/x86syscall_32.c
@@ -389,6 +389,14 @@ void EXPORT x86Syscall(x64emu_t *emu)
                     R_EAX = (uint32_t)-errno;
             }
             break;
+        case 449:
+            #ifdef __NR_futex_waitv
+            if(box64_futex_waitv)
+                S_RAX = syscall(__NR_futex_waitv, R_EBX, R_ECX, R_EDX, R_ESI, R_EDI);
+            else
+            #endif
+                S_RAX = -ENOSYS;
+            break;
         default:
             printf_log(LOG_INFO, "Warning: Unsupported Syscall 0x%02Xh (%d)\n", s, s);
             R_EAX = (uint32_t)-ENOSYS;
@@ -595,6 +603,17 @@ uint32_t EXPORT my32_syscall(x64emu_t *emu, ptr_t* b)
             return (uint32_t)my32_memfd_create(emu, p(4), u32(8));
 #endif
 #endif
+        case 449:
+            #ifdef __NR_futex_waitv
+            if(box64_futex_waitv)
+                return syscall(__NR_futex_waitv, u32(4), u32(8), u32(12), u32(16), u32(20));
+            else
+            #endif
+                {
+                    errno = ENOSYS;
+                    return -1;
+                }
+            break;
         default:
             if((s>>6)<sizeof(warned)/sizeof(warned[0])) {
                 if(!(warned[s>>6]&(1<<(s&0x3f)))) {
diff --git a/src/include/myalign32.h b/src/include/myalign32.h
index 57ae0194..fae5b2cf 100755
--- a/src/include/myalign32.h
+++ b/src/include/myalign32.h
@@ -496,11 +496,19 @@ struct i386_msghdr
   ulong_t   msg_controllen;
   int msg_flags;
 };
+
+struct i386_cmsghdr
+{
+  ulong_t cmsg_len;
+  int cmsg_level;
+  int cmsg_type;
+};
+
 void AlignIOV_32(void* dest, void* source);   // x86 -> Native
 void UnalignIOV_32(void* dest, void* source); // Native -> x86
 
-void AlignMsgHdr_32(void* dest, void* dest_iov, void* source);   // x86 -> Native
-//void UnalignMsgHdr_32(void* dest, void* source, void* source_iov); // Native -> x86
+void AlignMsgHdr_32(void* dest, void* dest_iov, void* dest_cmsg, void* source, int convert_control);   // x86 -> Native
+void UnalignMsgHdr_32(void* dest, void* source); // back to Native -> x86
 
 struct i386_passwd
 {
diff --git a/src/libtools/libc_net32.c b/src/libtools/libc_net32.c
index 6bdbce82..533104d2 100644
--- a/src/libtools/libc_net32.c
+++ b/src/libtools/libc_net32.c
@@ -36,26 +36,43 @@
 #include "box32.h"
 #include "converter32.h"
 
-EXPORT ssize_t my32_recvmsg(x64emu_t* emu, int socket, void* msg, int flags)
+EXPORT ssize_t my32_recvmsg(x64emu_t* emu, int socket, struct i386_msghdr* msg, int flags)
 {
-    struct iovec iov;
+    struct iovec iov[msg->msg_iovlen];
     struct msghdr m;
-    AlignMsgHdr_32(&m, &iov, msg);
+    uint8_t buff[msg->msg_controllen+256];
+    AlignMsgHdr_32(&m, iov, buff, msg, 0);
     ssize_t ret = recvmsg(socket, &m, flags);
-    // put back msg_flags in place
-    ((struct i386_msghdr*)msg)->msg_flags = m.msg_flags;
+    UnalignMsgHdr_32(msg, &m);
     return ret;
 }
 
-EXPORT ssize_t my32_sendmsg(x64emu_t* emu, int socket, void* msg, int flags)
+EXPORT ssize_t my32_sendmsg(x64emu_t* emu, int socket, struct i386_msghdr* msg, int flags)
 {
-    struct iovec iov[256];
+    struct iovec iov[msg->msg_iovlen];
     struct msghdr m;
-    AlignMsgHdr_32(&m, &iov, msg);
+    uint8_t buff[msg->msg_controllen+256];
+    AlignMsgHdr_32(&m, iov, buff, msg, 1);
     ssize_t ret = sendmsg(socket, &m, flags);
+    UnalignMsgHdr_32(msg, &m);
     return ret;
 }
 
+EXPORT void* my32___cmsg_nxthdr(struct i386_msghdr* mhdr, struct i386_cmsghdr* cmsg)
+{
+    // simpler to redo, also, will be used internaly
+    if(cmsg->cmsg_len < sizeof(struct i386_cmsghdr))
+        return NULL;
+    // compute next
+    cmsg = (struct i386_cmsghdr*)(((uintptr_t)cmsg) + ((cmsg->cmsg_len+3)&~3));
+    // check it still inside limits
+    if((uintptr_t)(cmsg+1) > mhdr->msg_control+mhdr->msg_controllen)
+        return NULL;
+    if((uintptr_t)(cmsg)+cmsg->cmsg_len > mhdr->msg_control+mhdr->msg_controllen)
+        return NULL;
+    return cmsg;
+}
+
 EXPORT int my32_getaddrinfo(x64emu_t* emu, void* node, void* service, struct i386_addrinfo* hints, ptr_t* res)
 {
     struct addrinfo* hints_ = (struct addrinfo*)hints;  // only first part is used, wich is identical
diff --git a/src/libtools/myalign32.c b/src/libtools/myalign32.c
index 83a4fbdd..42ff785a 100755
--- a/src/libtools/myalign32.c
+++ b/src/libtools/myalign32.c
@@ -149,6 +149,7 @@ size_t myStackAlignScanf32(const char* fmt, uint32_t* st, uint64_t* mystack, siz
     size_t conv = 0;
     int state = 0;
     int ign = 0;
+    uint64_t* saved = mystack;
     while(*p)
     {
         switch(state) {
@@ -202,9 +203,9 @@ size_t myStackAlignScanf32(const char* fmt, uint32_t* st, uint64_t* mystack, siz
                     case '-': ++p; break; // formating, ignored
                     case 'm': state = 0; ++p; break; // no argument
                     case 'n':
-                    case 'p':
+                    case 'p': state = 30; break; // pointers
                     case 'S':
-                    case 's': state = 30; break; // pointers
+                    case 's': state = 50; break; // string
                     case '$': ++p; break; // should issue a warning, it's not handled...
                     case '*': ign=1; ++p; break; // ignore arg
                     case ' ': state=0; ++p; break;
@@ -219,8 +220,8 @@ size_t myStackAlignScanf32(const char* fmt, uint32_t* st, uint64_t* mystack, siz
             case 30:    // pointer
                 if(!ign) {
                     ++conv;
-                    mystack[nb_elem-conv] = 0;
-                    *mystack = (uintptr_t)&mystack[nb_elem-conv];
+                    saved[nb_elem-conv] = 0;
+                    *mystack = (uintptr_t)&saved[nb_elem-conv];
                     ++st;
                     ++mystack;
                 }
@@ -241,6 +242,7 @@ size_t myStackAlignScanf32(const char* fmt, uint32_t* st, uint64_t* mystack, siz
             case 41:
             case 43:
             case 44:
+            case 50:
                 if(!ign) {
                     *mystack = *st;
                     ++st;
@@ -267,6 +269,7 @@ void myStackAlignScanf32_final(const char* fmt, uint32_t* st, uint64_t* mystack,
     size_t conv = 0;
     int state = 0;
     int ign = 0;
+    uint64_t* saved = mystack;
     while(*p)
     {
         switch(state) {
@@ -320,9 +323,9 @@ void myStackAlignScanf32_final(const char* fmt, uint32_t* st, uint64_t* mystack,
                     case '-': ++p; break; // formating, ignored
                     case 'm': state = 0; ++p; break; // no argument
                     case 'n':
-                    case 'p':
+                    case 'p': state = 30; break; // pointers
                     case 'S':
-                    case 's': state = 30; break; // pointers
+                    case 's': state = 50; break; // strings
                     case '$': ++p; break; // should issue a warning, it's not handled...
                     case '*': ign=1; ++p; break; // ignore arg
                     case ' ': state=0; ++p; break;
@@ -337,22 +340,22 @@ void myStackAlignScanf32_final(const char* fmt, uint32_t* st, uint64_t* mystack,
             case 30:    // pointer
                 if(!ign) {
                     ++conv;
-                    if(state==22 || state==0x25) {
-                        int32_t* dst = from_ptrv(*st);
-                        *dst = to_long(mystack[nb_elem-conv]);
+                    if((state==22) || (state==25)) {
+                        long_t* dst = from_ptrv(*st);
+                        *dst = to_long(saved[nb_elem-conv]);
                     } else if(state==30) {
                         ptr_t* dst = from_ptrv(*st);
-                        *dst = to_ptr(mystack[nb_elem-conv]);
+                        *dst = to_ptr(saved[nb_elem-conv]);
                     } else {
-                        uint32_t* dst = from_ptrv(*st);
-                        *dst = to_ulong(mystack[nb_elem-conv]);
+                        ulong_t* dst = from_ptrv(*st);
+                        *dst = to_ulong(saved[nb_elem-conv]);
                     }
                     ++st;
                     ++mystack;
+                    if(!--n) return;
                 }
                 state = 0;
                 ++p;
-                if(!--n) return;
                 break;
             
             case 11:    //double
@@ -368,6 +371,7 @@ void myStackAlignScanf32_final(const char* fmt, uint32_t* st, uint64_t* mystack,
             case 41:
             case 43:
             case 44:
+            case 50:
                 if(!ign) {
                     *mystack = *st;
                     ++st;
@@ -394,6 +398,7 @@ size_t myStackAlignScanfW32(const char* fmt, uint32_t* st, uint64_t* mystack, si
     int state = 0;
     size_t conv = 0;
     int ign = 0;
+    uint64_t* saved = mystack;
     while(*p)
     {
         switch(state) {
@@ -447,9 +452,9 @@ size_t myStackAlignScanfW32(const char* fmt, uint32_t* st, uint64_t* mystack, si
                     case '-': ++p; break; // formating, ignored
                     case 'm': state = 0; ++p; break; // no argument
                     case 'n':
-                    case 'p':
+                    case 'p': state = 30; break; // pointers
                     case 'S':
-                    case 's': state = 30; break; // pointers
+                    case 's': state = 50; break; // strings
                     case '$': ++p; break; // should issue a warning, it's not handled...
                     case '*': ign=1; ++p; break; // ignore arg
                     case ' ': state=0; ++p; break;
@@ -464,8 +469,8 @@ size_t myStackAlignScanfW32(const char* fmt, uint32_t* st, uint64_t* mystack, si
             case 30:    // pointer
                 if(!ign) {
                     ++conv;
-                    mystack[nb_elem-conv] = 0;
-                    *mystack = (uintptr_t)&mystack[nb_elem-conv];
+                    saved[nb_elem-conv] = 0;
+                    *mystack = (uintptr_t)&saved[nb_elem-conv];
                     ++st;
                     ++mystack;
                 }
@@ -486,6 +491,7 @@ size_t myStackAlignScanfW32(const char* fmt, uint32_t* st, uint64_t* mystack, si
             case 41:
             case 43:
             case 44:
+            case 50:
                 if(!ign) {
                     *mystack = *st;
                     ++st;
@@ -512,6 +518,7 @@ void myStackAlignScanfW32_final(const char* fmt, uint32_t* st, uint64_t* mystack
     int state = 0;
     size_t conv = 0;
     int ign = 0;
+    uint64_t* saved = mystack;
     while(*p)
     {
         switch(state) {
@@ -565,9 +572,9 @@ void myStackAlignScanfW32_final(const char* fmt, uint32_t* st, uint64_t* mystack
                     case '-': ++p; break; // formating, ignored
                     case 'm': state = 0; ++p; break; // no argument
                     case 'n':
-                    case 'p':
+                    case 'p': state = 30; break; // pointers
                     case 'S':
-                    case 's': state = 30; break; // pointers
+                    case 's': state = 50; break; // string
                     case '$': ++p; break; // should issue a warning, it's not handled...
                     case '*': ign=1; ++p; break; // ignore arg
                     case ' ': state=0; ++p; break;
@@ -584,13 +591,13 @@ void myStackAlignScanfW32_final(const char* fmt, uint32_t* st, uint64_t* mystack
                     ++conv;
                     if(state==22 || state==0x25) {
                         int32_t* dst = from_ptrv(*st);
-                        *dst = to_long(mystack[nb_elem-conv]);
+                        *dst = to_long(saved[nb_elem-conv]);
                     } else if(state==30) {
                         ptr_t* dst = from_ptrv(*st);
-                        *dst = to_ptr(mystack[nb_elem-conv]);
+                        *dst = to_ptr(saved[nb_elem-conv]);
                     } else {
                         uint32_t* dst = from_ptrv(*st);
-                        *dst = to_ulong(mystack[nb_elem-conv]);
+                        *dst = to_ulong(saved[nb_elem-conv]);
                     }
                     ++st;
                     ++mystack;
@@ -613,6 +620,7 @@ void myStackAlignScanfW32_final(const char* fmt, uint32_t* st, uint64_t* mystack
             case 41:
             case 43:
             case 44:
+            case 50:
                 if(!ign) {
                     *mystack = *st;
                     ++st;
@@ -1445,9 +1453,10 @@ void UnalignIOV_32(void* dest, void* source)
     d->iov_len = s->iov_len;
 }
 
+void* my32___cmsg_nxthdr(struct i386_msghdr* mhdr, struct i386_cmsghdr* cmsg);
 
 // x86 -> Native
-void AlignMsgHdr_32(void* dest, void* dest_iov, void* source)
+void AlignMsgHdr_32(void* dest, void* dest_iov, void* dest_cmsg, void* source, int convert_control)
 {
     struct iovec* iov = dest_iov;
     struct msghdr* d = dest;
@@ -1462,8 +1471,64 @@ void AlignMsgHdr_32(void* dest, void* dest_iov, void* source)
         AlignIOV_32(d->msg_iov+i, s_iov+i);
     }
     d->msg_iovlen = s->msg_iovlen;
-    d->msg_control = from_ptrv(s->msg_control);
     d->msg_controllen = s->msg_controllen;
+    if(convert_control) {
+        if(s->msg_control) {
+            d->msg_control = dest_cmsg;
+            struct i386_cmsghdr* cmsg = from_ptrv(s->msg_control);
+            struct cmsghdr* dcmsg = dest_cmsg;
+            while(cmsg) {
+                dcmsg->cmsg_len = to_ulong(cmsg->cmsg_len);
+                dcmsg->cmsg_level = cmsg->cmsg_level;
+                dcmsg->cmsg_type = cmsg->cmsg_type;
+                if(cmsg->cmsg_len) {
+                    dcmsg->cmsg_len += 4;
+                    memcpy(CMSG_DATA(dcmsg), cmsg+1, cmsg->cmsg_len-sizeof(struct i386_cmsghdr));
+                    d->msg_controllen += 4;
+                }
+                dcmsg = (struct cmsghdr*)(((uintptr_t)dcmsg) + ((dcmsg->cmsg_len+7)&~7));
+                cmsg = my32___cmsg_nxthdr(s, cmsg);
+            }
+        } else 
+            d->msg_control = NULL;
+    } else {
+        d->msg_control = (s->msg_control)?dest_cmsg:NULL;
+        if(d->msg_control) memset(d->msg_control, 0, d->msg_controllen);
+    }
     d->msg_flags = s->msg_flags;
 }
 
+void UnalignMsgHdr_32(void* dest, void* source)
+{
+    struct msghdr* s = source;
+    struct i386_msghdr* d = dest;
+    struct iovec* s_iov = s->msg_iov;
+    struct i386_iovec* d_iov = from_ptrv(d->msg_iov);
+
+    d->msg_name = to_ptrv(s->msg_name);
+    d->msg_namelen = s->msg_namelen;
+    // TODO: check if iovlen is too big
+    for(int i=0; i<s->msg_iovlen; ++i) {
+        UnalignIOV_32(d_iov+i, s_iov+i);
+    }
+    d->msg_iovlen = s->msg_iovlen;
+    d->msg_controllen = s->msg_controllen;
+    if(s->msg_control) {
+        struct i386_cmsghdr* dcmsg = from_ptrv(d->msg_control);
+        struct cmsghdr* scmsg = s->msg_control;
+        while(scmsg) {
+            dcmsg->cmsg_len = from_ulong(scmsg->cmsg_len);
+            dcmsg->cmsg_level = scmsg->cmsg_level;
+            dcmsg->cmsg_type = scmsg->cmsg_type;
+            if(dcmsg->cmsg_len) {
+                dcmsg->cmsg_len -= 4;
+                memcpy(dcmsg+1, CMSG_DATA(scmsg), dcmsg->cmsg_len-sizeof(struct i386_cmsghdr));
+                d->msg_controllen -= 4;
+            }
+            (struct i386_cmsghdr*)(((uintptr_t)dcmsg) + ((dcmsg->cmsg_len+3)&~3));
+            scmsg = CMSG_NXTHDR(s, scmsg);
+        }
+    } else 
+        d->msg_control = 0;
+    d->msg_flags = s->msg_flags;
+}
\ No newline at end of file
diff --git a/src/wrapped32/generated/functions_list.txt b/src/wrapped32/generated/functions_list.txt
index 6700f69c..e6e8a22d 100644
--- a/src/wrapped32/generated/functions_list.txt
+++ b/src/wrapped32/generated/functions_list.txt
@@ -1272,6 +1272,7 @@ wrappedlibc:
 - pFpi:
   - backtrace_symbols
 - pFpp:
+  - __cmsg_nxthdr
   - gmtime_r
   - localtime_r
 - SFpp:
diff --git a/src/wrapped32/generated/wrappedlibctypes32.h b/src/wrapped32/generated/wrappedlibctypes32.h
index aa83e060..c712c92d 100644
--- a/src/wrapped32/generated/wrappedlibctypes32.h
+++ b/src/wrapped32/generated/wrappedlibctypes32.h
@@ -140,6 +140,7 @@ typedef int32_t (*iFpLiLppp_t)(void*, uintptr_t, int32_t, uintptr_t, void*, void
 	GO(execlp, iFpV_t) \
 	GO(signal, pFip_t) \
 	GO(backtrace_symbols, pFpi_t) \
+	GO(__cmsg_nxthdr, pFpp_t) \
 	GO(gmtime_r, pFpp_t) \
 	GO(localtime_r, pFpp_t) \
 	GO(_ITM_addUserCommitAction, vFpup_t) \
diff --git a/src/wrapped32/wrappedlibc_private.h b/src/wrapped32/wrappedlibc_private.h
index 09debe09..25aaa4c4 100755
--- a/src/wrapped32/wrappedlibc_private.h
+++ b/src/wrapped32/wrappedlibc_private.h
@@ -162,7 +162,7 @@ GOW(close, iFi)
 // __close  // Weak
 GOW(closedir, iFp)
 GO(closelog, vFv)
-//GO(__cmsg_nxthdr, pFpp)
+GOM(__cmsg_nxthdr, pFpp)    //%noE
 //GO(confstr, uFipu)
 // __confstr_chk
 GOW(connect, iFipu)