mbox series

[0/8] eBPF support for GCC

Message ID 20190814213651.20286-1-jose.marchesi@oracle.com
Headers show
Series eBPF support for GCC | expand

Message

Jose E. Marchesi Aug. 14, 2019, 9:36 p.m. UTC
Hi people!

This patch series introduces a port of GCC to eBPF, which is a virtual
machine that resides in the Linux kernel.  Initially intended for
user-level packet capture and filtering, eBPF is nowadays generalized
to serve as a general-purpose infrastructure also for non-networking
purposes.

The binutils support is already upstream.  See
https://sourceware.org/ml/binutils/2019-05/msg00306.html.

eBPF architecture and ABI
=========================
   
Documentation for eBPF can be found in the linux kernel source tree,
file Documentation/networking/filter.txt.  It covers the instructions
set, the way the interpreter works and the many restrictions imposed
by the kernel verifier.
   
As for the ABI, att this moment compiled eBPF doesn't have very well
established conventions.  The details on what is expected to be in an
ELF file containing eBPF is determined, in practice, by what the llvm
BPF backend generates and what is expected by the the two existing
kernel loaders: bpf_load.c and libbpf.

We hope that the addition of this port to the GNU toolchain will help
to mature this domain.

Overview of the patch series
============================
   
The first patch is preparatory.  It updates config.guess and
config.sub from the 'config' upstream project, in order to recognize
bpf-*-* triplets.

The second patch adds the new GCC port proper.  Machine description,
implementation of target hooks and macros, command-line options and
the like.

The third patch adds a libgcc port for eBPF.  At the moment, it is
minimal and it basically addresses the limitations imposed by the
target, by excluding a few functions in libgcc2 (all of them related
to TImodes) whose default implementations exceed the eBPF stack limit.

The fourth, fifth and sixth patches deal with testing the new
port. The gcc.target testsuite is extended with eBPF-specific tests,
covering the backend-specific built-in functions and diagnostics.  The
check-effective-target functions are made aware of eBPF targets. Many
tests in the gcc.c-torture/compile testsuite are annotated to be
skipped in bpf-*-* targets, since they violate some restriction
imposed by the hardware (such as surpassing the stack limit.)  The
resulting testsuite doesn't have unexpected failures, and is currently
the principal way to check for regressions in the port.  Likewise,
many tests in the gcc.dg testsuite are annotated to be skipped in
bpf-*-* targets.

The seventh patch adds documentation updates to the GCC manual,
including information on the new command line options and compiler
built-ins.

Finally, the eight patch adds myself as the maintainer of the BPF
port.  I personally commit to evolve and maintain the port for as long
as necessary, and to find a suitable replacement in case I have to
step down for whatever reason.

Some notes on the port
======================

As a compilation target, eBPF is rather peculiar.  This is mainly due
to the quite hard restrictions imposed by the kernel verifier, and
also due to the security-driven design of the architecture itself.

To list a few examples:

. The stack is disjoint, and each stack frame corresponding to a
  function activation is isolated: it is not possible for a callee to
  access the stack frame of the caller, nor for a caller to access the
  stack frame of it's callees.  The frame pointer register is
  read-only.

. Therefore it is not possible to pass arguments in the stack.

. Argument passing is restricted to 5 arguments.

. Each stack frame is limited to 512 bytes.

. The instruction set doesn't support indirect jumps.

. The instruction set doesn't support indirect calls.

. The architecture doesn't provide an explicit stack pointer.
  Instead, the eBPF "hardware" (in this case the kernel verifier)
  examines the compiled program and, by looking at the way the stack
  is accessed, estimates the size of the stack frame for each
  function.

. eBPF "programs" are not ELF executables, but relocatable ELF
  objects.  This is because the kernel loaders need access to certain
  relocations, and each object contains several entry points, which
  are different kind of eBPF kernel programs hooked to different parts
  of the kernel.  We are working on a more "Elf conventional"
  alternative load model for eBPF programs, but that's a tangent at
  this point.

Restrictions like the above impact the port in several ways, some of
which are good to keep in mind while reviewing the patches:

. Only (a subset of) C is supported at the moment.  It should be
  possible to add more languages in the future, as the eBPF kernel
  verifier gets smarter and therefore more sophisticated programs are
  allowed.

. The back end tries to issue errors when an eBPF restriction is
  violated.  This is to increase the chances of the resulting objects
  to be palatable to the kernel verifier, shortening the development
  cycle.

. Dynamic stack allocation (alloca and VLAs) is achieved by using what
  otherwise would be a perfectly normal general register, %r9, as a
  pseudo stack pointer.  This has the disadvantage of making the
  register "fixed" and therefore not available for general register
  allocation.  Hopefully there is a way to conditionalize this, since
  both alloca and VLAs are relatively uncommon; I haven't found it
  yet.

. The restrictions imposed by the kernel verifier, the characteristics
  of the virtual architecture, the available kernel helpers, and the
  behavior of the loaders, all change from one version of the kernel
  to another. Therefore, the GCC backend provides a -mkernel command
  line option that specifies the minimum kernel version in which the
  program is to be executed.  This is conceptually similar to the
  -mcpu option provided by most ports.

