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)

Reply via email to