https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125573
Bug ID: 125573
Summary: Support for BPF in libgccjit
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: jit
Assignee: dmalcolm at gcc dot gnu.org
Reporter: jemarch at gcc dot gnu.org
CC: antoyo at gcc dot gnu.org
Target Milestone: ---
This is a first attempt at using libgccjit in bpf-unknown-none targets.
GCC is built and installed with:
$ ../configure --enable-host-shared \
--enable-languages=jit,c++ \
--disable-bootstrap \
--enable-checking=release \
--prefix=$HOME/root-bpf \
--target=bpf-unknown-none
$ make
$ make install
This works properly. Next step is to build a test program, which is the
tut02-square.cc program from the libgccjit manual (in the sequel just
square.c):
$ gcc -L$HOME/root-bpf/lib \
-I$HOME/root-bpf/include \
square.c -o square -lgccjit -g
This compilation (done with the host compiler) works and results in a square
executable. Running the square executable, however, we get:
$ LD_LIBRARY_PATH=$HOME/root-bpf/lib ./square
libgccjit.so: error: : /tmp/libgccjit-kWS620/fake.so: cannot open shared
object file: \
No such file or directory
This is because the dlopen in playback::context::dlopen_built_dso:
handle = dlopen (m_tempdir->get_path_so_file (),
RTLD_NOW | RTLD_LOCAL);
cannot find the compiled fake.so, since its architecture (BPF) mismatches with
the host architecture (x86_64).
This boils down to the process documented in gcc/jit/notes.txt do not adapt
that well to the peculiar needs of BPF which, for starters, will always be a
cross.
The BPF use case is basically:
- Build code with jit_*.
- Compile it to BPF bytecodes in-memory.
- Get a pointer to that memory and load it into the kernel via syscall.
I think at least the following changes would be in order in libgccjit to
support the above:
- Rather than compiling fake.o and then linking fake.so, in BPF compiling
fake.o suffices. It happens that we do have a working BPF linker in binutils,
and in fact currently libgccjit uses it properly and links a valid fake.so, but
in the BPF world no external linking is done and the code for the compiled
functions shall be get from the non-linked object.
- Rather than dlopening fake.so and wrapping the resulting memory in a
jit_result, we would need to open and read fake.o (or mmap it) and wrap the
resulting memory in a jit_result. The jit_result_get_code will then use ELF
symbols etc in order to fetch the code for a function.
Does this sound good? (Note this is the first time I meddle with libgccjit, so
I might be missing the point entirely)