diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-10-04 12:28:11 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2024-10-04 12:28:11 +0200 |
| commit | 9f4eb36c99723f20e203bda0db07005284ae2eba (patch) | |
| tree | c4b1de9a09ef69c3ba597a82ead6c8017d9ecaaf | |
| parent | cbbafafb46b39b5ccb6f4c08d085317bcf09fba0 (diff) | |
| download | box64-9f4eb36c99723f20e203bda0db07005284ae2eba.tar.gz box64-9f4eb36c99723f20e203bda0db07005284ae2eba.zip | |
[BOX32][WRAPPER] More wrapped function to libc, and many fixes some existing ones
| -rwxr-xr-x | src/emu/x86int3.c | 6 | ||||
| -rw-r--r-- | src/emu/x86syscall_32.c | 19 | ||||
| -rwxr-xr-x | src/include/myalign32.h | 12 | ||||
| -rw-r--r-- | src/libtools/libc_net32.c | 33 | ||||
| -rwxr-xr-x | src/libtools/myalign32.c | 113 | ||||
| -rw-r--r-- | src/wrapped32/generated/functions_list.txt | 1 | ||||
| -rw-r--r-- | src/wrapped32/generated/wrappedlibctypes32.h | 1 | ||||
| -rwxr-xr-x | src/wrapped32/wrappedlibc_private.h | 2 |
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) |