Is there a way to get the number of or list of system calls supported by currently running Linux Kernel? So I want to find a way to ‘read’ the syscall table of a running kernel.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
The file /proc/kallsyms lists all the symbols of the running kernel. By convention, system calls have a name that begin with sys_. On a 64-bit system, system calls for 32-bit programs have a name that begin with sys32_. Strictly speaking, this lists internal kernel functions, not system call, but I think that the correspondence does work (every system call invokes an internal kernel function to do the job, and I think the name is always the name of the system call with sys_ prepended).
</proc/kallsyms sed -n 's/.* sys_//p'
This is usually not useful information, because system calls change very slowly. Optional components provide functionality in terms of existing system calls, using general features such as devices (with ioctl when read and write doesn’t cut it), filesystems, sockets, etc. Determining the list of supported syscalls won’t tell you anything about the features that the system supports. Other internal function names won’t help either because these change very quickly: the name of the function that implements some feature on one kernel version may change on the next version.
Method 2
TL;DR
I kept finding new alternatives when writing this answer, so I just wrote a bit of details about each of them, and made some stats. Basically, you can either:
- Read Gilles’ answer, which provides a clean and fast way to do it (relies on
/proc). - Use the documentation resources.
- Use your system’s C header files.
- Use the kernel source code itself.
- Use the
/sysdirectory.
After doing the math, I’d recommend (among my alternatives) using the /sys filesystem, since it seems to give the best result in terms of number of system calls. You may jump right to that section if you don’t want to read about the other tricks.
Using the documentation resources
While you might miss some of them, you can use apropos to list all manpages belonging to section 2 (system calls) :
$ apropos -s2 . | awk '{print $1}' | column
Remove column if you don’t want fancy columnised output.
I just found it out, but there is a Linux man page about system calls, and you’ll be able to find most of them in it.
$ man syscalls
I also came across these two web sites which could be interesting:
Using headers files
Edit : Now, when it comes to programatically (or at least, without relying on documented features) determining what system calls are available, I’m afraid the kernel does not keep a table of its system calls, at least not under the form of a list of strings (as you’d probably expect to manipulate them). At this level, we’re talking more about functions addresses and pointers, rather than function names.
I just browsed my /usr/include directory and grep-ed a few things: you might find the following directories interesting. Some of them may be different on your machine, depending on your architecture and distribution, but I’m sure you’ll be able to adapt them.
- /usr/include/linux
- /usr/include/x86_64-linux-gnu
- /usr/include/sys
- /usr/include/asm-generic
By looking for function definitions in this file, you’ll come across many system calls, even though they will not be fully defined in there. I ran a few greps in these directories and I was able to find mentions of some system calls. Here’s an example:
$ grep 'sys_exit' /usr/include -R asm-generic/unistd.h:__SYSCALL(__NR_exit, sys_exit)
So, I’m guessing another way to find some of them would be:
$ egrep '^__SYSCALL' /usr/include -Rh | awk '{print $2}' | tr -d ')'
Using the kernel’s source code and its syscall table
Another solution is to use the kernel source code itself (and not just the headers!), and find a way to search it efficiently. Since kernel commit 303395ac3bf3e2cb488435537d416bc840438fcb, you might find this a little easier than before. Here is an example for 3.13 (which is my kernel):
$ wget https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/plain/arch/x86/syscalls/syscall_64.tbl?id=refs/tags/v3.13 -O syscall_64.tbl
Now that you got the actual syscalls table, just browse it:
$ while read line; do awk '! /#/ {print $3}'; done < syscall_64.tbl
You could find a way, using uname and arch, to download the tbl file straight from git.kernel.org, based on your running kernel version and architecture.
Using the /sys filesystem
Gilles’ answer gave me a little bit of inspiration, and you may find those system calls inside /sys/kernel/debug/tracing/events/syscalls. This directory is used to monitor the use of each system call on the system. Each syscall has two directories in it:
- sys_enter_[syscall]
- sys_exit_[syscall]
Therefore, using ls, grep and cut…
$ ls /sys/kernel/debug/tracing/events/syscalls | grep 'sys_enter' | cut -d'_' -f3
Stats
On my system:
- Using the man pages revealed 440 system calls.
grep-ing for__SYSCALLin the header files revealed 212 system calls.- Reading the syscalls table from the kernel sources revealed 346 system calls.
- Using
/sysrevealed 290 system calls.
Now, if I bring everything together…
$ apropos -s2 . | awk '{print $1}' > system_calls.txt
$ egrep '^__SYSCALL' /usr/include -Rh | awk '{print $2}' | tr -d ')' >> system_calls.txt
$ while read line; do awk '! /#/ {print $3}'; done < syscall_64.tbl >> system_calls.txt
$ ls /sys/kernel/debug/tracing/events/syscalls | grep 'sys_enter' | cut -d'_' -f3 >> system_calls.txt
$ sort < system_calls.txt | uniq | wc -l
707
There we go, 707 system calls! Of course, this number reflects a very flexible definition of a “system call”, since 3.13 is supposed to provide 274 system calls only (reading /sys seems to be the closest solution).
Method 3
All answers are fine.
If you are looking for a specific System Call name :
$ cat /proc/kallsyms | grep <sys_call_name>
If you are looking for list of all System Calls :
$ cat /proc/kallsyms
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0