Hi Piyush.
> This patch adds new DejaGnu target board for BPF for runtime testing of > BPF programs using the `bpf-vmtest-tool` script in the contrib directory. > The kernel version used for the tests can be specified via KERNEL_VERSION, > for example: > make check-gcc RUNTESTFLAGS="--target_board=bpf bpf-torture.exp > KERNEL_VERSION=6.14" > > If not specified, the default kernel version used is 6.15. > > It also adds a new torture subdirectory for running torture tests on BPF > programs. > Passed tests covered in bpf.exp and bpf-torture.exp > > gcc/ChangeLog: > > * Makefile.in: Append boards directory to target boards search path. > > gcc/testsuite/ChangeLog: > > * boards/bpf.exp: New board for bpf-unknown-none target > * gcc.target/bpf/torture/bpf-testool-demo.c: New test. > * gcc.target/bpf/torture/bpf-torture.exp: New test. The board should be contributed to dejagnu rather than GCC. We already have a bpf-sim.exp board there. Project page: https://www.gnu.org/s/dejagnu Send patches to list: [email protected] (please CC me and David). Git repo: https://git.savannah.gnu.org/git/dejagnu.git or git://git.sv.gnu.org/dejagnu.git > Signed-off-by: Piyush Raj <[email protected]> > --- > gcc/Makefile.in | 1 + > gcc/testsuite/boards/bpf.exp | 123 ++++++++++++++++++ > .../gcc.target/bpf/torture/bpf-torture.exp | 46 +++++++ > .../bpf/torture/invalid-memory-access.c | 18 +++ > .../gcc.target/bpf/torture/trace_openat.c | 23 ++++ > 5 files changed, 211 insertions(+) > create mode 100644 gcc/testsuite/boards/bpf.exp > create mode 100644 gcc/testsuite/gcc.target/bpf/torture/bpf-torture.exp > create mode 100644 > gcc/testsuite/gcc.target/bpf/torture/invalid-memory-access.c > create mode 100644 gcc/testsuite/gcc.target/bpf/torture/trace_openat.c > > diff --git a/gcc/Makefile.in b/gcc/Makefile.in > index abf98aabac8..660ec3e0e78 100644 > --- a/gcc/Makefile.in > +++ b/gcc/Makefile.in > @@ -4653,6 +4653,7 @@ site.exp: ./config.status Makefile > fi > echo "set tmpdir $(objdir)/testsuite" >> ./site.tmp > @echo "set srcdir \"\$${srcdir}/testsuite\"" >> ./site.tmp > + @echo "lappend boards_dir \"\$${srcdir}/boards\"" >> ./site.tmp > @if [ "X$(ALT_CC_UNDER_TEST)" != "X" ] ; then \ > echo "set ALT_CC_UNDER_TEST \"$(ALT_CC_UNDER_TEST)\"" >> ./site.tmp; \ > else true; \ > diff --git a/gcc/testsuite/boards/bpf.exp b/gcc/testsuite/boards/bpf.exp > new file mode 100644 > index 00000000000..73722c778a5 > --- /dev/null > +++ b/gcc/testsuite/boards/bpf.exp > @@ -0,0 +1,123 @@ > +load_lib "standard.exp" > +set_board_info target_install {bpf-unknown-none} > +set_board_info generic_name bpf > +set_board_info mathlib "" > +unset_board_info isremote > +set_board_info isremote "0" > + > + > +if {![info exists KERNEL_VERSION]} { > + set KERNEL_VERSION 6.15 > + verbose -log "Using default kernel version: $KERNEL_VERSION" 1 > +} > + > +if {![info exists LOG_LEVEL]} { > + set LOG_LEVEL ERROR > + verbose -log "Using default log level: $LOG_LEVEL" 1 > +} > + > +proc bpf_compile {source destfile type options} { > + > + if { $type == "executable" } { > + return [bpf_target_compile $source $destfile $type $options] > + } > + return [default_target_compile $source $destfile $type $options] > +} > + > +proc bpf_target_compile {source destfile type options} { > + > + global srcdir > + global KERNEL_VERSION > + global LOG_LEVEL > + set python3 [find_python3] > + if {$python3 == ""} { > + error "Cannot find python3 in $PATH" > + } > + set script_path "$srcdir/../../contrib/bpf-vmtest-tool/main.py" > + set opts "" > + foreach i $options { > + if {[regexp "^compiler=" $i]} { > + regsub "^compiler=" $i "" tmp > + if { $tmp eq "" } { > + return "bpf_target_compile: No compiler to compile with" > + } > + set compiler [ lindex [split $tmp " "] 0 ] > + set compiler_flags [ lindex [split $tmp " "] 1 ] > + append opts " $compiler_flags" > + } > + > + if {[regexp "^additional_flags=" $i]} { > + regsub "^additional_flags=" $i "" tmp > + set tmp [string trim $tmp] > + append opts " $tmp" > + } > + } > + > + set opts [string trim $opts] > + > + setenv BPF_CFLAGS $opts > + setenv BPF_CC $compiler > + set args [list $script_path --log-level $LOG_LEVEL bpf compile $source > -k $KERNEL_VERSION -o $destfile ] > + set status [remote_exec host $python3 $args] > + set exit_code [lindex $status 0] > + set output [lindex $status 1] > + unsetenv BPF_CFLAGS > + unsetenv BPF_CC > + > + if { $exit_code < 0 } { > + verbose -log "Couldn't compile $source: $output" > + return $output > + } > + > + verbose -log "Executed $source, exit_code $exit_code" > + if {$output ne ""} { > + verbose -log -- $output 2 > + } > + > + return $output > +} > + > +proc bpf_load {dest prog args} { > + global srcdir > + global KERNEL_VERSION > + global LOG_LEVEL > + # Construct command > + set python3 [find_python3] > + if {$python3 == ""} { > + error "Cannot find python3 in $PATH" > + } > + set script_path "$srcdir/../../contrib/bpf-vmtest-tool/main.py" > + set bpf_object $prog > + > + set args [list $script_path --log-level $LOG_LEVEL vmtest -k > $KERNEL_VERSION --bpf-obj $prog ] > + set status [remote_exec $dest $python3 $args] > + set exit_code [lindex $status 0] > + set output [lindex $status 1] > + > + if { $exit_code < 0 } { > + verbose -log "Couldn't execute $prog: $output" > + return "unresolved" > + } > + > + verbose -log "Executed $prog, exit_code $exit_code" > + if {$output ne ""} { > + verbose -log -- $output 2 > + } > + > + if { $exit_code == 0 } { > + return [list "pass" $output] > + } else { > + return [list "fail" $output] > + } > +} > + > + > +proc find_python3 {} { > + foreach candidate {python3 python} { > + set path [which $candidate] > + if {$path != ""} { > + return $path > + } > + } > + return "" > +} > \ No newline at end of file > diff --git a/gcc/testsuite/gcc.target/bpf/torture/bpf-torture.exp > b/gcc/testsuite/gcc.target/bpf/torture/bpf-torture.exp > new file mode 100644 > index 00000000000..ad5fa58fdc3 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/bpf/torture/bpf-torture.exp > @@ -0,0 +1,46 @@ > +# Copyright (C) 2019-2025 Free Software Foundation, Inc. > + > +# 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 GCC; see the file COPYING3. If not see > +# <http://www.gnu.org/licenses/>. > + > +# GCC testsuite that uses the `dg.exp' driver. > + > +# Exit immediately if this isn't an eBPF target. > +if ![istarget bpf-*-*] then { > + return > +} > + > +# Default values for torture testing > +set TORTURE_OPTIONS [ list {-O1 -g} {-O2 -g} {-O3 -g} ] > +set LTO_TORTURE_OPTIONS "" > + > +# Load support procs. > +load_lib gcc-dg.exp > + > +# If a testcase doesn't have special options, use these. > +global DEFAULT_CFLAGS > +if ![info exists DEFAULT_CFLAGS] then { > + set DEFAULT_CFLAGS "-Wall -Werror" > +} > + > +# Initialize `dg'. > +dg-init > + > + > +# Main loop. > +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \ > + "" $DEFAULT_CFLAGS > + > +# All done. > +dg-finish > diff --git a/gcc/testsuite/gcc.target/bpf/torture/invalid-memory-access.c > b/gcc/testsuite/gcc.target/bpf/torture/invalid-memory-access.c > new file mode 100644 > index 00000000000..d0bfe8a0009 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/bpf/torture/invalid-memory-access.c > @@ -0,0 +1,18 @@ > +// { dg-do run { xfail *-*-* } } > + > +#include "vmlinux.h" > +#include <bpf/bpf_helpers.h> > +#include <bpf/bpf_tracing.h> > + > +char LICENSE[] SEC("license") = "GPL"; > + > +SEC("tracepoint/syscalls/sys_enter_openat") > +int bpf_prog(struct trace_event_raw_sys_enter *ctx) { > + int arr[4] = {1, 2, 3, 4}; > + > + // Invalid memory access: out-of-bounds > + int val = arr[5]; // This causes the verifier to fail > + > + return val; > +} > + > diff --git a/gcc/testsuite/gcc.target/bpf/torture/trace_openat.c > b/gcc/testsuite/gcc.target/bpf/torture/trace_openat.c > new file mode 100644 > index 00000000000..96f454bba84 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/bpf/torture/trace_openat.c > @@ -0,0 +1,23 @@ > +// { dg-do run } > + > +#include "vmlinux.h" > +#include <bpf/bpf_helpers.h> > +#include <bpf/bpf_tracing.h> > +#include <bpf/bpf_core_read.h> > + > +char LICENSE[] SEC("license") = "GPL"; > + > +int example_pid = 0; > + > +SEC("tracepoint/syscalls/sys_enter_openat") > +int handle_openat(struct trace_event_raw_sys_enter *ctx) > +{ > + int pid = bpf_get_current_pid_tgid() >> 32; > + char filename[256]; // filename buffer > + bpf_probe_read_user(&filename, sizeof(filename), (void *)ctx->args[1]); > + bpf_printk("sys_enter_openat() called from PID %d for file: %s\n", pid, > filename); > + > + return 0; > +} > + > +/* { dg-output "BPF programs successfully loaded" } */