I am preparing a white paper on "compiled eBPF" that will be available
at the Cauldron next month, addressing the points above, and many
others, in depth.

I am really eager to discuss with you people, how to best compile eBPF
:)

Present and future work
=======================

This port provides a rough equivalence of what the llvm port does [1]
and, along with the binutils support, it can be used to develop
compiled eBPF applications.

However, it is in no way finished.

There are a lot of further refinements and additions to the port on
our radar: how to translate more C, CO-RE capabilities (compile-once,
run-everywhere), generation of BTF, and much more...  the eBPF field
moves very fast!

Also, a simulator and GDB support is on the works.  Once completed, it
will emulate the different kernel contexts where eBPF programs
execute.  Once the simulator works, a suitable board description will
be added to dejagnu, making it possible to run the GCC testsuites on
it.

Now that GCC is entering the play, there will be two C compilers able
to generate eBPF, the other being clang/llvm.  Interoperability
between programs generated by both compilers becomes an important
concern, and keeping it will be an an on-going task, requiring
communication between the compilers communities and the kernel
community.

[1] modulus the very recently added CO-RE stuff added in llvm upstream
    a few weeks ago.
   
Testing
=======
   
The following test suites have been executed for target
bpf-unknown-none in a x86-64-pc-linux-gnu host, using the latest
binutils from master.

Running /home/jemarch/gnu/src/gcc-git/gcc/testsuite/gcc.target/bpf/bpf.exp ...

		=== gcc Summary ===

   # of expected passes		230

Running /home/jemarch/gnu/src/gcc-git/gcc/testsuite/gcc.c-torture/compile/compile.exp ...

		=== gcc Summary ===

   # of expected passes		11743
   # of unresolved testcases	28
   # of unsupported tests	1482

Running /home/jemarch/gnu/src/gcc-git/gcc/testsuite/gcc.dg/dg.exp ...

		=== gcc Summary ===

   # of expected passes		23062
   # of unexpected failures	819
   # of unexpected successes	3
   # of expected failures	267
   # of unresolved testcases	559
   # of unsupported tests	649
   
