Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/emu/x64printer.c
Original file line number Diff line number Diff line change
Expand Up @@ -2809,6 +2809,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) {
Expand Down
36 changes: 36 additions & 0 deletions src/include/myalign.h
Original file line number Diff line number Diff line change
Expand Up @@ -325,4 +325,40 @@ 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 */

struct x64_ftsent* get_mapped_x64_ftsent(void* fts, void* ent);
void cleanup_fts_mappings(void* fts);

void UnalignFTSENT(void* dest, void* source);
void AlignFTSENT(void* dest, void* source);

#endif //__MY_ALIGN__H_
148 changes: 148 additions & 0 deletions src/libtools/myalign.c
Original file line number Diff line number Diff line change
Expand Up @@ -1760,3 +1760,151 @@ void unregister_xcb_display(void* d)
return;
}
}

struct ftsent_node {
void* ent;
struct x64_ftsent* x64_ent;
struct ftsent_node* next;
};

struct fts_node {
void* fts;
struct ftsent_node* head;
struct fts_node* next;
};

static pthread_mutex_t fts_mutex = PTHREAD_MUTEX_INITIALIZER;
static struct fts_node* fts_list = NULL;

struct x64_ftsent* get_mapped_x64_ftsent(void* fts, void* ent)
{
pthread_mutex_lock(&fts_mutex);

struct x64_ftsent* x64_ent = NULL;

struct fts_node *node;
for (node = fts_list; node; node = node->next) {
if (node->fts == fts) break;
}
if (!node) {
node = malloc(sizeof(struct fts_node));
if (!node) goto out;
node->fts = fts;
node->head = NULL;
node->next = fts_list;
fts_list = node;
}

struct ftsent_node* n;
for (struct ftsent_node* n = node->head; n; n = n->next) {
if (n->ent == ent) {
x64_ent = n->x64_ent;
goto out;
}
}

n = malloc(sizeof(struct ftsent_node));
if (!n) goto out;
x64_ent = malloc(sizeof(struct x64_ftsent) + ((FTSENT*)ent)->fts_namelen);
if (!x64_ent) {
free(n);
goto out;
}
n->ent = ent;
n->x64_ent = x64_ent;
n->next = node->head;
node->head = n;

out:
pthread_mutex_unlock(&fts_mutex);
return x64_ent;
}

void cleanup_fts_mappings(void* fts)
{
pthread_mutex_lock(&fts_mutex);

struct fts_node** pp = &fts_list;
while (*pp) {
if ((*pp)->fts == fts) {
struct fts_node* t = *pp;
struct ftsent_node *n = t->head;
while (n) {
struct ftsent_node *next = n->next;
free(n->x64_ent);
free(n);
n = next;
}
*pp = t->next;
free(t);
break;
}
pp = &(*pp)->next;
}

pthread_mutex_unlock(&fts_mutex);
}

void UnalignFTSENT(void* dest, void* source)
{
struct x64_ftsent* d = (struct x64_ftsent*)dest;
FTSENT* s = (FTSENT*)source;
/*
* fts_cycle, fts_parent, fts_link and fts_statp are copied as raw
* pointers without layout conversion for now. Recursively calling
* UnalignFTSENT on them may walk up the fts_parent chain to the
* root, and fts_cycle may form a loop, causing unbounded recursion
*/
d->fts_cycle = ((struct x64_ftsent*)s)->fts_cycle;
d->fts_parent = ((struct x64_ftsent*)s)->fts_parent;
d->fts_link = ((struct x64_ftsent*)s)->fts_link;
d->fts_number = s->fts_number;
d->fts_pointer = s->fts_pointer;
d->fts_accpath = s->fts_accpath;
d->fts_path = s->fts_path;
d->fts_errno = s->fts_errno;
d->fts_symfd = s->fts_symfd;
d->fts_pathlen = s->fts_pathlen;
d->fts_namelen = s->fts_namelen;
d->_pad0 = 0;
d->fts_ino = s->fts_ino;
d->fts_dev = s->fts_dev;
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;
d->fts_statp = ((struct x64_ftsent*)s)->fts_statp;
memcpy(d->fts_name, s->fts_name, s->fts_namelen + 1);
}

void AlignFTSENT(void* dest, void* source)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is never used.

