9

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.

14

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. – John WH Smith Oct 29 '14 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. – Gilles Oct 29 '14 at 1:02
7

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 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 __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 – Swair Oct 28 '14 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 ;) – John WH Smith Oct 28 '14 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? – Swair Oct 28 '14 at 23:52
  • 1
    If 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. – John WH Smith Oct 29 '14 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. – Gilles Oct 29 '14 at 0:51
1

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.