Most of the failures running the gcc-dg tests are due to linker errors
like undefined references to `exit' and other standard functions,
which are not available for the target.

Jose E. Marchesi (8):
  Update config.sub and config.guess.
  bpf: new GCC port
  bpf: new libgcc port
  bpf: gcc.target eBPF testsuite
  bpf: make target-supports.exp aware of eBPF
  bpf: adjust GCC testsuite to eBPF limitations
  bpf: manual updates for eBPF
  bpf: add myself as the maintainer for the eBPF port

 ChangeLog                                          |   14 +
 MAINTAINERS                                        |    1 +
 config.guess                                       |  264 ++++-
 config.sub                                         |   50 +-
 configure                                          |   68 +-
 configure.ac                                       |   54 +-
 contrib/ChangeLog                                  |    4 +
 contrib/config-list.mk                             |    2 +-
 gcc/ChangeLog                                      |   23 +
 gcc/common/config/bpf/bpf-common.c                 |   57 +
 gcc/config.gcc                                     |    9 +
 gcc/config/bpf/bpf-helpers.def                     |  194 ++++
 gcc/config/bpf/bpf-helpers.h                       |  324 ++++++
 gcc/config/bpf/bpf-opts.h                          |   56 +
 gcc/config/bpf/bpf-protos.h                        |   33 +
 gcc/config/bpf/bpf.c                               | 1136 ++++++++++++++++++++
 gcc/config/bpf/bpf.h                               |  565 ++++++++++
 gcc/config/bpf/bpf.md                              |  528 +++++++++
 gcc/config/bpf/bpf.opt                             |  119 ++
 gcc/config/bpf/constraints.md                      |   29 +
 gcc/config/bpf/predicates.md                       |  105 ++
 gcc/config/bpf/t-bpf                               |    0
 gcc/doc/extend.texi                                |  171 +++
 gcc/doc/invoke.texi                                |   30 +
 gcc/testsuite/ChangeLog                            |  293 +++++
 gcc/testsuite/gcc.c-torture/compile/20000211-1.c   |    2 +
 gcc/testsuite/gcc.c-torture/compile/20000403-1.c   |    2 +
 gcc/testsuite/gcc.c-torture/compile/20000609-1.c   |    2 +
 gcc/testsuite/gcc.c-torture/compile/20000804-1.c   |    1 +
 gcc/testsuite/gcc.c-torture/compile/20001226-1.c   |    1 +
 gcc/testsuite/gcc.c-torture/compile/20010102-1.c   |    2 +
 gcc/testsuite/gcc.c-torture/compile/20010107-1.c   |    2 +
 gcc/testsuite/gcc.c-torture/compile/20011109-1.c   |    2 +
 gcc/testsuite/gcc.c-torture/compile/20011218-1.c   |    2 +
 gcc/testsuite/gcc.c-torture/compile/20011229-1.c   |    2 +
 gcc/testsuite/gcc.c-torture/compile/20020129-1.c   |    1 +
 gcc/testsuite/gcc.c-torture/compile/20020304-1.c   |    2 +
 gcc/testsuite/gcc.c-torture/compile/20020320-1.c   |    2 +
 gcc/testsuite/gcc.c-torture/compile/20020604-1.c   |    1 +
 gcc/testsuite/gcc.c-torture/compile/20020706-1.c   |    1 +
 gcc/testsuite/gcc.c-torture/compile/20020706-2.c   |    1 +
 gcc/testsuite/gcc.c-torture/compile/20021015-1.c   |    1 +
 gcc/testsuite/gcc.c-torture/compile/20021205-1.c   |    2 +
 gcc/testsuite/gcc.c-torture/compile/20030903-1.c   |    2 +
 gcc/testsuite/gcc.c-torture/compile/20030921-1.c   |    1 +
 gcc/testsuite/gcc.c-torture/compile/20031023-1.c   |    2 +
 gcc/testsuite/gcc.c-torture/compile/20031023-2.c   |    2 +
 gcc/testsuite/gcc.c-torture/compile/20031023-3.c   |    2 +
 gcc/testsuite/gcc.c-torture/compile/20031023-4.c   |    2 +
 gcc/testsuite/gcc.c-torture/compile/20031125-1.c   |    2 +
 gcc/testsuite/gcc.c-torture/compile/20040101-1.c   |    1 +
 gcc/testsuite/gcc.c-torture/compile/20040317-2.c   |    2 +
 gcc/testsuite/gcc.c-torture/compile/20040614-1.c   |    1 +
 gcc/testsuite/gcc.c-torture/compile/20040726-1.c   |    2 +
 gcc/testsuite/gcc.c-torture/compile/20040909-1.c   |    2 +
 gcc/testsuite/gcc.c-torture/compile/20050122-1.c   |    2 +
 gcc/testsuite/gcc.c-torture/compile/20050202-1.c   |    2 +
 gcc/testsuite/gcc.c-torture/compile/20050303-1.c   |    1 +
 gcc/testsuite/gcc.c-torture/compile/20050622-1.c   |    1 +
 gcc/testsuite/gcc.c-torture/compile/20051216-1.c   |    1 +
 gcc/testsuite/gcc.c-torture/compile/20060208-1.c   |    2 +
 gcc/testsuite/gcc.c-torture/compile/20060421-1.c   |    2 +
 gcc/testsuite/gcc.c-torture/compile/20071207-1.c   |    1 +
 gcc/testsuite/gcc.c-torture/compile/20080903-1.c   |    2 +
 gcc/testsuite/gcc.c-torture/compile/20081108-1.c   |    2 +
 gcc/testsuite/gcc.c-torture/compile/20101217-1.c   |    2 +
 gcc/testsuite/gcc.c-torture/compile/20121027-1.c   |    2 +
 gcc/testsuite/gcc.c-torture/compile/20150327.c     |    2 +
 gcc/testsuite/gcc.c-torture/compile/20151204.c     |    1 +
 gcc/testsuite/gcc.c-torture/compile/900313-1.c     |    2 +
 gcc/testsuite/gcc.c-torture/compile/920428-2.c     |    2 +
 gcc/testsuite/gcc.c-torture/compile/920501-12.c    |    1 +
 gcc/testsuite/gcc.c-torture/compile/920501-4.c     |    1 +
 gcc/testsuite/gcc.c-torture/compile/920501-7.c     |    1 +
 gcc/testsuite/gcc.c-torture/compile/920625-1.c     |    2 +
 gcc/testsuite/gcc.c-torture/compile/920723-1.c     |    1 +
 gcc/testsuite/gcc.c-torture/compile/920928-5.c     |    3 +
 gcc/testsuite/gcc.c-torture/compile/921202-1.c     |    2 +
 gcc/testsuite/gcc.c-torture/compile/930117-1.c     |    2 +
 gcc/testsuite/gcc.c-torture/compile/930421-1.c     |    2 +
 gcc/testsuite/gcc.c-torture/compile/930607-1.c     |    2 +
 gcc/testsuite/gcc.c-torture/compile/930623-1.c     |    1 +
 gcc/testsuite/gcc.c-torture/compile/931003-1.c     |    2 +
 gcc/testsuite/gcc.c-torture/compile/931004-1.c     |    2 +
 gcc/testsuite/gcc.c-torture/compile/950719-1.c     |    2 +
 gcc/testsuite/gcc.c-torture/compile/951222-1.c     |    2 +
 gcc/testsuite/gcc.c-torture/compile/961004-1.c     |    2 +
 gcc/testsuite/gcc.c-torture/compile/980504-1.c     |    2 +
 gcc/testsuite/gcc.c-torture/compile/980816-1.c     |    2 +
 gcc/testsuite/gcc.c-torture/compile/990517-1.c     |    3 +
 gcc/testsuite/gcc.c-torture/compile/990625-1.c     |    2 +
 gcc/testsuite/gcc.c-torture/compile/991213-2.c     |    2 +
 gcc/testsuite/gcc.c-torture/compile/DFcmp.c        |    2 +
 gcc/testsuite/gcc.c-torture/compile/HIcmp.c        |    2 +
 gcc/testsuite/gcc.c-torture/compile/HIset.c        |    2 +
 gcc/testsuite/gcc.c-torture/compile/QIcmp.c        |    2 +
 gcc/testsuite/gcc.c-torture/compile/QIset.c        |    2 +
 gcc/testsuite/gcc.c-torture/compile/SFset.c        |    1 +
 gcc/testsuite/gcc.c-torture/compile/SIcmp.c        |    2 +
 gcc/testsuite/gcc.c-torture/compile/SIset.c        |    2 +
 gcc/testsuite/gcc.c-torture/compile/UHIcmp.c       |    2 +
 gcc/testsuite/gcc.c-torture/compile/UQIcmp.c       |    2 +
 gcc/testsuite/gcc.c-torture/compile/USIcmp.c       |    2 +
 gcc/testsuite/gcc.c-torture/compile/bcopy.c        |    1 +
 gcc/testsuite/gcc.c-torture/compile/callind.c      |    2 +
 gcc/testsuite/gcc.c-torture/compile/calls-void.c   |    1 +
 gcc/testsuite/gcc.c-torture/compile/calls.c        |    1 +
 gcc/testsuite/gcc.c-torture/compile/consec.c       |    2 +
 .../gcc.c-torture/compile/limits-fndefn.c          |    1 +
 gcc/testsuite/gcc.c-torture/compile/lll.c          |    1 +
 gcc/testsuite/gcc.c-torture/compile/parms.c        |    1 +
 gcc/testsuite/gcc.c-torture/compile/pass.c         |    2 +
 gcc/testsuite/gcc.c-torture/compile/poor.c         |    2 +
 gcc/testsuite/gcc.c-torture/compile/pp.c           |    2 +
 gcc/testsuite/gcc.c-torture/compile/pr21840.c      |    2 +
 gcc/testsuite/gcc.c-torture/compile/pr23929.c      |    1 +
 gcc/testsuite/gcc.c-torture/compile/pr25310.c      |    1 +
 gcc/testsuite/gcc.c-torture/compile/pr25311.c      |    1 +
 gcc/testsuite/gcc.c-torture/compile/pr32139.c      |    2 +
 gcc/testsuite/gcc.c-torture/compile/pr32399.c      |    2 +
 gcc/testsuite/gcc.c-torture/compile/pr34091.c      |    2 +
 gcc/testsuite/gcc.c-torture/compile/pr34458.c      |    1 +
 gcc/testsuite/gcc.c-torture/compile/pr34688.c      |    2 +
 gcc/testsuite/gcc.c-torture/compile/pr35607.c      |    2 +
 gcc/testsuite/gcc.c-torture/compile/pr37258.c      |    2 +
 gcc/testsuite/gcc.c-torture/compile/pr37327.c      |    2 +
 gcc/testsuite/gcc.c-torture/compile/pr37381.c      |    2 +
 gcc/testsuite/gcc.c-torture/compile/pr37433-1.c    |    2 +
 gcc/testsuite/gcc.c-torture/compile/pr37433.c      |    2 +
 gcc/testsuite/gcc.c-torture/compile/pr37669-2.c    |    1 +
 gcc/testsuite/gcc.c-torture/compile/pr37669.c      |    1 +
 gcc/testsuite/gcc.c-torture/compile/pr37742-3.c    |    2 +
 gcc/testsuite/gcc.c-torture/compile/pr39937.c      |    2 +
 gcc/testsuite/gcc.c-torture/compile/pr39941.c      |    2 +
 gcc/testsuite/gcc.c-torture/compile/pr40080.c      |    2 +
 gcc/testsuite/gcc.c-torture/compile/pr41181.c      |    2 +
 gcc/testsuite/gcc.c-torture/compile/pr41634.c      |    2 +
 gcc/testsuite/gcc.c-torture/compile/pr43415.c      |    2 +
 gcc/testsuite/gcc.c-torture/compile/pr43417.c      |    2 +
 gcc/testsuite/gcc.c-torture/compile/pr43635.c      |    2 +
 gcc/testsuite/gcc.c-torture/compile/pr43791.c      |    2 +
 gcc/testsuite/gcc.c-torture/compile/pr43845.c      |    2 +
 gcc/testsuite/gcc.c-torture/compile/pr44043.c      |    2 +
 gcc/testsuite/gcc.c-torture/compile/pr44063.c      |    2 +
 gcc/testsuite/gcc.c-torture/compile/pr44788.c      |    2 +
 gcc/testsuite/gcc.c-torture/compile/pr48596.c      |    2 +
 gcc/testsuite/gcc.c-torture/compile/pr51694.c      |    2 +
 gcc/testsuite/gcc.c-torture/compile/pr51856.c      |    2 +
 gcc/testsuite/gcc.c-torture/compile/pr52750.c      |    1 +
 gcc/testsuite/gcc.c-torture/compile/pr54713-1.c    |    1 +
 gcc/testsuite/gcc.c-torture/compile/pr54713-2.c    |    1 +
 gcc/testsuite/gcc.c-torture/compile/pr54713-3.c    |    1 +
 gcc/testsuite/gcc.c-torture/compile/pr55921.c      |    1 +
 gcc/testsuite/gcc.c-torture/compile/pr70240.c      |    2 +
 gcc/testsuite/gcc.c-torture/compile/pr70355.c      |    2 +
 gcc/testsuite/gcc.c-torture/compile/pr77754-2.c    |    1 +
 gcc/testsuite/gcc.c-torture/compile/pr77754-3.c    |    1 +
 gcc/testsuite/gcc.c-torture/compile/pr77754-4.c    |    1 +
 gcc/testsuite/gcc.c-torture/compile/pr82052.c      |    2 +
 gcc/testsuite/gcc.c-torture/compile/pr83487.c      |    1 +
 gcc/testsuite/gcc.c-torture/compile/pr86122.c      |    1 +
 gcc/testsuite/gcc.c-torture/compile/pr89280.c      |    1 +
 gcc/testsuite/gcc.c-torture/compile/pr89663-2.c    |    1 +
 gcc/testsuite/gcc.c-torture/compile/pret-arg.c     |    2 +
 gcc/testsuite/gcc.c-torture/compile/pta-1.c        |    2 +
 .../gcc.c-torture/compile/regs-arg-size.c          |    2 +
 gcc/testsuite/gcc.c-torture/compile/sound.c        |    1 +
 .../gcc.c-torture/compile/stack-check-1.c          |    1 +
 gcc/testsuite/gcc.c-torture/compile/structret.c    |    2 +
 gcc/testsuite/gcc.c-torture/compile/uuarg.c        |    2 +
 gcc/testsuite/gcc.dg/20001009-1.c                  |    1 +
 gcc/testsuite/gcc.dg/20020418-1.c                  |    1 +
 gcc/testsuite/gcc.dg/20020426-2.c                  |    1 +
 gcc/testsuite/gcc.dg/20020430-1.c                  |    1 +
 gcc/testsuite/gcc.dg/20040306-1.c                  |    2 +-
 gcc/testsuite/gcc.dg/20040622-2.c                  |    1 +
 gcc/testsuite/gcc.dg/20050603-2.c                  |    1 +
 gcc/testsuite/gcc.dg/20050629-1.c                  |    1 +
 gcc/testsuite/gcc.dg/20061026.c                    |    1 +
 gcc/testsuite/gcc.dg/Walloc-size-larger-than-18.c  |    1 +
 gcc/testsuite/gcc.dg/Warray-bounds-3.c             |    1 +
 gcc/testsuite/gcc.dg/Warray-bounds-30.c            |    3 +-
 gcc/testsuite/gcc.dg/Wframe-larger-than-2.c        |    3 +-
 gcc/testsuite/gcc.dg/Wframe-larger-than.c          |    1 +
 gcc/testsuite/gcc.dg/Wrestrict-11.c                |    3 +-
 gcc/testsuite/gcc.dg/builtins-config.h             |    4 +-
 gcc/testsuite/gcc.target/bpf/bpf.exp               |   41 +
 gcc/testsuite/gcc.target/bpf/builtin-load.c        |   20 +
 gcc/testsuite/gcc.target/bpf/constant-calls.c      |   19 +
 gcc/testsuite/gcc.target/bpf/diag-funargs.c        |   15 +
 gcc/testsuite/gcc.target/bpf/diag-indcalls.c       |   11 +
 gcc/testsuite/gcc.target/bpf/helper-bind.c         |   15 +
 gcc/testsuite/gcc.target/bpf/helper-bpf-redirect.c |   15 +
 .../gcc.target/bpf/helper-clone-redirect.c         |   16 +
 gcc/testsuite/gcc.target/bpf/helper-csum-diff.c    |   16 +
 gcc/testsuite/gcc.target/bpf/helper-csum-update.c  |   15 +
 .../bpf/helper-current-task-under-cgroup.c         |   15 +
 gcc/testsuite/gcc.target/bpf/helper-fib-lookup.c   |   16 +
 .../gcc.target/bpf/helper-get-cgroup-classid.c     |   14 +
 .../gcc.target/bpf/helper-get-current-cgroup-id.c  |   13 +
 .../gcc.target/bpf/helper-get-current-comm.c       |   15 +
 .../gcc.target/bpf/helper-get-current-pid-tgid.c   |   13 +
 .../gcc.target/bpf/helper-get-current-task.c       |   14 +
 .../gcc.target/bpf/helper-get-current-uid-gid.c    |   13 +
 .../gcc.target/bpf/helper-get-hash-recalc.c        |   14 +
 .../gcc.target/bpf/helper-get-listener-sock.c      |   13 +
 .../gcc.target/bpf/helper-get-local-storage.c      |   14 +
 .../gcc.target/bpf/helper-get-numa-node-id.c       |   13 +
 .../gcc.target/bpf/helper-get-prandom-u32.c        |   13 +
 .../gcc.target/bpf/helper-get-route-realm.c        |   14 +
 .../gcc.target/bpf/helper-get-smp-processor-id.c   |   13 +
 .../gcc.target/bpf/helper-get-socket-cookie.c      |   14 +
 .../gcc.target/bpf/helper-get-socket-uid.c         |   14 +
 gcc/testsuite/gcc.target/bpf/helper-get-stack.c    |   16 +
 gcc/testsuite/gcc.target/bpf/helper-get-stackid.c  |   15 +
 gcc/testsuite/gcc.target/bpf/helper-getsockopt.c   |   17 +
 gcc/testsuite/gcc.target/bpf/helper-ktime-get-ns.c |   12 +
 .../gcc.target/bpf/helper-l3-csum-replace.c        |   16 +
 .../gcc.target/bpf/helper-l4-csum-replace.c        |   16 +
 .../gcc.target/bpf/helper-lwt-push-encap.c         |   15 +
 .../gcc.target/bpf/helper-lwt-seg6-action.c        |   16 +
 .../gcc.target/bpf/helper-lwt-seg6-adjust-srh.c    |   16 +
 .../gcc.target/bpf/helper-lwt-seg6-store-bytes.c   |   16 +
 .../gcc.target/bpf/helper-map-delete-elem.c        |   14 +
 .../gcc.target/bpf/helper-map-lookup-elem.c        |   12 +
 .../gcc.target/bpf/helper-map-peek-elem.c          |   14 +
 gcc/testsuite/gcc.target/bpf/helper-map-pop-elem.c |   14 +
 .../gcc.target/bpf/helper-map-push-elem.c          |   16 +
 .../gcc.target/bpf/helper-map-update-elem.c        |   16 +
 .../gcc.target/bpf/helper-msg-apply-bytes.c        |   15 +
 .../gcc.target/bpf/helper-msg-cork-bytes.c         |   15 +
 gcc/testsuite/gcc.target/bpf/helper-msg-pop-data.c |   16 +
 .../gcc.target/bpf/helper-msg-pull-data.c          |   16 +
 .../gcc.target/bpf/helper-msg-push-data.c          |   16 +
 .../gcc.target/bpf/helper-msg-redirect-hash.c      |   16 +
 .../gcc.target/bpf/helper-msg-redirect-map.c       |   17 +
 .../gcc.target/bpf/helper-override-return.c        |   15 +
 .../gcc.target/bpf/helper-perf-event-output.c      |   17 +
 .../gcc.target/bpf/helper-perf-event-read-value.c  |   16 +
 .../gcc.target/bpf/helper-perf-event-read.c        |   15 +
 .../gcc.target/bpf/helper-perf-prog-read-value.c   |   15 +
 .../gcc.target/bpf/helper-probe-read-str.c         |   16 +
 gcc/testsuite/gcc.target/bpf/helper-probe-read.c   |   15 +
 .../gcc.target/bpf/helper-probe-write-user.c       |   15 +
 gcc/testsuite/gcc.target/bpf/helper-rc-keydown.c   |   17 +
 .../gcc.target/bpf/helper-rc-pointer-rel.c         |   15 +
 gcc/testsuite/gcc.target/bpf/helper-rc-repeat.c    |   14 +
 gcc/testsuite/gcc.target/bpf/helper-redirect-map.c |   16 +
 .../gcc.target/bpf/helper-set-hash-invalid.c       |   13 +
 gcc/testsuite/gcc.target/bpf/helper-set-hash.c     |   15 +
 gcc/testsuite/gcc.target/bpf/helper-setsockopt.c   |   19 +
 gcc/testsuite/gcc.target/bpf/helper-sk-fullsock.c  |   13 +
 .../gcc.target/bpf/helper-sk-lookup-tcp.c          |   19 +
 .../gcc.target/bpf/helper-sk-lookup-upd.c          |   19 +
 .../gcc.target/bpf/helper-sk-redirect-hash.c       |   16 +
 .../gcc.target/bpf/helper-sk-redirect-map.c        |   16 +
 gcc/testsuite/gcc.target/bpf/helper-sk-release.c   |   14 +
 .../gcc.target/bpf/helper-sk-select-reuseport.c    |   16 +
 .../gcc.target/bpf/helper-sk-storage-delete.c      |   14 +
 .../gcc.target/bpf/helper-sk-storage-get.c         |   16 +
 .../gcc.target/bpf/helper-skb-adjust-room.c        |   17 +
 .../gcc.target/bpf/helper-skb-cgroup-id.c          |   14 +
 .../gcc.target/bpf/helper-skb-change-head.c        |   16 +
 .../gcc.target/bpf/helper-skb-change-proto.c       |   16 +
 .../gcc.target/bpf/helper-skb-change-tail.c        |   16 +
 .../gcc.target/bpf/helper-skb-change-type.c        |   15 +
 .../gcc.target/bpf/helper-skb-ecn-set-ce.c         |   14 +
 .../gcc.target/bpf/helper-skb-get-tunnel-key.c     |   16 +
 .../gcc.target/bpf/helper-skb-get-tunnel-opt.c     |   16 +
 .../gcc.target/bpf/helper-skb-get-xfrm-state.c     |   17 +
 .../bpf/helper-skb-load-bytes-relative.c           |   17 +
 .../gcc.target/bpf/helper-skb-load-bytes.c         |   15 +
 .../gcc.target/bpf/helper-skb-pull-data.c          |   15 +
 .../gcc.target/bpf/helper-skb-set-tunnel-key.c     |   16 +
 .../gcc.target/bpf/helper-skb-set-tunnel-opt.c     |   16 +
 .../gcc.target/bpf/helper-skb-store-bytes.c        |   18 +
 .../gcc.target/bpf/helper-skb-under-cgroup.c       |   15 +
 gcc/testsuite/gcc.target/bpf/helper-skb-vlan-pop.c |   14 +
 .../gcc.target/bpf/helper-skb-vlan-push.c          |   16 +
 .../gcc.target/bpf/helper-skc-lookup-tcp.c         |   17 +
 .../gcc.target/bpf/helper-sock-hash-update.c       |   16 +
 .../gcc.target/bpf/helper-sock-map-update.c        |   16 +
 .../gcc.target/bpf/helper-sock-ops-cb-flags-set.c  |   16 +
 gcc/testsuite/gcc.target/bpf/helper-spin-lock.c    |   13 +
 gcc/testsuite/gcc.target/bpf/helper-spin-unlock.c  |   13 +
 gcc/testsuite/gcc.target/bpf/helper-strtol.c       |   18 +
 gcc/testsuite/gcc.target/bpf/helper-strtoul.c      |   18 +
 .../bpf/helper-sysctl-get-current-value.c          |   17 +
 .../gcc.target/bpf/helper-sysctl-get-name.c        |   18 +
 .../gcc.target/bpf/helper-sysctl-get-new-value.c   |   17 +
 .../gcc.target/bpf/helper-sysctl-set-new-value.c   |   17 +
 gcc/testsuite/gcc.target/bpf/helper-tail-call.c    |   14 +
 .../gcc.target/bpf/helper-tcp-check-syncookie.c    |   17 +
 gcc/testsuite/gcc.target/bpf/helper-tcp-sock.c     |   13 +
 gcc/testsuite/gcc.target/bpf/helper-trace-printk.c |   13 +
 .../gcc.target/bpf/helper-xdp-adjust-head.c        |   15 +
 .../gcc.target/bpf/helper-xdp-adjust-meta.c        |   15 +
 .../gcc.target/bpf/helper-xdp-adjust-tail.c        |   15 +
 .../gcc.target/bpf/skb-ancestor-cgroup-id.c        |   16 +
 gcc/testsuite/gcc.target/bpf/sync-fetch-and-add.c  |   14 +
 gcc/testsuite/lib/target-supports.exp              |   27 +-
 libgcc/ChangeLog                                   |    7 +
 libgcc/config.host                                 |    7 +
 libgcc/config/bpf/crti.S                           |    0
 libgcc/config/bpf/crtn.S                           |    0
 libgcc/config/bpf/t-bpf                            |   24 +
 306 files changed, 6142 insertions(+), 96 deletions(-)
 create mode 100644 gcc/common/config/bpf/bpf-common.c
 create mode 100644 gcc/config/bpf/bpf-helpers.def
 create mode 100644 gcc/config/bpf/bpf-helpers.h
 create mode 100644 gcc/config/bpf/bpf-opts.h
 create mode 100644 gcc/config/bpf/bpf-protos.h
 create mode 100644 gcc/config/bpf/bpf.c
 create mode 100644 gcc/config/bpf/bpf.h
 create mode 100644 gcc/config/bpf/bpf.md
 create mode 100644 gcc/config/bpf/bpf.opt
 create mode 100644 gcc/config/bpf/constraints.md
 create mode 100644 gcc/config/bpf/predicates.md
 create mode 100644 gcc/config/bpf/t-bpf
 create mode 100644 gcc/testsuite/gcc.target/bpf/bpf.exp
 create mode 100644 gcc/testsuite/gcc.target/bpf/builtin-load.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/constant-calls.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/diag-funargs.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/diag-indcalls.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-bind.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-bpf-redirect.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-clone-redirect.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-csum-diff.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-csum-update.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-current-task-under-cgroup.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-fib-lookup.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-cgroup-classid.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-current-cgroup-id.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-current-comm.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-current-pid-tgid.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-current-task.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-current-uid-gid.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-hash-recalc.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-listener-sock.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-local-storage.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-numa-node-id.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-prandom-u32.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-route-realm.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-smp-processor-id.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-socket-cookie.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-socket-uid.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-stack.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-get-stackid.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-getsockopt.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-ktime-get-ns.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-l3-csum-replace.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-l4-csum-replace.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-lwt-push-encap.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-action.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-adjust-srh.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-lwt-seg6-store-bytes.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-map-delete-elem.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-map-lookup-elem.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-map-peek-elem.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-map-pop-elem.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-map-push-elem.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-map-update-elem.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-msg-apply-bytes.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-msg-cork-bytes.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-msg-pop-data.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-msg-pull-data.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-msg-push-data.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-msg-redirect-hash.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-msg-redirect-map.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-override-return.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-perf-event-output.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-perf-event-read-value.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-perf-event-read.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-perf-prog-read-value.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-probe-read-str.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-probe-read.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-probe-write-user.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-rc-keydown.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-rc-pointer-rel.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-rc-repeat.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-redirect-map.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-set-hash-invalid.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-set-hash.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-setsockopt.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sk-fullsock.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sk-lookup-tcp.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sk-lookup-upd.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sk-redirect-hash.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sk-redirect-map.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sk-release.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sk-select-reuseport.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sk-storage-delete.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sk-storage-get.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-adjust-room.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-cgroup-id.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-change-head.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-change-proto.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-change-tail.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-change-type.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-ecn-set-ce.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-get-tunnel-key.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-get-tunnel-opt.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-get-xfrm-state.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-load-bytes-relative.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-load-bytes.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-pull-data.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-set-tunnel-key.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-set-tunnel-opt.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-store-bytes.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-under-cgroup.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-vlan-pop.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skb-vlan-push.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-skc-lookup-tcp.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sock-hash-update.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sock-map-update.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sock-ops-cb-flags-set.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-spin-lock.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-spin-unlock.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-strtol.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-strtoul.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sysctl-get-current-value.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sysctl-get-name.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sysctl-get-new-value.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-sysctl-set-new-value.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-tail-call.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-tcp-check-syncookie.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-tcp-sock.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-trace-printk.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-head.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-meta.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/helper-xdp-adjust-tail.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/skb-ancestor-cgroup-id.c
 create mode 100644 gcc/testsuite/gcc.target/bpf/sync-fetch-and-add.c
 create mode 100644 libgcc/config/bpf/crti.S
 create mode 100644 libgcc/config/bpf/crtn.S
 create mode 100644 libgcc/config/bpf/t-bpf

Comments

David Malcolm Aug. 14, 2019, 10:12 p.m. UTC | #1
On Wed, 2019-08-14 at 23:36 +0200, Jose E. Marchesi wrote:
> Hi people!
> 

[...]

> The second patch adds the new GCC port proper.  Machine description,
> implementation of target hooks and macros, command-line options and
> the like.

Looks like [PATCH 2/8] didn't make it to the mailing list for some
reason (maybe it exceeded a size limit?)

[...]

Dave
Jose E. Marchesi Aug. 14, 2019, 10:25 p.m. UTC | #2
> The second patch adds the new GCC port proper.  Machine description,
    > implementation of target hooks and macros, command-line options and
    > the like.
    
    Looks like [PATCH 2/8] didn't make it to the mailing list for some
    reason (maybe it exceeded a size limit?)

Yeah the Oracle smtpmail server seems to not be routing 2/8... how
annoying.  I just sent it again using my GNU account.
Richard Sandiford Aug. 15, 2019, 7:41 a.m. UTC | #3
"Jose E. Marchesi" <jose.marchesi@oracle.com> writes:
> . Dynamic stack allocation (alloca and VLAs) is achieved by using what
>   otherwise would be a perfectly normal general register, %r9, as a
>   pseudo stack pointer.  This has the disadvantage of making the
>   register "fixed" and therefore not available for general register
>   allocation.  Hopefully there is a way to conditionalize this, since
>   both alloca and VLAs are relatively uncommon; I haven't found it
>   yet.

In principle it's possible to define register eliminations for
target-specific registers as well as the usual FRAME/ARG_POINTER_REGNUM
crowd.  So you could have a fake fixed register to represent the pseudo
stack pointer, then allow that to be "eliminated" to %r9 in functions
that need it.  Functions that don't need it can continue (not) using the
fake register and leave %r9 free for general use.

Richard
Jose E. Marchesi Aug. 15, 2019, 10:52 p.m. UTC | #4
Hi Richard.

    > . Dynamic stack allocation (alloca and VLAs) is achieved by using what
    >   otherwise would be a perfectly normal general register, %r9, as a
    >   pseudo stack pointer.  This has the disadvantage of making the
    >   register "fixed" and therefore not available for general register
    >   allocation.  Hopefully there is a way to conditionalize this, since
    >   both alloca and VLAs are relatively uncommon; I haven't found it
    >   yet.
    
    In principle it's possible to define register eliminations for
    target-specific registers as well as the usual
    FRAME/ARG_POINTER_REGNUM crowd.

Yeah, before I started using %r9 as a stack pointer, I was indeed
"eliminating" a fake stack pointer hard register to the frame register,
i.e. the opposite of what is usually done.

That seemed to work well, but as soon as __builtin_alloca and/or VLAs
were used, lra-eliminations would enter into an infinite loop: it didn't
like the stack pointer being eliminated.

    So you could have a fake fixed register to represent the pseudo
    stack pointer, then allow that to be "eliminated" to %r9 in
    functions that need it.  Functions that don't need it can continue
    (not) using the fake register and leave %r9 free for general use.

Interesting idea...  but wouldn't that require to have %r9 declared as a
fixed register, in functions that cfun->calls_alloca?

After reading your reply I investigated a bit, and found out that
CONDITIONAL_REGISTER_USAGE can indeed be called at pleasure, via
reinit_regs(). The i386 port calls reinit_regs in set_current_function,
for example.

So it should be possible to declare %r9 as fixed or non-fixed, in
bpf_set_current_function, depending on the value of
cfun->calls_alloca...