Issue
Sorry, I'm not very familiar with C and kernel programming, just need to write some bindings around syscalls.
I'm trying to compile a program to call Linux syscall directly. I've installed linux headers to /usr/src/kernel-headers-6.5.4_1/
. When I'm compiling it using gcc, the file asm/rwonce.h
could not be found. I created a minimal reproducible example:
#include <linux/syscalls.h>
int main() {
return 0;
}
And I'm compiling it using gcc -I/usr/src/kernel-headers-6.5.4_1/include -o test_program test_program.c
. The error is:
In file included from /usr/src/kernel-headers-6.5.4_1/include/linux/export.h:5,
from /usr/src/kernel-headers-6.5.4_1/include/linux/linkage.h:7,
from /usr/src/kernel-headers-6.5.4_1/include/linux/fs.h:5,
from /usr/include/linux/aio_abi.h:31,
from /usr/src/kernel-headers-6.5.4_1/include/linux/syscalls.h:79,
from test_program.c:1:
/usr/src/kernel-headers-6.5.4_1/include/linux/compiler.h:246:10: fatal error: asm/rwonce.h: No such file or directory
246 | #include <asm/rwonce.h>
| ^~~~~~~~~~~~~~
compilation terminated.
I have double checked the file /usr/src/kernel-headers-6.5.4_1/include/linux/syscalls.h
exists. gcc works fine with this include:
$ gcc -E -I/usr/src/kernel-headers-6.5.4_1/include - < /dev/null
# 0 "<stdin>"
# 0 "<built-in>"
# 0 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 0 "<command-line>" 2
# 1 "<stdin>"
I tried to add manually /usr/include
but it didn't help: gcc -I/usr/src/kernel-headers-6.5.4_1/include -I/usr/include -o test_program test_program.c
I found that asm/rwonce.h
is located at /usr/src/kernel-headers-6.5.4_1/arch/x86/include/generated/asm/rwonce.h
, but adding it as gcc -I/usr/src/kernel-headers-6.5.4_1/include -I/usr/include -I/usr/src/kernel-headers-6.5.4_1/arch/x86/include/generated -o test_program test_program.c
caused much more problems (first it can't find asm/linkage.h
header, then it can't match some function signatures).
I'm using Void linux kernel headers package. My current kernel is 6.5.4_1
, gcc version is gcc (GCC) 12.2.0
.
How to solve this include issue and compile program with kernel headers correctly?
Solution
If you want to manually issue a syscall use the syscall
library function from unistd.h
(you may need to add #define _DEFAULT_SOURCE
at the very top of your source code), do not include kernel headers directly e.g. with -I
. What you need should already be available without additional compiler flags. Userspace kernel headers are usually installed along with libc development headers. You may have a libc version that is too old.
RE: "I want to call a new cachestat syscall" - if you have a 6.5 kernel for which userspace headers were correctly installed, you should be able to find the definitions for struct cachestat
and struct cachestat_range
in sys/mman.h
or linux/mman.h
.
In any case, these structures are pretty simple. You can just re-define them in your source code if other options don't work:
struct cachestat_range {
uint64_t off;
uint64_t len;
};
struct cachestat {
uint64_t nr_cache;
uint64_t nr_dirty;
uint64_t nr_writeback;
uint64_t nr_evicted;
uint64_t nr_recently_evicted;
};
Answered By - Marco Bonelli Answer Checked By - Clifford M. (WPSolving Volunteer)