All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH bpf-next v1 0/8] bpftool: Per-record CO-RE attributes in the C dump
@ 2026-10-16  0:00 Ihor Solodrai
  2026-10-16  0:00 ` [PATCH bpf-next v1 1/8] bpftool: Dump C from a detached BTF copy Ihor Solodrai
                   ` (7 more replies)
  0 siblings, 8 replies; 20+ messages in thread
From: Ihor Solodrai @ 2026-10-16  0:00 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Kumar Kartikeya Dwivedi, Quentin Monnet
  Cc: bpf, Alan Maguire, Cupertino Miranda, David Faust, Ian Rogers,
	Jose E . Marchesi, Vineet Gupta, Yonghong Song

bpftool's C dump wraps its output in a clang attribute pragma:

  #pragma clang attribute push (__attribute__((preserve_access_index)), apply_to = record)

GCC-BPF implements preserve_access_index, but not the pragma. Since
the commit 675b4e24bc50 ("bpf: Temporarily define
BPF_NO_PRESEVE_ACCESS_INDEX for GCC") the BPF selftests build GCC
objects with -DBPF_NO_PRESERVE_ACCESS_INDEX, which drops CO-RE from
vmlinux.h altogether.

This series replaces the pragma with an explicit attribute on each
record definition, and uses the same mechanism to annotate the context
types that the verifier rewrites with preserve_static_offset.

Jose proposed per-record attributes in May 2024 [1]. It stalled on a
requirement from preserve_static_offset (PSO) work [2] to add
attributes on selected types only, which a fixed string cannot
express.

BTF decl tags can carry an arbitrary attribute list since commit
51d1b1d42841 ("libbpf: Introduce kflag for type_tags and decl_tags in
BTF"), and btf_dump renders them on record definitions, since
76ea31239021 ("libbpf: Render decl_tags in btf_dump"). This allows
bpftool put any attribute on any subset of records, with no new libbpf
API changes.

[1] https://lore.kernel.org/bpf/20240503111836.25275-1-jose.marchesi@oracle.com/
[2] https://lore.kernel.org/bpf/20231208000531.19179-1-eddyz87@gmail.com/

---

Ihor Solodrai (8):
  bpftool: Dump C from a detached BTF copy
  selftests/bpf: Cover unknown BTF header-extension bytes in btf dump
  bpftool: Apply __bpf_core_pai per record on BTF dump
  bpftool: Skip __bpf_core_pai on verifier-rewritten context types
  bpftool: Emit __bpf_core_pso on verifier-rewritten context types
  selftests/bpf: Cover record attributes in bpftool BTF dumps
  selftests/bpf: Cover context and socket accesses through vmlinux.h
  bpftool: Document __bpf_core_pai and __bpf_core_pso

 .../bpf/bpftool/Documentation/bpftool-btf.rst |  18 ++
 tools/bpf/bpftool/btf.c                       | 174 ++++++++++++++++--
 .../bpf/bpftool_btf_dump_sorted.expected      |  48 ++++-
 .../bpf/bpftool_btf_dump_unsorted.expected    |  48 ++++-
 .../bpf/prog_tests/bpftool_btf_dump.c         | 102 +++++++++-
 .../selftests/bpf/prog_tests/verifier.c       |   2 +
 .../bpf/progs/verifier_ctx_rewritten.c        |  59 ++++++
 7 files changed, 417 insertions(+), 34 deletions(-)
 create mode 100644 tools/testing/selftests/bpf/progs/verifier_ctx_rewritten.c


base-commit: 7f34009230b796a06198da2c7204fd4efab9a2a1
-- 
2.56.0


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH bpf-next v1 1/8] bpftool: Dump C from a detached BTF copy
  2026-10-16  0:00 [PATCH bpf-next v1 0/8] bpftool: Per-record CO-RE attributes in the C dump Ihor Solodrai
@ 2026-10-16  0:00 ` Ihor Solodrai
  2026-10-16  1:18   ` Alexei Starovoitov
  2026-10-16  9:25   ` Alan Maguire
  2026-10-16  0:00 ` [PATCH bpf-next v1 2/8] selftests/bpf: Cover unknown BTF header-extension bytes in btf dump Ihor Solodrai
                   ` (6 subsequent siblings)
  7 siblings, 2 replies; 20+ messages in thread
From: Ihor Solodrai @ 2026-10-16  0:00 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Kumar Kartikeya Dwivedi, Quentin Monnet
  Cc: bpf, Alan Maguire, Cupertino Miranda, David Faust, Ian Rogers,
	Jose E . Marchesi, Vineet Gupta, Yonghong Song

To emit per-record attributes in the C dump, bpftool needs to add decl
tags to the BTF it dumps.

Modifying the parsed BTF fails for some valid input: libbpf refuses to
modify BTF whose header carries unknown nonzero extension bytes, so
such a dump would stop with -EOPNOTSUPP.

Dump from a flat copy built with btf__add_type(), which only requires
the destination to be modifiable. Appending types in ID order preserves
every reference, including when flattening split BTF. Carry the pointer
size so cross-architecture input keeps its layout: btf__new_empty()
assumes the host's. The layout section is not copied, since btf_dump
does not consult it.

The C output is unchanged on vmlinux, split module BTF, object files
and root_id dumps.

Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 tools/bpf/bpftool/btf.c | 48 ++++++++++++++++++++++++++++++++++++-----
 1 file changed, 43 insertions(+), 5 deletions(-)

diff --git a/tools/bpf/bpftool/btf.c b/tools/bpf/bpftool/btf.c
index abd661db91e6..cc15989643cf 100644
--- a/tools/bpf/bpftool/btf.c
+++ b/tools/bpf/bpftool/btf.c
@@ -1092,17 +1092,53 @@ static struct sort_datum *sort_btf_c(const struct btf *btf)
 	return datums;
 }
 
+static struct btf *btf_c_detached_copy(const struct btf *src)
+{
+	struct btf *copy;
+	size_t ptr_sz;
+	__u32 i, cnt;
+	int err;
+
+	copy = btf__new_empty();
+	if (!copy)
+		return NULL;
+
+	/* Retain the native default if the pointer size cannot be inferred. */
+	ptr_sz = btf__pointer_size(src);
+	if (ptr_sz)
+		btf__set_pointer_size(copy, ptr_sz);
+
+	cnt = btf__type_cnt(src);
+	for (i = 1; i < cnt; i++) {
+		err = btf__add_type(copy, src, btf__type_by_id(src, i));
+		if (err < 0) {
+			btf__free(copy);
+			errno = -err;
+			return NULL;
+		}
+	}
+
+	return copy;
+}
+
 static int dump_btf_c(const struct btf *btf,
 		      __u32 *root_type_ids, int root_type_cnt, bool sort_dump)
 {
 	struct sort_datum *datums = NULL;
+	struct btf *copy;
 	struct btf_dump *d;
 	int err = 0, i;
 
-	d = btf_dump__new(btf, btf_dump_printf, NULL, NULL);
-	if (!d)
+	copy = btf_c_detached_copy(btf);
+	if (!copy)
 		return -errno;
 
+	d = btf_dump__new(copy, btf_dump_printf, NULL, NULL);
+	if (!d) {
+		err = -errno;
+		goto done_free;
+	}
+
 	printf("#ifndef __VMLINUX_H__\n");
 	printf("#define __VMLINUX_H__\n");
 	printf("\n");
@@ -1130,10 +1166,10 @@ static int dump_btf_c(const struct btf *btf,
 				goto done;
 		}
 	} else {
-		int cnt = btf__type_cnt(btf);
+		int cnt = btf__type_cnt(copy);
 
 		if (sort_dump)
-			datums = sort_btf_c(btf);
+			datums = sort_btf_c(copy);
 		for (i = 0; i < cnt; i++) {
 			int idx = datums ? datums[i].index : i;
 
@@ -1146,7 +1182,7 @@ static int dump_btf_c(const struct btf *btf,
 				goto done;
 		}
 
-		err = dump_btf_kfuncs(d, btf);
+		err = dump_btf_kfuncs(d, copy);
 		if (err)
 			goto done;
 	}
@@ -1160,6 +1196,8 @@ static int dump_btf_c(const struct btf *btf,
 done:
 	free(datums);
 	btf_dump__free(d);
+done_free:
+	btf__free(copy);
 	return err;
 }
 
-- 
2.56.0


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH bpf-next v1 2/8] selftests/bpf: Cover unknown BTF header-extension bytes in btf dump
  2026-10-16  0:00 [PATCH bpf-next v1 0/8] bpftool: Per-record CO-RE attributes in the C dump Ihor Solodrai
  2026-10-16  0:00 ` [PATCH bpf-next v1 1/8] bpftool: Dump C from a detached BTF copy Ihor Solodrai
@ 2026-10-16  0:00 ` Ihor Solodrai
  2026-10-16  0:00 ` [PATCH bpf-next v1 3/8] bpftool: Apply __bpf_core_pai per record on BTF dump Ihor Solodrai
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 20+ messages in thread
From: Ihor Solodrai @ 2026-10-16  0:00 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Kumar Kartikeya Dwivedi, Quentin Monnet
  Cc: bpf, Alan Maguire, Cupertino Miranda, David Faust, Ian Rogers,
	Jose E . Marchesi, Vineet Gupta, Yonghong Song

libbpf can parse BTF with a header carrying unknown nonzero extension
bytes, but refuses to modify it. bpftool dumps C from a detached copy
so that it can modify BTF before dump.

It is expected for a C dump of a BTF with extension bytes to match the
dump of the same BTF without them, but there is no test for this.

Add a test case to bpftool_btf_dump to cover it.

Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 .../bpf/prog_tests/bpftool_btf_dump.c         | 55 ++++++++++++++++---
 1 file changed, 48 insertions(+), 7 deletions(-)

diff --git a/tools/testing/selftests/bpf/prog_tests/bpftool_btf_dump.c b/tools/testing/selftests/bpf/prog_tests/bpftool_btf_dump.c
index 534aa79a4278..9104c059a315 100644
--- a/tools/testing/selftests/bpf/prog_tests/bpftool_btf_dump.c
+++ b/tools/testing/selftests/bpf/prog_tests/bpftool_btf_dump.c
@@ -109,17 +109,11 @@ static struct btf *mk_loc_btf(void)
 	return btf;
 }
 
