about summary refs log tree commit diff stats
path: root/src/libtools
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-12-15 16:07:20 +0100
committerptitSeb <sebastien.chev@gmail.com>2024-12-15 16:07:25 +0100
commitd90522bc4ef003a3f643d53f390b77bc1e27b234 (patch)
treec681f7ffc14a638390e823245dd8879b099aef7d /src/libtools
parent0f7bec0d38597914e86fc3afc2fc431c661f4d1c (diff)
downloadbox64-d90522bc4ef003a3f643d53f390b77bc1e27b234.tar.gz
box64-d90522bc4ef003a3f643d53f390b77bc1e27b234.zip
[BOX32] Rollback simplied alignment of msghdr as cmsg also needs alignment (some docs are eroneous about cmsg_len field type)
Diffstat (limited to 'src/libtools')
-rw-r--r--src/libtools/libc_net32.c16
-rwxr-xr-xsrc/libtools/myalign32.c44
2 files changed, 53 insertions, 7 deletions
diff --git a/src/libtools/libc_net32.c b/src/libtools/libc_net32.c
index 0dd1ca37..0c222e5c 100644
--- a/src/libtools/libc_net32.c
+++ b/src/libtools/libc_net32.c
@@ -42,7 +42,8 @@ EXPORT ssize_t my32_recvmsg(x64emu_t* emu, int socket, struct i386_msghdr* msg,
 {
     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);
     UnalignMsgHdr_32(msg, &m);
     return ret;
@@ -52,7 +53,8 @@ EXPORT ssize_t my32_sendmsg(x64emu_t* emu, int socket, struct i386_msghdr* msg,
 {
     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;
@@ -62,13 +64,16 @@ EXPORT int my32_recvmmsg(x64emu_t* emu, int socket, struct i386_mmsghdr* msgs, u
 {
     struct mmsghdr m[vlen];
     uint32_t iovlen = 0;
+    size_t ctrlen = 0;
     for(uint32_t i=0; i<vlen; ++i) {
         if(msgs[i].msg_hdr.msg_iovlen>iovlen) iovlen = msgs[i].msg_hdr.msg_iovlen;
+        if(msgs[i].msg_hdr.msg_controllen>ctrlen) ctrlen = msgs[i].msg_hdr.msg_controllen;
         m[i].msg_len = msgs[i].msg_len;
     }
     struct iovec iov[vlen][iovlen];
+    uint8_t buff[vlen][ctrlen+256];
     for(uint32_t i=0; i<vlen; ++i)
-        AlignMsgHdr_32(&m[i].msg_hdr, iov[i], &msgs[i].msg_hdr);
+        AlignMsgHdr_32(&m[i].msg_hdr, iov[i], buff[i], &msgs[i].msg_hdr, 1);
     int ret = recvmmsg(socket, m, vlen, flags, timeout);
     for(uint32_t i=0; i<vlen; ++i) {
         UnalignMsgHdr_32(&msgs[i].msg_hdr, &m[i].msg_hdr);
@@ -81,13 +86,16 @@ EXPORT int my32_sendmmsg(x64emu_t* emu, int socket, struct i386_mmsghdr* msgs, u
 {
     struct mmsghdr m[vlen];
     uint32_t iovlen = 0;
+    size_t ctrlen = 0;
     for(uint32_t i=0; i<vlen; ++i) {
         if(msgs[i].msg_hdr.msg_iovlen>iovlen) iovlen = msgs[i].msg_hdr.msg_iovlen;
+        if(msgs[i].msg_hdr.msg_controllen>ctrlen) ctrlen = msgs[i].msg_hdr.msg_controllen;
         m[i].msg_len = msgs[i].msg_len;
     }
     struct iovec iov[vlen][iovlen];
+    uint8_t buff[vlen][ctrlen+256];
     for(uint32_t i=0; i<vlen; ++i)
-        AlignMsgHdr_32(&m[i].msg_hdr, iov[i], &msgs[i].msg_hdr);
+        AlignMsgHdr_32(&m[i].msg_hdr, iov[i], buff[i], &msgs[i].msg_hdr, 1);
     int ret = sendmmsg(socket, m, vlen, flags);
     for(uint32_t i=0; i<vlen; ++i) {
         UnalignMsgHdr_32(&msgs[i].msg_hdr, &m[i].msg_hdr);
diff --git a/src/libtools/myalign32.c b/src/libtools/myalign32.c
index 9121aa39..6f94ce99 100755
--- a/src/libtools/myalign32.c
+++ b/src/libtools/myalign32.c
@@ -1480,7 +1480,7 @@ void UnalignIOV_32(void* dest, void* source)
 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;
@@ -1496,7 +1496,29 @@ void AlignMsgHdr_32(void* dest, void* dest_iov, void* source)
     }
     d->msg_iovlen = s->msg_iovlen;
     d->msg_controllen = s->msg_controllen;
-    d->msg_control = from_ptrv(s->msg_control);
+    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 = from_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;
 }
 
@@ -1515,7 +1537,23 @@ void UnalignMsgHdr_32(void* dest, void* source)
     }
     d->msg_iovlen = s->msg_iovlen;
     d->msg_controllen = s->msg_controllen;
-    d->msg_control = to_ptrv(s->msg_control);
+    if(s->msg_control) {
+        struct i386_cmsghdr* dcmsg = from_ptrv(d->msg_control);
+        struct cmsghdr* scmsg = s->msg_control;
+        while(scmsg) {
+            dcmsg->cmsg_len = to_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;
 }