• Uncategorized

About linux : What-happens-if-you-use-the-32-bit-int-0x80-Linux-ABI-in-64-bit-code

Question Detail

int 0x80 on Linux always invokes the 32-bit ABI, regardless of what mode it’s called from: args in ebx, ecx, … and syscall numbers from /usr/include/asm/unistd_32.h. (Or crashes on 64-bit kernels compiled without CONFIG_IA32_EMULATION).

64-bit code should use syscall, with call numbers from /usr/include/asm/unistd_64.h, and args in rdi, rsi, etc. See What are the calling conventions for UNIX & Linux system calls on i386 and x86-64. If your question was marked a duplicate of this, see that link for details on how you should make system calls in 32 or 64-bit code. If you want to understand what exactly happened, keep reading.

(For an example of 32-bit vs. 64-bit sys_write, see Using interrupt 0x80 on 64-bit Linux)

syscall system calls are faster than int 0x80 system calls, so use native 64-bit syscall unless you’re writing polyglot machine code that runs the same when executed as 32 or 64 bit. (sysenter always returns in 32-bit mode, so it’s not useful from 64-bit userspace, although it is a valid x86-64 instruction.)

Related: The Definitive Guide to Linux System Calls (on x86) for how to make int 0x80 or sysenter 32-bit system calls, or syscall 64-bit system calls, or calling the vDSO for “virtual” system calls like gettimeofday. Plus background on what system calls are all about.

Using int 0x80 makes it possible to write something that will assemble in 32 or 64-bit mode, so it’s handy for an exit_group() at the end of a microbenchmark or something.

Current PDFs of the official i386 and x86-64 System V psABI documents that standardize function and syscall calling conventions are linked from https://github.com/hjl-tools/x86-psABI/wiki/X86-psABI.

See the x86 tag wiki for beginner guides, x86 manuals, official documentation, and performance optimization guides / resources.

But since people keep posting questions with code that uses int 0x80 in 64-bit code, or accidentally building 64-bit binaries from source written for 32-bit, I wonder what exactly does happen on current Linux?

Does int 0x80 save/restore all the 64-bit registers? Does it truncate any registers to 32-bit? What happens if you pass pointer args that have non-zero upper halves?

Does it work if you pass it 32-bit pointers?

Question Answer

You may also like...

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.