-static int btf_to_tmpfile(const struct btf *btf, char *path)
+static int raw_to_tmpfile(const void *raw, __u32 sz, char *path)
 {
 	ssize_t written;
-	const void *raw;
-	__u32 sz;
 	int fd;
 
-	raw = btf__raw_data(btf, &sz);
-	if (!ASSERT_OK_PTR(raw, "raw_data"))
-		return -1;
-
 	snprintf(path, PATH_MAX, "/tmp/bpftool_btf_dump.XXXXXX");
 	fd = mkstemp(path);
 	if (!ASSERT_OK_FD(fd, "mkstemp_btf"))
@@ -135,6 +129,18 @@ static int btf_to_tmpfile(const struct btf *btf, char *path)
 	return 0;
 }
 
+static int btf_to_tmpfile(const struct btf *btf, char *path)
+{
+	const void *raw;
+	__u32 sz;
+
+	raw = btf__raw_data(btf, &sz);
+	if (!ASSERT_OK_PTR(raw, "raw_data"))
+		return -1;
+
+	return raw_to_tmpfile(raw, sz, path);
+}
+
 static char *dump_c(const char *btf_path, bool sorted)
 {
 	char args[MAX_BPFTOOL_CMD_LEN];
@@ -262,6 +268,39 @@ static void test_loc_dump(const char *btf_path)
 	free(dump);
 }
 
+static void test_hdr_extra(const struct btf *btf)
+{
+	const __u32 extra_sz = 4;
+	char path[PATH_MAX];
+	__u32 hdr_len, sz;
+	const void *raw;
+	char *ext;
+	int err;
+
+	raw = btf__raw_data(btf, &sz);
+	if (!ASSERT_OK_PTR(raw, "raw_data"))
+		return;
+
+	hdr_len = ((const struct btf_header *)raw)->hdr_len;
+
+	ext = calloc(1, sz + extra_sz);
+	if (!ASSERT_OK_PTR(ext, "alloc_ext"))
+		return;
+
+	memcpy(ext, raw, hdr_len);
+	ext[hdr_len] = 0xA5; /* any nonzero value */
+	memcpy(ext + hdr_len + extra_sz, raw + hdr_len, sz - hdr_len);
+	((struct btf_header *)ext)->hdr_len = hdr_len + extra_sz;
+
+	err = raw_to_tmpfile(ext, sz + extra_sz, path);
+	free(ext);
+	if (err)
+		return;
+
+	test_dump(path, true);
+	unlink(path);
+}
+
 void test_bpftool_btf_dump(void)
 {
 	char path[PATH_MAX];
@@ -278,6 +317,8 @@ void test_bpftool_btf_dump(void)
 		test_dump(path, true);
 	if (test__start_subtest("c_unsorted"))
 		test_dump(path, false);
+	if (test__start_subtest("hdr_extra"))
+		test_hdr_extra(btf);
 	unlink(path);
 
 	btf__free(btf);
-- 
2.56.0


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH bpf-next v1 3/8] bpftool: Apply __bpf_core_pai per record on BTF dump
  2026-10-16  0:00 [PATCH bpf-next v1 0/8] bpftool: Per-record CO-RE attributes in the C dump Ihor Solodrai
  2026-10-16  0:00 ` [PATCH bpf-next v1 1/8] bpftool: Dump C from a detached BTF copy Ihor Solodrai
  2026-10-16  0:00 ` [PATCH bpf-next v1 2/8] selftests/bpf: Cover unknown BTF header-extension bytes in btf dump Ihor Solodrai
