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.
3 Answers
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.
-
+1. Now that's what I meant when I said "I'll let someone with more experience than me answer you". Additionally, since
/proc/kallsyms
can be manipulated like any other file, it becomes quite easy to use it in a program. Oct 29, 2014 at 0:55 -
2@JohnWHSmith “Can be manipulated like any other file”… with the caveat that on systems with kernel ASLR, this file should be readable only by root. Oct 29, 2014 at 1:02
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
/sys
directory.
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 grep
s 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__SYSCALL
in the header files revealed 212 system calls.- Reading the syscalls table from the kernel sources revealed 346 system calls.
- Using
/sys
revealed 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).
-
I am looking for a way more in terms of 'reading' the system call table in some way rather than finding out which of the system calls are documented in man pages– SwairOct 28, 2014 at 23:10
-
I don't think the kernel keeps a list of its syscalls, at least not as a list of strings. I edited my answer. If there's an actual way to do this, I'll let someone with more experience than me answer you ;) Oct 28, 2014 at 23:31
-
so I was wondering about this after I added a system call to the kernel and trying to use it was giving "function not implemented", and I wondered if there was some way to get the syscall table for current kernel. when I do '#make install', update grub and start a new kernel, at what step does the new kernel get relevant include files which contains the new system call?– SwairOct 28, 2014 at 23:52
-
1If you system call isn't found, then you did not implement it correctly. My answer tells you how to find Linux's system calls, but not how to debug your own (since it's not what you're asking for). If you're having trouble developing it, you should ask a question specifically about it, and avoid the XY problem. Oct 29, 2014 at 0:03
-
@swair It is highly unusual to add functionality by adding a system call. We can't tell for sure what's wrong since you didn't provide any code (and if your question requires C code, it's off-topic here, but at home on Stack Overflow). I suspect that you implemented a system call (correctly or not) and that you're trying to use it from a C program, and that you're missing the step of writing a C function that makes the system call. A system call is not an ordinary function call. Oct 29, 2014 at 0:51
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