Since x86-64 CPU can run x86-32 code directly, and write to eax
will zeros out the higher bits of rax
, so the syscall number will be right. What other job does the kernel have to do to run x86-32 program?
Asked
Active
Viewed 245 times
3

炸鱼薯条德里克
- 899
- 8
- 25
-
1It puts the CPU into compat mode, by clearing the `L` bit in a segment descriptor in the GDT, and using an `iret` to set `cs:rip` to a 32-bit code segment while jumping to user-space. Of course it needs some special options for some system calls like `mmap` to make sure allocated memory is within the low 32 bits of virtual address space, and ABI differences for structs... – Peter Cordes Mar 19 '18 at 07:00
1 Answers
2
What other job does the kernel have to do to run x86-32 program?
All 64-bit parameters need to be split (e.g. passed in edx:eax
instead of just rax
). The mechanism used to call the kernel API is completely different (int 0x80
vs. syscall
). The stack layout (which matters for things like sending signals back to user-space signal handlers) is different. Virtual memory management has to be aware that user-space can't use 64-bit pointers. Different segment registers are used for TLS (gs
for 32-bit, fs
for 64-bit).
Mostly it's different enough that that you end up with completely separate system call entry/exit and dispatch code (where both interfaces call the same internal functions after parameters and calling conventions are handled).

Brendan
- 35,656
- 2
- 39
- 66
-
1Indeed. Some entries in `ia32_sys_call_table[]` are the native 64-bit system call functions that are also in the native system-call dispatch table, but many are wrapper functions that handle stuff like [`sys_llseek(2)`](http://man7.org/linux/man-pages/man2/llseek.2.html) taking separate `unsigned long offset_high` and `unsigned long offset_low` args, or that account for struct-layout differences. (Actually, `sys_llseek` only only exists for 32-bit; For 64-bit `lseek`'s single arg is wide enough.). – Peter Cordes Mar 19 '18 at 07:46
-
1See [What happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code?](https://stackoverflow.com/questions/46087730/what-happens-if-you-use-the-32-bit-int-0x80-linux-abi-in-64-bit-code) for a tour of the Linux kernel entry points into an x86-64 kernel from 32-bit user-space (or from 64-bit user-space using the 32-bit `int 0x80` ABI; it always returns to user-space via `iret`, restoring the 32-bit or 64-bit code segment that user-space was running from). – Peter Cordes Mar 19 '18 at 07:49