Arch/X86/Include/Asm/Unistd.H VS. Include/Asm-Generic/Unistd.H

arch/x86/include/asm/unistd.h vs. include/asm-generic/unistd.h

I don't have a definite answer, but it's not uncommon for redundant files to exist when devs try to shift from old mechanisms to newer ones. Your case here looks quite similar.

If you checkout the 3.4 kernel, you will find that both arch/x86/include/asm/unistd_32.h and arch/x86/include/asm/unistd_64.h are gone. Instead, they are generated using arch/x86/syscalls.

Checkout the latest kernel (3.4.2 stable works for me), and do a "git log --stat arch/x86/include/asm", search for unistd_64.h or unistd_32.h or unistd.h.

I found the following commit might be interesting to you.
commit 303395ac3bf3e2cb488435537d416bc840438fcb

I've never touched syscalls before, so I'd rather not say too much. git log is usually how I sort out confusing files. You can also get into makefiles if you are good at it. (I am not, so I rely on git log. )

What is the linux-2.6.3x.x/include/asm-generic/' for?

asm-generic is a generic versions of functions usually coded in assembly, but coded in plain C, without any inline assembly. It's probably made for easy porting of the kernel to new platforms, and to keep platfom-independent common code in one place.

unistd_64.h in Linux

The syscalls provided by your kernel does not have to match the syscalls your C library knows about. The openat2 was added to glibc by commit e788bea in April 2020:

Update syscall lists for Linux 5.6.

Linux 5.6 has new openat2 and pidfd_getfd syscalls. This patch adds
them to syscall-names.list and regenerates the arch-syscall.h files.

The next glibc release was 2.32, in August 2020. In Ubuntu, libc6 packages with version >=2.32 are currently only available for groovy and hirsute:

Package libc6

  • bionic-updates (libs): GNU C Library: Shared libraries

    2.27-3ubuntu1.4: amd64 arm64 armhf i386 ppc64el s390x

    also provided by: libc6-udeb
  • focal-updates (libs): GNU C Library: Shared libraries

    2.31-0ubuntu9.2: amd64 arm64 armhf i386 ppc64el s390x

    also provided by: libc6-udeb
  • groovy (20.10) (libs): GNU C Library: Shared libraries

    2.32-0ubuntu3: amd64 arm64 armhf i386 ppc64el s390x

    also provided by: libc6-udeb
  • hirsute (21.04) (libs): GNU C Library: Shared libraries

    2.33-0ubuntu5: amd64 arm64 armhf i386 ppc64el s390x

But since you would not be getting much portability by requiring glibc>=2.32 and linux-kernel>=5.6 anyway, you could define the syscall numbers in your code (ifndef) and use syscall(2) instead.

Which header file of system call numbers is correct?

The asm-generic one is a template version that can be used if you're developing a new architecture for the kernel. I believe you'll find that there are actually many versions of unistd.h in the kernel source, because the ordering of system calls (and indeed system call existence) varies by architecture. Try this from the root of your kernel source hierarchy:

find . -name 'unistd*.h'

For x86 specifically, the uapi version is generated when you build the kernel. See the Makefile and various *.tbl files in arch/x86/entry/syscalls/ directory. This ends up generating files:

arch/x86/include/generated/uapi/asm/unistd_64.h
arch/x86/include/generated/uapi/asm/unistd_32.h
arch/x86/include/generated/uapi/asm/unistd_x32.h

(all of which are #included from a stub unistd.h file).

Ultimately the creation of a linux "distro" is very architecture-specific, so it's up to the distro creator to copy the correct unistd.h file(s) into some appropriate location within the /usr/include hierarchy. (And of course, your libc will also need to be compiled against the correct version in order for ordinary libc system calls to work correctly.)

In summary, the version in /usr/include/asm had better match your running kernel or it won't be possible to correctly generate an ad-hoc system call from a user process on your system, but you shouldn't be using that one within the kernel source hierarchy, because categorically the kernel source hierarchy never relies on user space headers. Within the kernel source, the mechanism for indexing that table is architecture-dependent because the layout and ordering of the table is itself architecture-dependent, and only architecture-specific code (the system call entry code) normally accesses the table, so only that code "needs to know" the correct indices.

Now if you're creating a new system call, you would need to go define its number in all of the unistd.h files for all of the architectures you want it to appear in.

ausyscall cannot extract new systemcall

They are generated from per-arch header files, e.g. lib/x86_64_table.h. You can see the commit that added openat2 is 8f41f04:

Update syscall table to the 5.11 kernel

master

v3.0.1

stevegrubb committed on Jan 18

The information in the headers in turn come from syscall table files from kernel sources. See: lib/syscall-update.txt.

The place where syscall information is gathered is:

arch/arm/tools/syscall.tbl

arch/arm/include/uapi/asm/unistd.h

arch/powerpc/include/uapi/asm/unistd.h

arch/s390/kernel/syscalls/syscall.tbl

arch/x86/entry/syscalls/syscall_32.tbl

arch/x86/entry/syscalls/syscall_64.tbl

include/uapi/asm-generic/unistd.h (aarch64)

Weird syscall numbers on Linux 32 bits

If you start with /usr/include/sys/syscall.h (as indicated in syscall(2)) and repeatedly follow the include directives you arrive at /usr/include/asm/unistd_32.h. Hence I recommend you use this header.

can't find the definition of __arm64_sys_ppoll function in linux source

For SYSCALL_DEFINE0, ..., SYSCALL_DEFINE6, first see @Ian Abbott's comment to my original question.

In file include/uapi/asm-generic/unistd.h, you can see the syscall definitions.

For example if you want to see the source code for shmat, you can use grep to see in the file these lines,

/* ipc/shm.c */
#define __NR_shmget 194
__SYSCALL(__NR_shmget, sys_shmget)
#define __NR_shmctl 195
__SC_COMP(__NR_shmctl, sys_shmctl, compat_sys_shmctl)
#define __NR_shmat 196
__SC_COMP(__NR_shmat, sys_shmat, compat_sys_shmat)
#define __NR_shmdt 197
__SYSCALL(__NR_shmdt, sys_shmdt)

So it says the definition is in file ipc/shm.c. There you can see these lines.

SYSCALL_DEFINE3(shmat, int, shmid, char __user *, shmaddr, int, shmflg)
{
unsigned long ret;
long err;

err = do_shmat(shmid, shmaddr, shmflg, &ret, SHMLBA);
if (err)
return err;
force_successful_syscall_return();
return (long)ret;
}

You can see the definition of shmat function with argments list.



Related Topics



Leave a reply



Submit