@ 2026-10-16  0:00 ` Ihor Solodrai
  2026-10-16  0:39   ` bot+bpf-ci
  2026-10-16  1:17   ` Alexei Starovoitov
  2026-10-16  0:00 ` [PATCH bpf-next v1 4/8] bpftool: Skip __bpf_core_pai on verifier-rewritten context types Ihor Solodrai
                   ` (4 subsequent siblings)
  7 siblings, 2 replies; 20+ messages in thread
From: Ihor Solodrai @ 2026-10-16  0:00 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Kumar Kartikeya Dwivedi, Quentin Monnet
  Cc: bpf, Alan Maguire, Cupertino Miranda, David Faust, Ian Rogers,
	Jose E . Marchesi, Vineet Gupta, Yonghong Song

bpftool wraps the C dump in a clang attribute pragma that applies
preserve_access_index to every struct and union, so field accesses
through vmlinux.h types get CO-RE relocations. GCC-BPF supports the
attribute but not the pragma, so it gets no CO-RE from the header.

Jose proposed replacing the Clang pragmas with per-record attributes
in May 2024 [1]. The declaration attribute support in btf_dump [2]
now provides the per-type control discussed in that thread.

Apply the attribute to each struct and union definition instead, as
kflagged decl tags on the detached BTF copy, rendered by btf_dump. The
tags use the __bpf_core_pai macro, which expands to
preserve_access_index where supported and to nothing under
BPF_NO_PRESERVE_ACCESS_INDEX.

The attribute covers the same records as the pragma, so Clang output
is unchanged.

[1]: https://lore.kernel.org/bpf/20240503111836.25275-1-jose.marchesi@oracle.com/
[2]: https://lore.kernel.org/bpf/20260929234608.48503-1-ihor.solodrai@linux.dev/

Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 tools/bpf/bpftool/btf.c                       | 34 +++++++++++++++----
 .../bpf/bpftool_btf_dump_sorted.expected      | 16 ++++-----
 .../bpf/bpftool_btf_dump_unsorted.expected    | 16 ++++-----
 3 files changed, 44 insertions(+), 22 deletions(-)

diff --git a/tools/bpf/bpftool/btf.c b/tools/bpf/bpftool/btf.c
index cc15989643cf..6182f2c41db0 100644
--- a/tools/bpf/bpftool/btf.c
+++ b/tools/bpf/bpftool/btf.c
@@ -1121,6 +1121,24 @@ static struct btf *btf_c_detached_copy(const struct btf *src)
 	return copy;
 }
 
+static int btf_c_annotate_records(struct btf *btf)
+{
+	__u32 i, cnt = btf__type_cnt(btf);
+	int err;
+
+	for (i = 1; i < cnt; i++) {
+		const struct btf_type *t = btf__type_by_id(btf, i);
+
+		if (!btf_is_composite(t))
+			continue;
+		err = btf__add_decl_attr(btf, "__bpf_core_pai", i, -1);
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
+}
+
 static int dump_btf_c(const struct btf *btf,
 		      __u32 *root_type_ids, int root_type_cnt, bool sort_dump)
 {
@@ -1133,6 +1151,10 @@ static int dump_btf_c(const struct btf *btf,
 	if (!copy)
 		return -errno;
 
+	err = btf_c_annotate_records(copy);
+	if (err)
+		goto done_free;
+
 	d = btf_dump__new(copy, btf_dump_printf, NULL, NULL);
 	if (!d) {
 		err = -errno;
@@ -1142,8 +1164,12 @@ static int dump_btf_c(const struct btf *btf,
 	printf("#ifndef __VMLINUX_H__\n");
 	printf("#define __VMLINUX_H__\n");
 	printf("\n");
-	printf("#ifndef BPF_NO_PRESERVE_ACCESS_INDEX\n");
-	printf("#pragma clang attribute push (__attribute__((preserve_access_index)), apply_to = record)\n");
+	printf("#ifndef __bpf_core_pai\n");
+	printf("#if !defined(BPF_NO_PRESERVE_ACCESS_INDEX) && __has_attribute(preserve_access_index)\n");
+	printf("#define __bpf_core_pai preserve_access_index\n");
+	printf("#else\n");
+	printf("#define __bpf_core_pai\n");
+	printf("#endif\n");
 	printf("#endif\n\n");
 	printf("#ifndef __ksym\n");
 	printf("#define __ksym __attribute__((section(\".ksyms\")))\n");
@@ -1187,10 +1213,6 @@ static int dump_btf_c(const struct btf *btf,
 			goto done;
 	}
 
-	printf("#ifndef BPF_NO_PRESERVE_ACCESS_INDEX\n");
-	printf("#pragma clang attribute pop\n");
-	printf("#endif\n");
-	printf("\n");
 	printf("#endif /* __VMLINUX_H__ */\n");
 
 done:
diff --git a/tools/testing/selftests/bpf/bpftool_btf_dump_sorted.expected b/tools/testing/selftests/bpf/bpftool_btf_dump_sorted.expected
index 5470b2b43229..02c8fe8b4859 100644
--- a/tools/testing/selftests/bpf/bpftool_btf_dump_sorted.expected
+++ b/tools/testing/selftests/bpf/bpftool_btf_dump_sorted.expected
@@ -1,8 +1,12 @@
 #ifndef __VMLINUX_H__
 #define __VMLINUX_H__
 
-#ifndef BPF_NO_PRESERVE_ACCESS_INDEX
-#pragma clang attribute push (__attribute__((preserve_access_index)), apply_to = record)
+#ifndef __bpf_core_pai
+#if !defined(BPF_NO_PRESERVE_ACCESS_INDEX) && __has_attribute(preserve_access_index)
+#define __bpf_core_pai preserve_access_index
+#else
+#define __bpf_core_pai
+#endif
 #endif
 
 #ifndef __ksym
@@ -30,19 +34,15 @@ struct holey {
 	long: 32;
 	long: 32;
 	int tail;
-};
+} __attribute__((__bpf_core_pai));
 
 struct s {
 	int f;
-};
+} __attribute__((__bpf_core_pai));
 
 
 /* BPF kfuncs */
 #ifndef BPF_NO_KFUNC_PROTOTYPES
 #endif
 
-#ifndef BPF_NO_PRESERVE_ACCESS_INDEX
-#pragma clang attribute pop
-#endif
-
 #endif /* __VMLINUX_H__ */
diff --git a/tools/testing/selftests/bpf/bpftool_btf_dump_unsorted.expected b/tools/testing/selftests/bpf/bpftool_btf_dump_unsorted.expected
index 4310adc2ed51..9b6589d2bda3 100644
--- a/tools/testing/selftests/bpf/bpftool_btf_dump_unsorted.expected
+++ b/tools/testing/selftests/bpf/bpftool_btf_dump_unsorted.expected
@@ -1,8 +1,12 @@
 #ifndef __VMLINUX_H__
 #define __VMLINUX_H__
 
-#ifndef BPF_NO_PRESERVE_ACCESS_INDEX
-#pragma clang attribute push (__attribute__((preserve_access_index)), apply_to = record)
+#ifndef __bpf_core_pai
+#if !defined(BPF_NO_PRESERVE_ACCESS_INDEX) && __has_attribute(preserve_access_index)
+#define __bpf_core_pai preserve_access_index
+#else
+#define __bpf_core_pai
+#endif
 #endif
 
 #ifndef __ksym
@@ -26,7 +30,7 @@ struct holey {
 	long: 32;
 	long: 32;
 	int tail;
-};
+} __attribute__((__bpf_core_pai));
 
 enum {
 	E0 = 1,
@@ -34,15 +38,11 @@ enum {
 
 struct s {
 	int f;
-};
+} __attribute__((__bpf_core_pai));
 
 
 /* BPF kfuncs */
 #ifndef BPF_NO_KFUNC_PROTOTYPES
 #endif
 
-#ifndef BPF_NO_PRESERVE_ACCESS_INDEX
-#pragma clang attribute pop
-#endif
-
 #endif /* __VMLINUX_H__ */
-- 
2.56.0


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH bpf-next v1 4/8] bpftool: Skip __bpf_core_pai on verifier-rewritten context types
  2026-10-16  0:00 [PATCH bpf-next v1 0/8] bpftool: Per-record CO-RE attributes in the C dump Ihor Solodrai
                   ` (2 preceding siblings ...)
  2026-10-16  0:00 ` [PATCH bpf-next v1 3/8] bpftool: Apply __bpf_core_pai per record on BTF dump Ihor Solodrai
@ 2026-10-16  0:00 ` Ihor Solodrai
  2026-10-16  0:00 ` [PATCH bpf-next v1 5/8] bpftool: Emit __bpf_core_pso " Ihor Solodrai
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 20+ messages in thread
From: Ihor Solodrai @ 2026-10-16  0:00 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Kumar Kartikeya Dwivedi, Quentin Monnet
  Cc: bpf, Alan Maguire, Cupertino Miranda, David Faust, Ian Rogers,
	Jose E . Marchesi, Vineet Gupta, Yonghong Song

The verifier translates accesses to UAPI context and socket types,
such as __sk_buff and bpf_sock, into accesses to kernel structures.
It picks the kernel field by the instruction's offset and keeps the
base register. For example, in bpf_convert_ctx_access() [1]:

	switch (si->off) {
	...
	case offsetof(struct __sk_buff, mark):
		...
		*insn++ = BPF_LDX_MEM(BPF_W, si->dst_reg, si->src_reg,
				      bpf_target_off(struct sk_buff, mark,
						     4, target_size));

So these accesses require a load or store with an immediate offset from
an unmodified pointer. Their UAPI field offsets are fixed, so CO-RE
relocation is unnecessary. With preserve_access_index, Clang can instead
emit pointer arithmetic, for example for ((u8 *)&skb->mark)[1]. The
verifier then rejects an otherwise valid program.

Omit the attribute from the 13 such types when dumping C. Also omit it
from their nested anonymous records: keeping it there can root
relocations at an unnamed type, which libbpf cannot resolve.

The last addition to this set was bpf_sk_lookup, introduced in 2020 by
commit e9ddbb7707ff ("bpf: Introduce SK_LOOKUP program type with a
dedicated attach point"). Keep the set hardcoded in bpftool so the
exclusion also works with older kernels.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/core/filter.c?h=v7.2#n9939

Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 tools/bpf/bpftool/btf.c | 84 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 82 insertions(+), 2 deletions(-)

diff --git a/tools/bpf/bpftool/btf.c b/tools/bpf/bpftool/btf.c
index 6182f2c41db0..30f30314ec29 100644
--- a/tools/bpf/bpftool/btf.c
+++ b/tools/bpf/bpftool/btf.c
@@ -6,6 +6,7 @@
 #endif
 #include <errno.h>
 #include <fcntl.h>
+#include <linux/bitmap.h>
 #include <linux/err.h>
 #include <stdbool.h>
 #include <stdio.h>
@@ -1121,22 +1122,101 @@ static struct btf *btf_c_detached_copy(const struct btf *src)
 	return copy;
 }
 
+/*
+ * The verifier translates field accesses of some types into accesses
+ * to kernel structures, see bpf_convert_ctx_accesses().
+ * The translation keys on the immediate offset of each load or store,
+ * so offsets into these types must stay immediates.
+ */
+static const char * const btf_c_static_offset_types[] = {
+	"__sk_buff",
+	"bpf_perf_event_data",
+	"bpf_sk_lookup",
+	"bpf_sock",
+	"bpf_sock_addr",
+	"bpf_sock_ops",
+	"bpf_sockopt",
+	"bpf_sysctl",
+	"bpf_tcp_sock",
+	"bpf_xdp_sock",
+	"sk_msg_md",
+	"sk_reuseport_md",
+	"xdp_md",
+};
+
+static bool btf_c_needs_static_offset(const struct btf *btf, const struct btf_type *t)
+{
+	const char *name;
+	size_t i;
+
+	if (!btf_is_struct(t))
+		return false;
+
+	name = btf__name_by_offset(btf, t->name_off);
+	for (i = 0; i < ARRAY_SIZE(btf_c_static_offset_types); i++) {
+		if (!strcmp(name, btf_c_static_offset_types[i]))
+			return true;
+	}
+	return false;
+}
+
+/*
+ * Anonymous records within types that need static offsets must not start
+ * CO-RE access chains. Named records, typedefs and pointer targets are
+ * separate types.
+ */
+static void btf_c_mark_no_pai(const struct btf *btf, __u32 id, unsigned long *no_pai)
+{
+	const struct btf_type *t = btf__type_by_id(btf, id);
+	const struct btf_member *m = btf_members(t);
+	__u32 i;
+
+	__set_bit(id, no_pai);
+	for (i = 0; i < btf_vlen(t); i++, m++) {
+		const struct btf_type *mt;
+		__u32 mid = m->type;
+
+		mt = btf__type_by_id(btf, mid);
+		while (btf_is_array(mt) || btf_is_mod(mt)) {
+			mid = btf_is_array(mt) ? btf_array(mt)->type : mt->type;
+			mt = btf__type_by_id(btf, mid);
+		}
+		if (btf_is_composite(mt) && !mt->name_off && !test_bit(mid, no_pai))
+			btf_c_mark_no_pai(btf, mid, no_pai);
+	}
+}
+
 static int btf_c_annotate_records(struct btf *btf)
 {
 	__u32 i, cnt = btf__type_cnt(btf);
+	unsigned long *no_pai;
 	int err;
 
+	no_pai = bitmap_zalloc(cnt);
+	if (!no_pai)
+		return -ENOMEM;
+
+	for (i = 1; i < cnt; i++) {
+		if (btf_c_needs_static_offset(btf, btf__type_by_id(btf, i)))
+			btf_c_mark_no_pai(btf, i, no_pai);
+	}
+
 	for (i = 1; i < cnt; i++) {
 		const struct btf_type *t = btf__type_by_id(btf, i);
 
 		if (!btf_is_composite(t))
 			continue;
+		if (test_bit(i, no_pai))
+			continue;
 		err = btf__add_decl_attr(btf, "__bpf_core_pai", i, -1);
 		if (err < 0)
-			return err;
+			goto out;
 	}
 
-	return 0;
+	err = 0;
+out:
+	bitmap_free(no_pai);
+	return err;
 }
 
 static int dump_btf_c(const struct btf *btf,
-- 
2.56.0


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH bpf-next v1 5/8] bpftool: Emit __bpf_core_pso on verifier-rewritten context types
  2026-10-16  0:00 [PATCH bpf-next v1 0/8] bpftool: Per-record CO-RE attributes in the C dump Ihor Solodrai
                   ` (3 preceding siblings ...)
  2026-10-16  0:00 ` [PATCH bpf-next v1 4/8] bpftool: Skip __bpf_core_pai on verifier-rewritten context types Ihor Solodrai
@ 2026-10-16  0:00 ` Ihor Solodrai
  2026-10-16  1:27   ` Alexei Starovoitov
  2026-10-16  0:00 ` [PATCH bpf-next v1 6/8] selftests/bpf: Cover record attributes in bpftool BTF dumps Ihor Solodrai
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 20+ messages in thread
From: Ihor Solodrai @ 2026-10-16  0:00 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Kumar Kartikeya Dwivedi, Quentin Monnet
  Cc: bpf, Alan Maguire, Cupertino Miranda, David Faust, Ian Rogers,
	Jose E . Marchesi, Vineet Gupta, Yonghong Song

