diff --git a/src/emu/x64printer.c b/src/emu/x64printer.c index 964018df18..d44848522c 100644 --- a/src/emu/x64printer.c +++ b/src/emu/x64printer.c @@ -2808,6 +2808,8 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIu64 ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (uintptr_t)R_RCX); } else if (w == LFpppp) { snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX); + } else if (w == pFEipi) { + snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi32 ", %" PRIp ", %" PRIi32 ")", tid, *(void**)(R_RSP), func, (int32_t)R_RDI, (void*)R_RSI, (int32_t)R_RDX); } else if (w == pFEipp) { snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi32 ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (int32_t)R_RDI, (void*)R_RSI, (void*)R_RDX); } else if (w == pFEipV) { diff --git a/src/include/myalign.h b/src/include/myalign.h index a9b4ce3b33..a691065e47 100644 --- a/src/include/myalign.h +++ b/src/include/myalign.h @@ -326,4 +326,39 @@ typedef struct my_x64_user_s } my_x64_user_t; +/* FTSENT layout difference between x86_64 and other architectures: + * - On x86_64: nlink_t is 8 bytes + * - On other architectures (ARM, RISC-V, etc.): nlink_t is 4 bytes + * See: https://github.com/gnutools/glibc/blob/master/sysdeps/unix/sysv/linux/x86/bits/typesizes.h + * - FTSENT definition: https://github.com/gnutools/glibc/blob/master/io/fts.h + */ +struct x64_ftsent { /* x86_64 other */ + struct x64_ftsent *fts_cycle; /* 0 */ /* 0 */ + struct x64_ftsent *fts_parent; /* 8 */ /* 8 */ + struct x64_ftsent *fts_link; /* 16 */ /* 16 */ + long fts_number; /* 24 */ /* 24 */ + void *fts_pointer; /* 32 */ /* 32 */ + char *fts_accpath; /* 40 */ /* 40 */ + char *fts_path; /* 48 */ /* 48 */ + int fts_errno; /* 56 */ /* 56 */ + int fts_symfd; /* 60 */ /* 60 */ + uint16_t fts_pathlen; /* 64 */ /* 64 */ + uint16_t fts_namelen; /* 66 */ /* 66 */ + uint32_t _pad0; /* 68 */ /* --- */ + uint64_t fts_ino; /* 72 */ /* 72 */ + uint64_t fts_dev; /* 80 */ /* 80 */ + uint64_t fts_nlink; /* 88 */ /* 88 */ + int16_t fts_level; /* 96 */ /* 92 */ + uint16_t fts_info; /* 98 */ /* 94 */ + uint16_t fts_flags; /* 100 */ /* 96 */ + uint16_t fts_instr; /* 102 */ /* 98 */ + struct x64_stat64 *fts_statp; /* 104 */ /* 104 */ + char fts_name[1]; /* 112 */ /* 112 */ +} __attribute__((packed)); /* 120 */ /* 120 */ + +void UnalignFTSENT(void* a); +void AlignFTSENT(void* a); +void unalign_all_ftsent(void* fts); +void align_all_ftsent(void* fts); + #endif //__MY_ALIGN__H_ diff --git a/src/libtools/myalign.c b/src/libtools/myalign.c index 8291c5e74f..86638f466d 100644 --- a/src/libtools/myalign.c +++ b/src/libtools/myalign.c @@ -1761,3 +1761,46 @@ void unregister_xcb_display(void* d) return; } } + +void UnalignFTSENT(void* a) +{ + struct x64_ftsent* d = a; + FTSENT* s = a; + d->fts_instr = s->fts_instr; + d->fts_flags = s->fts_flags; + d->fts_info = s->fts_info; + d->fts_level = s->fts_level; + d->fts_nlink = s->fts_nlink; + d->_pad0 = 0; +} + +void AlignFTSENT(void* a) +{ + FTSENT *d = a; + struct x64_ftsent *s = a; + d->fts_nlink = s->fts_nlink; + d->fts_level = s->fts_level; + d->fts_info = s->fts_info; + d->fts_flags = s->fts_flags; + d->fts_instr = s->fts_instr; +} + +void unalign_all_ftsent(void* fts) +{ + FTS* sp = (FTS*)fts; + for (FTSENT* p = sp->fts_cur; p; p = p->fts_parent) + UnalignFTSENT(p); + for (FTSENT* p = sp->fts_child; p; p = p->fts_link) + if (p != sp->fts_cur) + UnalignFTSENT(p); +} + +void align_all_ftsent(void* fts) +{ + FTS* sp = (FTS*)fts; + for (FTSENT* p = sp->fts_cur; p; p = p->fts_parent) + AlignFTSENT(p); + for (FTSENT* p = sp->fts_child; p; p = p->fts_link) + if (p != sp->fts_cur) + AlignFTSENT(p); +} diff --git a/src/wrapped/generated/functions_list.txt b/src/wrapped/generated/functions_list.txt index e3a7873ded..a38dc33e4a 100644 --- a/src/wrapped/generated/functions_list.txt +++ b/src/wrapped/generated/functions_list.txt @@ -1575,6 +1575,7 @@ #() LFpppl #() LFpppL #() LFpppp +#() pFEipi #() pFEipp #() pFEipV #() pFEuup @@ -5580,6 +5581,8 @@ wrappedlibc: - _ZGTtnam - pFp: - __deregister_frame_info + - fts64_read + - fts_read - mallinfo - mallinfo2 - vFpi: @@ -5666,6 +5669,7 @@ wrappedlibc: - pFpi: - __libc_dlopen_mode - backtrace_symbols + - fts64_children - pFpp: - __libc_dlsym - __realpath_chk @@ -5731,6 +5735,8 @@ wrappedlibc: - iFpLp: - init_module - iFppi: + - fts64_set + - fts_set - ftw - ftw64 - iFppp: @@ -5787,6 +5793,8 @@ wrappedlibc: - LFppL: - strlcat - strlcpy +- pFipi: + - fts_children - pFpip: - fts64_open - fts_open diff --git a/src/wrapped/generated/wrappedlibctypes.h b/src/wrapped/generated/wrappedlibctypes.h index b4072e328e..5c1ef7df1b 100644 --- a/src/wrapped/generated/wrappedlibctypes.h +++ b/src/wrapped/generated/wrappedlibctypes.h @@ -74,6 +74,7 @@ typedef intptr_t (*lFipL_t)(int32_t, void*, uintptr_t); typedef intptr_t (*lFipV_t)(int32_t, void*, ...); typedef intptr_t (*lFppL_t)(void*, void*, uintptr_t); typedef uintptr_t (*LFppL_t)(void*, void*, uintptr_t); +typedef void* (*pFipi_t)(int32_t, void*, int32_t); typedef void* (*pFpip_t)(void*, int32_t, void*); typedef void* (*pFppp_t)(void*, void*, void*); typedef void* (*pFppV_t)(void*, void*, ...); @@ -172,6 +173,8 @@ typedef int32_t (*iFppipppp_t)(void*, void*, int32_t, void*, void*, void*, void* GO(_ZGTtnaX, pFL_t) \ GO(_ZGTtnam, pFL_t) \ GO(__deregister_frame_info, pFp_t) \ + GO(fts64_read, pFp_t) \ + GO(fts_read, pFp_t) \ GO(mallinfo, pFp_t) \ GO(mallinfo2, pFp_t) \ GO(__longjmp_chk, vFpi_t) \ @@ -241,6 +244,7 @@ typedef int32_t (*iFppipppp_t)(void*, void*, int32_t, void*, void*, void*, void* GO(sysv_signal, pFip_t) \ GO(__libc_dlopen_mode, pFpi_t) \ GO(backtrace_symbols, pFpi_t) \ + GO(fts64_children, pFpi_t) \ GO(__libc_dlsym, pFpp_t) \ GO(__realpath_chk, pFpp_t) \ GO(realpath, pFpp_t) \ @@ -285,6 +289,8 @@ typedef int32_t (*iFppipppp_t)(void*, void*, int32_t, void*, void*, void*, void* GO(mprotect, iFpLi_t) \ GO(posix_madvise, iFpLi_t) \ GO(init_module, iFpLp_t) \ + GO(fts64_set, iFppi_t) \ + GO(fts_set, iFppi_t) \ GO(ftw, iFppi_t) \ GO(ftw64, iFppi_t) \ GO(__cxa_atexit, iFppp_t) \ @@ -331,6 +337,7 @@ typedef int32_t (*iFppipppp_t)(void*, void*, int32_t, void*, void*, void*, void* GO(readlink, lFppL_t) \ GO(strlcat, LFppL_t) \ GO(strlcpy, LFppL_t) \ + GO(fts_children, pFipi_t) \ GO(fts64_open, pFpip_t) \ GO(fts_open, pFpip_t) \ GO(tdelete, pFppp_t) \ diff --git a/src/wrapped/generated/wrapper.c b/src/wrapped/generated/wrapper.c index 5e8a2daede..62e125624e 100644 --- a/src/wrapped/generated/wrapper.c +++ b/src/wrapped/generated/wrapper.c @@ -1606,6 +1606,7 @@ typedef uintptr_t (*LFpppu_t)(void*, void*, void*, uint32_t); typedef uintptr_t (*LFpppl_t)(void*, void*, void*, intptr_t); typedef uintptr_t (*LFpppL_t)(void*, void*, void*, uintptr_t); typedef uintptr_t (*LFpppp_t)(void*, void*, void*, void*); +typedef void* (*pFEipi_t)(x64emu_t*, int32_t, void*, int32_t); typedef void* (*pFEipp_t)(x64emu_t*, int32_t, void*, void*); typedef void* (*pFEipV_t)(x64emu_t*, int32_t, void*, void*); typedef void* (*pFEuup_t)(x64emu_t*, uint32_t, uint32_t, void*); @@ -5890,6 +5891,7 @@ void LFpppu(x64emu_t *emu, uintptr_t fcn) { LFpppu_t fn = (LFpppu_t)fcn; R_RAX=( void LFpppl(x64emu_t *emu, uintptr_t fcn) { LFpppl_t fn = (LFpppl_t)fcn; R_RAX=(uintptr_t)fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (intptr_t)R_RCX); } void LFpppL(x64emu_t *emu, uintptr_t fcn) { LFpppL_t fn = (LFpppL_t)fcn; R_RAX=(uintptr_t)fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (uintptr_t)R_RCX); } void LFpppp(x64emu_t *emu, uintptr_t fcn) { LFpppp_t fn = (LFpppp_t)fcn; R_RAX=(uintptr_t)fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX); } +void pFEipi(x64emu_t *emu, uintptr_t fcn) { pFEipi_t fn = (pFEipi_t)fcn; R_RAX=(uintptr_t)fn(emu, (int32_t)R_RDI, (void*)R_RSI, (int32_t)R_RDX); } void pFEipp(x64emu_t *emu, uintptr_t fcn) { pFEipp_t fn = (pFEipp_t)fcn; R_RAX=(uintptr_t)fn(emu, (int32_t)R_RDI, (void*)R_RSI, (void*)R_RDX); } void pFEipV(x64emu_t *emu, uintptr_t fcn) { pFEipV_t fn = (pFEipV_t)fcn; R_RAX=(uintptr_t)fn(emu, (int32_t)R_RDI, (void*)R_RSI, (void*)(R_RSP + 8)); } void pFEuup(x64emu_t *emu, uintptr_t fcn) { pFEuup_t fn = (pFEuup_t)fcn; R_RAX=(uintptr_t)fn(emu, (uint32_t)R_RDI, (uint32_t)R_RSI, (void*)R_RDX); } diff --git a/src/wrapped/generated/wrapper.h b/src/wrapped/generated/wrapper.h index 6dc4b79bd5..180f931457 100644 --- a/src/wrapped/generated/wrapper.h +++ b/src/wrapped/generated/wrapper.h @@ -1613,6 +1613,7 @@ void LFpppu(x64emu_t *emu, uintptr_t fnc); void LFpppl(x64emu_t *emu, uintptr_t fnc); void LFpppL(x64emu_t *emu, uintptr_t fnc); void LFpppp(x64emu_t *emu, uintptr_t fnc); +void pFEipi(x64emu_t *emu, uintptr_t fnc); void pFEipp(x64emu_t *emu, uintptr_t fnc); void pFEipV(x64emu_t *emu, uintptr_t fnc); void pFEuup(x64emu_t *emu, uintptr_t fnc); diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c index 0a8d06ff63..1a4b451a3a 100644 --- a/src/wrapped/wrappedlibc.c +++ b/src/wrapped/wrappedlibc.c @@ -1980,14 +1980,42 @@ EXPORT void* my_lfind(x64emu_t* emu, void* key, void* base, size_t* nmemb, size_ EXPORT void* my_fts_open(x64emu_t* emu, void* path, int options, void* c) { (void)emu; - return fts_open(path, options, findcompareFct(c)); + FTS* fts = fts_open(path, options, findcompareFct(c)); + if (!fts) return NULL; + unalign_all_ftsent(fts); + return fts; } +EXPORT void* my_fts64_open(x64emu_t* emu, void* path, int options, void* c) __attribute__((alias("my_fts_open"))); -EXPORT void* my_fts64_open(x64emu_t* emu, void* path, int options, void* c) +EXPORT void* my_fts_children(x64emu_t* emu, void* fts, int instr) { (void)emu; - return my->fts64_open(path, options, findcompareFct(c)); + align_all_ftsent(fts); + void* ent = fts_children(fts, instr); + unalign_all_ftsent(fts); + return ent; } +EXPORT void* my_fts64_children(x64emu_t* emu, void* fts, int instr) __attribute__((alias("my_fts_children"))); + +EXPORT void* my_fts_read(x64emu_t* emu, void* fts) +{ + (void)emu; + align_all_ftsent(fts); + void* ent = fts_read(fts); + unalign_all_ftsent(fts); + return ent; +} +EXPORT void* my_fts64_read(x64emu_t* emu, void* fts) __attribute__((alias("my_fts_read"))); + +EXPORT int my_fts_set(x64emu_t* emu, void* fts, void* ftsent, int instr) +{ + (void)emu; + AlignFTSENT(ftsent); + int r = fts_set(fts, ftsent, instr); + UnalignFTSENT(ftsent); + return r; +} +EXPORT int my_fts64_set(x64emu_t* emu, void* fts, void* ftsent, int instr) __attribute__((alias("my_fts_set"))); #if 0 struct i386_dirent { diff --git a/src/wrapped/wrappedlibc_private.h b/src/wrapped/wrappedlibc_private.h index e21a6b3084..12afe32532 100644 --- a/src/wrapped/wrappedlibc_private.h +++ b/src/wrapped/wrappedlibc_private.h @@ -525,16 +525,16 @@ GO(ftok, iFpi) GO(ftruncate, iFil) GO(ftruncate64, iFiI) GOW(ftrylockfile, iFS) -GOW(fts64_children, pFpi) +GOWM(fts64_children, pFEpi) GOW(fts64_close, iFp) GOWM(fts64_open, pFEpip) -GOW(fts64_read, pFp) -GOW(fts64_set, iFppi) -GO(fts_children, pFpi) +GOWM(fts64_read, pFEp) +GOWM(fts64_set, iFEppi) +GOM(fts_children, pFEipi) GO(fts_close, iFp) GOM(fts_open, pFEpip) -GO(fts_read, pFp) -GO(fts_set, iFppi) +GOM(fts_read, pFEp) +GOM(fts_set, iFEppi) GOM(ftw, iFEppi) GOM(ftw64, iFEppi) GOW(funlockfile, vFS)