Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Andrew Burgess <andrew.burgess@embecosm.com>
To: "Jose E. Marchesi" <jose.marchesi@oracle.com>
Cc: gdb-patches@sourceware.org
Subject: Re: [PATCH V4 2/3] sim: eBPF simulator
Date: Sun, 12 Jul 2020 09:25:03 +0100	[thread overview]
Message-ID: <20200712082503.GC2737@embecosm.com> (raw)
In-Reply-To: <20200710122530.32541-3-jose.marchesi@oracle.com>

* Jose E. Marchesi via Gdb-patches <gdb-patches@sourceware.org> [2020-07-10 14:25:29 +0200]:

> This patch introduces the basics of an instruction-simulator for eBPF.
> The simulator is based on CGEN.

Thanks I took a look through and I'm basically happy.  There's a few
small issues that I've highlighted inline below.

Thanks,
Andrew


> 
> sim/ChangeLog:
> 
> 2020-07-10  Jose E. Marchesi  <jose.marchesi@oracle.com>
> 	    David Faust <david.faust@oracle.com>
> 
> 	* configure.tgt (sim_arch): Add entry for bpf-*-*.
> 	* configure: Regenerate.
> 	* MAINTAINERS: Add maintainer for the BPF simulator.
> 	* bpf/Makefile.in: New file.
> 	* bpf/bpf-helpers.c: Likewise.
> 	* bpf/bpf-helpers.def: Likewise.
> 	* bpf/bpf-helpers.h: Likewise.
> 	* bpf/bpf-sim.h: Likewise.
> 	* bpf/bpf.c: Likewise.
> 	* bpf/config.in: Likewise.
> 	* bpf/configure.ac: Likewise.
> 	* bpf/decode.h: Likewise.
> 	* bpf/eng.h: Likewise.
> 	* bpf/mloop.in: Likewise.
> 	* bpf/sim-if.c: Likewise.
> 	* bpf/sim-main.h: Likewise.
> 	* bpf/traps.c: Likewise.
> 	* bpf/configure: Generate.

This file is missing from this message.

> 	* bpf/aclocal.m4: Likewise.
> 
> sim/testsuite/ChangeLog:
> 
> 2020-07-10  David Faust  <david.faust@oracle.com>
> 	    Jose E. Marchesi  <jose.marchesi@oracle.com>
> 
> 	* configure: Regenerate.
> 	* sim/bpf/allinsn.exp: New file.
> 	* sim/bpf/alu.s: Likewise.
> 	* sim/bpf/alu32.s: Likewise.
> 	* sim/bpf/endbe.s: Likewise.
> 	* sim/bpf/endle.s: Likewise.
> 	* sim/bpf/jmp.s: Likewise.
> 	* sim/bpf/jmp32.s: Likewise.
> 	* sim/bpf/ldabs.s: Likewise.
> 	* sim/bpf/mem.s: Likewise.
> 	* sim/bpf/mov.s: Likewise.
> 	* sim/bpf/testutils.inc: Likewise.
> 	* sim/bpf/xadd.s: Likewise.
> ---
>  sim/ChangeLog                       |    23 +
>  sim/MAINTAINERS                     |     1 +
>  sim/bpf/Makefile.in                 |   205 +
>  sim/bpf/aclocal.m4                  |   119 +
>  sim/bpf/bpf-helpers.c               |   175 +
>  sim/bpf/bpf-helpers.def             |   194 +
>  sim/bpf/bpf-helpers.h               |    31 +
>  sim/bpf/bpf-sim.h                   |    31 +
>  sim/bpf/bpf.c                       |   327 +
>  sim/bpf/config.in                   |   248 +
>  sim/bpf/configure                   | 15942 ++++++++++++++++++++++++++
>  sim/bpf/configure.ac                |    13 +
>  sim/bpf/decode.h                    |    37 +
>  sim/bpf/eng.h                       |    24 +
>  sim/bpf/mloop.in                    |   165 +
>  sim/bpf/sim-if.c                    |   216 +
>  sim/bpf/sim-main.h                  |    51 +
>  sim/bpf/traps.c                     |    33 +
>  sim/configure                       |     8 +
>  sim/configure.tgt                   |     3 +
>  sim/testsuite/ChangeLog             |    17 +
>  sim/testsuite/configure             |     9 +-
>  sim/testsuite/sim/bpf/allinsn.exp   |    26 +
>  sim/testsuite/sim/bpf/alu.s         |   109 +
>  sim/testsuite/sim/bpf/alu32.s       |    99 +
>  sim/testsuite/sim/bpf/endbe.s       |    46 +
>  sim/testsuite/sim/bpf/endle.s       |    43 +
>  sim/testsuite/sim/bpf/jmp.s         |   120 +
>  sim/testsuite/sim/bpf/jmp32.s       |   120 +
>  sim/testsuite/sim/bpf/ldabs.s       |    87 +
>  sim/testsuite/sim/bpf/mem.s         |    56 +
>  sim/testsuite/sim/bpf/mov.s         |    54 +
>  sim/testsuite/sim/bpf/testutils.inc |    38 +
>  sim/testsuite/sim/bpf/xadd.s        |    44 +
>  34 files changed, 18711 insertions(+), 3 deletions(-)
>  create mode 100644 sim/bpf/Makefile.in
>  create mode 100644 sim/bpf/aclocal.m4
>  create mode 100644 sim/bpf/bpf-helpers.c
>  create mode 100644 sim/bpf/bpf-helpers.def
>  create mode 100644 sim/bpf/bpf-helpers.h
>  create mode 100644 sim/bpf/bpf-sim.h
>  create mode 100644 sim/bpf/bpf.c
>  create mode 100644 sim/bpf/config.in
>  create mode 100755 sim/bpf/configure
>  create mode 100644 sim/bpf/configure.ac
>  create mode 100644 sim/bpf/decode.h
>  create mode 100644 sim/bpf/eng.h
>  create mode 100644 sim/bpf/mloop.in
>  create mode 100644 sim/bpf/sim-if.c
>  create mode 100644 sim/bpf/sim-main.h
>  create mode 100644 sim/bpf/traps.c
>  create mode 100644 sim/testsuite/sim/bpf/allinsn.exp
>  create mode 100644 sim/testsuite/sim/bpf/alu.s
>  create mode 100644 sim/testsuite/sim/bpf/alu32.s
>  create mode 100644 sim/testsuite/sim/bpf/endbe.s
>  create mode 100644 sim/testsuite/sim/bpf/endle.s
>  create mode 100644 sim/testsuite/sim/bpf/jmp.s
>  create mode 100644 sim/testsuite/sim/bpf/jmp32.s
>  create mode 100644 sim/testsuite/sim/bpf/ldabs.s
>  create mode 100644 sim/testsuite/sim/bpf/mem.s
>  create mode 100644 sim/testsuite/sim/bpf/mov.s
>  create mode 100644 sim/testsuite/sim/bpf/testutils.inc
>  create mode 100644 sim/testsuite/sim/bpf/xadd.s
> 
> diff --git a/sim/MAINTAINERS b/sim/MAINTAINERS
> index 4ca67cfd1d..7dcd88422c 100644
> --- a/sim/MAINTAINERS
> +++ b/sim/MAINTAINERS
> @@ -17,6 +17,7 @@ aarch64	        Nick Clifton <nickc@redhat.com>
>  aarch64	        Jim Wilson <wilson@tuliptree.org>
>  arm	        Nick Clifton <nickc@redhat.com>
>  bfin		Mike Frysinger <vapier@gentoo.org>
> +bpf		Jose E. Marchesi <jose.marchesi@oracle.com>
>  cr16	        M R Swami Reddy <MR.Swami.Reddy@nsc.com>
>  frv		Dave Brolley <brolley@redhat.com>
>  ft32		James Bowman <james.bowman@ftdichip.com>
> diff --git a/sim/bpf/Makefile.in b/sim/bpf/Makefile.in
> new file mode 100644
> index 0000000000..b12bb6a7d5
> --- /dev/null
> +++ b/sim/bpf/Makefile.in
> @@ -0,0 +1,205 @@
> +# Makefile template for configure for the eBPF simulator
> +# Copyright (C) 2019 Free Software Foundation, Inc.

This should probably be 2020 here.

> +#
> +# This file is part of GDB, the GNU debugger.
> +#
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
> +
> +## COMMON_PRE_CONFIG_FRAG
> +
> +CGEN_STD_OBJS = cgen-run.o cgen-scache.o cgen-trace.o cgen-utils.o
> +BPF_GEN_OBJS = arch.o cpu.o \
> +               decode-le.o decode-be.o \
> +               sem-le.o sem-be.o \
> +               mloop-le.o mloop-be.o
> +BPF_HAND_OBJS = bpf.o sim-if.o traps.o bpf-helpers.o
> +
> +SIM_OBJS = \
> +	$(SIM_NEW_COMMON_OBJS) \
> +	$(CGEN_STD_OBJS) \
> +	$(BPF_GEN_OBJS) \
> +	$(BPF_HAND_OBJS)
> +
> +SIM_EXTRA_DEPS = \
> +	$(CGEN_INCLUDE_DEPS) \
> +	arch.h \
> +	bpf-sim.h \
> +	$(srcdir)/../../opcodes/bpf-desc.h \
> +	$(srcdir)/../../opcodes/bpf-opc.h
> +
> +SIM_EXTRA_CLEAN = bpf-clean
> +
> +## COMMON_POST_CONFIG_FRAG
> +
> +# cgen support, enable with --enable-cgen-maint
> +CGEN_MAIN = ; @true

This is a typo, should be CGEN_MAINT here.

> +# The following line is commented in or out depending upon --enable-cgen-maint.
> +@CGEN_MAINT@CGEN_MAINT = 
> +
> +# BPF headers
> +
> +BPF_INCLUDE_DEPS = \
> +	$(CGEN_MAIN_CPU_DEPS) \
> +	$(SIM_EXTRA_DEPS) \
> +	cpu.h cpuall.h \
> +        decode-le.h decode-be.h \
> +        defs-le.h defs-be.h \
> +        eng-le.h eng-be.h \
> +        config.h
> +
> +# Dependencies for binaries from CGEN generated source
> +
> +arch.o: arch.c $(SIM_MAIN_DEPS)
> +cpu.o: cpu.c $(BPF_INCLUDE_DEPS)
> +decode-le.o: decode-le.c $(BPF_INCLUDE_DEPS)
> +decode-be.o: decode-be.c $(BPF_INCLUDE_DEPS)
> +# XXX sem-switch.o: sem-switch.c $(BPF_INCLUDE_DEPS)
> +# XXX model.o: model.c $(BPF_INCLUDE_DEPS)

As I mentioned in my review of patch #1, I'm not a fan of these XXX
comments.  I'm not going to insist these be removed (where they are
limited to the bpf directories), but I don't think things like the
above add any value, so I'd prefer they be removed, and you shouldn't
assume that these wont be removed in the future.