The verifier translates accesses to some UAPI context and socket types
into accesses to kernel structures. These accesses require an
unmodified base and an immediate field offset.

Leaving preserve_access_index off does not stop the compiler from
merging loads at different field offsets into one load through an
adjusted pointer. The verifier rejects the resulting program.

preserve_static_offset, available since Clang 18, preserves static
field offsets in load and store instruction immediates. Apply it to
the 13 types that need static offsets through __bpf_core_pso.

Eduard introduced PSO in Clang and proposed annotating BPF context
types in 2023 [1]. His v3 RFC [2] left pt_regs annotations in
architecture headers unresolved. However since commit de6c7d99f898
("bpf: Relax fixed offset check for PTR_TO_CTX"), program types without
convert_ctx_access() accept fixed offsets from modified context
pointers. pt_regs can now keep PAI, while PSO on bpf_perf_event_data
covers its regs member.

PSO creates no CO-RE relocations, so BPF_NO_PRESERVE_ACCESS_INDEX does
not disable it.

Clang 18 through 23 crash on __builtin_preserve_field_info over a PSO
record, including bpf_core_field_*() and the CO-RE bitfield helpers.
-D__bpf_core_pso= can disable PSO for affected programs.

[1]: https://lore.kernel.org/bpf/20231208000531.19179-1-eddyz87@gmail.com/
[2]: https://lore.kernel.org/bpf/20231220133411.22978-1-eddyz87@gmail.com/

Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 tools/bpf/bpftool/btf.c                          | 16 ++++++++++++++--
 .../bpf/bpftool_btf_dump_sorted.expected         |  8 ++++++++
 .../bpf/bpftool_btf_dump_unsorted.expected       |  8 ++++++++
 3 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/tools/bpf/bpftool/btf.c b/tools/bpf/bpftool/btf.c
index 30f30314ec29..fff2ea0a5c7e 100644
--- a/tools/bpf/bpftool/btf.c
+++ b/tools/bpf/bpftool/btf.c
@@ -1203,12 +1203,17 @@ static int btf_c_annotate_records(struct btf *btf)
 
 	for (i = 1; i < cnt; i++) {
 		const struct btf_type *t = btf__type_by_id(btf, i);
+		const char *attr;
 
 		if (!btf_is_composite(t))
 			continue;
-		if (test_bit(i, no_pai))
+		if (!test_bit(i, no_pai))
+			attr = "__bpf_core_pai";
+		else if (btf_c_needs_static_offset(btf, t))
+			attr = "__bpf_core_pso";
+		else
 			continue;
-		err = btf__add_decl_attr(btf, "__bpf_core_pai", i, -1);
+		err = btf__add_decl_attr(btf, attr, i, -1);
 		if (err < 0)
 			goto out;
 	}
@@ -1251,6 +1256,13 @@ static int dump_btf_c(const struct btf *btf,
 	printf("#define __bpf_core_pai\n");
 	printf("#endif\n");
 	printf("#endif\n\n");
+	printf("#ifndef __bpf_core_pso\n");
+	printf("#if __has_attribute(preserve_static_offset)\n");
+	printf("#define __bpf_core_pso preserve_static_offset\n");
+	printf("#else\n");
+	printf("#define __bpf_core_pso\n");
+	printf("#endif\n");
+	printf("#endif\n\n");
 	printf("#ifndef __ksym\n");
 	printf("#define __ksym __attribute__((section(\".ksyms\")))\n");
 	printf("#endif\n\n");
diff --git a/tools/testing/selftests/bpf/bpftool_btf_dump_sorted.expected b/tools/testing/selftests/bpf/bpftool_btf_dump_sorted.expected
index 02c8fe8b4859..7da4df1da207 100644
--- a/tools/testing/selftests/bpf/bpftool_btf_dump_sorted.expected
+++ b/tools/testing/selftests/bpf/bpftool_btf_dump_sorted.expected
@@ -9,6 +9,14 @@
 #endif
 #endif
 
+#ifndef __bpf_core_pso
+#if __has_attribute(preserve_static_offset)
+#define __bpf_core_pso preserve_static_offset
+#else
+#define __bpf_core_pso
+#endif
+#endif
+
 #ifndef __ksym
 #define __ksym __attribute__((section(".ksyms")))
 #endif
diff --git a/tools/testing/selftests/bpf/bpftool_btf_dump_unsorted.expected b/tools/testing/selftests/bpf/bpftool_btf_dump_unsorted.expected
index 9b6589d2bda3..f082da51d630 100644
--- a/tools/testing/selftests/bpf/bpftool_btf_dump_unsorted.expected
+++ b/tools/testing/selftests/bpf/bpftool_btf_dump_unsorted.expected
@@ -9,6 +9,14 @@
 #endif
 #endif
 
+#ifndef __bpf_core_pso
+#if __has_attribute(preserve_static_offset)
+#define __bpf_core_pso preserve_static_offset
+#else
+#define __bpf_core_pso
+#endif
+#endif
+
 #ifndef __ksym
 #define __ksym __attribute__((section(".ksyms")))
 #endif
-- 
2.56.0


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH bpf-next v1 6/8] selftests/bpf: Cover record attributes in bpftool BTF dumps
  2026-10-16  0:00 [PATCH bpf-next v1 0/8] bpftool: Per-record CO-RE attributes in the C dump Ihor Solodrai
                   ` (4 preceding siblings ...)
  2026-10-16  0:00 ` [PATCH bpf-next v1 5/8] bpftool: Emit __bpf_core_pso " Ihor Solodrai
