BPF List
 help / color / mirror / Atom feed
From: Ihor Solodrai <ihor.solodrai@linux.dev>
To: Alexei Starovoitov <ast@kernel.org>,
	Andrii Nakryiko <andrii@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Eduard Zingerman <eddyz87@gmail.com>,
	Kumar Kartikeya Dwivedi <memxor@gmail.com>,
	Quentin Monnet <qmo@kernel.org>
Cc: bpf@vger.kernel.org
Subject: [PATCH bpf-next v1 4/4] selftests/bpf: Check that sorting preserves types in bpftool dump
Date: Wed, 19 Aug 2026 17:06:27 -0700	[thread overview]
Message-ID: <20260820000627.3826188-5-ihor.solodrai@linux.dev> (raw)
In-Reply-To: <20260820000627.3826188-1-ihor.solodrai@linux.dev>

Sorting the C dump is meant to make generated headers diffable. The
sorted and unsorted dumps of the same BTF have to emit the same types.

Extend the fixture with a few more top-level definitions, including
anonymous enums, and add a subtest comparing how many types are
emitted with or without sort.

Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 .../bpf/prog_tests/bpftool_btf_dump.c         | 78 ++++++++++++++++++-
 1 file changed, 75 insertions(+), 3 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 53bb7065b3ca..28059820ea0b 100644
--- a/tools/testing/selftests/bpf/prog_tests/bpftool_btf_dump.c
+++ b/tools/testing/selftests/bpf/prog_tests/bpftool_btf_dump.c
@@ -53,15 +53,18 @@ static char *dump_c(const char *path, bool sorted)
 
 /*
  * struct holey { int c; <32 bit hole> int tail; };
+ * enum { E0 = 1 }; enum { E1 = 2 }; enum { E2 = 3 };
+ * struct s { int f; };
+ * union u { int f; };
  *
  * One record with a hole, and a 4-byte long to pad it with. How records
- * themselves are rendered is already covered by the build, so the fixture does
- * not need to be more elaborate than that.
+ * themselves are rendered is already covered by the build.
+ * The anonymous enums matter to the sorting subtest.
  */
 static struct btf *mk_btf(void)
 {
 	struct btf *btf;
-	int id, err;
+	int id, err, i;
 
 	btf = btf__new_empty();
 	if (!ASSERT_OK_PTR(btf, "new_empty"))
@@ -87,6 +90,36 @@ static struct btf *mk_btf(void)
 	if (!ASSERT_OK(err, "holey_tail"))
 		goto err_out;
 
+	for (i = 0; i < 3; i++) {
+		char name[16];
+
+		snprintf(name, sizeof(name), "E%d", i);
+
+		id = btf__add_enum(btf, NULL, 4);
+		if (!ASSERT_GT(id, 0, "anon_enum"))
+			goto err_out;
+
+		err = btf__add_enum_value(btf, name, i + 1);
+		if (!ASSERT_OK(err, "enum_val"))
+			goto err_out;
+	}
+
+	id = btf__add_struct(btf, "s", 4);
+	if (!ASSERT_GT(id, 0, "struct_s"))
+		goto err_out;
+
+	err = btf__add_field(btf, "f", 1, 0, 0);
+	if (!ASSERT_OK(err, "s_field"))
+		goto err_out;
+
+	id = btf__add_union(btf, "u", 4);
+	if (!ASSERT_GT(id, 0, "union_u"))
+		goto err_out;
+
+	err = btf__add_field(btf, "f", 1, 0, 0);
+	if (!ASSERT_OK(err, "u_field"))
+		goto err_out;
+
 	btf__set_pointer_size(btf, 4);
 
 	return btf;
@@ -95,6 +128,42 @@ static struct btf *mk_btf(void)
 	return NULL;
 }
 
+static int count_substr(const char *haystack, const char *needle)
+{
+	const char *p = haystack;
+	int n = 0;
+
+	for (; (p = strstr(p, needle)); p++)
+		n++;
+
+	return n;
+}
+
+static void test_sort_preserves_types(const char *path)
+{
+	char *sorted = NULL, *unsorted = NULL;
+	int n_sorted, n_unsorted;
+
+	sorted = dump_c(path, true);
+	unsorted = dump_c(path, false);
+	if (!sorted || !unsorted)
+		goto out;
+
+	/*
+	 * Count definitions by the closing brace in their first column. Counting
+	 * "struct"/"union"/"enum" openers instead would also count forward
+	 * declarations, and which types need one depends on emission order.
+	 */
+	n_unsorted = count_substr(unsorted, "\n}");
+	n_sorted = count_substr(sorted, "\n}");
+	ASSERT_GT(n_unsorted, 0, "types_emitted");
+	ASSERT_EQ(n_sorted, n_unsorted, "same_type_count");
+
+out:
+	free(sorted);
+	free(unsorted);
+}
+
 /*
  * Check only what the selftests build cannot:
  *   - bpf_helpers.h defines __ksym and __weak as well, and no program uses
@@ -145,6 +214,9 @@ void test_bpftool_btf_dump(void)
 	if (test__start_subtest("c_unsorted"))
 		test_dump(path, false);
 
+	if (test__start_subtest("c_sort_preserves_types"))
+		test_sort_preserves_types(path);
+
 	unlink(path);
 out:
 	btf__free(btf);
-- 
2.55.0


      parent reply	other threads:[~2026-08-20  0:07 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-20  0:06 [PATCH bpf-next v1 0/4] bpftool, selftests: Add tests for C dump and fix a dropped type Ihor Solodrai
2026-08-20  0:06 ` [PATCH bpf-next v1 1/4] selftests/bpf: NUL-terminate bpftool command output Ihor Solodrai
2026-08-20  0:06 ` [PATCH bpf-next v1 2/4] selftests/bpf: Add tests for bpftool btf dump format c Ihor Solodrai
2026-08-20  0:16   ` sashiko-bot
2026-08-20  0:51   ` bot+bpf-ci
2026-08-20  0:06 ` [PATCH bpf-next v1 3/4] bpftool: Don't drop a type in the sorted C dump Ihor Solodrai
2026-08-20  0:06 ` Ihor Solodrai [this message]

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=20260820000627.3826188-5-ihor.solodrai@linux.dev \
    --to=ihor.solodrai@linux.dev \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=eddyz87@gmail.com \
    --cc=memxor@gmail.com \
    --cc=qmo@kernel.org \
    /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