selftests/bpf: Fix build of callx tests with GCC

GCC doesn't support indirect calls in BPF:

  progs/verifier_callx.c: In function 'apply_op':
  progs/verifier_callx.c:977:1: error: indirect call in function, which are not supported by eBPF
  progs/verifier_callx_rodata.c: In function 'use_shape':
  progs/verifier_callx_rodata.c:746:1: error: indirect call in function, which are not supported by eBPF

Build verifier_callx, verifier_callx_rodata and callx_rodata progs
with clang only. Skip callx_rodata_lskel test when progs are built
with GCC.

Fixes: e9b22d5079 ("selftests/bpf: Add tests for callx")
Fixes: b018e998e6 ("selftests/bpf: Add tests for callx through pointers in read-only data")
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Tested-by: Ihor Solodrai <ihor.solodrai@linux.dev>
Link: https://patch.msgid.link/20260924182104.261823-1-alexei.starovoitov@gmail.com
This commit is contained in:
Alexei Starovoitov 2026-09-24 18:21:04 +00:00
parent ce5cbbef27
commit 7cd1f73b37
No known key found for this signature in database
4 changed files with 36 additions and 4 deletions

View File

@ -35,6 +35,12 @@ void test_callx_rodata_lskel(void)
if (!ASSERT_OK_PTR(skel, "open"))
return;
/* gcc doesn't support indirect calls */
if (skel->rodata->skip) {
test__skip();
goto out;
}
skel->rodata->bias = 7;
if (!ASSERT_OK(callx_rodata_lskel__load(skel), "load"))

View File

@ -1,16 +1,21 @@
// SPDX-License-Identifier: GPL-2.0
/* callx through pointers to functions in .rodata, loaded by light skeleton */
#include <stdbool.h>
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
typedef int (*op_fn)(int);
/* set by user space before the programs are loaded, it's in .rodata too */
const volatile int bias = 1;
int op_idx;
#ifdef __clang__
const volatile bool skip = false;
typedef int (*op_fn)(int);
static __noinline int add_bias(int x)
{
return x + bias;
@ -41,6 +46,25 @@ int both_ops(void *ctx)
return ops[1](ops[0](4));
}
#else
/* gcc doesn't support indirect calls */
const volatile bool skip = true;
SEC("socket")
int select_op(void *ctx)
{
return 0;
}
SEC("socket")
int both_ops(void *ctx)
{
return 0;
}
#endif
/* no callx here */
SEC("socket")
int read_bias(void *ctx)

View File

@ -6,7 +6,8 @@
#include "bpf_misc.h"
#include "../../../include/linux/filter.h"
#if defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64)
/* gcc doesn't support indirect calls */
#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64)) && defined(__clang__)
#define CALLX_INSN(DST, SRC, OFF, IMM) \
BPF_RAW_INSN(BPF_JMP | BPF_CALL | BPF_X, DST, SRC, OFF, IMM)

View File

@ -6,7 +6,8 @@
#include "bpf_misc.h"
#include "../../../include/linux/filter.h"
#if defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64)
/* gcc doesn't support indirect calls */
#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64)) && defined(__clang__)
/*
* Read-only data with pointers to functions, where the compiler puts tables