@ 2026-10-16  0:00 ` Ihor Solodrai
  2026-10-16  0:00 ` [PATCH bpf-next v1 7/8] selftests/bpf: Cover context and socket accesses through vmlinux.h Ihor Solodrai
  2026-10-16  0:00 ` [PATCH bpf-next v1 8/8] bpftool: Document __bpf_core_pai and __bpf_core_pso Ihor Solodrai
  7 siblings, 0 replies; 20+ messages in thread
From: Ihor Solodrai @ 2026-10-16  0:00 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Kumar Kartikeya Dwivedi, Quentin Monnet
  Cc: bpf, Alan Maguire, Cupertino Miranda, David Faust, Ian Rogers,
	Jose E . Marchesi, Vineet Gupta, Yonghong Song

Types whose field accesses need static offsets carry __bpf_core_pso,
while their nested anonymous records must stay unannotated. Other
records retain __bpf_core_pai, including context types such as
bpf_nf_ctx whose accesses do not need static offsets.

Extend the existing C dump test fixture with selected context and
socket types and recursively nested anonymous unions.

Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 .../bpf/bpftool_btf_dump_sorted.expected      | 24 ++++++++++
 .../bpf/bpftool_btf_dump_unsorted.expected    | 24 ++++++++++
 .../bpf/prog_tests/bpftool_btf_dump.c         | 47 +++++++++++++++++++
 3 files changed, 95 insertions(+)

diff --git a/tools/testing/selftests/bpf/bpftool_btf_dump_sorted.expected b/tools/testing/selftests/bpf/bpftool_btf_dump_sorted.expected
index 7da4df1da207..ee093f08d123 100644
--- a/tools/testing/selftests/bpf/bpftool_btf_dump_sorted.expected
+++ b/tools/testing/selftests/bpf/bpftool_btf_dump_sorted.expected
@@ -37,6 +37,30 @@ enum {
 	E0 = 1,
 };
 
+struct __sk_buff {
+	int len;
+	union {
+		int sk;
+	};
+} __attribute__((__bpf_core_pso));
+
+struct bpf_nf_ctx {
+	int f;
+} __attribute__((__bpf_core_pai));
+
+struct bpf_sk_lookup {
+	union {
+		union {
+			int cookie;
+		};
+		int family;
+	};
+} __attribute__((__bpf_core_pso));
+
+struct bpf_tcp_sock {
+	int snd_cwnd;
+} __attribute__((__bpf_core_pso));
+
 struct holey {
 	int c;
 	long: 32;
diff --git a/tools/testing/selftests/bpf/bpftool_btf_dump_unsorted.expected b/tools/testing/selftests/bpf/bpftool_btf_dump_unsorted.expected
index f082da51d630..42233e435a04 100644
--- a/tools/testing/selftests/bpf/bpftool_btf_dump_unsorted.expected
+++ b/tools/testing/selftests/bpf/bpftool_btf_dump_unsorted.expected
@@ -48,6 +48,30 @@ struct s {
 	int f;
 } __attribute__((__bpf_core_pai));
 
+struct __sk_buff {
+	int len;
+	union {
+		int sk;
+	};
+} __attribute__((__bpf_core_pso));
+
+struct bpf_sk_lookup {
+	union {
+		union {
+			int cookie;
+		};
+		int family;
+	};
+} __attribute__((__bpf_core_pso));
+
+struct bpf_tcp_sock {
+	int snd_cwnd;
+} __attribute__((__bpf_core_pso));
+
+struct bpf_nf_ctx {
+	int f;
+} __attribute__((__bpf_core_pai));
+
 
 /* BPF kfuncs */
 #ifndef BPF_NO_KFUNC_PROTOTYPES
diff --git a/tools/testing/selftests/bpf/prog_tests/bpftool_btf_dump.c b/tools/testing/selftests/bpf/prog_tests/bpftool_btf_dump.c
index 9104c059a315..0277f054410c 100644
--- a/tools/testing/selftests/bpf/prog_tests/bpftool_btf_dump.c
+++ b/tools/testing/selftests/bpf/prog_tests/bpftool_btf_dump.c
@@ -20,6 +20,18 @@
  *	};
  *	enum { E0 = 1 };
  *	struct s { int f; };
+ *	struct __sk_buff {
+ *		int len;
+ *		union { int sk; };
+ *	};
+ *	struct bpf_sk_lookup {
+ *		union {
+ *			union { int cookie; };
+ *			int family;
+ *		};
+ *	};
+ *	struct bpf_tcp_sock { int snd_cwnd; };
+ *	struct bpf_nf_ctx { int f; };
  */
 static struct btf *mk_btf(void)
 {
@@ -42,6 +54,25 @@ static struct btf *mk_btf(void)
 	btf__add_struct(btf, "s", 4);
 	btf__add_field(btf, "f", 1, 0, 0);
 
+	btf__add_union(btf, NULL, 4);
+	btf__add_field(btf, "sk", 1, 0, 0);
+	btf__add_struct(btf, "__sk_buff", 8);
+	btf__add_field(btf, "len", 1, 0, 0);
+	btf__add_field(btf, NULL, 6, 32, 0);
+
+	btf__add_union(btf, NULL, 4);
+	btf__add_field(btf, "cookie", 1, 0, 0);
+	btf__add_union(btf, NULL, 4);
+	btf__add_field(btf, NULL, 8, 0, 0);
+	btf__add_field(btf, "family", 1, 0, 0);
+	btf__add_struct(btf, "bpf_sk_lookup", 4);
+	btf__add_field(btf, NULL, 9, 0, 0);
+
+	btf__add_struct(btf, "bpf_tcp_sock", 4);
+	btf__add_field(btf, "snd_cwnd", 1, 0, 0);
+	btf__add_struct(btf, "bpf_nf_ctx", 4);
+	btf__add_field(btf, "f", 1, 0, 0);
+
 	VALIDATE_RAW_BTF(
 		btf,
 		"[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
@@ -52,6 +83,22 @@ static struct btf *mk_btf(void)
 		"[4] ENUM '(anon)' encoding=UNSIGNED size=4 vlen=1\n"
 		"\t'E0' val=1",
 		"[5] STRUCT 's' size=4 vlen=1\n"
+		"\t'f' type_id=1 bits_offset=0",
+		"[6] UNION '(anon)' size=4 vlen=1\n"
+		"\t'sk' type_id=1 bits_offset=0",
+		"[7] STRUCT '__sk_buff' size=8 vlen=2\n"
+		"\t'len' type_id=1 bits_offset=0\n"
+		"\t'(anon)' type_id=6 bits_offset=32",
+		"[8] UNION '(anon)' size=4 vlen=1\n"
+		"\t'cookie' type_id=1 bits_offset=0",
+		"[9] UNION '(anon)' size=4 vlen=2\n"
+		"\t'(anon)' type_id=8 bits_offset=0\n"
+		"\t'family' type_id=1 bits_offset=0",
+		"[10] STRUCT 'bpf_sk_lookup' size=4 vlen=1\n"
+		"\t'(anon)' type_id=9 bits_offset=0",
+		"[11] STRUCT 'bpf_tcp_sock' size=4 vlen=1\n"
+		"\t'snd_cwnd' type_id=1 bits_offset=0",
+		"[12] STRUCT 'bpf_nf_ctx' size=4 vlen=1\n"
 		"\t'f' type_id=1 bits_offset=0");
 
 	return btf;
-- 
2.56.0


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH bpf-next v1 7/8] selftests/bpf: Cover context and socket accesses through vmlinux.h
  2026-10-16  0:00 [PATCH bpf-next v1 0/8] bpftool: Per-record CO-RE attributes in the C dump Ihor Solodrai
                   ` (5 preceding siblings ...)
  2026-10-16  0:00 ` [PATCH bpf-next v1 6/8] selftests/bpf: Cover record attributes in bpftool BTF dumps Ihor Solodrai
@ 2026-10-16  0:00 ` Ihor Solodrai
  2026-10-16  0:00 ` [PATCH bpf-next v1 8/8] bpftool: Document __bpf_core_pai and __bpf_core_pso Ihor Solodrai
  7 siblings, 0 replies; 20+ messages in thread
From: Ihor Solodrai @ 2026-10-16  0:00 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Kumar Kartikeya Dwivedi, Quentin Monnet
  Cc: bpf, Alan Maguire, Cupertino Miranda, David Faust, Ian Rogers,
	Jose E . Marchesi, Vineet Gupta, Yonghong Song

The generated vmlinux.h leaves __bpf_core_pai off the types whose field
accesses need static offsets and off their nested anonymous records,
and marks these types with __bpf_core_pso.

Some accesses fail to load if any part is missing. With __bpf_core_pai
on an anonymous member but not on its enclosing type, Clang roots the
CO-RE relocation at an unnamed type that libbpf cannot resolve. With
__bpf_core_pai on the type, a narrow field load can become pointer
arithmetic on the context pointer, which the verifier rejects. Without
__bpf_core_pso, merging field loads from two branches into one does the
same.

Cover each case with programs loaded through the generated header:
accesses through the anonymous unions of four context types, a narrow
skb->mark load, and a merged load where the compiler supports
preserve_static_offset.

Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 .../selftests/bpf/prog_tests/verifier.c       |  2 +
 .../bpf/progs/verifier_ctx_rewritten.c        | 59 +++++++++++++++++++
 2 files changed, 61 insertions(+)
 create mode 100644 tools/testing/selftests/bpf/progs/verifier_ctx_rewritten.c

diff --git a/tools/testing/selftests/bpf/prog_tests/verifier.c b/tools/testing/selftests/bpf/prog_tests/verifier.c
index c69c0f7e9cc8..56b626419ab6 100644
--- a/tools/testing/selftests/bpf/prog_tests/verifier.c
+++ b/tools/testing/selftests/bpf/prog_tests/verifier.c
@@ -41,6 +41,7 @@
 #include "verifier_const.skel.h"
 #include "verifier_const_or.skel.h"
 #include "verifier_ctx.skel.h"
+#include "verifier_ctx_rewritten.skel.h"
 #include "verifier_ctx_sk_msg.skel.h"
 #include "verifier_d_path.skel.h"
 #include "verifier_default_trusted_ptr.skel.h"
@@ -231,6 +232,7 @@ void test_verifier_cgroup_storage(void)       { RUN(verifier_cgroup_storage); }
 void test_verifier_const(void)                { RUN(verifier_const); }
 void test_verifier_const_or(void)             { RUN(verifier_const_or); }
 void test_verifier_ctx(void)                  { RUN_TESTS(verifier_ctx); }
+void test_verifier_ctx_rewritten(void)        { RUN_TESTS(verifier_ctx_rewritten); }
 void test_verifier_ctx_sk_msg(void)           { RUN(verifier_ctx_sk_msg); }
 void test_verifier_d_path(void)               { RUN(verifier_d_path); }
 void test_verifier_default_trusted_ptr(void)  { RUN_TESTS(verifier_default_trusted_ptr); }
diff --git a/tools/testing/selftests/bpf/progs/verifier_ctx_rewritten.c b/tools/testing/selftests/bpf/progs/verifier_ctx_rewritten.c
new file mode 100644
index 000000000000..33eb975a170a
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/verifier_ctx_rewritten.c
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <vmlinux.h>
+#include <bpf/bpf_helpers.h>
+#include "bpf_misc.h"
+
+SEC("tc")
+__success
+int skb_socket(struct __sk_buff *skb)
+{
+	struct bpf_sock *sk = skb->sk;
+
+	return sk ? sk->family : 0;
+}
+
+SEC("sockops")
+__success
+int sockops_args_reply(struct bpf_sock_ops *skops)
+{
+	skops->reply = skops->args[1];
+	return 0;
+}
+
+SEC("sk_msg")
+__success
+int sk_msg_data(struct sk_msg_md *msg)
+{
+	return msg->data < msg->data_end;
+}
+
+SEC("cgroup/getsockopt")
+__success
+int sockopt_optval(struct bpf_sockopt *ctx)
+{
+	return ctx->optval < ctx->optval_end;
+}
+
+SEC("tc")
+__success
+int skb_narrow_field(struct __sk_buff *skb)
+{
+	return ((__u8 *)&skb->mark)[1];
+}
+
+#if __has_attribute(preserve_static_offset)
+SEC("tc")
+__success
+int skb_merge_loads(struct __sk_buff *skb)
+{
+	__u32 value;
+
+	if (skb->len)
+		value = skb->pkt_type;
+	else
+		value = skb->mark;
+	return value;
+}
+#endif
+
+char _license[] SEC("license") = "GPL";
-- 
2.56.0


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH bpf-next v1 8/8] bpftool: Document __bpf_core_pai and __bpf_core_pso
  2026-10-16  0:00 [PATCH bpf-next v1 0/8] bpftool: Per-record CO-RE attributes in the C dump Ihor Solodrai
                   ` (6 preceding siblings ...)
  2026-10-16  0:00 ` [PATCH bpf-next v1 7/8] selftests/bpf: Cover context and socket accesses through vmlinux.h Ihor Solodrai
@ 2026-10-16  0:00 ` Ihor Solodrai
  7 siblings, 0 replies; 20+ messages in thread
