Skip to content

[WRAPPER] ioctl number x86_64 -> ppc64le translation#3689

Merged
ptitSeb merged 4 commits intoptitSeb:mainfrom
runlevel5:ioctl-ppc64le
Mar 20, 2026
Merged

[WRAPPER] ioctl number x86_64 -> ppc64le translation#3689
ptitSeb merged 4 commits intoptitSeb:mainfrom
runlevel5:ioctl-ppc64le

Conversation

@runlevel5
Copy link
Contributor

Return to Monkey Island game refuses to run, digging in a bit I realize ioctl number of ppc64le is totally different to that x86_64, aarch64.

Add the iFEiLp wrapper signature — int32_t fn(x64emu_t*, int32_t,
uintptr_t, void*) — needed by the PPC64LE ioctl wrapper (GOWM).

Also add the iFiLp_t typedef and GO(ioctl, iFiLp_t) entry to
wrappedlibctypes.h so the libc wrapper type table includes ioctl.
…slation

x86_64 and PPC64LE encode ioctl numbers differently:
- Direction bits: x86 uses 2 bits (NONE=0, WRITE=1, READ=2) at bit 30;
  PPC uses 3 bits (NONE=1, READ=2, WRITE=4) at bit 29
- Size field: x86 uses 14 bits; PPC uses 13 bits
- Old-style terminal ioctls have entirely different hardcoded values
  (e.g. x86 TCGETS=0x5401 vs PPC TCGETS=_IOR('t',19,termios))

Add ioctl_convert() under #ifdef PPC64LE with:
- Switch-based lookup for ~35 old-style terminal/file ioctls (TCGETS,
  FIONREAD, TIOCGWINSZ, etc.)
- Algorithmic translation for _IOC-encoded ioctls: decompose x86
  fields, remap direction bits, recompose as PPC64LE
- Debug logging via printf_log(LOG_DEBUG, ...)

Also add my_ioctl() handler that calls ioctl_convert() then native
ioctl(), to be hooked via GOWM in the next commit.
Wire up the ioctl number translation via both code paths that x86_64
programs use to call ioctl:

1. Libc wrapper path: Under #ifdef PPC64LE, change GOW(ioctl, iFiLN)
   to GOWM(ioctl, iFEiLp) so calls go through my_ioctl() which
   translates the ioctl number before calling native ioctl().

2. Syscall path: Add case 16 (sys_ioctl) under #ifdef PPC64LE in
   x64Syscall_linux() that calls ioctl_convert() before the native
   ioctl syscall. Guard the generic table entry [16] with
   #ifndef PPC64LE to avoid conflict.
Add debug trace formatting for the iFEiLp signature under
#ifdef PPC64LE so BOX64_LOG=1 output shows readable argument values
for ioctl calls: int32_t fd, uintptr_t request, void* arg.
@ptitSeb
Copy link
Owner

ptitSeb commented Mar 20, 2026

Need to check if Loongarch & RISC-V don't need something like that @ksco

@ptitSeb ptitSeb merged commit d69d116 into ptitSeb:main Mar 20, 2026
28 checks passed
@ksco
Copy link
Collaborator

ksco commented Mar 20, 2026

Thank you for the reminder, but I think we are good here ;) https://elixir.bootlin.com/linux/v6.19.8/A/ident/TCGETS

@ksco
Copy link
Collaborator

ksco commented Mar 20, 2026

See it in action: https://godbolt.org/z/d3483j66a

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants