diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-12-15 16:07:20 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2024-12-15 16:07:25 +0100 |
| commit | d90522bc4ef003a3f643d53f390b77bc1e27b234 (patch) | |
| tree | c681f7ffc14a638390e823245dd8879b099aef7d /src/libtools | |
| parent | 0f7bec0d38597914e86fc3afc2fc431c661f4d1c (diff) | |
| download | box64-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.c | 16 | ||||
| -rwxr-xr-x | src/libtools/myalign32.c | 44 |
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; } |