From: Ihor Solodrai @ 2026-10-16  0:00 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Kumar Kartikeya Dwivedi, Quentin Monnet
  Cc: bpf, Alan Maguire, Cupertino Miranda, David Faust, Ian Rogers,
	Jose E . Marchesi, Vineet Gupta, Yonghong Song

The C dump annotates records with the __bpf_core_pai and
__bpf_core_pso macros. Programs control the attributes through these
macros and BPF_NO_PRESERVE_ACCESS_INDEX, which disables only
__bpf_core_pai.

Update bpftool documentation to explain __bpf_core_pai and
__bpf_core_pso macros.

Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 .../bpf/bpftool/Documentation/bpftool-btf.rst  | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/tools/bpf/bpftool/Documentation/bpftool-btf.rst b/tools/bpf/bpftool/Documentation/bpftool-btf.rst
index c6dc445cd4a1..0bd50c4fa68a 100644
--- a/tools/bpf/bpftool/Documentation/bpftool-btf.rst
+++ b/tools/bpf/bpftool/Documentation/bpftool-btf.rst
@@ -70,6 +70,24 @@ bpftool btf dump *BTF_SRC* [format *FORMAT*] [root_id *ROOT_ID*]
     formatting, the output is sorted by default. Use the **unsorted** option
     to avoid sorting the output.
 
+    C output annotates struct and union definitions individually, with or
+    without **unsorted**. Most records carry
+    ``__attribute__((__bpf_core_pai))``. The generated header defines
+    ``__bpf_core_pai`` as ``preserve_access_index`` where supported, or as
+    empty when **BPF_NO_PRESERVE_ACCESS_INDEX** is defined or the compiler
+    lacks the attribute. GCC-BPF can apply CO-RE through these attributes.
+
+    Context and socket types whose field accesses the verifier rewrites
+    carry ``__attribute__((__bpf_core_pso))`` instead, and their nested
+    anonymous records carry no attribute. ``__bpf_core_pso`` expands to
+    ``preserve_static_offset`` where supported (Clang 18 and later), or to
+    empty otherwise. The attribute keeps static field offsets in load and
+    store instruction immediates. **BPF_NO_PRESERVE_ACCESS_INDEX** does
+    not affect ``__bpf_core_pso``.
+
+    Either macro may be pre-defined as a bare attribute name, such as
+    ``preserve_access_index``, or as empty to override the policy.
+
     **root_id** option can be used to filter a dump to a single type and all
     its dependent types. It cannot be used with any other types of filtering
     (such as the "key", "value", or "kv" arguments when dumping BTF for a map).
-- 
2.56.0


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH bpf-next v1 3/8] bpftool: Apply __bpf_core_pai per record on BTF dump
  2026-10-16  0:00 ` [PATCH bpf-next v1 3/8] bpftool: Apply __bpf_core_pai per record on BTF dump Ihor Solodrai
@ 2026-10-16  0:39   ` bot+bpf-ci
  2026-10-16  1:17   ` Alexei Starovoitov
  1 sibling, 0 replies; 20+ messages in thread
From: bot+bpf-ci @ 2026-10-16  0:39 UTC (permalink / raw)
  To: ihor.solodrai, ast, andrii, daniel, eddyz87, memxor, qmo
  Cc: bpf, alan.maguire, cupertino.miranda, david.faust, irogers,
	jose.marchesi, vineet.gupta, yonghong.song, ast, andrii, daniel,
	martin.lau, eddyz87, yonghong.song, mason, ihor.solodrai

[-- Attachment #1: Type: text/plain, Size: 3272 bytes --]

> bpftool: Apply __bpf_core_pai per record on BTF dump

TL;DR: Tagging every struct with __bpf_core_pai may make GCC-BPF programs'
narrow ctx accesses (e.g. skb->mark) be rejected by the verifier at this
patch; later patches fix it, so bisection may regress. Fold fix in or reorder?

> diff --git a/tools/bpf/bpftool/btf.c b/tools/bpf/bpftool/btf.c
> --- a/tools/bpf/bpftool/btf.c
> +++ b/tools/bpf/bpftool/btf.c

[ ... ]

> @@ -1121,6 +1121,24 @@ static struct btf *btf_c_detached_copy(const struct btf *src)
>  	return copy;
>  }
>
> +static int btf_c_annotate_records(struct btf *btf)
> +{
> +	__u32 i, cnt = btf__type_cnt(btf);
> +	int err;
> +
> +	for (i = 1; i < cnt; i++) {
> +		const struct btf_type *t = btf__type_by_id(btf, i);
> +
> +		if (!btf_is_composite(t))
> +			continue;
> +		err = btf__add_decl_attr(btf, "__bpf_core_pai", i, -1);

Can this tag on every struct and union break GCC-BPF programs that access
verifier-rewritten context types through vmlinux.h?

The tagged types include __sk_buff, xdp_md, bpf_sock, bpf_sock_ops,
sk_msg_md and similar UAPI context types.  In dump_btf_c(), __bpf_core_pai
now expands to preserve_access_index whenever:

    !defined(BPF_NO_PRESERVE_ACCESS_INDEX) &&
    __has_attribute(preserve_access_index)

GCC-BPF ignored the old "#pragma clang attribute push", but it does have the
attribute, so with this patch it emits CO-RE relocated accesses for these
types for the first time.

check_ctx_access() in kernel/bpf/verifier.c calls

    __check_ptr_off_reg(env, reg, argno, fixed_off_ok)

with fixed_off_ok = !env->ops->convert_ctx_access, so a ctx pointer with an
adjusted offset is rejected.  libbpf can only patch an LDX whose offset
equals the original field offset (relo_core.c reports "unexpected insn
(LDX/ST/STX) value" otherwise).

A narrow access such as ((__u8 *)&skb->mark)[1] therefore cannot become a
single "ldxb [r1 + 9]" any more.  It turns into pointer arithmetic on the
ctx register, which the verifier then rejects.  The same GCC program built
before this patch uses a constant offset that the verifier accepts.

Clang is unaffected, since the old pragma already behaved this way.  The
in-tree GCC selftest flavor passes -DBPF_NO_PRESERVE_ACCESS_INDEX (see
tools/testing/selftests/bpf/Makefile), so it does not exercise this.

Later patches in this series address it:

  59158e0d2295 ("bpftool: Skip __bpf_core_pai on verifier-rewritten context
  types") removes the attribute from these 13 types and their nested
  anonymous records.

  d7ea54ed605e ("bpftool: Emit __bpf_core_pso on verifier-rewritten context
  types") adds preserve_static_offset to them.

  57ae13c435b8 ("selftests/bpf: Cover context and socket accesses through
  vmlinux.h") adds tests for the narrow skb->mark load.

If the series is applied in order, this patch is a bisection point where
GCC-BPF ctx accesses regress.  Should the exclusion be folded into this
patch, or should the patch order be changed?

> +		if (err < 0)
> +			return err;
> +	}
> +
> +	return 0;
> +}

[ ... ]


---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md

CI run summary: https://github.com/kernel-patches/bpf/actions/runs/38828475934

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH bpf-next v1 3/8] bpftool: Apply __bpf_core_pai per record on BTF dump
  2026-10-16  0:00 ` [PATCH bpf-next v1 3/8] bpftool: Apply __bpf_core_pai per record on BTF dump Ihor Solodrai
  2026-10-16  0:39   ` bot+bpf-ci
@ 2026-10-16  1:17   ` Alexei Starovoitov
  1 sibling, 0 replies; 20+ messages in thread