> +
> +sim-if.o: sim-if.c $(SIM_MAIN_DEPS) $(srcdir)/../common/sim-core.h eng.h
> +	$(COMPILE) $<
> +	$(POSTCOMPILE)
> +
> +traps.o: traps.c $(SIM_MAIN_DEPS) eng.h
> +	$(COMPILE) $<
> +	$(POSTCOMPILE)
> +
> +mloop-le.o: mloop-le.c $(BPF_INCLUDE_DEPS)
> +	$(CC) -c mloop-le.c $(ALL_CFLAGS) -DWANT_ISA_EBPFLE
> +mloop-be.o: mloop-be.c $(BPF_INCLUDE_DEPS)
> +	$(CC) -c mloop-be.c $(ALL_CFLAGS) -DWANT_ISA_EBPFBE
> +
> +decode-le.o: decode-le.c $(BPF_INCLUDE_DEPS)
> +	$(CC) -c $(srcdir)/decode-le.c $(ALL_CFLAGS) -DWANT_ISA_EBPFLE
> +decode-be.o: decode-be.c $(BPF_INCLUDE_DEPS)
> +	$(CC) -c $(srcdir)/decode-be.c $(ALL_CFLAGS) -DWANT_ISA_EBPFBE
> +
> +sem-le.o: sem-le.c $(BPF_INCLUDE_DEPS)
> +	$(CC) -c $(srcdir)/sem-le.c $(ALL_CFLAGS) -DWANT_ISA_EBPFLE
> +sem-be.o: sem-be.c $(BPF_INCLUDE_DEPS)
> +	$(CC) -c $(srcdir)/sem-be.c $(ALL_CFLAGS) -DWANT_ISA_EBPFBE
> +
> +arch = bpf
> +
> +CGEN_COMMON_DEPS = \
> +	$(CGEN_READ_SCM) \
> +	$(srcdir)/../../cpu/bpf.cpu \
> +	$(srcdir)/../../cpu/bpf.opc \
> +	Makefile
> +
> +stamp-arch: $(CGEN_COMMON_DEPS) $(CGEN_ARCH_SCM)
> +	$(MAKE) cgen-arch $(CGEN_FLAGS_TO_PASS) \
> +		mach=bpf cpu=bpfbf \
> +		archfile=$(srcdir)/../../cpu/bpf.cpu \
> +		FLAGS="with-scache"
> +	touch $@
> +$(srcdir)/arch.h $(srcdir)/arch.c $(srcdir)/cpuall.h: $(CGEN_MAINT) stamp-arch
> +	@true
> +
> +stamp-cpu: $(CGEN_COMMON_DEPS) $(CGEN_CPU_SCM)
> +	$(MAKE) cgen-cpu  $(CGEN_FLAGS_TO_PASS) \
> +		isa=ebpfle,ebpfbe cpu=bpfbf mach=bpf \
> +		archfile=$(srcdir)/../../cpu/bpf.cpu \
> +		FLAGS="with-multiple-isa with-scache"
> +	rm -f $(srcdir)/model.c
> +	touch $@
> +$(srcdir)/cpu.h $(srcdir)/cpu.c $(srcdir)/model.c: $(CGEN_MAINT) stamp-cpu
> +	@true
> +
> +# We need to generate a group of files per ISA.
> +# For eBPF little-endian:
> +#    defs-le.h
> +#    sem-le.c, decode-le.c, decode-le.h
> +#    $(objdir)/mloop-le.c $(objdir)/eng-le.h
> +# For eBPF big-endian:
> +#    defs-be.h
> +#    sem-be.c, decode-be.c, decode-be.h
> +#    $(objdir)/mloop-be.c $(objdir)/eng-le.h
> +#
> +# The rules below take care of that.
> +
> +stamp-defs-le: $(CGEN_COMMON_DEPS) $(CGEN_CPU_SCM)
> +	$(MAKE) cgen-defs $(CGEN_FLAGS_TO_PASS) \
> +		isa=ebpfle cpu=bpfbf mach=bpf \
> +		archfile=$(srcdir)/../../cpu/bpf.cpu \
> +		FLAGS="with-scache" \
> +                SUFFIX="-le"
> +	touch $@
> +$(srcdir)/defs-le.h: $(CGEN_MAINT) stamp-defs-le
> +	@true
> +
> +
> +stamp-defs-be: $(CGEN_COMMON_DEPS) $(CGEN_CPU_SCM)
> +	$(MAKE) cgen-defs $(CGEN_FLAGS_TO_PASS) \
> +		isa=ebpfbe cpu=bpfbf mach=bpf \
> +		archfile=$(srcdir)/../../cpu/bpf.cpu \
> +		FLAGS="with-scache" \
> +                SUFFIX="-be"
> +	touch $@
> +$(srcdir)/defs-be.h: $(CGEN_MAINT) stamp-defs-be
> +	@true
> +
> +stamp-decode-le: $(CGEN_COMMON_DEPS) $(CGEN_CPU_SCM) $(GEN_DECODE_SCM)
> +	$(MAKE) cgen-decode $(CGEN_FLAGS_TO_PASS) \
> +		isa=ebpfle cpu=bpfbf mach=bpf \
> +		archfile=$(srcdir)/../../cpu/bpf.cpu \
> +		FLAGS="with-scache" \
> +                SUFFIX="-le" \
> +		EXTRAFILES="$(CGEN_CPU_SEM)"
> +	touch $@
> +$(srcdir)/sem-le.c $(srcdir)/decode-le.c $(srcdir)/decode-le.h: \
> +              $(CGEN_MAINT) stamp-decode-le
> +	@true
> +
> +
> +stamp-decode-be: $(CGEN_COMMON_DEPS) $(CGEN_CPU_SCM) $(GEN_DECODE_SCM)
> +	$(MAKE) cgen-decode $(CGEN_FLAGS_TO_PASS) \
> +		isa=ebpfbe cpu=bpfbf mach=bpf \
> +		archfile=$(srcdir)/../../cpu/bpf.cpu \
> +		FLAGS="with-scache" \
> +                SUFFIX="-be" \
> +		EXTRAFILES="$(CGEN_CPU_SEM)"
> +	touch $@
> +$(srcdir)/sem-be.c $(srcdir)/decode-be.c $(srcdir)/decode-be.h: \
> +              $(CGEN_MAINT) stamp-decode-be
> +	@true
> +
> +# Note the following files are generated in objdir, not srcdir.
> +
> +stamp-mloop: stamp-mloop-le stamp-mloop-be
> +
> +stamp-mloop-le: $(srcdir)/../common/genmloop.sh mloop.in Makefile
> +	$(SHELL) $(srccom)/genmloop.sh -shell $(SHELL) \
> +		-mono -scache -prefix bpfbf_ebpfle -cpu bpfbf \
> +                -infile $(srcdir)/mloop.in
> +	$(SHELL) $(srcroot)/move-if-change eng.hin eng-le.h
> +	$(SHELL) $(srcroot)/move-if-change mloop.cin mloop-le.c
> +	touch $@
> +mloop-le.c eng-le.h: stamp-mloop-le
> +	@true
> +
> +stamp-mloop-be: $(srcdir)/../common/genmloop.sh mloop.in Makefile
> +	$(SHELL) $(srccom)/genmloop.sh -shell $(SHELL) \
> +		-mono -scache -prefix bpfbf_ebpfbe -cpu bpfbf \
> +                -infile $(srcdir)/mloop.in
> +	$(SHELL) $(srcroot)/move-if-change eng.hin eng-be.h
> +	$(SHELL) $(srcroot)/move-if-change mloop.cin mloop-be.c
> +	touch $@
> +mloop-be.c eng-be.h: stamp-mloop-be
> +	@true
> +
> +.PHONY = bpf-clean
> +
> +bpf-clean:
> +	rm -f stamp-arch stamp-cpu stamp-decode stamp-defs stamp-mloop
> diff --git a/sim/bpf/aclocal.m4 b/sim/bpf/aclocal.m4
> new file mode 100644
> index 0000000000..e9f11c775c
> --- /dev/null
> +++ b/sim/bpf/aclocal.m4
> @@ -0,0 +1,119 @@
> +# generated automatically by aclocal 1.15.1 -*- Autoconf -*-
> +
> +# Copyright (C) 1996-2017 Free Software Foundation, Inc.
> +
> +# This file is free software; the Free Software Foundation
> +# gives unlimited permission to copy and/or distribute it,
> +# with or without modifications, as long as this notice is preserved.
> +
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
> +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
> +# PARTICULAR PURPOSE.
> +
> +m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
> +# AM_CONDITIONAL                                            -*- Autoconf -*-
> +
> +# Copyright (C) 1997-2017 Free Software Foundation, Inc.
> +#
> +# This file is free software; the Free Software Foundation
> +# gives unlimited permission to copy and/or distribute it,
> +# with or without modifications, as long as this notice is preserved.
> +
> +# AM_CONDITIONAL(NAME, SHELL-CONDITION)
> +# -------------------------------------
> +# Define a conditional.
> +AC_DEFUN([AM_CONDITIONAL],
> +[AC_PREREQ([2.52])dnl
> + m4_if([$1], [TRUE],  [AC_FATAL([$0: invalid condition: $1])],
> +       [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
> +AC_SUBST([$1_TRUE])dnl
> +AC_SUBST([$1_FALSE])dnl
> +_AM_SUBST_NOTMAKE([$1_TRUE])dnl
> +_AM_SUBST_NOTMAKE([$1_FALSE])dnl
> +m4_define([_AM_COND_VALUE_$1], [$2])dnl
> +if $2; then
> +  $1_TRUE=
> +  $1_FALSE='#'
> +else
> +  $1_TRUE='#'
> +  $1_FALSE=
> +fi
> +AC_CONFIG_COMMANDS_PRE(
> +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
> +  AC_MSG_ERROR([[conditional "$1" was never defined.
> +Usually this means the macro was only invoked conditionally.]])
> +fi])])
> +
> +# Copyright (C) 2003-2017 Free Software Foundation, Inc.
> +#
> +# This file is free software; the Free Software Foundation
> +# gives unlimited permission to copy and/or distribute it,
> +# with or without modifications, as long as this notice is preserved.
> +
> +# Check whether the underlying file-system supports filenames
> +# with a leading dot.  For instance MS-DOS doesn't.
> +AC_DEFUN([AM_SET_LEADING_DOT],
> +[rm -rf .tst 2>/dev/null
> +mkdir .tst 2>/dev/null
> +if test -d .tst; then
> +  am__leading_dot=.
> +else
> +  am__leading_dot=_
> +fi
> +rmdir .tst 2>/dev/null
> +AC_SUBST([am__leading_dot])])
> +
> +# Add --enable-maintainer-mode option to configure.         -*- Autoconf -*-
> +# From Jim Meyering
> +
> +# Copyright (C) 1996-2017 Free Software Foundation, Inc.
> +#
> +# This file is free software; the Free Software Foundation
> +# gives unlimited permission to copy and/or distribute it,
> +# with or without modifications, as long as this notice is preserved.
> +
> +# AM_MAINTAINER_MODE([DEFAULT-MODE])
> +# ----------------------------------
> +# Control maintainer-specific portions of Makefiles.
> +# Default is to disable them, unless 'enable' is passed literally.
> +# For symmetry, 'disable' may be passed as well.  Anyway, the user
> +# can override the default with the --enable/--disable switch.
> +AC_DEFUN([AM_MAINTAINER_MODE],
> +[m4_case(m4_default([$1], [disable]),
> +       [enable], [m4_define([am_maintainer_other], [disable])],
> +       [disable], [m4_define([am_maintainer_other], [enable])],
> +       [m4_define([am_maintainer_other], [enable])
> +        m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
> +AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
> +  dnl maintainer-mode's default is 'disable' unless 'enable' is passed
> +  AC_ARG_ENABLE([maintainer-mode],
> +    [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode],
> +      am_maintainer_other[ make rules and dependencies not useful
> +      (and sometimes confusing) to the casual installer])],
> +    [USE_MAINTAINER_MODE=$enableval],
> +    [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
> +  AC_MSG_RESULT([$USE_MAINTAINER_MODE])
> +  AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
> +  MAINT=$MAINTAINER_MODE_TRUE
> +  AC_SUBST([MAINT])dnl
> +]
> +)
> +
> +# Copyright (C) 2006-2017 Free Software Foundation, Inc.
> +#
> +# This file is free software; the Free Software Foundation
> +# gives unlimited permission to copy and/or distribute it,
> +# with or without modifications, as long as this notice is preserved.
> +
> +# _AM_SUBST_NOTMAKE(VARIABLE)
> +# ---------------------------
> +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
> +# This macro is traced by Automake.
> +AC_DEFUN([_AM_SUBST_NOTMAKE])
> +
> +# AM_SUBST_NOTMAKE(VARIABLE)
> +# --------------------------
> +# Public sister of _AM_SUBST_NOTMAKE.
> +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
> +
> diff --git a/sim/bpf/bpf-helpers.c b/sim/bpf/bpf-helpers.c
> new file mode 100644
> index 0000000000..8d979e0fe0
> --- /dev/null
> +++ b/sim/bpf/bpf-helpers.c
> @@ -0,0 +1,175 @@
> +/* Emulation of eBPF helpers.
> +   Copyright (C) 2020 Free Software Foundation, Inc.
> +
> +   This file is part of GDB, the GNU debugger.
> +
> +   This program is free software; you can redistribute it and/or modify
> +   it under the terms of the GNU General Public License as published by
> +   the Free Software Foundation; either version 3 of the License, or
> +   (at your option) any later version.
> +
> +   This program is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
> +
> +/* BPF programs rely on the existence of several helper functions,
> +   which are provided by the kernel.  This simulator provides an
> +   implementation of the helpers, which can be customized by the
> +   user.  */
> +
> +#define WANT_CPU_BPFBF
> +#define WANT_CPU bpfbf
> +
> +#include "sim-main.h"
> +#include "cgen-mem.h"
> +#include "cgen-ops.h"
> +#include "cpu.h"
> +
> +/* bpf_trace_printk is a printk-like facility for debugging.
> +
> +   In the kernel, it appends a line to the Linux's tracing debugging
> +   interface.
> +
> +   In this simulator, it uses the simulator's tracing interface
> +   instead.
> +
> +   The format tags recognized by this helper are:
> +   %d, %i, %u, %x, %ld, %li, %lu, %lx, %lld, %lli, %llu, %llx,
> +   %p, %s
> +   
> +   A maximum of three tags are supported.
> +
> +   This helper returns the number of bytes written, or a negative
> +   value in case of failure.  */
> +
> +int
> +bpf_trace_printk (SIM_CPU *current_cpu)
> +{ 
> +  va_list ap;
> +  SIM_DESC sd = CPU_STATE (current_cpu);
> +
> +  DI fmt_address;
> +  uint32_t size, tags_processed;
> +  size_t i, bytes_written = 0;
> +
> +  /* The first argument is the format string, which is passed as a
> +     pointer in %r1.  */
> +  fmt_address = GET_H_GPR (1);
> +  
> +  /* The second argument is the length of the format string, as an
> +     unsigned 32-bit number in %r2.  */
> +  size = GET_H_GPR (2);
> +
> +  /* Read the format string from the memory pointed by %r2, printing
> +     out the stuff as we go.  There is a maximum of three format tags
> +     supported, which are read from %r3, %r4 and %r5 respectively.  */
> +  for (i = 0, tags_processed = 0; i < size;)
> +    {
> +      QI c = GETMEMUQI (current_cpu, CPU_PC_GET (current_cpu),
> +                        fmt_address + i);
> +
> +      switch (c)
> +        {
> +        case '%':
> +          /* Check we are not exceeding the limit of three format
> +             tags.  */
> +          if (tags_processed > 2)
> +            return -1; /* XXX look for kernel error code.  */
> +          
> +          /* Depending on the kind of tag, extract the value from the
> +             proper argument.  */
> +          if (i++ >= size)
> +            return -1; /* XXX look for kernel error code.  */
> +
> +          UDI value = GET_H_GPR (3 + tags_processed);
> +
> +          switch ((GETMEMUQI (current_cpu, CPU_PC_GET (current_cpu),
> +                             fmt_address + i)))
> +            {
> +            case 'd':
> +              trace_printf (sd, current_cpu, "%d", value);
> +              break;
> +            case 'i':
> +              trace_printf (sd, current_cpu, "%i", value);
> +              break;
> +            case 'u':
> +              trace_printf (sd, current_cpu, "%u", value);
> +              break;
> +            case 'x':
> +              trace_printf (sd, current_cpu, "%x", value);
> +              break;
> +            case 'l':
> +              {
> +                if (i++ >= size)
> +                  return -1;
> +                switch (GETMEMUQI (current_cpu, CPU_PC_GET (current_cpu),
> +                             fmt_address + i))
> +                  {
> +                  case 'd':
> +                    trace_printf (sd, current_cpu, "%ld", value);
> +                    break;
> +                  case 'i':
> +                    trace_printf (sd, current_cpu, "%li", value);
> +                    break;
> +                  case 'u':
> +                    trace_printf (sd, current_cpu, "%lu", value);
> +                    break;
> +                  case 'x':
> +                    trace_printf (sd, current_cpu, "%lx", value);
> +                    break;
> +                  case 'l':
> +                    {
> +                      if (i++ >= size)
> +                        return -1;
> +                      switch (GETMEMUQI (current_cpu, CPU_PC_GET (current_cpu),
> +                                fmt_address + i)) {
> +                        case 'd':
> +                          trace_printf (sd, current_cpu, "%lld", value);
> +                          break;
> +                        case 'i':
> +                          trace_printf (sd, current_cpu, "%lli", value);
> +                          break;
> +                        case 'u':
> +                          trace_printf (sd, current_cpu, "%llu", value);
> +                          break;
> +                        case 'x':
> +                          trace_printf (sd, current_cpu, "%llx", value);
> +                          break;
> +                        default:
> +                          assert (0);
> +                          break;
> +                      }
> +                      break;
> +                    }
> +                  default:
> +                    assert (0);
> +                    break;
> +                }
> +                break;
> +              }
> +            default:
> +              /* XXX completeme */
> +              assert (0);
> +              break;
> +            }
> +
> +          tags_processed++;
> +          i++;
> +          break;
> +        case '\0':
> +          i = size;
> +          break;
> +        default:
> +          trace_printf (sd, current_cpu, "%c", c);
> +          bytes_written++;
> +          i++;
> +          break;
> +        }
> +    }
> +  
> +  return bytes_written;
> +}
> diff --git a/sim/bpf/bpf-helpers.def b/sim/bpf/bpf-helpers.def
> new file mode 100644
> index 0000000000..6106ac794a
> --- /dev/null
> +++ b/sim/bpf/bpf-helpers.def
> @@ -0,0 +1,194 @@
> +/* BPF helpers database.
> +   Copyright (C) 2019-2020 Free Software Foundation, Inc.

Is this really 2019-2020?  If it's copied from some other file that is
2019-2020 then could you mention on the preceding line, just to make
it clear.

> +
> +This file is part of the GNU simulator.
> +
> +GCC is free software; you can redistribute it and/or modify
> +it under the terms of the GNU General Public License as published by
> +the Free Software Foundation; either version 3, or (at your option)
> +any later version.
> +
> +GCC is distributed in the hope that it will be useful,
> +but WITHOUT ANY WARRANTY; without even the implied warranty of
> +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +GNU General Public License for more details.
> +
> +You should have received a copy of the GNU General Public License
> +along with GCC; see the file COPYING3.  If not see
> +<http://www.gnu.org/licenses/>.  */
> +
> +/* This file contains the definition of the helpers that are available
> +   to BPF programs.
> +
> +   The primary source for information on kernel helpers is the
> +   linux/include/uapi/linux/bpf.h file in the Linux source tree.
> +   Please keep this database in sync.
> +
> +   The first column is the first kernel version featuring the helper
> +   function.  This should be an enumerate from bpf_kernel_version,
> +   defined in bpf-opts.h.  Note that the backend assumes that helpers
> +   never get deprecated in the kernel.  If that eventually happens,
> +   then we will need to use a bitmask here instead of an enumerate.
> +
> +   The second column is the constant-name for the helper.
> +   The third column is the program-name of the helper.
> +
> +   The fourth column is a list of names describing the types of the
> +   values returned and accepted by the helper, in one of these forms:
> +
> +     TYPES (type1, type2, ..., 0)
> +     VTYPES (type1, type2, ..., 0)
> +
> +   VTYPES should be used should the helper accept a variable number of
> +   arguments, TYPES otherwise.  The valid type names are:
> +
> +     `vt' for void.
> +     `it' for signed int.
> +     `ut' for unsigned int.
> +     `pt' for void*.
> +     `cpt' for const void*.
> +     `st' for short int.
> +     `ust' for unsigned short int.
> +     `cst' for const char *.
> +     `ullt' for unsigned long long.
> +     `llt' for long long.
> +     `u32t' for uint32.
> +     `u64t' for uint64.
> +  
> +   In types descriptions, the firt entry corresponds to the value
> +   returned by the helper.  Subsequent names correspond to the helper
> +   arguments.  Finally, a 0 should close the list.
> +
> +   VERY IMPORTANT: the helper entries should be listed in the same
> +   order than in the definition of __BPF_FUNC_MAPPER in
> +   linux/include/uapi/linux/bpf.h!  */
> +
> +DEF_HELPER (LINUX_V4_0, MAP_LOOKUP_ELEM, map_lookup_elem, TYPES (pt, pt, pt, 0))
> +DEF_HELPER (LINUX_V4_0, MAP_UPDATE_ELEM, map_update_elem, TYPES (it, pt, pt, pt, ullt, 0))
> +DEF_HELPER (LINUX_V4_0, MAP_DELETE_ELEM, map_delete_elem, TYPES (it, pt, pt, 0))
> +DEF_HELPER (LINUX_V4_1, PROBE_READ, probe_read, TYPES (it, pt, ut, cpt, 0))
> +DEF_HELPER (LINUX_V4_1, KTIME_GET_NS, ktime_get_ns, TYPES (ullt, 0))
> +DEF_HELPER (LINUX_V4_1, TRACE_PRINTK, trace_printk, VTYPES (it, cst, it, 0))
> +DEF_HELPER (LINUX_V4_1, GET_PRANDOM_U32, get_prandom_u32, TYPES (ullt, 0))
> +DEF_HELPER (LINUX_V4_1, GET_SMP_PROCESSOR_ID, get_smp_processor_id, TYPES (ullt, 0))
> +DEF_HELPER (LINUX_V4_1, SKB_STORE_BYTES, skb_store_bytes, TYPES (it, pt, it, pt, it, it, 0))
> +DEF_HELPER (LINUX_V4_1, L3_CSUM_REPLACE, l3_csum_replace, TYPES (it, pt, it, it ,it ,it, 0))
> +DEF_HELPER (LINUX_V4_1, L4_CSUM_REPLACE, l4_csum_replace, TYPES (it, pt, it, it, it, it, 0))
> +DEF_HELPER (LINUX_V4_2, TAIL_CALL, tail_call, TYPES (vt, pt, pt, it, 0))
> +DEF_HELPER (LINUX_V4_2, CLONE_REDIRECT, clone_redirect, TYPES (it, pt, it, it, 0))
> +DEF_HELPER (LINUX_V4_2, GET_CURRENT_PID_TGID, get_current_pid_tgid, TYPES (ullt, 0))
> +DEF_HELPER (LINUX_V4_2, GET_CURRENT_UID_GID, get_current_uid_gid, TYPES (ullt, 0))
> +DEF_HELPER (LINUX_V4_2, GET_CURRENT_COMM, get_current_comm, TYPES (it, pt, it, 0))
> +DEF_HELPER (LINUX_V4_3, GET_CGROUP_CLASSID, get_cgroup_classid, TYPES (it, pt, 0))
> +DEF_HELPER (LINUX_V4_3, SKB_VLAN_PUSH, skb_vlan_push, TYPES (it, pt, st, ust, 0))
> +DEF_HELPER (LINUX_V4_3, SKB_VLAN_POP, skb_vlan_pop, TYPES (it, pt, 0))
> +DEF_HELPER (LINUX_V4_3, SKB_GET_TUNNEL_KEY, skb_get_tunnel_key, TYPES (it, pt, pt, it, it, 0))
> +DEF_HELPER (LINUX_V4_3, SKB_SET_TUNNEL_KEY, skb_set_tunnel_key, TYPES (it, pt, pt, it, it, 0))
> +DEF_HELPER (LINUX_V4_3, PERF_EVENT_READ, perf_event_read, TYPES (ullt, pt, ullt, 0))
> +DEF_HELPER (LINUX_V4_4, REDIRECT, redirect, TYPES (it, it, it, 0))
> +DEF_HELPER (LINUX_V4_4, GET_ROUTE_REALM, get_route_realm, TYPES (ut, pt, 0))
> +DEF_HELPER (LINUX_V4_4, PERF_EVENT_OUTPUT, perf_event_output, \
> +	    TYPES (it, pt, pt, ullt, pt, it, 0))
> +DEF_HELPER (LINUX_V4_5, SKB_LOAD_BYTES, skb_load_bytes, TYPES (it, pt, it, pt, it, 0))
> +DEF_HELPER (LINUX_V4_6, GET_STACKID, get_stackid, TYPES (it, pt, pt, it, 0))
> +DEF_HELPER (LINUX_V4_6, CSUM_DIFF, csum_diff, TYPES (it, pt, it, pt, it, it, 0))
> +DEF_HELPER (LINUX_V4_6, SKB_GET_TUNNEL_OPT, skb_get_tunnel_opt, TYPES (it, pt, pt, it, 0))
> +DEF_HELPER (LINUX_V4_6, SKB_SET_TUNNEL_OPT, skb_set_tunnel_opt, TYPES (it, pt, pt, it, 0))
> +DEF_HELPER (LINUX_V4_8, SKB_CHANGE_PROTO, skb_change_proto, TYPES (it, pt, st, u64t, 0))
> +DEF_HELPER (LINUX_V4_8, SKB_CHANGE_TYPE, skb_change_type, TYPES (it, pt, u32t, 0))
> +DEF_HELPER (LINUX_V4_8, SKB_UNDER_CGROUP, skb_under_cgroup, TYPES (it, pt, pt, it, 0))
> +DEF_HELPER (LINUX_V4_8, GET_HASH_RECALC, get_hash_recalc, TYPES (ut, pt, 0))
> +DEF_HELPER (LINUX_V4_8, GET_CURRENT_TASK, get_current_task, TYPES (ullt, 0))
> +DEF_HELPER (LINUX_V4_8, PROBE_WRITE_USER, probe_write_user, TYPES (it, pt, cpt, ut, 0))
> +DEF_HELPER (LINUX_V4_9, CURRENT_TASK_UNDER_CGROUP, current_task_under_cgroup, \
> +	    TYPES (it, pt, it, 0))
> +DEF_HELPER (LINUX_V4_9, SKB_CHANGE_TAIL, skb_change_tail, TYPES (it, pt, ut, u64t, 0))
> +DEF_HELPER (LINUX_V4_9, SKB_PULL_DATA, skb_pull_data, TYPES (it, pt, it, 0))
> +DEF_HELPER (LINUX_V4_9, CSUM_UPDATE, csum_update, TYPES (llt, pt, u32t, 0))
> +DEF_HELPER (LINUX_V4_9, SET_HASH_INVALID, set_hash_invalid, TYPES (vt, pt, 0))
> +DEF_HELPER (LINUX_V4_10, GET_NUMA_NODE_ID, get_numa_node_id, TYPES (it, 0))
> +DEF_HELPER (LINUX_V4_10, SKB_CHANGE_HEAD, skb_change_head, TYPES (it, pt, it, it, 0))
> +DEF_HELPER (LINUX_V4_10, XDP_ADJUST_HEAD, xdp_adjust_head, TYPES (it, pt, it, 0))
> +DEF_HELPER (LINUX_V4_11, PROBE_READ_STR, probe_read_str, TYPES (it, pt, u32t, cpt, 0))
> +DEF_HELPER (LINUX_V4_12, GET_SOCKET_COOKIE, get_socket_cookie, TYPES (it, pt, 0))
> +DEF_HELPER (LINUX_V4_12, GET_SOCKET_UID, get_socket_uid, TYPES (ut, pt, 0))
> +DEF_HELPER (LINUX_V4_13, SET_HASH, set_hash, TYPES (ut, pt, u32t, 0))
> +DEF_HELPER (LINUX_V4_13, SETSOCKOPT, setsockopt, TYPES (it, pt, it, it, pt, it, 0))
> +DEF_HELPER (LINUX_V4_13, SKB_ADJUST_ROOM, skb_adjust_room, TYPES (it, pt, st, u32t, ullt, 0))
> +DEF_HELPER (LINUX_V4_14, REDIRECT_MAP, redirect_map, TYPES (it, pt, it, it, 0))
> +DEF_HELPER (LINUX_V4_14, SK_REDIRECT_MAP, sk_redirect_map, TYPES (it, pt, pt, it, it, 0))
> +DEF_HELPER (LINUX_V4_14, SOCK_MAP_UPDATE, sock_map_update, TYPES (it, pt, pt, pt, ullt, 0))
> +DEF_HELPER (LINUX_V4_15, XDP_ADJUST_META, xdp_adjust_meta, TYPES (it, pt, it, 0))
> +DEF_HELPER (LINUX_V4_15, PERF_EVENT_READ_VALUE, perf_event_read_value,
> +	    TYPES (it, pt, ullt, pt, ut, 0))
> +DEF_HELPER (LINUX_V4_15, PERF_PROG_READ_VALUE, perf_prog_read_value,
> +	    TYPES (it, pt, pt, ut, 0))
> +DEF_HELPER (LINUX_V4_15, GETSOCKOPT, getsockopt, TYPES (it, pt, it, it, pt, it, 0))
> +
> +DEF_HELPER (LINUX_V4_16, OVERRIDE_RETURN, override_return, TYPES (it, pt, ult, 0))
> +DEF_HELPER (LINUX_V4_16, SOCK_OPS_CB_FLAGS_SET, sock_ops_cb_flags_set, TYPES (it, pt, it, 0))
> +DEF_HELPER (LINUX_V4_17, MSG_REDIRECT_MAP, msg_redirect_map, TYPES (it, pt, pt, it, it, 0))
> +DEF_HELPER (LINUX_V4_17, MSG_APPLY_BYTES, msg_apply_bytes, TYPES (it, pt, it, 0))
> +DEF_HELPER (LINUX_V4_17, MSG_CORK_BYTES, msg_cork_bytes, TYPES (it, pt, it, 0))
> +DEF_HELPER (LINUX_V4_17, MSG_PULL_DATA, msg_pull_data, TYPES (it, pt, it, it, it, 0))
> +DEF_HELPER (LINUX_V4_17, BIND, bind, TYPES (it, pt, pt, it, 0))
> +DEF_HELPER (LINUX_V4_18, XDP_ADJUST_TAIL, xdp_adjust_tail, TYPES (it, pt, it, 0))
> +DEF_HELPER (LINUX_V4_18, SKB_GET_XFRM_STATE,
> +	    skb_get_xfrm_state, TYPES (it, pt, it, pt, it, it, 0))
> +DEF_HELPER (LINUX_V4_18, GET_STACK, get_stack, TYPES (it, pt, pt, it, it, 0))
> +DEF_HELPER (LINUX_V4_18, SKB_LOAD_BYTES_RELATIVE, skb_load_bytes_relative,
> +	    TYPES (it, pt, it, pt, it, ut, 0))
> +DEF_HELPER (LINUX_V4_18, FIB_LOOKUP, fib_lookup, TYPES (it, pt, pt, it, ut, 0))
> +DEF_HELPER (LINUX_V4_18, SOCK_HASH_UPDATE, sock_hash_update, TYPES (it, pt, pt, pt, ullt, 0))
> +DEF_HELPER (LINUX_V4_18, MSG_REDIRECT_HASH, msg_redirect_hash, TYPES (it, pt, pt, pt, it, 0))
> +DEF_HELPER (LINUX_V4_18, SK_REDIRECT_HASH, sk_redirect_hash, TYPES (it, pt, pt, pt, it, 0))
> +DEF_HELPER (LINUX_V4_18, LWT_PUSH_ENCAP, lwt_push_encap, TYPES (it, pt, ut, pt, ut, 0))
> +DEF_HELPER (LINUX_V4_18, LWT_SEG6_STORE_BYTES, lwt_seg6_store_bytes,
> +	    TYPES (it, pt, ut, pt, ut, 0))
> +DEF_HELPER (LINUX_V4_18, LWT_SEG6_ADJUST_SRH, lwt_seg6_adjust_srh, TYPES (it, pt, ut, ut, 0))
> +DEF_HELPER (LINUX_V4_18, LWT_SEG6_ACTION, lwt_seg6_action, TYPES (it, pt, ut, pt, ut, 0))
> +DEF_HELPER (LINUX_V4_18, RC_REPEAT, rc_repeat, TYPES (it, pt, 0))
> +DEF_HELPER (LINUX_V4_18, RC_KEYDOWN, rc_keydown, TYPES (it, pt, ut, ullt, ut, 0))
> +DEF_HELPER (LINUX_V4_18, SKB_CGROUP_ID, skb_cgroup_id, TYPES (ullt, pt, 0))
> +DEF_HELPER (LINUX_V4_18, GET_CURRENT_CGROUP_ID, get_current_cgroup_id, TYPES (ullt, 0))
> +DEF_HELPER (LINUX_V4_19, GET_LOCAL_STORAGE, get_local_storage, TYPES (pt, pt, ullt, 0))
> +DEF_HELPER (LINUX_V4_19, SK_SELECT_REUSEPORT, sk_select_reuseport,
> +	    TYPES (it, pt, pt, pt, ut, 0))
> +DEF_HELPER (LINUX_V4_19, SKB_ANCESTOR_CGROUP_ID, skb_ancestor_cgroup_id,
> +	    TYPES (ullt, pt, it, 0))
> +DEF_HELPER (LINUX_V4_20, SK_LOOKUP_TCP, sk_lookup_tcp, TYPES (pt, pt, pt, it, ullt, ullt, 0))
> +DEF_HELPER (LINUX_V4_20, SK_LOOKUP_UDP, sk_lookup_udp, TYPES (pt, pt, pt, it, ullt, ullt, 0))
> +DEF_HELPER (LINUX_V4_20, SK_RELEASE, sk_release, TYPES (it, pt, 0))
> +DEF_HELPER (LINUX_V4_20, MAP_PUSH_ELEM, map_push_elem, TYPES (it, pt, pt, ullt, 0))
> +DEF_HELPER (LINUX_V4_20, MAP_POP_ELEM, map_pop_elem, TYPES (it, pt, pt, 0))
> +DEF_HELPER (LINUX_V4_20, MAP_PEEK_ELEM, map_peek_elem, TYPES (it, pt, pt, 0))
> +DEF_HELPER (LINUX_V4_20, MSG_PUSH_DATA, msg_push_data, TYPES (it, pt, it, it, it, 0))
> +DEF_HELPER (LINUX_V5_0, MSG_POP_DATA, msg_pop_data, TYPES (it, pt, it, it, it, 0))
> +DEF_HELPER (LINUX_V5_0, RC_POINTER_REL, rc_pointer_rel, TYPES (it, pt, it, it, 0))
> +DEF_HELPER (LINUX_V5_1, SPIN_LOCK, spin_lock, TYPES (vt, pt, 0))
> +DEF_HELPER (LINUX_V5_1, SPIN_UNLOCK, spin_unlock, TYPES (vt, pt, 0))
> +DEF_HELPER (LINUX_V5_1, SK_FULLSOCK, sk_fullsock, TYPES (pt, pt, 0))
> +DEF_HELPER (LINUX_V5_1, TCP_SOCK, tcp_sock, TYPES (pt, pt, 0))
> +DEF_HELPER (LINUX_V5_1, SKB_ECN_SET_CE, skb_ecn_set_ce, TYPES (it, pt, 0))
> +DEF_HELPER (LINUX_V5_1, GET_LISTENER_SOCK, get_listener_sock, TYPES (pt, pt, 0))
> +DEF_HELPER (LINUX_V5_2, SKC_LOOKUP_TCP, skc_lookup_tcp,
> +	    TYPES (pt, pt, pt, u32t, u64t, u64t, 0))
> +DEF_HELPER (LINUX_V5_2, TCP_CHECK_SYNCOOKIE, tcp_check_syncookie,
> +	    TYPES (it, pt, pt, u32t, pt, u32t, 0))
> +DEF_HELPER (LINUX_V5_2, SYSCTL_GET_NAME, sysctl_get_name, TYPES (it, pt, pt, ullt, u64t, 0))
> +DEF_HELPER (LINUX_V5_2, SYSCTL_GET_CURRENT_VALUE, sysctl_get_current_value,
> +	    TYPES (it, pt, pt, ullt, 0))
> +DEF_HELPER (LINUX_V5_2, SYSCTL_GET_NEW_VALUE, sysctl_get_new_value,
> +	    TYPES (it, pt, pt, ullt, 0))
> +DEF_HELPER (LINUX_V5_2, SYSCTL_SET_NEW_VALUE, sysctl_set_new_value,
> +	    TYPES (it, pt, pt, ullt, 0))
> +DEF_HELPER (LINUX_V5_2, STRTOL, strtol, TYPES (it, cst, ullt, u64t, pt, 0))
> +DEF_HELPER (LINUX_V5_2, STRTOUL, strtoul, TYPES (it, pt, ullt, u64t, pt, 0))
> +DEF_HELPER (LINUX_V5_2, SK_STORAGE_GET, sk_storage_get, TYPES (pt, pt, pt, pt, u64t, 0))
> +DEF_HELPER (LINUX_V5_2, SK_STORAGE_DELETE, sk_storage_delete, TYPES (it, pt, pt, 0))
> +
> +/*
> +Local variables:
> +mode:c
> +End:
> +*/
> diff --git a/sim/bpf/bpf-helpers.h b/sim/bpf/bpf-helpers.h
> new file mode 100644
> index 0000000000..fe9413f266
> --- /dev/null
> +++ b/sim/bpf/bpf-helpers.h
> @@ -0,0 +1,31 @@
> +/* Emulation of eBPF helpers.  Interface.
> +   Copyright (C) 2020 Free Software Foundation, Inc.
> +
> +   This file is part of GDB, the GNU debugger.
> +
> +   This program is free software; you can redistribute it and/or modify
> +   it under the terms of the GNU General Public License as published by
> +   the Free Software Foundation; either version 3 of the License, or
> +   (at your option) any later version.
> +
> +   This program is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
> +
> +#ifndef BPF_HELPERS_H
> +#define BPF_HELPERS_H
> +
> +enum bpf_kernel_helper
> +  {
> +#define DEF_HELPER(kver, name, fn, types) name,
> +#include "bpf-helpers.def"
> +#undef DEF_HELPER
> +  };
> +
> +/* void bpf_trace_printk (const char *fmt); */
> +
> +#endif /* ! BPF_HELPERS_H */
> diff --git a/sim/bpf/bpf-sim.h b/sim/bpf/bpf-sim.h
> new file mode 100644
> index 0000000000..6b5c275cd5
> --- /dev/null
> +++ b/sim/bpf/bpf-sim.h
> @@ -0,0 +1,31 @@
> +/* eBPF simulator support code header
> +   Copyright (C) 2020 Free Software Foundation, Inc.
> +
> +   This file is part of GDB, the GNU debugger.
> +
> +   This program is free software; you can redistribute it and/or modify
> +   it under the terms of the GNU General Public License as published by
> +   the Free Software Foundation; either version 3 of the License, or
> +   (at your option) any later version.
> +
> +   This program is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
> +
> +#ifndef BPF_SIM_H
> +#define BPF_SIM_H
> +
> +void bpfbf_insn_before (sim_cpu* current_cpu, SEM_PC vpc, const IDESC *idesc);
> +void bpfbf_insn_after (sim_cpu* current_cpu, SEM_PC vpc, const IDESC *idesc);
> +
> +DI bpfbf_endbe (SIM_CPU *, DI, UINT);
> +DI bpfbf_endle (SIM_CPU *, DI, UINT);
> +DI bpfbf_skb_data_offset (SIM_CPU *);
> +VOID bpfbf_call (SIM_CPU *, INT, UINT);
> +VOID bpfbf_exit (SIM_CPU *);
> +
> +#endif /* ! BPF_SIM_H */
> diff --git a/sim/bpf/bpf.c b/sim/bpf/bpf.c
> new file mode 100644
> index 0000000000..766b7ddc1c
> --- /dev/null
> +++ b/sim/bpf/bpf.c
> @@ -0,0 +1,327 @@
> +/* eBPF simulator support code
> +   Copyright (C) 2020 Free Software Foundation, Inc.
> +
> +   This file is part of GDB, the GNU debugger.
> +
> +   This program is free software; you can redistribute it and/or modify
> +   it under the terms of the GNU General Public License as published by
> +   the Free Software Foundation; either version 3 of the License, or
> +   (at your option) any later version.
> +
> +   This program is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
> +
> +#define WANT_CPU_BPFBF
> +#define WANT_CPU bpfbf
> +
> +#include "sim-main.h"
> +#include "sim-fpu.h"
> +#include "cgen-mem.h"
> +#include "cgen-ops.h"
> +#include "cpuall.h"
> +#include "decode.h"
> +
> +#include "defs-le.h"  /* For SCACHE */
> +
> +/* It is not possible to include both defs-le.h and defs-be.h due to
> +   duplicated definitions, so we need a bunch of forward declarations
> +   here.  */
> +extern void bpfbf_ebpfle_init_idesc_table (SIM_CPU *);
> +extern void bpfbf_ebpfbe_init_idesc_table (SIM_CPU *);
> +
> +uint64_t skb_data_offset;
> +
> +IDESC *bpf_idesc_le;
> +IDESC *bpf_idesc_be;
> +
> +
> +int
> +bpfbf_fetch_register (SIM_CPU *current_cpu,
> +                      int rn,
> +                      unsigned char *buf,
> +                      int len)
> +{
> +  if (rn == 11)
> +    SETTDI (buf, CPU_PC_GET (current_cpu));
> +  else if (0 <= rn && rn < 10)
> +    SETTDI (buf, GET_H_GPR (rn));
> +  else
> +    return 0;
> +
> +  return len;
> +}
> +
> +int
> +bpfbf_store_register (SIM_CPU *current_cpu,
> +                      int rn,
> +                      unsigned char *buf,
> +                      int len)
> +{
> +  if (rn == 11)
> +    CPU_PC_SET (current_cpu, GETTDI (buf));
> +  else if (0 <= rn && rn < 10)
> +    SET_H_GPR (rn, GETTDI (buf));
> +  else
> +    return 0;
> +
> +  return len;
> +}
> +
> +void
> +bpfbf_model_insn_before (SIM_CPU *current_cpu, int first_p)
> +{
> +  /* XXX */
> +}
> +
> +void
> +bpfbf_model_insn_after (SIM_CPU *current_cpu, int first_p)
> +{
> +  /* XXX */
> +}
> +
> +\f
> +/***** Instruction helpers.  *****/
> +
> +/* The semantic routines for most instructions are expressed in RTL in
> +   the cpu/bpf.cpu file, and automatically translated to C in the
> +   sem-*.c files in this directory.
> +
> +   However, some of the semantic routines make use of helper C
> +   functions.  This happens when the semantics of the instructions
> +   can't be expressed in RTL alone in a satisfactory way, or not at
> +   all.
> +
> +   The following functions implement these C helpers. */
> +
> +DI
> +bpfbf_endle (SIM_CPU *current_cpu, DI value, UINT bitsize)
> +{
> +  switch (bitsize)
> +    {
> +      case 16: return endian_h2le_2(endian_t2h_2(value));
> +      case 32: return endian_h2le_4(endian_t2h_4(value));
> +      case 64: return endian_h2le_8(endian_t2h_8(value));
> +      default: assert(0);
> +    }
> +  return value;
> +}
> +
> +DI
> +bpfbf_endbe (SIM_CPU *current_cpu, DI value, UINT bitsize)
> +{
> +  switch (bitsize)
> +    {
> +      case 16: return endian_h2be_2(endian_t2h_2(value));
> +      case 32: return endian_h2be_4(endian_t2h_4(value));
> +      case 64: return endian_h2be_8(endian_t2h_8(value));
> +      default: assert(0);
> +    }
> +  return value;
> +}
> +
> +DI
> +bpfbf_skb_data_offset (SIM_CPU *current_cpu)
> +{
> +  /* Simply return the user-configured value.
> +     This will be 0 if it has not been set. */
> +  return skb_data_offset;
> +}
> +
> +
> +VOID
> +bpfbf_call (SIM_CPU *current_cpu, INT disp32, UINT src)
> +{
> +  /* eBPF supports two kind of CALL instructions: the so called pseudo
> +     calls ("bpf to bpf") and external calls ("bpf to helper").
> +
> +     Both kind of calls use the same instruction (CALL).  However,
> +     external calls are constructed by passing a constant argument to
> +     the instruction, that identifies the helper, whereas pseudo calls
> +     result from expressions involving symbols.
> +
> +     We distinguish calls from pseudo-calls with the later having a 1
> +     stored in the SRC field of the instruction.  */
> +
> +  if (src == 1)
> +    {
> +      /* This is a pseudo-call.  */
> +
> +      /* XXX allocate a new stack frame and transfer control.  For
> +         that we need to analyze the target function, like the kernel
> +         verifier does.  We better populate a cache
> +         (function_start_address -> frame_size) so we avoid
> +         calculating this more than once.  */
> +      /* XXX note that disp32 is PC-relative in number of 64-bit
> +         words, _minus one_.  */
> +    }
> +  else
> +    {
> +      /* This is a call to a helper. 
> +
> +         DISP32 contains the helper number.  Dispatch to the
> +         corresponding helper emulator in bpf-helpers.c.  */
> +
> +      switch (disp32) {
> +        /* case TRACE_PRINTK: */
> +        case 7:
> +          bpf_trace_printk (current_cpu);
> +          break;
> +        default:;
> +      }
> +    }
> +}
> +
> +VOID
> +bpfbf_exit (SIM_CPU *current_cpu)
> +{
> +  SIM_DESC sd = CPU_STATE (current_cpu);
> +
> +  /*  r0 holds "return code" */
> +  DI r0 = GET_H_GPR (0);
> +
> +  printf ("exit %ld (0x%lx)\n", r0, r0);
> +
> +  sim_engine_halt (sd, current_cpu, NULL, CPU_PC_GET (current_cpu),
> +                   sim_exited, 0 /* sigrc */);
> +}
> +
> +VOID
> +bpfbf_breakpoint (SIM_CPU *current_cpu)
> +{
> +  SIM_DESC sd = CPU_STATE (current_cpu);
> +
> +  sim_engine_halt (sd, current_cpu, NULL, CPU_PC_GET (current_cpu),
> +                   sim_stopped, SIM_SIGTRAP);
> +}
> +
> +/* We use the definitions below instead of the cgen-generated model.c,
> +   because the later is not really able to work with cpus featuring
> +   several ISAs.  This should be fixed in CGEN.  */
> +
> +static void
> +bpf_def_model_init ()
> +{
> +  /* Do nothing.  */
> +}
> +
> +static void
> +bpfbf_prepare_run (SIM_CPU *cpu)
> +{
> +  /* Nothing.  */
> +}
> +
> +void
> +bpf_engine_run_full (SIM_CPU *cpu)
> +{
> +  if (current_target_byte_order == BFD_ENDIAN_LITTLE)
> +    {
> +      if (!bpf_idesc_le)
> +        {
> +          bpfbf_ebpfle_init_idesc_table (cpu);
> +          bpf_idesc_le = CPU_IDESC (cpu);
> +        }
> +      else
> +        CPU_IDESC (cpu) = bpf_idesc_le;
> +
> +      bpfbf_ebpfle_engine_run_full (cpu);
> +    }
> +  else
> +    {
> +      if (!bpf_idesc_be)
> +        {
> +          bpfbf_ebpfbe_init_idesc_table (cpu);
> +          bpf_idesc_be = CPU_IDESC (cpu);
> +        }
> +      else
> +        CPU_IDESC (cpu) = bpf_idesc_be;
> +
> +      bpfbf_ebpfbe_engine_run_full (cpu);
> +    }
> +}
> +
> +#if WITH_FAST
> +
> +void
> +bpf_engine_run_fast (SIM_CPU *cpu)
> +{
> +  if (current_target_byte_order == BFD_ENDIAN_LITTLE)
> +    {
> +      if (!bpf_idesc_le)
> +        {
> +          bpfbf_ebpfle_init_idesc_table (cpu);
> +          bpf_idesc_le = CPU_IDESC (cpu);
> +        }
> +      else
> +        CPU_IDESC (cpu) = bpf_idesc_le;
> +
> +      bpfbf_ebpfle_engine_run_fast (cpu);
> +    }
> +  else
> +    {
> +      if (!bpf_idesc_be)
> +        {
> +          bpfbf_ebpfbe_init_idesc_table (cpu);
> +          bpf_idesc_be = CPU_IDESC (cpu);
> +        }
> +      else
> +        CPU_IDESC (cpu) = bpf_idesc_be;
> +
> +      bpfbf_ebpfbe_engine_run_fast (cpu);
> +    }
> +}
> +
> +#endif /* WITH_FAST */
> +
> +static const CGEN_INSN *
> +bpfbf_get_idata (SIM_CPU *cpu, int inum)
> +{
> +  return CPU_IDESC (cpu) [inum].idata;
> +}
> +
> +static void
> +bpf_init_cpu (SIM_CPU *cpu)
> +{
> +  CPU_REG_FETCH (cpu) = bpfbf_fetch_register;
> +  CPU_REG_STORE (cpu) = bpfbf_store_register;
> +  CPU_PC_FETCH (cpu) = bpfbf_h_pc_get;
> +  CPU_PC_STORE (cpu) = bpfbf_h_pc_set;
> +  CPU_GET_IDATA (cpu) = bpfbf_get_idata;
> +  /* Only used by profiling.  0 disables it. */
> +  CPU_MAX_INSNS (cpu) = 0;
> +  CPU_INSN_NAME (cpu) = cgen_insn_name;
> +  CPU_FULL_ENGINE_FN (cpu) = bpf_engine_run_full;
> +#if WITH_FAST
> +  CPU_FAST_ENGINE_FN (cpu) = bpf_engine_run_fast;
> +#else
> +  CPU_FAST_ENGINE_FN (cpu) = bpf_engine_run_full;
> +#endif
> +}
> +
> +static const SIM_MODEL bpf_models[] =
> +{
> + { "bpf-def", & bpf_mach, MODEL_BPF_DEF, NULL, bpf_def_model_init },
> + { 0 }
> +};
> +
> +static const SIM_MACH_IMP_PROPERTIES bpfbf_imp_properties =
> +{
> +  sizeof (SIM_CPU),
> +#if WITH_SCACHE
> +  sizeof (SCACHE)
> +#else
> +  0
> +#endif
> +};
> +
> +const SIM_MACH bpf_mach =
> +{
> +  "bpf", "bpf", MACH_BPF,
> +  32, 32, & bpf_models[0], & bpfbf_imp_properties,
> +  bpf_init_cpu,
> +  bpfbf_prepare_run
> +};
> diff --git a/sim/bpf/config.in b/sim/bpf/config.in
> new file mode 100644
> index 0000000000..7c667a1c0d
> --- /dev/null
> +++ b/sim/bpf/config.in
> @@ -0,0 +1,248 @@
> +/* config.in.  Generated from configure.ac by autoheader.  */
> +
> +/* Define if building universal (internal helper macro) */
> +#undef AC_APPLE_UNIVERSAL_BUILD
> +
> +/* Sim debug setting */
> +#undef DEBUG
> +
> +/* Define to 1 if translation of program messages to the user's native
> +   language is requested. */
> +#undef ENABLE_NLS
> +
> +/* Define to 1 if you have the <dlfcn.h> header file. */
> +#undef HAVE_DLFCN_H
> +
> +/* Define to 1 if you have the <errno.h> header file. */
> +#undef HAVE_ERRNO_H
> +
> +/* Define to 1 if you have the <fcntl.h> header file. */
> +#undef HAVE_FCNTL_H
> +
> +/* Define to 1 if you have the <fpu_control.h> header file. */
> +#undef HAVE_FPU_CONTROL_H
> +
> +/* Define to 1 if you have the `ftruncate' function. */
> +#undef HAVE_FTRUNCATE
> +
> +/* Define to 1 if you have the `getrusage' function. */
> +#undef HAVE_GETRUSAGE
> +
> +/* Define to 1 if you have the <inttypes.h> header file. */
> +#undef HAVE_INTTYPES_H
> +
> +/* Define to 1 if you have the `nsl' library (-lnsl). */
> +#undef HAVE_LIBNSL
> +
> +/* Define to 1 if you have the `socket' library (-lsocket). */
> +#undef HAVE_LIBSOCKET
> +
> +/* Define to 1 if you have the `lstat' function. */
> +#undef HAVE_LSTAT
> +
> +/* Define to 1 if you have the <memory.h> header file. */
> +#undef HAVE_MEMORY_H
> +
> +/* Define to 1 if you have the `mmap' function. */
> +#undef HAVE_MMAP
> +
> +/* Define to 1 if you have the `munmap' function. */
> +#undef HAVE_MUNMAP
> +
> +/* Define to 1 if you have the `posix_fallocate' function. */
> +#undef HAVE_POSIX_FALLOCATE
> +
> +/* Define to 1 if you have the `sigaction' function. */
> +#undef HAVE_SIGACTION
> +
> +/* Define to 1 if the system has the type `socklen_t'. */
> +#undef HAVE_SOCKLEN_T
> +
> +/* Define to 1 if you have the <stdint.h> header file. */
> +#undef HAVE_STDINT_H
> +
> +/* Define to 1 if you have the <stdlib.h> header file. */
> +#undef HAVE_STDLIB_H
> +
> +/* Define to 1 if you have the <strings.h> header file. */
> +#undef HAVE_STRINGS_H
> +
> +/* Define to 1 if you have the <string.h> header file. */
> +#undef HAVE_STRING_H
> +
> +/* Define to 1 if `st_atime' is a member of `struct stat'. */
> +#undef HAVE_STRUCT_STAT_ST_ATIME
> +
> +/* Define to 1 if `st_blksize' is a member of `struct stat'. */
> +#undef HAVE_STRUCT_STAT_ST_BLKSIZE
> +
> +/* Define to 1 if `st_blocks' is a member of `struct stat'. */
> +#undef HAVE_STRUCT_STAT_ST_BLOCKS
> +
> +/* Define to 1 if `st_ctime' is a member of `struct stat'. */
> +#undef HAVE_STRUCT_STAT_ST_CTIME
> +
> +/* Define to 1 if `st_dev' is a member of `struct stat'. */
> +#undef HAVE_STRUCT_STAT_ST_DEV
> +
> +/* Define to 1 if `st_gid' is a member of `struct stat'. */
> +#undef HAVE_STRUCT_STAT_ST_GID
> +
> +/* Define to 1 if `st_ino' is a member of `struct stat'. */
> +#undef HAVE_STRUCT_STAT_ST_INO
> +
> +/* Define to 1 if `st_mode' is a member of `struct stat'. */
> +#undef HAVE_STRUCT_STAT_ST_MODE
> +
> +/* Define to 1 if `st_mtime' is a member of `struct stat'. */
> +#undef HAVE_STRUCT_STAT_ST_MTIME
> +
> +/* Define to 1 if `st_nlink' is a member of `struct stat'. */
> +#undef HAVE_STRUCT_STAT_ST_NLINK
> +
> +/* Define to 1 if `st_rdev' is a member of `struct stat'. */
> +#undef HAVE_STRUCT_STAT_ST_RDEV
> +
> +/* Define to 1 if `st_size' is a member of `struct stat'. */
> +#undef HAVE_STRUCT_STAT_ST_SIZE
> +
> +/* Define to 1 if `st_uid' is a member of `struct stat'. */
> +#undef HAVE_STRUCT_STAT_ST_UID
> +
> +/* Define to 1 if you have the <sys/mman.h> header file. */
> +#undef HAVE_SYS_MMAN_H
> +
> +/* Define to 1 if you have the <sys/resource.h> header file. */
> +#undef HAVE_SYS_RESOURCE_H
> +
> +/* Define to 1 if you have the <sys/stat.h> header file. */
> +#undef HAVE_SYS_STAT_H
> +
> +/* Define to 1 if you have the <sys/times.h> header file. */
> +#undef HAVE_SYS_TIMES_H
> +
> +/* Define to 1 if you have the <sys/time.h> header file. */
> +#undef HAVE_SYS_TIME_H
> +
> +/* Define to 1 if you have the <sys/types.h> header file. */
> +#undef HAVE_SYS_TYPES_H
> +
> +/* Define to 1 if you have the `time' function. */
> +#undef HAVE_TIME
> +
> +/* Define to 1 if you have the <time.h> header file. */
> +#undef HAVE_TIME_H
> +
> +/* Define to 1 if you have the `truncate' function. */
> +#undef HAVE_TRUNCATE
> +
> +/* Define to 1 if you have the <unistd.h> header file. */
> +#undef HAVE_UNISTD_H
> +
> +/* Define to 1 if you have the <windows.h> header file. */
> +#undef HAVE_WINDOWS_H
> +
> +/* Define to 1 if you have the `__setfpucw' function. */
> +#undef HAVE___SETFPUCW
> +
> +/* Define to the sub-directory in which libtool stores uninstalled libraries.
> +   */
> +#undef LT_OBJDIR
> +
> +/* Name of this package. */
> +#undef PACKAGE
> +
> +/* Define to the address where bug reports for this package should be sent. */
> +#undef PACKAGE_BUGREPORT
> +
> +/* Define to the full name of this package. */
> +#undef PACKAGE_NAME
> +
> +/* Define to the full name and version of this package. */
> +#undef PACKAGE_STRING
> +
> +/* Define to the one symbol short name of this package. */
> +#undef PACKAGE_TARNAME
> +
> +/* Define to the home page for this package. */
> +#undef PACKAGE_URL
> +
> +/* Define to the version of this package. */
> +#undef PACKAGE_VERSION
> +
> +/* Additional package description */
> +#undef PKGVERSION
> +
> +/* Sim profile settings */
> +#undef PROFILE
> +
> +/* Bug reporting address */
> +#undef REPORT_BUGS_TO
> +
> +/* Define as the return type of signal handlers (`int' or `void'). */
> +#undef RETSIGTYPE
> +
> +/* Define to 1 if you have the ANSI C header files. */
> +#undef STDC_HEADERS
> +
> +/* Enable extensions on AIX 3, Interix.  */
> +#ifndef _ALL_SOURCE
> +# undef _ALL_SOURCE
> +#endif
> +/* Enable GNU extensions on systems that have them.  */
> +#ifndef _GNU_SOURCE
> +# undef _GNU_SOURCE
> +#endif
> +/* Enable threading extensions on Solaris.  */
> +#ifndef _POSIX_PTHREAD_SEMANTICS
> +# undef _POSIX_PTHREAD_SEMANTICS
> +#endif
> +/* Enable extensions on HP NonStop.  */
> +#ifndef _TANDEM_SOURCE
> +# undef _TANDEM_SOURCE
> +#endif
> +/* Enable general extensions on Solaris.  */
> +#ifndef __EXTENSIONS__
> +# undef __EXTENSIONS__
> +#endif
> +
> +
> +/* Sim assert settings */
> +#undef WITH_ASSERT
> +
> +/* Sim debug setting */
> +#undef WITH_DEBUG
> +
> +/* Sim default environment */
> +#undef WITH_ENVIRONMENT
> +
> +/* Sim profile settings */
> +#undef WITH_PROFILE
> +
> +/* How to route I/O */
> +#undef WITH_STDIO
> +
> +/* Sim trace settings */
> +#undef WITH_TRACE
> +
> +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
> +   significant byte first (like Motorola and SPARC, unlike Intel). */
> +#if defined AC_APPLE_UNIVERSAL_BUILD
> +# if defined __BIG_ENDIAN__
> +#  define WORDS_BIGENDIAN 1
> +# endif
> +#else
> +# ifndef WORDS_BIGENDIAN
> +#  undef WORDS_BIGENDIAN
> +# endif
> +#endif
> +
> +/* Define to 1 if on MINIX. */
> +#undef _MINIX
> +
> +/* Define to 2 if the system does not provide POSIX.1 features except with
> +   this defined. */
> +#undef _POSIX_1_SOURCE
> +
> +/* Define to 1 if you need to in order for `stat' and other things to work. */
> +#undef _POSIX_SOURCE
> diff --git a/sim/bpf/configure.ac b/sim/bpf/configure.ac
> new file mode 100644
> index 0000000000..16ca54e86c
> --- /dev/null
> +++ b/sim/bpf/configure.ac
> @@ -0,0 +1,13 @@
> +dnl Process this file with autoconf to produce a configure script.
> +AC_INIT(Makefile.in)
> +sinclude(../common/acinclude.m4)
> +
> +SIM_AC_COMMON
> +
> +SIM_AC_OPTION_ENDIAN([], [LITTLE])
> +SIM_AC_OPTION_ALIGNMENT(NONSTRICT_ALIGNMENT)
> +SIM_AC_OPTION_SCACHE(16384)
> +SIM_AC_OPTION_DEFAULT_MODEL([bpf-def])
> +SIM_AC_OPTION_CGEN_MAINT
> +
> +SIM_AC_OUTPUT
> diff --git a/sim/bpf/decode.h b/sim/bpf/decode.h
> new file mode 100644
> index 0000000000..74d31cbdfe
> --- /dev/null
> +++ b/sim/bpf/decode.h
> @@ -0,0 +1,37 @@
> +/* Decode declarations.
> +   Copyright (C) 2020 Free Software Foundation, Inc.
> +   Contributed by Oracle, Inc.
> +
> +This file is part of the GNU simulators.
> +
> +This program is free software; you can redistribute it and/or modify
> +it under the terms of the GNU General Public License as published by
> +the Free Software Foundation; either version 3 of the License, or
> +(at your option) any later version.
> +
> +This program is distributed in the hope that it will be useful,
> +but WITHOUT ANY WARRANTY; without even the implied warranty of
> +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +GNU General Public License for more details.
> +
> +You should have received a copy of the GNU General Public License
> +along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
> +
> +/* Include declarations for eBPF LE and eBPF BE ISAs. */
> +
> +#ifndef DECODE_H
> +#define DECODE_H
> +
> +#undef WITH_PROFILE_MODEL_P
> +
> +#ifdef WANT_ISA_EBPFLE
> +#include "decode-le.h"
> +#include "defs-le.h"
> +#endif /* WANT_ISA_EBPFLE */
> +
> +#ifdef WANT_ISA_EBPFBE
> +#include "decode-be.h"
> +#include "defs-be.h"
> +#endif /* WANT_ISA_EBPFBE */
> +
> +#endif /* DECODE_H */
> diff --git a/sim/bpf/eng.h b/sim/bpf/eng.h
> new file mode 100644
> index 0000000000..08e29f99a8
> --- /dev/null
> +++ b/sim/bpf/eng.h
> @@ -0,0 +1,24 @@
> +/* Engine declarations.
> +   Copyright (C) 2020 Free Software Foundation, Inc.
> +   Contributed by Oracle, Inc.
> +
> +This file is part of the GNU simulators.
> +
> +This program is free software; you can redistribute it and/or modify
> +it under the terms of the GNU General Public License as published by
> +the Free Software Foundation; either version 3 of the License, or
> +(at your option) any later version.
> +
> +This program is distributed in the hope that it will be useful,
> +but WITHOUT ANY WARRANTY; without even the implied warranty of
> +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +GNU General Public License for more details.
> +
> +You should have received a copy of the GNU General Public License
> +along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
> +
> +/* Include declarations for eBPF LE and eBPF BE ISAs. */
> +
> +#include "eng-le.h"
> +#include "eng-be.h"
> +
> diff --git a/sim/bpf/mloop.in b/sim/bpf/mloop.in
> new file mode 100644
> index 0000000000..2661eed8a8
> --- /dev/null
> +++ b/sim/bpf/mloop.in
> @@ -0,0 +1,165 @@
> +# Simulator main loop for eBPF. -*- C -*-
> +#
> +# Copyright (C) 2020 Free Software Foundation, Inc.
> +#
> +# This file is part of the GNU Simulators.
> +#
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
> +
> +# Syntax:
> +# /bin/sh mloop.in command
> +#
> +# Command is one of:
> +#
> +# init
> +# support
> +# extract-{simple,scache,pbb}
> +# {full,fast}-exec-{simple,scache,pbb}
> +#
> +# A target need only provide a "full" version of one of simple,scache,pbb.
> +# If the target wants it can also provide a fast version of same, or if
> +# the slow (full featured) version is `simple', then the fast version can be
> +# one of scache/pbb.
> +# A target can't provide more than this.
> +# However for illustration's sake this file provides examples of all.
> +
> +# ??? After a few more ports are done, revisit.
> +# Will eventually need to machine generate a lot of this.
> +
> +case "x$1" in
> +
> +xsupport)
> +
> +cat <<EOF
> +
> +static INLINE const IDESC *
> +extract (SIM_CPU *current_cpu, PCADDR pc, CGEN_INSN_WORD insn,
> +         ARGBUF *abuf, int fast_p)
> +{
> +  const IDESC *id = @prefix@_decode (current_cpu, pc, insn, abuf);
> +  @prefix@_fill_argbuf (current_cpu, abuf, id, pc, fast_p);
> +  if (!fast_p)
> +    {
> +      int trace_p = PC_IN_TRACE_RANGE_P (current_cpu, pc);
> +      int profile_p = PC_IN_PROFILE_RANGE_P (current_cpu, pc);
> +      @prefix@_fill_argbuf_tp (current_cpu, abuf, trace_p, profile_p);
> +    }
> +  return id;
> +}
> +
> +static INLINE SEM_PC
> +execute (SIM_CPU *current_cpu, SCACHE *sc, int fast_p)
> +{
> +  SEM_PC vpc;
> +  
> +  if (fast_p)
> +      vpc = (*sc->argbuf.semantic.sem_fast) (current_cpu, sc);
> +  else
> +    {
> +      ARGBUF *abuf = &sc->argbuf;
> +      const IDESC *idesc = abuf->idesc;
> +      const CGEN_INSN *idata = idesc->idata;
> +      int virtual_p = 0;
> +
> +      if (! virtual_p)
> +        {
> +          /* FIXME: call x-before */
> +          if (ARGBUF_PROFILE_P (abuf))
> +            PROFILE_COUNT_INSN (current_cpu, abuf->addr, idesc->num);
> +          /* FIXME: Later make cover macros: PROFILE_INSN_{INIT,FINI}.  */
> +          if (PROFILE_MODEL_P (current_cpu)
> +              && ARGBUF_PROFILE_P (abuf))
> +            @cpu@_model_insn_before (current_cpu, 1 /*first_p*/);
> +          CGEN_TRACE_INSN_INIT (current_cpu, abuf, 1);
> +          CGEN_TRACE_INSN (current_cpu, idata,
> +                      (const struct argbuf *) abuf, abuf->addr);
> +        }
> +      vpc = (*sc->argbuf.semantic.sem_full) (current_cpu, sc);
> +      if (! virtual_p)
> +        {
> +          /* FIXME: call x-after */
> +          if (PROFILE_MODEL_P (current_cpu)
> +              && ARGBUF_PROFILE_P (abuf))
> +            {
> +              int cycles;
> +
> +              cycles = (*idesc->timing->model_fn) (current_cpu, sc);
> +              @cpu@_model_insn_after (current_cpu, 1 /*last_p*/, cycles);
> +            }
> +          CGEN_TRACE_INSN_FINI (current_cpu, abuf, 1);
> +        }
> +    }
> +
> +  return vpc;
> +}
> +
> +EOF
> +
> +;;
> +
> +xinit)
> +
> +# Nothing needed.
> +
> +;;
> +
> +xextract-scache)
> +
> +cat <<EOF
> +{
> +
> +  UDI insn = GETIMEMUDI (current_cpu, vpc);
> +
> +  if (current_target_byte_order == BFD_ENDIAN_BIG)
> +    {
> +      /* eBPF instructions are little-endian, but GETIMEMUDI reads according
> +         to target byte order. Swap to little-endian. */
> +      insn = SWAP_8 (insn);
> +
> +      /* But, the imm32 and offset16 fields within instructions follow target
> +         byte order. Swap those fields back. */
> +      UHI off16 = (UHI) ((insn & 0x00000000ffff0000) >> 16);
> +      USI imm32 = (USI) ((insn & 0xffffffff00000000) >> 32);
> +      off16 = SWAP_2 (off16);
> +      imm32 = SWAP_4 (imm32);
> +
> +      insn = (((UDI) imm32) << 32) | (((UDI) off16) << 16) | (insn & 0xffff);
> +    }
> +
> +  extract (current_cpu, vpc, insn, sc, FAST_P);
> +
> +  //XXX  SEM_SKIP_COMPILE (current_cpu, sc, 1);

Comments are /* ... */ please.  Please don't leave random lines
commented out like this though.  There should be a comment that
explains why the lines commented out.

> +}
> +EOF
> +
> +;;
> +
> +xfull-exec-* | xfast-exec-*)
> +
> +# Inputs: current_cpu, vpc, sc, FAST_P
> +# Outputs: vpc
> +# vpc is the virtual program counter.
> +
> +cat <<EOF
> +   vpc = execute (current_cpu, sc, FAST_P);
> +EOF
> +
> +;;
> +
> +*)
> +  echo "Invalid argument to mainloop.in: $1" >&2
> +  exit 1
> +  ;;
> +
> +esac
> diff --git a/sim/bpf/sim-if.c b/sim/bpf/sim-if.c
> new file mode 100644
> index 0000000000..964cc705eb
> --- /dev/null
> +++ b/sim/bpf/sim-if.c
> @@ -0,0 +1,216 @@
> +/* Main simulator entry points specific to the eBPF.
> +   Copyright (C) 2020 Free Software Foundation, Inc.
> +
> +   This file is part of GDB, the GNU debugger.
> +
> +   This program is free software; you can redistribute it and/or modify
> +   it under the terms of the GNU General Public License as published by
> +   the Free Software Foundation; either version 3 of the License, or
> +   (at your option) any later version.
> +
> +   This program is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
> +
> +#include "sim-main.h"
> +#include "sim-options.h"
> +#include "libiberty.h"
> +#include "bfd.h"
> +
> +/* Globals.  */
> +
> +/* String with the name of the section containing the BPF program to
> +   run.  */
> +static char *bpf_program_section = NULL;
> +
> +extern uint64_t skb_data_offset;
> +
> +\f
> +/* Handle BPF-specific options.  */
> +
> +static SIM_RC bpf_option_handler (SIM_DESC, sim_cpu *, int, char *, int);
> +
> +typedef enum
> +{
> + OPTION_BPF_SET_PROGRAM = OPTION_START,
> + OPTION_BPF_LIST_PROGRAMS,
> + OPTION_BPF_VERIFY_PROGRAM,
> + OPTION_BPF_SKB_DATA_OFFSET,
> +} BPF_OPTION;
> +
> +static const OPTION bpf_options[] =
> +{
> + { {"bpf-set-program", required_argument, NULL, OPTION_BPF_SET_PROGRAM},
> +   '\0', "SECTION_NAME", "Set the entry point",
> +   bpf_option_handler },
> + { {"bpf-list-programs", no_argument, NULL, OPTION_BPF_LIST_PROGRAMS},
> +   '\0', "", "List loaded bpf programs",
> +   bpf_option_handler },
> + { {"bpf-verify-program", required_argument, NULL, OPTION_BPF_VERIFY_PROGRAM},
> +   '\0', "PROGRAM", "Run the verifier on the given BPF program",
> +   bpf_option_handler },
> + { {"skb-data-offset", required_argument, NULL, OPTION_BPF_SKB_DATA_OFFSET},
> +   '\0', "OFFSET", "Configure offsetof(struct sk_buff, data)",
> +   bpf_option_handler },
> +
> + { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL, NULL }
> +};
> +
> +static SIM_RC
> +bpf_option_handler (SIM_DESC sd, sim_cpu *cpu ATTRIBUTE_UNUSED, int opt,
> +                    char *arg, int is_command ATTRIBUTE_UNUSED)
> +{
> +  switch ((BPF_OPTION) opt)
> +    {
> +    case OPTION_BPF_VERIFY_PROGRAM:
> +      /* XXX call the verifier. */
> +      sim_io_printf (sd, "Verifying BPF program %s...\n", arg);
> +      break;
> +
> +    case OPTION_BPF_LIST_PROGRAMS:
> +      /* XXX list programs.  */
> +      sim_io_printf (sd, "BPF programs available:\n");
> +      break;
> +
> +    case OPTION_BPF_SET_PROGRAM:
> +      /* XXX: check that the section exists and tell the user about a
> +         new start_address.  */
> +      bpf_program_section = xstrdup (arg);
> +      break;
> +
> +    case OPTION_BPF_SKB_DATA_OFFSET:
> +      skb_data_offset = strtoul (arg, NULL, 0);
> +      break;
> +
> +    default:
> +      sim_io_eprintf (sd, "Unknown option `%s'\n", arg);
> +      return SIM_RC_FAIL;
> +    }
> +
> +  return SIM_RC_OK;
> +}
> +
> +/* Like sim_state_free, but free the cpu buffers as well.  */
> +
> +static void
> +bpf_free_state (SIM_DESC sd)
> +{
> +  if (STATE_MODULES (sd) != NULL)
> +    sim_module_uninstall (sd);
> +
> +  sim_cpu_free_all (sd);
> +  sim_state_free (sd);
> +}
> +
> +/* Create an instance of the simulator.  */
> +
> +SIM_DESC
> +sim_open (SIM_OPEN_KIND kind,
> +          host_callback *callback,
> +          struct bfd *abfd,
> +	  char * const *argv)
> +{
> +  /* XXX Analyze the program, and collect per-function information
> +     like the kernel verifier does.  The implementation of the CALL
> +     instruction will need that information, to update %fp.  */
> +
> +  SIM_DESC sd = sim_state_alloc (kind, callback);
> +
> +  /* ... */
> +
> +  if (sim_cpu_alloc_all (sd, 1, cgen_cpu_max_extra_bytes ())
> +      != SIM_RC_OK)
> +    goto error;
> +
> +  if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
> +    goto error;
> +
> +  /* Add the BPF-specific option list to the simulator.  */
> +  if (sim_add_option_table (sd, NULL, bpf_options) != SIM_RC_OK)
> +    {
> +      bpf_free_state (sd);
> +      return 0;
> +    }
> +
> +  if (sim_parse_args (sd, argv) != SIM_RC_OK)
> +    goto error;
> +
> +  if (sim_analyze_program (sd,
> +                           (STATE_PROG_ARGV (sd) != NULL
> +                            ? *STATE_PROG_ARGV (sd)
> +                            : NULL), abfd) != SIM_RC_OK)
> +    goto error;
> +
> +  if (sim_config (sd) != SIM_RC_OK)
> +    goto error;
> +
> +  if (sim_post_argv_init (sd) != SIM_RC_OK)
> +    goto error;
> +
> +  /* ... */

Could you delete this comment?

> +
> +  /* Initialize the CPU descriptors and the disassemble in the cpu
> +     descriptor table entries.  */
> +  {
> +    int i;
> +    CGEN_CPU_DESC cd = bpf_cgen_cpu_open_1 (STATE_ARCHITECTURE (sd)->printable_name,
> +                                            CGEN_ENDIAN_LITTLE);
> +
> +    /* We have one cpu per installed program! MAX_NR_PROCESSORS is an
> +       arbitrary upper limit.  XXX where is it defined?  */
> +    for (i = 0; i < MAX_NR_PROCESSORS; ++i)
> +      {
> +        SIM_CPU *cpu = STATE_CPU (sd, i);
> +
> +        CPU_CPU_DESC (cpu) = cd;
> +        CPU_DISASSEMBLER (cpu) = sim_cgen_disassemble_insn;
> +      }
> +
> +    bpf_cgen_init_dis (cd);
> +  }
> +
> +  /* Initialize various cgen things not done by common framework.
> +     Must be done after bpf_cgen_cpu_open.  */
> +  cgen_init (sd);
> +
> +  /* XXX do eBPF sim specific initializations.  */
> +
> +  return sd;
> +
> + error:
> +      bpf_free_state (sd);
> +      return NULL;
> +}
> +\f
> +
> +SIM_RC
> +sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
> +		     char *const *argv, char *const *envp)
> +{
> +  SIM_CPU *current_cpu = STATE_CPU (sd, 0);
> +  SIM_ADDR addr;
> +
> +  /* Determine the start address.
> +
> +     XXX acknowledge bpf_program_section.  If it is NULL, emit a
> +     warning explaining that we are using the ELF file start address,
> +     which often is not what is actually wanted.  */
> +  if (abfd != NULL)
> +    addr = bfd_get_start_address (abfd);
> +  else
> +    addr = 0;
> +
> +  sim_pc_set (current_cpu, addr);
> +
> +  if (STATE_PROG_ARGV (sd) != argv)
> +    {
> +      freeargv (STATE_PROG_ARGV (sd));
> +      STATE_PROG_ARGV (sd) = dupargv (argv);
> +    }
> +
> +  return SIM_RC_OK;
> +}
> diff --git a/sim/bpf/sim-main.h b/sim/bpf/sim-main.h
> new file mode 100644
> index 0000000000..fc1e69f6f3
> --- /dev/null
> +++ b/sim/bpf/sim-main.h
> @@ -0,0 +1,51 @@
> +/* eBPF simulator main header
> +   Copyright (C) 2020 Free Software Foundation, Inc.
> +
> +   This file is part of GDB, the GNU debugger.
> +
> +   This program is free software; you can redistribute it and/or modify
> +   it under the terms of the GNU General Public License as published by
> +   the Free Software Foundation; either version 3 of the License, or
> +   (at your option) any later version.
> +
> +   This program is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
> +
> +#ifndef SIM_MAIN_H
> +#define SIM_MAIN_H
> +
> +#include "sim-basics.h"
> +#include "cgen-types.h"
> +#include "bpf-desc.h"
> +#include "bpf-opc.h"
> +#include "arch.h"
> +#include "sim-base.h"
> +#include "cgen-sim.h"
> +#include "bpf-sim.h"
> +
> +
> +struct _sim_cpu
> +{
> +  sim_cpu_base base;
> +  CGEN_CPU cgen_cpu;
> +
> +#if defined (WANT_CPU_BPFBF)
> +  BPFBF_CPU_DATA cpu_data;
> +#endif
> +};
> +
> +\f
> +
> +struct sim_state
> +{
> +  sim_cpu *cpu[MAX_NR_PROCESSORS];
> +  CGEN_STATE cgen_state;
> +  sim_state_base base;
> +};
> +
> +#endif /* ! SIM_MAIN_H */
> diff --git a/sim/bpf/traps.c b/sim/bpf/traps.c
> new file mode 100644
> index 0000000000..e7ac0c2838
> --- /dev/null
> +++ b/sim/bpf/traps.c
> @@ -0,0 +1,33 @@
> +/* Trap handlers for eBPF.
> +   Copyright (C) 2020 Free Software Foundation, Inc.
> +
> +   This file is part of GDB, the GNU debugger.
> +
> +   This program is free software; you can redistribute it and/or modify
> +   it under the terms of the GNU General Public License as published by
> +   the Free Software Foundation; either version 3 of the License, or
> +   (at your option) any later version.
> +
> +   This program is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
> +
> +#define WANT_CPU bpfbf
> +#define WANT_CPU_BPFBF
> +
> +#include "sim-main.h"
> +
> +SEM_PC
> +sim_engine_invalid_insn (SIM_CPU *current_cpu ATTRIBUTE_UNUSED,
> +                         IADDR cia ATTRIBUTE_UNUSED,
> +                         SEM_PC pc ATTRIBUTE_UNUSED)
> +{
> +  /* Can't just return 0 here: the return value is used to set vpc
> +     (see decdde-{le,be}.c)
> +     Returning 0 will cause an infinite loop! */
> +  abort();
> +}
> diff --git a/sim/configure b/sim/configure
> index 72f95cd5c7..37a86f435c 100755
> --- a/sim/configure
> +++ b/sim/configure
> @@ -669,6 +669,7 @@ ac_subdirs_all='aarch64
>  arm
>  avr
>  bfin
> +bpf
>  cr16
>  cris
>  d10v
> @@ -3717,6 +3718,13 @@ subdirs="$subdirs aarch64"
>    subdirs="$subdirs bfin"
>  
>  
> +       ;;
> +   bpf-*-*)
> +
> +  sim_arch=bpf
> +  subdirs="$subdirs bpf"
> +
> +
>         ;;
>     cr16*-*-*)
>  
> diff --git a/sim/configure.tgt b/sim/configure.tgt
> index 8a8e03d96f..c115c3c8dd 100644
> --- a/sim/configure.tgt
> +++ b/sim/configure.tgt
> @@ -26,6 +26,9 @@ case "${target}" in
>     bfin-*-*)
>         SIM_ARCH(bfin)
>         ;;
> +   bpf-*-*)
> +       SIM_ARCH(bpf)
> +       ;;
>     cr16*-*-*)
>         SIM_ARCH(cr16)
>         ;;
> diff --git a/sim/testsuite/configure b/sim/testsuite/configure
> index a3e7fa7131..c3674c2fa0 100755
> --- a/sim/testsuite/configure
> +++ b/sim/testsuite/configure
> @@ -1875,6 +1875,9 @@ case "${target}" in
>     bfin-*-*)
>         sim_arch=bfin
>         ;;
> +   bpf-*-*)
> +       sim_arch=bpf
> +       ;;
>     cr16*-*-*)
>         sim_arch=cr16
>         ;;
> @@ -1928,6 +1931,9 @@ case "${target}" in
>     or1k-*-* | or1knd-*-*)
>         sim_arch=or1k
>         ;;
> +   pru*-*-*)
> +       sim_arch=pru
> +       ;;
>     rl78-*-*)
>         sim_arch=rl78
>         ;;
> @@ -1946,9 +1952,6 @@ case "${target}" in
>     powerpc*-*-*)
>         sim_arch=ppc
>         ;;
> -   pru*-*-*)
> -       sim_arch=pru
> -       ;;
>     ft32-*-*)
>         sim_arch=ft32
>         ;;
> diff --git a/sim/testsuite/sim/bpf/allinsn.exp b/sim/testsuite/sim/bpf/allinsn.exp
> new file mode 100644
> index 0000000000..2cca77021a
> --- /dev/null
> +++ b/sim/testsuite/sim/bpf/allinsn.exp
> @@ -0,0 +1,26 @@
> +# eBPF simulator testsuite
> +
> +if [istarget bpf-unknown-none] {
> +    # all machines
> +    set all_machs "bpf"
> +
> +    global global_sim_options
> +    if ![info exists global_sim_options] {
> +	set global_sim_options "--memory-size=4Mb"
> +    }
> +
> +    global global_ld_options
> +    if ![info exists global_ld_options] {
> +        set global_ld_options "-Ttext=0x0"
> +    }
> +
> +    foreach src [lsort [glob -nocomplain $srcdir/$subdir/*.s]] {
> +	# If we're only testing specific files and this isn't one of them,
> +	# skip it.
> +	if ![runtest_file_p $runtests $src] {
> +	    continue
> +	}
> +
> +	run_sim_test $src $all_machs
> +    }
> +}
> diff --git a/sim/testsuite/sim/bpf/alu.s b/sim/testsuite/sim/bpf/alu.s
> new file mode 100644
> index 0000000000..6013ac7eb9
> --- /dev/null
> +++ b/sim/testsuite/sim/bpf/alu.s
> @@ -0,0 +1,109 @@
> +# mach: bpf
> +# output: pass\nexit 0 (0x0)\n
> +;;; alu.s
> +;;; Tests for ALU64 BPF instructions in simulator
> +
> +    .include "testutils.inc"
> +
> +    .text
> +    .global main
> +    .type main, @function
> +main:
> +    mov         %r1, 0
> +    mov         %r2, -1
> +
> +    ;; add
> +    add         %r1, 1
> +    add         %r2, -1
> +    add         %r1, %r2
> +    fail_ne     %r1, -1
> +
> +    ;; sub
> +    sub         %r1, %r1
> +    fail_ne     %r1, 0
> +    sub         %r1, 10
> +    sub         %r2, %r1
> +    fail_ne     %r2, 8
> +
> +    ;; mul
> +    mul         %r2, %r2        ; r2 = 64
> +    mul         %r2, 3          ; r2 = 192
> +    mov         %r1, -3
> +    mul         %r1, %r2        ; r1 = -576
> +    mul         %r2, 0
> +    fail_ne     %r1, -576
> +    fail_ne     %r2, 0
> +    mul         %r1, %r1
> +    mul         %r1, %r1
> +    fail_ne     %r1, 110075314176
> +
> +    ;; div
> +    div         %r2, %r1
> +    fail_ne     %r2, 0
> +    div         %r1, -10000
> +    fail_ne     %r1, -11007531
> +    div         %r1, %r1
> +    fail_ne     %r1, 1
> +
> +    ;; and
> +    lddw        %r1, 0xaaaaaaaa55555555
> +    and         %r1, 0x55aaaaaa         ; we still only have 32-bit imm.
> +    fail_ne     %r1, 0x0000000055000000
> +    lddw        %r2, 0x5555555a5aaaaaaa
> +    and         %r2, %r1
> +    fail_ne     %r2, 0x0000000050000000
> +
> +    ;; or
> +    or          %r2, 0xdeadbeef
> +    fail_ne     %r2, 0xffffffffdeadbeef ; 0xdeadbeef gets sign extended
> +    lddw        %r1, 0xdead00000000beef
> +    lddw        %r2, 0x0000123456780000
> +    or          %r1, %r2
> +    fail_ne     %r1, 0xdead12345678beef
> +
> +    ;; lsh
> +    mov         %r1, 0xdeadbeef
> +    lsh         %r1, 11
> +    fail_ne     %r1, 0xfffffef56df77800 ; because deadbeef gets sign ext.
> +    mov         %r2, 21
> +    lsh         %r1, %r2
> +    fail_ne     %r1, 0xdeadbeef00000000
> +
> +    ;; rsh
> +    rsh         %r1, 11
> +    fail_ne     %r1, 0x001bd5b7dde00000 ; 0xdeadbeef 00000000 >> 0xb
> +    rsh         %r1, %r2
> +    fail_ne     %r1, 0x00000000deadbeef
> +
> +    ;; arsh
> +    arsh        %r1, 8
> +    fail_ne     %r1, 0x0000000000deadbe
> +    lsh         %r1, 40                 ; r1 = 0xdead be00 0000 0000
> +    arsh        %r1, %r2                ; r1 arsh (r2 == 21)
> +    fail_ne     %r1, 0xfffffef56df00000
> +
> +    ;; mod
> +    mov         %r1, 1025
> +    mod         %r1, -16
> +    fail_ne     %r1, 1
> +    mov         %r1, -25
> +    mov         %r2, 5
> +    mod         %r1, %r2
> +    fail_ne     %r1, 0
> +
> +    ;; xor
> +    xor         %r1, %r2
> +    fail_ne     %r1, 5
> +    xor         %r1, 0x7eadbeef
> +    fail_ne     %r1, 0x7eadbeea
> +    xor         %r1, %r1
> +    fail_ne     %r1, 0
> +
> +    ;; neg
> +    neg         %r2
> +    fail_ne     %r2, -5
> +    mov         %r1, -1025
> +    neg         %r1
> +    fail_ne     %r1, 1025
> +
> +    pass
> diff --git a/sim/testsuite/sim/bpf/alu32.s b/sim/testsuite/sim/bpf/alu32.s
> new file mode 100644
> index 0000000000..a611abd6f6
> --- /dev/null
> +++ b/sim/testsuite/sim/bpf/alu32.s
> @@ -0,0 +1,99 @@
> +# mach: bpf
> +# output: pass\nexit 0 (0x0)\n
> +;; alu32.s
> +;; Tests for ALU(32) BPF instructions in simulator
> +
> +    .include "testutils.inc"
> +
> +    .text
> +    .global main
> +    .type main, @function
> +main:
> +    mov32       %r1, 10         ; r1 = 10
> +    mov32       %r2, -5         ; r2 = -5
> +   
> +    ;; add
> +    add32       %r1, 1          ; r1 += 1  (r1 = 11)
> +    add32       %r2, -1         ; r2 += -1 (r2 = -6)
> +    add32       %r1, %r2        ; r1 += r2 (r1 = 11 + -6 = 5)
> +    fail_ne32   %r1, 5
> +
> +    ;; sub
> +    sub32       %r1, 5          ; r1 -= 5 (r1 = 0)
> +    sub32       %r1, -5         ; r1 -= -5 (r1 = 5)
> +    sub32       %r1, %r2        ; r1 -= r2 (r1 = 5 - -6 = 11)
> +    fail_ne32   %r1, 11
> +
> +    ;; mul
> +    mul32       %r1, 2          ; r1 *= 2  (r1 = 22)
> +    mul32       %r1, -2         ; r1 *= -2 (r1 = -44)
> +    mul32       %r1, %r2        ; r1 *= r2 (r1 = -44 * -6 = 264)
> +    fail_ne32   %r1, 264
> +
> +    ;; div
> +    div32       %r1, %r2        ; r1 /= r2 (r1 = 264 / -6 = -44)
> +    div32       %r1, -2         ; r1 /= -2 (r1 = 22)
> +    div32       %r1, 2          ; r1 /= 2  (r1 = 11)
> +    fail_ne32   %r1, 11
> +
> +    ;; and (bitwise)
> +    mov32       %r1, 0xb        ; r1  = (0xb = 0b1011)
> +    mov32       %r2, 0x5        ; r2  = (0x5 = 0b0101)
> +    and32       %r1, 0xa        ; r1 &= (0xa = 0b1010) = (0b1010 = 0xa)
> +    fail_ne32   %r1, 0xa
> +    and32       %r1, %r2        ; r1 &= r2 = 0x0
> +    fail_ne32   %r1, 0x0
> +
> +    ;; or (bitwise)
> +    or32        %r1, 0xb
> +    or32        %r1, %r2
> +    fail_ne32   %r1, 0xf
> +
> +    ;; lsh (left shift)
> +    lsh32       %r1, 4          ; r1 <<= 4 (r1 = 0xf0)
> +    mov32       %r2, 24         ; r2 = 24
> +    lsh32       %r1, %r2
> +    fail_ne32   %r1, 0xf0000000
> +
> +    ;; rsh (right logical shift)
> +    rsh32       %r1, 2
> +    rsh32       %r1, %r2
> +    fail_ne32   %r1, 0x3c       ; (0xf000 0000 >> 26)
> +
> +    ;; arsh (right arithmetic shift)
> +    arsh32      %r1, 1
> +    or32        %r1, 0x80000000
> +    mov32       %r2, 3
> +    arsh32      %r1, %r2
> +    fail_ne     %r1, 0x00000000F0000003
> +                                ; Note: make sure r1 is NOT sign-extended
> +                                ; i.e. upper-32 bits should be untouched
> +
> +    ;; mod
> +    mov32       %r1, -25
> +    mov32       %r2, 4
> +    mod32       %r1, %r2
> +    fail_ne32   %r1, -1
> +    mov32       %r1, 25
> +    mod32       %r1, 5
> +    fail_ne32   %r1, 0
> +
> +    ;; xor
> +    xor32       %r1, %r2
> +    fail_ne32   %r1, 4
> +    xor32       %r1, 0xF000000F
> +    fail_ne     %r1, 0xF000000B ; Note: check for (bad) sign-extend
> +    xor32       %r1, %r1
> +    fail_ne     %r1, 0
> +
> +    ;; neg
> +    mov32       %r1, -1
> +    mov32       %r2, 0x7fffffff
> +    neg32       %r1
> +    neg32       %r2
> +    fail_ne32   %r1, 1
> +    fail_ne     %r2, 0x80000001 ; Note: check for (bad) sign-extend
> +    neg32       %r2
> +    fail_ne32   %r2, 0x7fffffff
> +
> +    pass
> diff --git a/sim/testsuite/sim/bpf/endbe.s b/sim/testsuite/sim/bpf/endbe.s
> new file mode 100644
> index 0000000000..2f662aec02
> --- /dev/null
> +++ b/sim/testsuite/sim/bpf/endbe.s
> @@ -0,0 +1,46 @@
> +# mach: bpf
> +# as: --EB
> +# ld: --EB
> +# sim: -E big
> +# output: pass\nexit 0 (0x0)\n
> +;;; endbe.s
> +;;; Tests for BPF endianness-conversion instructions in simulator
> +;;; running in BIG ENDIAN
> +;;;
> +;;; Both 'be' and 'le' ISAs have both endbe and endle instructions.
> +
> +    .include "testutils.inc"
> +
> +    .text
> +    .global main
> +    .type main, @function
> +main:
> +    lddw        %r1, 0x12345678deadbeef
> +    endle       %r1, 64
> +    fail_ne     %r1, 0xefbeadde78563412
> +    endle       %r1, 64
> +    fail_ne     %r1, 0x12345678deadbeef
> +
> +    ;; `bitsize` < 64 will truncate
> +    endle       %r1, 32
> +    fail_ne     %r1, 0xefbeadde
> +    endle       %r1, 32
> +    fail_ne     %r1, 0xdeadbeef
> +
> +    endle       %r1, 16
> +    fail_ne     %r1, 0xefbe
> +    endle       %r1, 16
> +    fail_ne     %r1, 0xbeef
> +
> +    ;; endbe on be should be noop (except truncate)
> +    lddw        %r1, 0x12345678deadbeef
> +    endbe       %r1, 64
> +    fail_ne     %r1, 0x12345678deadbeef
> +
> +    endbe       %r1, 32
> +    fail_ne     %r1, 0xdeadbeef
> +
> +    endbe       %r1, 16
> +    fail_ne     %r1, 0xbeef
> +
> +    pass
> diff --git a/sim/testsuite/sim/bpf/endle.s b/sim/testsuite/sim/bpf/endle.s
> new file mode 100644
> index 0000000000..d8f5ceb977
> --- /dev/null
> +++ b/sim/testsuite/sim/bpf/endle.s
> @@ -0,0 +1,43 @@
> +# mach: bpf
> +# output: pass\nexit 0 (0x0)\n
> +;;; endle.s
> +;;; Tests for BPF endianness-conversion instructions in simulator
> +;;; running in LITTLE ENDIAN
> +;;;
> +;;; Both 'be' and 'le' ISAs have both endbe and endle instructions.
> +
> +    .include "testutils.inc"
> +
> +    .text
> +    .global main
> +    .type main, @function
> +main:
> +    lddw        %r1, 0x12345678deadbeef
> +    endbe       %r1, 64
> +    fail_ne     %r1, 0xefbeadde78563412
> +    endbe       %r1, 64
> +    fail_ne     %r1, 0x12345678deadbeef
> +
> +    ;; `bitsize` < 64 will truncate
> +    endbe       %r1, 32
> +    fail_ne     %r1, 0xefbeadde
> +    endbe       %r1, 32
> +    fail_ne     %r1, 0xdeadbeef
> +
> +    endbe       %r1, 16
> +    fail_ne     %r1, 0xefbe
> +    endbe       %r1, 16
> +    fail_ne     %r1, 0xbeef
> +
> +    ;; endle on le should be noop (except truncate)
> +    lddw        %r1, 0x12345678deadbeef
> +    endle       %r1, 64
> +    fail_ne     %r1, 0x12345678deadbeef
> +
> +    endle       %r1, 32
> +    fail_ne     %r1, 0xdeadbeef
> +
> +    endle       %r1, 16
> +    fail_ne     %r1, 0xbeef
> +
> +    pass
> diff --git a/sim/testsuite/sim/bpf/jmp.s b/sim/testsuite/sim/bpf/jmp.s
> new file mode 100644
> index 0000000000..a9fe88be4a
> --- /dev/null
> +++ b/sim/testsuite/sim/bpf/jmp.s
> @@ -0,0 +1,120 @@
> +# mach: bpf
> +# output: pass\nexit 0 (0x0)\n
> +;;; jmp.s
> +;;; Tests for eBPF JMP instructions in simulator
> +
> +    .include "testutils.inc"
> +
> +    .text
> +    .global main
> +    .type main, @function
> +main:
> +    mov         %r1, 5
> +    mov         %r2, 2
> +    mov         %r3, 7
> +    mov         %r4, -1
> +
> +    ;; ja - jump absolute (unconditional)
> +    ja          2f
> +1:  fail
> +
> +2:  ;; jeq - jump eq
> +    jeq         %r1, 4, 1b      ; no
> +    jeq         %r1, %r2, 1b    ; no
> +    jeq         %r1, 5, 2f      ; yes
> +    fail
> +2:  jeq         %r1, %r1, 2f    ; yes
> +    fail
> +
> +2:  ;; jgt - jump (unsigned) greater-than
> +    jgt         %r1, 6, 1b      ; no
> +    jgt         %r1, -5, 1b     ; no - unsigned
> +    jgt         %r1, %r4, 1b    ; no - unsigned
> +    jgt         %r1, 4, 2f      ; yes
> +    fail
> +2:  jgt         %r1, %r2, 2f    ; yes
> +    fail
> +
> +2:  ;; jge - jump (unsigned) greater-than-or-equal-to
> +    jge         %r1, 6, 1b      ; no
> +    jge         %r1, 5, 2f      ; yes
> +    fail
> +2:  jge         %r1, %r3, 1b    ; no
> +    jge         %r1, -5, 1b     ; no - unsigned
> +    jge         %r1, %r2, 2f    ; yes
> +    fail
> +
> +2:  ;; jlt - jump (unsigned) less-than
> +    jlt         %r1, 5, 1b      ; no
> +    jlt         %r1, %r2, 1b    ; no
> +    jlt         %r4, %r1, 1b    ; no - unsigned
> +    jlt         %r1, 6, 2f      ; yes
> +    fail
> +2:
> +    jlt         %r1, %r3, 2f    ; yes
> +    fail
> +
> +2:  ;; jle - jump (unsigned) less-than-or-equal-to
> +    jle         %r1, 4, 1b      ; no
> +    jle         %r1, %r2, 1b    ; no
> +    jle         %r4, %r1, 1b    ; no
> +    jle         %r1, 5, 2f      ; yes
> +    fail
> +2:  jle         %r1, %r1, 2f    ; yes
> +    fail
> +   
> +2:  ;; jset - jump "test" (AND)
> +    jset        %r1, 2, 1b      ; no (5 & 2 = 0)
> +    jset        %r1, %r2, 1b    ; no (same)
> +    jset        %r1, 4, 2f      ; yes (5 & 4 != 0)
> +    fail
> +
> +2:  ;; jne  - jump not-equal-to
> +    jne         %r1, 5, 1b      ; no
> +    jne         %r1, %r1, 1b    ; no
> +    jne         %r1, 6, 2f      ; yes
> +    fail
> +2:  jne         %r1, %r4, 2f    ; yes
> +    fail
> +
> +2:  ;; jsgt - jump (signed) greater-than
> +    jsgt        %r1, %r3, 1b    ; no
> +    jsgt        %r1, %r1, 1b    ; no
> +    jsgt        %r1, 5, 1b      ; no
> +    jsgt        %r1, -4, 2f     ; yes
> +    fail
> +2:  jsgt        %r1, %r4, 2f    ; yes
> +    fail
> +
> +2:  ;; jsge - jump (signed) greater-than-or-equal-to
> +    jsge        %r1, %r3, 1b    ; no
> +    jsge        %r1, %r1, 2f    ; yes
> +    fail
> +2:  jsge        %r1, 7, 1b      ; no
> +    jsge        %r1, -4, 2f     ; yes
> +    fail
> +2:  jsge        %r1, %r4, 2f    ; yes
> +    fail
> +
> +2:  ;; jslt - jump (signed) less-than
> +    jslt        %r1, 5, 1b      ; no
> +    jslt        %r1, %r2, 1b    ; no
> +    jslt        %r4, %r1, 2f    ; yes
> +    fail
> +2:  jslt        %r1, 6, 2f      ; yes
> +    fail
> +2:  jslt        %r1, %r3, 2f    ; yes
> +    fail
> +
> +2:  ;; jsle - jump (signed) less-than-or-equal-to
> +    jsle         %r1, 4, 1b      ; no
> +    jsle         %r1, %r2, 1b    ; no
> +    jsle         %r4, %r1, 2f    ; yes
> +    fail
> +2:  jsle         %r1, 5, 2f      ; yes
> +    fail
> +2:  jsle         %r1, %r3, 2f    ; yes
> +    fail
> +
> +2: 
> +    pass
> diff --git a/sim/testsuite/sim/bpf/jmp32.s b/sim/testsuite/sim/bpf/jmp32.s
> new file mode 100644
> index 0000000000..3621295129
> --- /dev/null
> +++ b/sim/testsuite/sim/bpf/jmp32.s
> @@ -0,0 +1,120 @@
> +# mach: bpf
> +# output: pass\nexit 0 (0x0)\n
> +;;; jmp32.s
> +;;; Tests for eBPF JMP32 instructions in simulator
> +
> +    .include "testutils.inc"
> +
> +    .text
> +    .global main
> +    .type main, @function
> +main:
> +    mov32       %r1, 5
> +    mov32       %r2, 2
> +    mov32       %r3, 7
> +    mov32       %r4, -1
> +
> +    ;; ja - jump absolute (unconditional)
> +    ja          2f
> +1:  fail
> +
> +2:  ;; jeq - jump eq
> +    jeq32       %r1, 4, 1b      ; no
> +    jeq32       %r1, %r2, 1b    ; no
> +    jeq32       %r1, 5, 2f      ; yes
> +    fail
> +2:  jeq32       %r1, %r1, 2f    ; yes
> +    fail
> +
> +2:  ;; jgt - jump (unsigned) greater-than
> +    jgt32       %r1, 6, 1b      ; no
> +    jgt32       %r1, -5, 1b     ; no - unsigned
> +    jgt32       %r1, %r4, 1b    ; no - unsigned
> +    jgt32       %r1, 4, 2f      ; yes
> +    fail
> +2:  jgt32       %r1, %r2, 2f    ; yes
> +    fail
> +
> +2:  ;; jge - jump (unsigned) greater-than-or-equal-to
> +    jge32       %r1, 6, 1b      ; no
> +    jge32       %r1, 5, 2f      ; yes
> +    fail
> +2:  jge32       %r1, %r3, 1b    ; no
> +    jge32       %r1, -5, 1b     ; no - unsigned
> +    jge32       %r1, %r2, 2f    ; yes
> +    fail
> +
> +2:  ;; jlt - jump (unsigned) less-than
> +    jlt32       %r1, 5, 1b      ; no
> +    jlt32       %r1, %r2, 1b    ; no
> +    jlt32       %r4, %r1, 1b    ; no - unsigned
> +    jlt32       %r1, 6, 2f      ; yes
> +    fail
> +2:
> +    jlt32       %r1, %r3, 2f    ; yes
> +    fail
> +
> +2:  ;; jle - jump (unsigned) less-than-or-equal-to
> +    jle32       %r1, 4, 1b      ; no
> +    jle32       %r1, %r2, 1b    ; no
> +    jle32       %r4, %r1, 1b    ; no
> +    jle32       %r1, 5, 2f      ; yes
> +    fail
> +2:  jle32       %r1, %r1, 2f    ; yes
> +    fail
> +   
> +2:  ;; jset - jump "test" (AND)
> +    jset32      %r1, 2, 1b      ; no (5 & 2 = 0)
> +    jset32      %r1, %r2, 1b    ; no (same)
> +    jset32      %r1, 4, 2f      ; yes (5 & 4 != 0)
> +    fail
> +
> +2:  ;; jne  - jump not-equal-to
> +    jne32       %r1, 5, 1b      ; no
> +    jne32       %r1, %r1, 1b    ; no
> +    jne32       %r1, 6, 2f      ; yes
> +    fail
> +2:  jne32       %r1, %r4, 2f    ; yes
> +    fail
> +
> +2:  ;; jsgt - jump (signed) greater-than
> +    jsgt32      %r1, %r3, 1b    ; no
> +    jsgt32      %r1, %r1, 1b    ; no
> +    jsgt32      %r1, 5, 1b      ; no
> +    jsgt32      %r1, -4, 2f     ; yes
> +    fail
> +2:  jsgt32      %r1, %r4, 2f    ; yes
> +    fail
> +
> +2:  ;; jsge - jump (signed) greater-than-or-equal-to
> +    jsge32      %r1, %r3, 1b    ; no
> +    jsge32      %r1, %r1, 2f    ; yes
> +    fail
> +2:  jsge32      %r1, 7, 1b      ; no
> +    jsge32      %r1, -4, 2f     ; yes
> +    fail
> +2:  jsge32      %r1, %r4, 2f    ; yes
> +    fail
> +
> +2:  ;; jslt - jump (signed) less-than
> +    jslt32      %r1, 5, 1b      ; no
> +    jslt32      %r1, %r2, 1b    ; no
> +    jslt32      %r4, %r1, 2f    ; yes
> +    fail
> +2:  jslt32      %r1, 6, 2f      ; yes
> +    fail
> +2:  jslt32      %r1, %r3, 2f    ; yes
> +    fail
> +
> +2:  ;; jsle - jump (signed) less-than-or-equal-to
> +    jsle32       %r1, 4, 1b      ; no
> +    jsle32       %r1, %r2, 1b    ; no
> +    jsle32       %r4, %r1, 2f    ; yes
> +    fail
> +2:  jsle32       %r1, 5, 2f      ; yes
> +    fail
> +2:  jsle32       %r1, %r3, 2f    ; yes
> +    fail
> +
> +2: 
> +    pass
> diff --git a/sim/testsuite/sim/bpf/ldabs.s b/sim/testsuite/sim/bpf/ldabs.s
> new file mode 100644
> index 0000000000..ae777f1cf5
> --- /dev/null
> +++ b/sim/testsuite/sim/bpf/ldabs.s
> @@ -0,0 +1,87 @@
> +# mach: bpf
> +# sim: --skb-data-offset=0x20
> +# output: pass\nexit 0 (0x0)\n
> +;;; ldabs.s
> +;;; Tests for non-generic BPF load instructions in simulator.
> +;;; These instructions (ld{abs,ind}{b,h,w,dw}) are used to access
> +;;; kernel socket data from BPF programs for high performance filters.
> +;;;
> +;;; Register r6 is an implicit input holding a pointer to a struct sk_buff.
> +;;; Register r0 is an implicit output, holding the fetched data.
> +;;;
> +;;; e.g.
> +;;; ldabsw means:
> +;;; r0 = ntohl (*(u32 *) (((struct sk_buff *)r6)->data + imm32))
> +;;;
> +;;; ldindw means
> +;;; r0 = ntohl (*(u32 *) (((struct sk_buff *)r6)->data + src_reg + imm32))
> +
> +    .include "testutils.inc"
> +
> +    .text
> +    .global main
> +    .type main, @function
> +main:
> +    ;; R6 holds a pointer to a struct sk_buff, which we pretend
> +    ;; exists at 0x1000
> +    mov         %r6, 0x1000
> +
> +    ;; We configure skb-data-offset=0x20
> +    ;; This specifies offsetof(struct sk_buff, data), where the field 'data'
> +    ;; is a pointer a data buffer, in this case at 0x2000
> +    stw         [%r6+0x20], 0x2000
> +
> +    ;; Write the value 0x7eadbeef into memory at 0x2004
> +    ;; i.e. offset 4 within the data buffer pointed to by
> +    ;; ((struct sk_buff *)r6)->data
> +    stw         [%r6+0x1004], 0xdeadbeef
> +
> +    ;; Now load data[4] into r0 using the ldabsw instruction
> +    ldabsw      0x4
> +
> +    ;; ...and compare to what we expect
> +    fail_ne32   %r0, 0xdeadbeef
> +
> +    ;; Repeat for a half-word (2-bytes)
> +    sth         [%r6+0x1008], 0x1234
> +    ldabsh      0x8
> +    fail_ne32   %r0, 0x1234
> +
> +    ;; Repeat for a single byte
> +    stb         [%r6+0x1010], 0x5a
> +    ldabsb      0x10
> +    fail_ne32   %r0, 0x5a
> +
> +    ;; Repeat for a double-word (8-byte)
> +    ;; (note: fail_ne macro uses r0, so copy to another r1 to compare)
> +    lddw        %r2, 0x1234deadbeef5678
> +    stxdw       [%r6+0x1018], %r2
> +    ldabsdw     0x18
> +    mov         %r1, %r0
> +    fail_ne     %r1, 0x1234deadbeef5678
> +
> +    ;; Now, we do the same for the indirect loads
> +    mov         %r7, 0x100
> +    stw         [%r6+0x1100], 0xfeedbeef
> +
> +    ldindw      %r7, 0x0
> +    fail_ne32   %r0, 0xfeedbeef
> +
> +    ;; half-word
> +    sth         [%r6+0x1104], 0x6789
> +    ldindh      %r7, 0x4
> +    fail_ne32   %r0, 0x6789
> +
> +    ;; byte
> +    stb         [%r6+0x1108], 0x5f
> +    ldindb      %r7, 0x8
> +    fail_ne32   %r0, 0x5f
> +
> +    ;; double-word
> +    lddw        %r2, 0xcafe12345678d00d
> +    stxdw       [%r6+0x1110], %r2
> +    ldinddw     %r7, 0x10
> +    mov         %r1, %r0
> +    fail_ne     %r1, 0xcafe12345678d00d
> +
> +    pass
> diff --git a/sim/testsuite/sim/bpf/mem.s b/sim/testsuite/sim/bpf/mem.s
> new file mode 100644
> index 0000000000..2dea57d227
> --- /dev/null
> +++ b/sim/testsuite/sim/bpf/mem.s
> @@ -0,0 +1,56 @@
> +# mach: bpf
> +# output: pass\nexit 0 (0x0)\n
> +;;; mem.s
> +;;; Tests for BPF memory (ldx, stx, ..) instructions in simulator
> +
> +    .include "testutils.inc"
> +
> +    .text
> +    .global main
> +    .type main, @function
> +main:  
> +    lddw        %r1, 0x1234deadbeef5678
> +    mov         %r2, 0x1000
> +
> +    ;; basic store/load check
> +    stxb        [%r2+0], %r1
> +    stxh        [%r2+2], %r1
> +    stxw        [%r2+4], %r1
> +    stxdw       [%r2+8], %r1
> +
> +    stb         [%r2+16], 0x5a
> +    sth         [%r2+18], 0xcafe
> +    stw         [%r2+20], 0xbeefface
> +    stdw        [%r2+24], 0x7eadbeef
> +
> +    ldxb        %r1, [%r2+16]
> +    fail_ne     %r1, 0x5a
> +    ldxh        %r1, [%r2+18]
> +    fail_ne     %r1, 0xffffffffffffcafe
> +    ldxw        %r1, [%r2+20]
> +    fail_ne     %r1, 0xffffffffbeefface
> +    ldxdw       %r1, [%r2+24]
> +    fail_ne     %r1, 0x7eadbeef
> +
> +    ldxb        %r3, [%r2+0]
> +    fail_ne     %r3, 0x78
> +    ldxh        %r3, [%r2+2]
> +    fail_ne     %r3, 0x5678
> +    ldxw        %r3, [%r2+4]
> +    fail_ne     %r3, 0xffffffffbeef5678
> +    ldxdw       %r3, [%r2+8]
> +    fail_ne     %r3, 0x1234deadbeef5678
> +
> +    ldxw        %r4, [%r2+10]
> +    fail_ne     %r4, 0xffffffffdeadbeef
> +
> +    ;; negative offsets
> +    add         %r2, 16
> +    ldxh        %r5, [%r2+-14]
> +    fail_ne     %r5, 0x5678
> +    ldxw        %r5, [%r2+-12]
> +    fail_ne     %r5, 0xffffffffbeef5678
> +    ldxdw       %r5, [%r2+-8]
> +    fail_ne     %r5, 0x1234deadbeef5678
> +
> +    pass
> diff --git a/sim/testsuite/sim/bpf/mov.s b/sim/testsuite/sim/bpf/mov.s
> new file mode 100644
> index 0000000000..6665450468
> --- /dev/null
> +++ b/sim/testsuite/sim/bpf/mov.s
> @@ -0,0 +1,54 @@
> +# mach: bpf
> +# output: pass\nexit 0 (0x0)\n
> +;; mov.s
> +;; Tests for mov and mov32 instructions
> +
> +    .include "testutils.inc"
> +
> +    .text
> +    .global main
> +    .type main, @function
> +main:
> +    ;; some basic sanity checks
> +    mov32       %r1, 5
> +    fail_ne     %r1, 5
> +
> +    mov32       %r2, %r1
> +    fail_ne     %r2, 5
> +
> +    mov         %r2, %r1
> +    fail_ne     %r2, 5
> +
> +    mov         %r1, -666
> +    fail_ne     %r1, -666
> +
> +    ;; should NOT sign extend
> +    mov32       %r1, -1
> +    fail_ne     %r1, 0x00000000ffffffff
> +
> +    ;; should sign extend
> +    mov         %r2, -1
> +    fail_ne     %r2, 0xffffffffffffffff
> +
> +    mov         %r3, 0x80000000
> +
> +    ;; should NOT sign extend
> +    mov32       %r4, %r3
> +    fail_ne     %r4, 0x0000000080000000
> +
> +    ;; should sign extend
> +    mov         %r5, %r3
> +    fail_ne     %r5, 0xffffffff80000000
> +
> +    mov32       %r1, -2147483648
> +    mov32       %r1, %r1
> +    fail_ne32   %r1, -2147483648
> +
> +    ;; casting shenanigans
> +    mov         %r1, %r1
> +    fail_ne     %r1, +2147483648
> +    mov32       %r2, -1
> +    mov         %r2, %r2
> +    fail_ne     %r2, +4294967295
> +
> +    pass
> diff --git a/sim/testsuite/sim/bpf/testutils.inc b/sim/testsuite/sim/bpf/testutils.inc
> new file mode 100644
> index 0000000000..d3d6b17b5b
> --- /dev/null
> +++ b/sim/testsuite/sim/bpf/testutils.inc
> @@ -0,0 +1,38 @@
> +
> +    ;; Print "pass\n" and 'exit 0'
> +    .macro      pass
> +    .data
> +mpass:
> +    .string "pass\n"
> +    .text
> +_pass:
> +    mov         %r1, mpass      ; point to "pass\n" string
> +    mov         %r2, 5          ; strlen mpass
> +    call        7               ; printk
> +    mov         %r0, 0          ;
> +    exit                        ; exit 0
> +    .endm
> +
> +;;; MACRO fail
> +;;; Exit with status 1
> +    .macro fail
> +    mov %r0, 1
> +    exit
> +    .endm
> +
> +;;; MACRO fail_ne32
> +;;; Exit with status 1 if \reg32 != \val
> +    .macro      fail_ne32 reg val
> +    jeq32       \reg, \val, 2
> +    mov         %r0, 1
> +    exit
> +    .endm
> +
> +;;; MACRO fail_ne
> +;;; Exit with status1 if \reg ne \val
> +    .macro      fail_ne reg val
> +    lddw        %r0, \val
> +    jeq         \reg, %r0, 2
> +    mov         %r0, 1
> +    exit
> +    .endm
> diff --git a/sim/testsuite/sim/bpf/xadd.s b/sim/testsuite/sim/bpf/xadd.s
> new file mode 100644
> index 0000000000..1ca7577145
> --- /dev/null
> +++ b/sim/testsuite/sim/bpf/xadd.s
> @@ -0,0 +1,44 @@
> +# mach: bpf
> +# output: pass\nexit 0 (0x0)\n
> +;;; xadd.s
> +;;; Tests for BPF atomic exchange-and-add instructions in simulator
> +;;;
> +;;; The xadd instructions (XADDW, XADDDW) operate on a memory location
> +;;; specified in $dst + offset16, atomically adding the value in $src.
> +;;;
> +;;; In the simulator, there isn't anything else happening. The atomic
> +;;; instructions are identical to a non-atomic load/add/store.
> +
> +    .include "testutils.inc"
> +   
> +    .text
> +    .global main
> +    .type main, @function
> +main:
> +    mov         %r1, 0x1000
> +    mov         %r2, 5
> +
> +    ;; basic xadd w
> +    stw         [%r1+0], 10
> +    xaddw       [%r1+0], %r2
> +    ldxw        %r3, [%r1+0]
> +    fail_ne     %r3, 15
> +
> +    ;; basic xadd dw
> +    stdw        [%r1+8], 42
> +    xadddw      [%r1+8], %r2
> +    ldxdw       %r3, [%r1+8]
> +    fail_ne     %r3, 47
> +
> +    ;; xadd w negative value
> +    mov         %r4, -1
> +    xaddw       [%r1+0], %r4
> +    ldxw        %r3, [%r1+0]
> +    fail_ne     %r3, 14
> +
> +    ;; xadd dw negative val
> +    xadddw      [%r1+8], %r4
> +    ldxdw       %r3, [%r1+8]
> +    fail_ne     %r3, 46
> +
> +    pass
> -- 
> 2.25.0.2.g232378479e
> 


  reply	other threads:[~2020-07-12  8:25 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-10 12:25 [PATCH V4 0/3] eBPF support Jose E. Marchesi
2020-07-10 12:25 ` [PATCH V4 1/3] gdb: support for eBPF Jose E. Marchesi
2020-07-10 12:38   ` Eli Zaretskii
2020-07-10 13:51   ` Simon Marchi
2020-07-10 14:29     ` Jose E. Marchesi
2020-07-10 14:49       ` Simon Marchi
2020-07-10 12:25 ` [PATCH V4 2/3] sim: eBPF simulator Jose E. Marchesi
2020-07-12  8:25   ` Andrew Burgess [this message]
2020-07-12 10:06     ` Jose E. Marchesi
2020-07-10 12:25 ` [PATCH V4 3/3] sim: generated files for the " Jose E. Marchesi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200712082503.GC2737@embecosm.com \
    --to=andrew.burgess@embecosm.com \
    --cc=gdb-patches@sourceware.org \
    --cc=jose.marchesi@oracle.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox