I have come across these files on Linux after reading more about system call numbers for particular architecture.
When I ran this command
locate unistd_64.h it gives me a path to the system call file
/usr/include/asm/unistd_64.h but when I looked in the
asm folder I found out there are other two files (
unistd_x32.h) as well. I know that they are existed for different architecture.
What I observe is that the system call number for
unistd_32.h are completely different.
// unistd_64.h #define __NR_read 0 #define __NR_write 1 #define __NR_open 2 #define __NR_close 3 #define __NR_stat 4 #define __NR_fstat 5 #define __NR_rt_sigaction 13 // this doesn't exist in unistd_x32
// unistd_32.h #define __NR_restart_syscall 0 #define __NR_exit 1 #define __NR_fork 2 #define __NR_read 3 #define __NR_write 4 #define __NR_open 5
And I believe it is because
i386 architecture and I think it will only allow
4GB of ram with
32 bit, maybe and
x86-64 architecture, and we can have 18-Quintillion bytes of RAM at maximum.
What I didn’t understood exactly is that what is this
unistd_x32.h file stands for? If we see it’s content, it’s pretty much similar to
unistd_64.h so I guess system call numbers are the same after all, but it does have a new macro or variable
__X32_SYSCALL_BIT. I don’t understand why we are adding this?
// unistd_x32.h #define __NR_read (__X32_SYSCALL_BIT + 0) #define __NR_write (__X32_SYSCALL_BIT + 1) #define __NR_open (__X32_SYSCALL_BIT + 2) #define __NR_close (__X32_SYSCALL_BIT + 3) #define __NR_stat (__X32_SYSCALL_BIT + 4) #define __NR_fstat (__X32_SYSCALL_BIT + 5)
Also, there are few system call numbers missing in
unistd_x32.h version, like we have
#define __NR_rt_sigaction 13 this system call in
unistd_64.h but not in
x32 version. There are many system calls like this. So If I assume that
x32 is basically
32 bit pointer architecture but it can run on 64 bit version? So it can access only
4GB of ram even if we have more RAM? Correct me if I am wrong in stating the question.
Yes, Linux’s x32 ABI is an ILP32 ABI for 64-bit mode. https://en.wikipedia.org/wiki/X32_ABI.
As you can see, its syscall numbers are not all the same as for x86-64, because pointer width is different and arg-passing registers holding pointers might have high garbage in the top 32 bits. The kernel needs to ignore this and only use the 32-bit pointer in the low half of the register.
Also some struct layouts maybe be different, as
long is a 32-bit type in the x32 ABI.
Answered By – Peter Cordes