From: Alexei Starovoitov @ 2026-10-16  1:17 UTC (permalink / raw)
  To: Ihor Solodrai, Alexei Starovoitov, Andrii Nakryiko,
	Daniel Borkmann, Eduard Zingerman, Kumar Kartikeya Dwivedi,
	Quentin Monnet
  Cc: bpf, Alan Maguire, Cupertino Miranda, David Faust, Ian Rogers,
	Jose E . Marchesi, Vineet Gupta, Yonghong Song

On Fri Oct 16, 2026 at 12:00 AM UTC, Ihor Solodrai wrote:
> -	printf("#ifndef BPF_NO_PRESERVE_ACCESS_INDEX\n");
> -	printf("#pragma clang attribute push (__attribute__((preserve_access_index)), apply_to = record)\n");
> +	printf("#ifndef __bpf_core_pai\n");
> +	printf("#if !defined(BPF_NO_PRESERVE_ACCESS_INDEX) && __has_attribute(preserve_access_index)\n");
> +	printf("#define __bpf_core_pai preserve_access_index\n");
> +	printf("#else\n");
> +	printf("#define __bpf_core_pai\n");
> +	printf("#endif\n");

in rust we're going with 'btf_relocatable' name

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH bpf-next v1 1/8] bpftool: Dump C from a detached BTF copy
  2026-10-16  0:00 ` [PATCH bpf-next v1 1/8] bpftool: Dump C from a detached BTF copy Ihor Solodrai
@ 2026-10-16  1:18   ` Alexei Starovoitov
  2026-10-16  9:44     ` Alan Maguire
  2026-10-16  9:25   ` Alan Maguire
  1 sibling, 1 reply; 20+ messages in thread
From: Alexei Starovoitov @ 2026-10-16  1:18 UTC (permalink / raw)
  To: Ihor Solodrai, Andrii Nakryiko, Daniel Borkmann, Eduard Zingerman,
	Kumar Kartikeya Dwivedi, Quentin Monnet
  Cc: bpf, Alan Maguire, Cupertino Miranda, David Faust, Ian Rogers,
	Jose E . Marchesi, Vineet Gupta, Yonghong Song

On Thu, Oct 15, 2026 at 05:00 PM Ihor Solodrai <ihor.solodrai@linux.dev> wrote:
> Modifying the parsed BTF fails for some valid input: libbpf refuses to
> modify BTF whose header carries unknown nonzero extension bytes, so
> such a dump would stop with -EOPNOTSUPP.
>
> Dump from a flat copy built with btf__add_type(), which only requires
> the destination to be modifiable.

can we do btf__new_empty_split(btf) and add decl attrs there
instead of copying all types ?
It fails on such BTF only because btf__add_str() does
btf__find_str(base) and that calls btf_ensure_modifiable(base).
The lookup shouldn't need it.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH bpf-next v1 5/8] bpftool: Emit __bpf_core_pso on verifier-rewritten context types
  2026-10-16  0:00 ` [PATCH bpf-next v1 5/8] bpftool: Emit __bpf_core_pso " Ihor Solodrai
@ 2026-10-16  1:27   ` Alexei Starovoitov
  2026-10-16  5:49     ` Ihor Solodrai
  0 siblings, 1 reply; 20+ messages in thread
From: Alexei Starovoitov @ 2026-10-16  1:27 UTC (permalink / raw)
  To: Ihor Solodrai, Andrii Nakryiko, Daniel Borkmann, Eduard Zingerman,
	Kumar Kartikeya Dwivedi, Quentin Monnet
  Cc: bpf, Alan Maguire, Cupertino Miranda, David Faust, Ian Rogers,
	Jose E . Marchesi, Vineet Gupta, Yonghong Song

On Thu, Oct 15, 2026 at 05:00 PM Ihor Solodrai <ihor.solodrai@linux.dev> wrote:
> Clang 18 through 23 crash on __builtin_preserve_field_info over a PSO
> record, including bpf_core_field_*() and the CO-RE bitfield helpers.
> -D__bpf_core_pso= can disable PSO for affected programs.

ouch. anyone working on fixing llvm ?
hopefully people don't do
bpf_core_field_exists(skb->tstamp_type) 
when skb is __sk_buff.

since nobody will know about -D__bpf_core_pso= workaround.

Name is also not great.
"bpf_context" ?

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH bpf-next v1 5/8] bpftool: Emit __bpf_core_pso on verifier-rewritten context types
  2026-10-16  1:27   ` Alexei Starovoitov
@ 2026-10-16  5:49     ` Ihor Solodrai
  2026-10-16 15:53       ` Alexei Starovoitov
  0 siblings, 1 reply; 20+ messages in thread
From: Ihor Solodrai @ 2026-10-16  5:49 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Kumar Kartikeya Dwivedi, Quentin Monnet
  Cc: bpf, Alan Maguire, Cupertino Miranda, David Faust, Ian Rogers,
	Jose E . Marchesi, Vineet Gupta, Yonghong Song

On 2026-10-15 6:27 p.m., Alexei Starovoitov wrote:
> On Thu, Oct 15, 2026 at 05:00 PM Ihor Solodrai <ihor.solodrai@linux.dev> wrote:
>> Clang 18 through 23 crash on __builtin_preserve_field_info over a PSO
>> record, including bpf_core_field_*() and the CO-RE bitfield helpers.
>> -D__bpf_core_pso= can disable PSO for affected programs.
> 
> ouch. anyone working on fixing llvm ?

I have a vibe coded fix, planned to review it and send a PR.

> hopefully people don't do
> bpf_core_field_exists(skb->tstamp_type)
> when skb is __sk_buff.
> 
> since nobody will know about -D__bpf_core_pso= workaround.

When PSO lands, people might run into this as soon as they use new
bpftool to generate vmlinux.h, and the failure is very loud.

Since the bug is quite old, I am not sure it's feasible to fix it 
everywhere. Probably best we can do is advertise the workaround.

> 
> Name is also not great.
> "bpf_context" ?

Yeah, the __bpf_core_<foo> might not be the best name.
I like btf_relocatable for PAI, should this be btf_unrelocatable?..

In any case this is bikeshedding, the macro is local to vmlinux.h,
not a big deal.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH bpf-next v1 1/8] bpftool: Dump C from a detached BTF copy
  2026-10-16  0:00 ` [PATCH bpf-next v1 1/8] bpftool: Dump C from a detached BTF copy Ihor Solodrai
  2026-10-16  1:18   ` Alexei Starovoitov
@ 2026-10-16  9:25   ` Alan Maguire
  2026-10-16 17:41     ` Ihor Solodrai
  1 sibling, 1 reply; 20+ messages in thread
From: Alan Maguire @ 2026-10-16  9:25 UTC (permalink / raw)
  To: Ihor Solodrai, Alexei Starovoitov, Andrii Nakryiko,
	Daniel Borkmann, Eduard Zingerman, Kumar Kartikeya Dwivedi,
	Quentin Monnet
  Cc: bpf, Alan Maguire, Cupertino Miranda, David Faust, Ian Rogers,
	Jose E . Marchesi, Vineet Gupta, Yonghong Song

On 10/16/26 1:00 AM, Ihor Solodrai wrote:
> To emit per-record attributes in the C dump, bpftool needs to add decl
> tags to the BTF it dumps.
> 
> Modifying the parsed BTF fails for some valid input: libbpf refuses to
> modify BTF whose header carries unknown nonzero extension bytes, so
> such a dump would stop with -EOPNOTSUPP.
>

Curious here; did you run into such cases? I would have thought the
only case would be something like where we have kind layout info in
a bpftool that does not know about kind layout, but that can't happen
for an up-to-date bpftool with libbpf that knows about kind layout
unless there are issues with out-of-date UAPI headers for btf_header
or something. Wondering if there's something we need to fix somewhere?

Thanks!

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH bpf-next v1 1/8] bpftool: Dump C from a detached BTF copy
  2026-10-16  1:18   ` Alexei Starovoitov
@ 2026-10-16  9:44     ` Alan Maguire
  2026-10-16 17:40       ` Ihor Solodrai
  0 siblings, 1 reply; 20+ messages in thread
From: Alan Maguire @ 2026-10-16  9:44 UTC (permalink / raw)
  To: Alexei Starovoitov, Ihor Solodrai, Andrii Nakryiko,
	Daniel Borkmann, Eduard Zingerman, Kumar Kartikeya Dwivedi,
	Quentin Monnet
  Cc: bpf, Alan Maguire, Cupertino Miranda, David Faust, Ian Rogers,
	Jose E . Marchesi, Vineet Gupta, Yonghong Song

On 10/16/26 2:18 AM, Alexei Starovoitov wrote:
> On Thu, Oct 15, 2026 at 05:00 PM Ihor Solodrai <ihor.solodrai@linux.dev> wrote:
>> Modifying the parsed BTF fails for some valid input: libbpf refuses to
>> modify BTF whose header carries unknown nonzero extension bytes, so
>> such a dump would stop with -EOPNOTSUPP.
>>
>> Dump from a flat copy built with btf__add_type(), which only requires
>> the destination to be modifiable.
> 
> can we do btf__new_empty_split(btf) and add decl attrs there
> instead of copying all types ?
> It fails on such BTF only because btf__add_str() does
> btf__find_str(base) and that calls btf_ensure_modifiable(base).
> The lookup shouldn't need it.

+1 on using split BTF for new decl tags; even in the case of module
BTF we can use multi-split BTF to cover decl tags for vmlinux and
module BTF I think.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH bpf-next v1 5/8] bpftool: Emit __bpf_core_pso on verifier-rewritten context types
  2026-10-16  5:49     ` Ihor Solodrai