{
FTSENT *d = (FTSENT*)dest;
struct x64_ftsent *s = (struct x64_ftsent*)source;
/*
* Reverse conversion (x64 -> native). Same rationale as UnalignFTSENT:
* fts_cycle, fts_parent, fts_link, fts_statp are copied verbatim
* without recursing.
*/
d->fts_cycle = ((FTSENT*)s)->fts_cycle;
d->fts_parent = ((FTSENT*)s)->fts_parent;
d->fts_link = ((FTSENT*)s)->fts_link;
d->fts_number = s->fts_number;
d->fts_pointer = s->fts_pointer;
d->fts_accpath = s->fts_accpath;
d->fts_path = s->fts_path;
d->fts_errno = s->fts_errno;
d->fts_symfd = s->fts_symfd;
d->fts_pathlen = s->fts_pathlen;
d->fts_namelen = s->fts_namelen;
d->fts_ino = s->fts_ino;
d->fts_dev = s->fts_dev;
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;
d->fts_statp = ((FTSENT*)s)->fts_statp;
memcpy(d->fts_name, s->fts_name, s->fts_namelen + 1);
}
10 changes: 10 additions & 0 deletions src/wrapped/generated/functions_list.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1576,6 +1576,7 @@
#() LFpppl
#() LFpppL
#() LFpppp
#() pFEipi
#() pFEipp
#() pFEipV
#() pFEuup
Expand Down Expand Up @@ -5546,6 +5547,8 @@ wrappedlibc:
- cnd_broadcast
- cnd_init
- cnd_signal
- fts64_close
- fts_close
- getcontext
- register_printf_type
- setcontext
Expand All @@ -5570,6 +5573,8 @@ wrappedlibc:
- _ZGTtnam
- pFp:
- __deregister_frame_info
- fts64_read
- fts_read
- mallinfo
- mallinfo2
- vFpi:
Expand Down Expand Up @@ -5656,6 +5661,7 @@ wrappedlibc:
- pFpi:
- __libc_dlopen_mode
- backtrace_symbols
- fts64_children
- pFpp:
- __libc_dlsym
- __realpath_chk
Expand Down Expand Up @@ -5721,6 +5727,8 @@ wrappedlibc:
- iFpLp:
- init_module
- iFppi:
- fts64_set
- fts_set
- ftw
- ftw64
- iFppp:
Expand Down Expand Up @@ -5777,6 +5785,8 @@ wrappedlibc:
- LFppL:
- strlcat
- strlcpy
- pFipi:
- fts_children
- pFpip:
- fts64_open
- fts_open
Expand Down
9 changes: 9 additions & 0 deletions src/wrapped/generated/wrappedlibctypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,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*, ...);
Expand Down Expand Up @@ -155,6 +156,8 @@ typedef int32_t (*iFppipppp_t)(void*, void*, int32_t, void*, void*, void*, void*
GO(cnd_broadcast, iFp_t) \
GO(cnd_init, iFp_t) \
GO(cnd_signal, iFp_t) \
GO(fts64_close, iFp_t) \
GO(fts_close, iFp_t) \
GO(getcontext, iFp_t) \
GO(register_printf_type, iFp_t) \
GO(setcontext, iFp_t) \
Expand All @@ -171,6 +174,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) \
Expand Down Expand Up @@ -240,6 +245,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) \
Expand Down Expand Up @@ -284,6 +290,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) \
Expand Down Expand Up @@ -330,6 +338,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) \
Expand Down
2 changes: 2 additions & 0 deletions src/wrapped/generated/wrapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -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*);
Expand Down Expand Up @@ -5889,6 +5890,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); }
Expand Down
1 change: 1 addition & 0 deletions src/wrapped/generated/wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
45 changes: 45 additions & 0 deletions src/wrapped/wrappedlibc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1988,6 +1988,51 @@ EXPORT void* my_fts64_open(x64emu_t* emu, void* path, int options, void* c)
return my->fts64_open(path, options, findcompareFct(c));
}

EXPORT void* my_fts_children(x64emu_t* emu, void* fts, int instr)
{
(void)emu;
FTSENT* ent = fts_children((FTS*)fts, instr);
if (!ent) return NULL;

struct x64_ftsent* x64_ent = get_mapped_x64_ftsent(fts, ent);
if (!x64_ent) return ent;
UnalignFTSENT(x64_ent, ent);
return x64_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;
FTSENT* ent = fts_read((FTS*)fts);
if (!ent) return NULL;

struct x64_ftsent* x64_ent = get_mapped_x64_ftsent(fts, ent);
if (!x64_ent) return ent;
UnalignFTSENT(x64_ent, ent);
return x64_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;
FTSENT ent;
AlignFTSENT(&ent, ftsent);
int r = fts_set(fts, &ent, instr);
if (!r) UnalignFTSENT(ftsent, &ent);
return r;
}
EXPORT int my_fts64_set(x64emu_t* emu, void* fts, void* ftsent, int instr) __attribute__((alias("my_fts_set")));

EXPORT int my_fts_close(x64emu_t* emu, void* fts)
{
(void)emu;
cleanup_fts_mappings(fts);
return fts_close((FTS*)fts);
}
EXPORT int my_fts64_close(x64emu_t* emu, void* fts) __attribute__((alias("my_fts_close")));

#if 0
struct i386_dirent {
uint32_t d_ino;
Expand Down
Loading
Loading