Skip to content
Merged
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
6 changes: 6 additions & 0 deletions src/emu/x64printer.c
Original file line number Diff line number Diff line change
Expand Up @@ -7578,6 +7578,12 @@ void x64Print(x64emu_t* emu, char* buff, size_t buffsz, const char* func, int ti
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi32 ", %" PRIi32 ", %" PRIu64 ", %" PRIu64 ", %" PRIi32 ", %" PRIp ", %" PRIp ", %" PRIp ")", tid, *(void**)(R_RSP), func, (int32_t)R_RDI, (int32_t)R_RSI, (uint64_t)R_RDX, (uintptr_t)R_RCX, (int32_t)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16));
} else if (w == lFpLpdddddd) {
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIp ", %" PRIu64 ", %" PRIp ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ", %" PRIf ")", tid, *(void**)(R_RSP), func, (void*)R_RDI, (uintptr_t)R_RSI, (void*)R_RDX, emu->xmm[0].d[0], emu->xmm[1].d[0], emu->xmm[2].d[0], emu->xmm[3].d[0], emu->xmm[4].d[0], emu->xmm[5].d[0]);
#endif
#if defined(PPC64LE)
} else if (w == iFEiLp) {
snprintf(buff, buffsz, "%04d|%p: Calling %s(%" PRIi32 ", %" PRIu64 ", %" PRIp ")", tid, *(void**)(R_RSP), func, (int32_t)R_RDI, (uintptr_t)R_RSI, (void*)R_RDX);
#endif
#if !defined(PPC64LE)
#endif
}
else
Expand Down
12 changes: 12 additions & 0 deletions src/emu/x64syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ extern int fchmodat (int __fd, const char *__file, mode_t __mode, int __flag);
//int32_t my_getrandom(x64emu_t* emu, void* buf, uint32_t buflen, uint32_t flags);
int of_convert(int flag);
int32_t my_open(x64emu_t* emu, void* pathname, int32_t flags, uint32_t mode);
#ifdef PPC64LE
unsigned long ioctl_convert(unsigned long x86_req);
#endif
ssize_t my_readlink(x64emu_t* emu, void* path, void* buf, size_t sz);
int my_readlinkat(x64emu_t* emu, int fd, void* path, void* buf, size_t bufsize);
int my_stat(x64emu_t *emu, void* filename, void* buf);
Expand Down Expand Up @@ -108,7 +111,9 @@ static const scwrap_t syscallwrap[] = {
//[13] = {__NR_rt_sigaction, 4}, // wrapped to use my_ version
[14] = {__NR_rt_sigprocmask, 4},
[15] = {__NR_rt_sigreturn, 1},
#ifndef PPC64LE
[16] = {__NR_ioctl, 3},
#endif
[17] = {__NR_pread64, 4},
[18] = {__NR_pwrite64, 4},
[19] = {__NR_readv, 3},
Expand Down Expand Up @@ -579,6 +584,13 @@ void EXPORT x64Syscall_linux(x64emu_t *emu)
if(S_RAX==-1)
S_RAX = -errno;
break;
#ifdef PPC64LE
case 16: // sys_ioctl (PPC64LE needs ioctl number translation)
S_RAX = ioctl(S_EDI, ioctl_convert(R_RSI), R_RDX);
if(S_RAX==-1)
S_RAX = -errno;
break;
#endif
case 6: // sys_lstat
S_RAX = my_lstat(emu, (void*)R_RDI, (void*)R_RSI);
if(S_RAX==-1)
Expand Down
1 change: 1 addition & 0 deletions src/wrapped/generated/functions_list.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1161,6 +1161,7 @@
#() iFEiiu
#() iFEiip
#() iFEiiN
#() iFEiLp
#() iFEipp
#() iFEipV
#() iFEipA
Expand Down
2 changes: 2 additions & 0 deletions src/wrapped/generated/wrappedlibctypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ typedef void (*vFppV_t)(void*, void*, ...);
typedef int32_t (*iFiiu_t)(int32_t, int32_t, uint32_t);
typedef int32_t (*iFiip_t)(int32_t, int32_t, void*);
typedef int32_t (*iFiiN_t)(int32_t, int32_t, ...);
typedef int32_t (*iFiLp_t)(int32_t, uintptr_t, void*);
typedef int32_t (*iFiuu_t)(int32_t, uint32_t, uint32_t);
typedef int32_t (*iFipu_t)(int32_t, void*, uint32_t);
typedef int32_t (*iFipp_t)(int32_t, void*, void*);
Expand Down Expand Up @@ -241,6 +242,7 @@ typedef int32_t (*iFppipppp_t)(void*, void*, int32_t, void*, void*, void*, void*
GO(__fcntl, iFiiN_t) \
GO(fcntl, iFiiN_t) \
GO(fcntl64, iFiiN_t) \
GO(ioctl, iFiLp_t) \
GO(fsmount, iFiuu_t) \
GO(fspick, iFipu_t) \
GO(__lxstat, iFipp_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 @@ -1191,6 +1191,7 @@ typedef int8_t (*cFpipp_t)(void*, int32_t, void*, void*);
typedef int32_t (*iFEiiu_t)(x64emu_t*, int32_t, int32_t, uint32_t);
typedef int32_t (*iFEiip_t)(x64emu_t*, int32_t, int32_t, void*);
typedef int32_t (*iFEiiN_t)(x64emu_t*, int32_t, int32_t, ...);
typedef int32_t (*iFEiLp_t)(x64emu_t*, int32_t, uintptr_t, void*);
typedef int32_t (*iFEipp_t)(x64emu_t*, int32_t, void*, void*);
typedef int32_t (*iFEipV_t)(x64emu_t*, int32_t, void*, void*);
typedef int32_t (*iFEipA_t)(x64emu_t*, int32_t, void*, void*);
Expand Down Expand Up @@ -5366,6 +5367,7 @@ void cFpipp(x64emu_t *emu, uintptr_t fcn) { cFpipp_t fn = (cFpipp_t)fcn; R_RAX=(
void iFEiiu(x64emu_t *emu, uintptr_t fcn) { iFEiiu_t fn = (iFEiiu_t)fcn; R_RAX=(int)fn(emu, (int32_t)R_RDI, (int32_t)R_RSI, (uint32_t)R_RDX); }
void iFEiip(x64emu_t *emu, uintptr_t fcn) { iFEiip_t fn = (iFEiip_t)fcn; R_RAX=(int)fn(emu, (int32_t)R_RDI, (int32_t)R_RSI, (void*)R_RDX); }
void iFEiiN(x64emu_t *emu, uintptr_t fcn) { iFEiiN_t fn = (iFEiiN_t)fcn; R_RAX=(int)fn(emu, (int32_t)R_RDI, (int32_t)R_RSI, (void*)R_RDX); }
void iFEiLp(x64emu_t *emu, uintptr_t fcn) { iFEiLp_t fn = (iFEiLp_t)fcn; R_RAX=(int)fn(emu, (int32_t)R_RDI, (uintptr_t)R_RSI, (void*)R_RDX); }
void iFEipp(x64emu_t *emu, uintptr_t fcn) { iFEipp_t fn = (iFEipp_t)fcn; R_RAX=(int)fn(emu, (int32_t)R_RDI, (void*)R_RSI, (void*)R_RDX); }
void iFEipV(x64emu_t *emu, uintptr_t fcn) { iFEipV_t fn = (iFEipV_t)fcn; R_RAX=(int)fn(emu, (int32_t)R_RDI, (void*)R_RSI, (void*)(R_RSP + 8)); }
void iFEipA(x64emu_t *emu, uintptr_t fcn) { iFEipA_t fn = (iFEipA_t)fcn; R_RAX=(int)fn(emu, (int32_t)R_RDI, (void*)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 @@ -1198,6 +1198,7 @@ void cFpipp(x64emu_t *emu, uintptr_t fnc);
void iFEiiu(x64emu_t *emu, uintptr_t fnc);
void iFEiip(x64emu_t *emu, uintptr_t fnc);
void iFEiiN(x64emu_t *emu, uintptr_t fnc);
void iFEiLp(x64emu_t *emu, uintptr_t fnc);
void iFEipp(x64emu_t *emu, uintptr_t fnc);
void iFEipV(x64emu_t *emu, uintptr_t fnc);
void iFEipA(x64emu_t *emu, uintptr_t fnc);
Expand Down
170 changes: 170 additions & 0 deletions src/wrapped/wrappedlibc.c
Original file line number Diff line number Diff line change
Expand Up @@ -836,6 +836,176 @@ int of_unconvert(int a)
}
#undef SUPER


#ifdef PPC64LE
// ioctl number translation: x86_64 -> PPC64LE
// x86_64 _IOC encoding: dir(2 bits, 30-31) | size(14 bits, 16-29) | type(8 bits, 8-15) | nr(8 bits, 0-7)
// PPC64LE _IOC encoding: dir(3 bits, 29-31) | size(13 bits, 16-28) | type(8 bits, 8-15) | nr(8 bits, 0-7)
// Direction bits: x86: NONE=0, WRITE=1, READ=2 PPC: NONE=1, READ=2, WRITE=4

// x86_64 _IOC field extraction
#define X86_IOC_NRBITS 8
#define X86_IOC_TYPEBITS 8
#define X86_IOC_SIZEBITS 14
#define X86_IOC_DIRBITS 2
#define X86_IOC_NRSHIFT 0
#define X86_IOC_TYPESHIFT (X86_IOC_NRSHIFT + X86_IOC_NRBITS)
#define X86_IOC_SIZESHIFT (X86_IOC_TYPESHIFT + X86_IOC_TYPEBITS)
#define X86_IOC_DIRSHIFT (X86_IOC_SIZESHIFT + X86_IOC_SIZEBITS)
#define X86_IOC_NRMASK ((1 << X86_IOC_NRBITS) - 1)
#define X86_IOC_TYPEMASK ((1 << X86_IOC_TYPEBITS) - 1)
#define X86_IOC_SIZEMASK ((1 << X86_IOC_SIZEBITS) - 1)
#define X86_IOC_DIRMASK ((1 << X86_IOC_DIRBITS) - 1)
#define X86_IOC_DIR(nr) (((nr) >> X86_IOC_DIRSHIFT) & X86_IOC_DIRMASK)
#define X86_IOC_TYPE(nr) (((nr) >> X86_IOC_TYPESHIFT) & X86_IOC_TYPEMASK)
#define X86_IOC_NR(nr) (((nr) >> X86_IOC_NRSHIFT) & X86_IOC_NRMASK)
#define X86_IOC_SIZE(nr) (((nr) >> X86_IOC_SIZESHIFT) & X86_IOC_SIZEMASK)

// x86_64 direction values
#define X86_IOC_NONE 0
#define X86_IOC_WRITE 1
#define X86_IOC_READ 2

// Old-style x86 terminal/file ioctl values (not _IOC-encoded)
#define X86_TCGETS 0x5401
#define X86_TCSETS 0x5402
#define X86_TCSETSW 0x5403
#define X86_TCSETSF 0x5404
#define X86_TCGETA 0x5405
#define X86_TCSETA 0x5406
#define X86_TCSETAW 0x5407
#define X86_TCSETAF 0x5408
#define X86_TCSBRK 0x5409
#define X86_TCXONC 0x540A
#define X86_TCFLSH 0x540B
#define X86_TIOCEXCL 0x540C
#define X86_TIOCNXCL 0x540D
#define X86_TIOCSCTTY 0x540E
#define X86_TIOCGPGRP 0x540F
#define X86_TIOCSPGRP 0x5410
#define X86_TIOCOUTQ 0x5411
#define X86_TIOCSTI 0x5412
#define X86_TIOCGWINSZ 0x5413
#define X86_TIOCSWINSZ 0x5414
#define X86_TIOCMGET 0x5415
#define X86_TIOCMBIS 0x5416
#define X86_TIOCMBIC 0x5417
#define X86_TIOCMSET 0x5418
#define X86_TIOCGSOFTCAR 0x5419
#define X86_TIOCSSOFTCAR 0x541A
#define X86_FIONREAD 0x541B
#define X86_TIOCLINUX 0x541C
#define X86_TIOCCONS 0x541D
#define X86_TIOCGSERIAL 0x541E
#define X86_TIOCSSERIAL 0x541F
#define X86_TIOCPKT 0x5420
#define X86_FIONBIO 0x5421
#define X86_TIOCNOTTY 0x5422
#define X86_TIOCSETD 0x5423
#define X86_TIOCGETD 0x5424
#define X86_TCSBRKP 0x5425
#define X86_TIOCGSID 0x5429
#define X86_FIONCLEX 0x5450
#define X86_FIOCLEX 0x5451
#define X86_FIOASYNC 0x5452
#define X86_FIOQSIZE 0x5460

#include <sys/ioctl.h>
#include <termios.h>

unsigned long ioctl_convert(unsigned long x86_req)
{
// Lookup table for old-style x86 terminal/file ioctls
switch(x86_req)
{
case X86_TCGETS: return TCGETS;
case X86_TCSETS: return TCSETS;
case X86_TCSETSW: return TCSETSW;
case X86_TCSETSF: return TCSETSF;
case X86_TCGETA: return TCGETA;
case X86_TCSETA: return TCSETA;
case X86_TCSETAW: return TCSETAW;
case X86_TCSETAF: return TCSETAF;
case X86_TCSBRK: return TCSBRK;
case X86_TCXONC: return TCXONC;
case X86_TCFLSH: return TCFLSH;
case X86_TIOCEXCL: return TIOCEXCL;
case X86_TIOCNXCL: return TIOCNXCL;
case X86_TIOCSCTTY: return TIOCSCTTY;
case X86_TIOCGPGRP: return TIOCGPGRP;
case X86_TIOCSPGRP: return TIOCSPGRP;
case X86_TIOCOUTQ: return TIOCOUTQ;
case X86_TIOCSTI: return TIOCSTI;
case X86_TIOCGWINSZ: return TIOCGWINSZ;
case X86_TIOCSWINSZ: return TIOCSWINSZ;
case X86_TIOCMGET: return TIOCMGET;
case X86_TIOCMBIS: return TIOCMBIS;
case X86_TIOCMBIC: return TIOCMBIC;
case X86_TIOCMSET: return TIOCMSET;
case X86_TIOCGSOFTCAR: return TIOCGSOFTCAR;
case X86_TIOCSSOFTCAR: return TIOCSSOFTCAR;
case X86_FIONREAD: return FIONREAD;
case X86_TIOCLINUX: return TIOCLINUX;
case X86_TIOCCONS: return TIOCCONS;
case X86_TIOCGSERIAL: return TIOCGSERIAL;
case X86_TIOCSSERIAL: return TIOCSSERIAL;
case X86_TIOCPKT: return TIOCPKT;
case X86_FIONBIO: return FIONBIO;
case X86_TIOCNOTTY: return TIOCNOTTY;
case X86_TIOCSETD: return TIOCSETD;
case X86_TIOCGETD: return TIOCGETD;
case X86_TCSBRKP: return TCSBRKP;
case X86_TIOCGSID: return TIOCGSID;
case X86_FIONCLEX: return FIONCLEX;
case X86_FIOCLEX: return FIOCLEX;
case X86_FIOASYNC: return FIOASYNC;
case X86_FIOQSIZE: return FIOQSIZE;
}

// For _IOC-encoded ioctls, translate the encoding
unsigned long x86_dir = X86_IOC_DIR(x86_req);
unsigned long x86_type = X86_IOC_TYPE(x86_req);
unsigned long x86_nr = X86_IOC_NR(x86_req);
unsigned long x86_size = X86_IOC_SIZE(x86_req);

// If it looks like a small raw number (not _IOC encoded), pass through
if(x86_dir == 0 && x86_type == 0) {
return x86_req;
}

// Translate x86 direction bits to PPC direction bits
unsigned long ppc_dir = 0;
if(x86_dir == X86_IOC_NONE) {
// x86 NONE=0, but if type!=0 it's a real _IOC_NONE ioctl
ppc_dir = 1; // PPC _IOC_NONE = 1
} else {
if(x86_dir & X86_IOC_READ) ppc_dir |= 2; // PPC _IOC_READ = 2
if(x86_dir & X86_IOC_WRITE) ppc_dir |= 4; // PPC _IOC_WRITE = 4
}

// PPC64LE: size is 13 bits (max 8191)
if(x86_size > 8191) {
printf_log(LOG_DEBUG, "Warning: ioctl size %lu exceeds PPC64LE 13-bit limit, clamping\n", x86_size);
x86_size = 8191;
}

// Recompose as PPC64LE _IOC: dir(3 bits, 29-31) | size(13 bits, 16-28) | type(8, 8-15) | nr(8, 0-7)
unsigned long ppc_req = (ppc_dir << 29) | (x86_size << 16) | (x86_type << 8) | x86_nr;

printf_log(LOG_DEBUG, "ioctl_convert: x86=0x%lx -> ppc=0x%lx (dir %lu->%lu, type 0x%lx, nr 0x%lx, size %lu)\n",
x86_req, ppc_req, X86_IOC_DIR(x86_req), ppc_dir, x86_type, x86_nr, x86_size);

return ppc_req;
}

EXPORT int my_ioctl(x64emu_t* emu, int fd, unsigned long req, void* arg)
{
(void)emu;
unsigned long native_req = ioctl_convert(req);
return ioctl(fd, native_req, arg);
}
#endif

EXPORT void* my__ZGTtnaX (size_t a) { (void)a; printf("warning _ZGTtnaX called\n"); return NULL; }
EXPORT void* my__ZGTtnam (size_t a) { (void)a; printf("warning _ZGTtnam called\n"); return NULL; }
EXPORT void my__ZGTtdlPv (void* a) { (void)a; printf("warning _ZGTtdlPv called\n"); }
Expand Down
4 changes: 4 additions & 0 deletions src/wrapped/wrappedlibc_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -861,7 +861,11 @@ DATA(_IO_2_1_stdin_, 224)
DATA(_IO_2_1_stdout_, 224)
//GO(_IO_adjust_column,
//GO(_IO_adjust_wcolumn,
#ifdef PPC64LE
GOWM(ioctl, iFEiLp)
#else
GOW(ioctl, iFiLN)
#endif
GO(_IO_default_doallocate, iFS)
GO(_IO_default_finish, vFSi)
GO(_IO_default_pbackfail, iFSi)
Expand Down
Loading