@ 2026-10-16 15:53       ` Alexei Starovoitov
  2026-10-16 17:44         ` Ihor Solodrai
  0 siblings, 1 reply; 20+ messages in thread
From: Alexei Starovoitov @ 2026-10-16 15:53 UTC (permalink / raw)
  To: Ihor Solodrai, Andrii Nakryiko, Daniel Borkmann, Eduard Zingerman,
	Kumar Kartikeya Dwivedi, Quentin Monnet
  Cc: bpf, Alan Maguire, Cupertino Miranda, David Faust, Ian Rogers,
	Jose E . Marchesi, Vineet Gupta, Yonghong Song

On Thu, Oct 15, 2026 at 10:49 PM Ihor Solodrai <ihor.solodrai@linux.dev> wrote:
> When PSO lands, people might run into this as soon as they use new
> bpftool to generate vmlinux.h, and the failure is very loud.

fwiw calico does
  if (bpf_core_field_exists(skb->gso_size)) {
on __sk_buff in skb_is_gso().
It includes linux/bpf.h and not vmlinux.h, so it's not affected,
but the pattern is out there.

> Yeah, the __bpf_core_<foo> might not be the best name.
> I like btf_relocatable for PAI, should this be btf_unrelocatable?..

A struct without any attribute is not relocatable either.
iirc Eduard used __bpf_ctx earlier.
It's more of 'hey compiler dont mess with field offset'.
'bpf_static_offset'? 'bpf_fixed_offset' ?

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH bpf-next v1 1/8] bpftool: Dump C from a detached BTF copy
  2026-10-16  9:44     ` Alan Maguire
@ 2026-10-16 17:40       ` Ihor Solodrai
  0 siblings, 0 replies; 20+ messages in thread
From: Ihor Solodrai @ 2026-10-16 17:40 UTC (permalink / raw)
  To: Alan Maguire, Alexei Starovoitov, Andrii Nakryiko,
	Daniel Borkmann, Eduard Zingerman, Kumar Kartikeya Dwivedi,
	Quentin Monnet
  Cc: bpf, Alan Maguire, Cupertino Miranda, David Faust, Ian Rogers,
	Jose E . Marchesi, Vineet Gupta, Yonghong Song

On 2026-10-16 2:44 a.m., Alan Maguire wrote:
> On 10/16/26 2:18 AM, Alexei Starovoitov wrote:
>> On Thu, Oct 15, 2026 at 05:00 PM Ihor Solodrai <ihor.solodrai@linux.dev> wrote:
>>> Modifying the parsed BTF fails for some valid input: libbpf refuses to
>>> modify BTF whose header carries unknown nonzero extension bytes, so
>>> such a dump would stop with -EOPNOTSUPP.
>>>
>>> Dump from a flat copy built with btf__add_type(), which only requires
>>> the destination to be modifiable.
>>
>> can we do btf__new_empty_split(btf) and add decl attrs there
>> instead of copying all types ?
>> It fails on such BTF only because btf__add_str() does
>> btf__find_str(base) and that calls btf_ensure_modifiable(base).
>> The lookup shouldn't need it.
> 
> +1 on using split BTF for new decl tags; even in the case of module
> BTF we can use multi-split BTF to cover decl tags for vmlinux and
> module BTF I think.

Yeah, these are good points.

I briefly considered this, but didn't look closely at what needs to
change in libbpf to make it work and just went with the copy. The
libbpf fix should be simple, I'll use a split in v2.

Thanks.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH bpf-next v1 1/8] bpftool: Dump C from a detached BTF copy
  2026-10-16  9:25   ` Alan Maguire
@ 2026-10-16 17:41     ` Ihor Solodrai
  0 siblings, 0 replies; 20+ messages in thread
From: Ihor Solodrai @ 2026-10-16 17:41 UTC (permalink / raw)
  To: Alan Maguire, Alexei Starovoitov, Andrii Nakryiko,
	Daniel Borkmann, Eduard Zingerman, Kumar Kartikeya Dwivedi,
	Quentin Monnet
  Cc: bpf, Alan Maguire, Cupertino Miranda, David Faust, Ian Rogers,
	Jose E . Marchesi, Vineet Gupta, Yonghong Song

On 2026-10-16 2:25 a.m., Alan Maguire wrote:
> On 10/16/26 1:00 AM, Ihor Solodrai wrote:
>> To emit per-record attributes in the C dump, bpftool needs to add decl
>> tags to the BTF it dumps.
>>
>> Modifying the parsed BTF fails for some valid input: libbpf refuses to
>> modify BTF whose header carries unknown nonzero extension bytes, so
>> such a dump would stop with -EOPNOTSUPP.
>>
> 
> Curious here; did you run into such cases? 

Nope.

> ...I would have thought the
> only case would be something like where we have kind layout info in
> a bpftool that does not know about kind layout, but that can't happen
> for an up-to-date bpftool with libbpf that knows about kind layout

I was thinking about forward compat.

Consider a bpftool (with this series) dumping BTF from an even newer
kernel, with data libbpf doesn't know about. has_hdr_extra check
correctly refuses to modify such BTF, and that's what bpftool is
doing.

But if we use the split BTF then this is not an issue, because input
BTF stays read only.

> unless there are issues with out-of-date UAPI headers for btf_header
> or something. Wondering if there's something we need to fix somewhere?
> 
> Thanks!


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH bpf-next v1 5/8] bpftool: Emit __bpf_core_pso on verifier-rewritten context types
  2026-10-16 15:53       ` Alexei Starovoitov
@ 2026-10-16 17:44         ` Ihor Solodrai
  0 siblings, 0 replies; 20+ messages in thread
From: Ihor Solodrai @ 2026-10-16 17:44 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Kumar Kartikeya Dwivedi, Quentin Monnet
  Cc: bpf, Alan Maguire, Cupertino Miranda, David Faust, Ian Rogers,
	Jose E . Marchesi, Vineet Gupta, Yonghong Song

On 2026-10-16 8:53 a.m., Alexei Starovoitov wrote:
> On Thu, Oct 15, 2026 at 10:49 PM Ihor Solodrai <ihor.solodrai@linux.dev> wrote:
>> When PSO lands, people might run into this as soon as they use new
>> bpftool to generate vmlinux.h, and the failure is very loud.
> 
> fwiw calico does
>    if (bpf_core_field_exists(skb->gso_size)) {
> on __sk_buff in skb_is_gso().
> It includes linux/bpf.h and not vmlinux.h, so it's not affected,
> but the pattern is out there.
> 
>> Yeah, the __bpf_core_<foo> might not be the best name.
>> I like btf_relocatable for PAI, should this be btf_unrelocatable?..
> 
> A struct without any attribute is not relocatable either.
> iirc Eduard used __bpf_ctx earlier.
> It's more of 'hey compiler dont mess with field offset'.
> 'bpf_static_offset'? 'bpf_fixed_offset' ?

 From these bpf_static_offset makes most sense to me, because it matches
the compiler attribute name (preserve_static_offset).

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2026-10-16 17:44 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-16  0:00 [PATCH bpf-next v1 0/8] bpftool: Per-record CO-RE attributes in the C dump Ihor Solodrai
2026-10-16  0:00 ` [PATCH bpf-next v1 1/8] bpftool: Dump C from a detached BTF copy Ihor Solodrai
2026-10-16  1:18   ` Alexei Starovoitov
2026-10-16  9:44     ` Alan Maguire
2026-10-16 17:40       ` Ihor Solodrai
2026-10-16  9:25   ` Alan Maguire
2026-10-16 17:41     ` Ihor Solodrai
2026-10-16  0:00 ` [PATCH bpf-next v1 2/8] selftests/bpf: Cover unknown BTF header-extension bytes in btf dump Ihor Solodrai
2026-10-16  0:00 ` [PATCH bpf-next v1 3/8] bpftool: Apply __bpf_core_pai per record on BTF dump Ihor Solodrai
2026-10-16  0:39   ` bot+bpf-ci
2026-10-16  1:17   ` Alexei Starovoitov
2026-10-16  0:00 ` [PATCH bpf-next v1 4/8] bpftool: Skip __bpf_core_pai on verifier-rewritten context types Ihor Solodrai
2026-10-16  0:00 ` [PATCH bpf-next v1 5/8] bpftool: Emit __bpf_core_pso " Ihor Solodrai
2026-10-16  1:27   ` Alexei Starovoitov
2026-10-16  5:49     ` Ihor Solodrai
2026-10-16 15:53       ` Alexei Starovoitov
2026-10-16 17:44         ` Ihor Solodrai
2026-10-16  0:00 ` [PATCH bpf-next v1 6/8] selftests/bpf: Cover record attributes in bpftool BTF dumps Ihor Solodrai
2026-10-16  0:00 ` [PATCH bpf-next v1 7/8] selftests/bpf: Cover context and socket accesses through vmlinux.h Ihor Solodrai
2026-10-16  0:00 ` [PATCH bpf-next v1 8/8] bpftool: Document __bpf_core_pai and __bpf_core_pso Ihor Solodrai

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.