]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
selftests/bpf: Add BTF dedup tests for recursive typedef definitions
authorPaul Houssel <paulhoussel2@gmail.com>
Thu, 13 Nov 2025 12:39:51 +0000 (13:39 +0100)
committerAndrii Nakryiko <andrii@kernel.org>
Sat, 15 Nov 2025 01:07:20 +0000 (17:07 -0800)
Add several ./test_progs tests:
    1.  btf/dedup:recursive typedef ensures that deduplication no
longer fails on recursive typedefs.
    2.  btf/dedup:typedef ensures that typedefs are deduplicated correctly
just as they were before this patch.

Signed-off-by: Paul Houssel <paul.houssel@orange.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/bpf/9fac2f744089f6090257d4c881914b79f6cd6c6a.1763037045.git.paul.houssel@orange.com
tools/testing/selftests/bpf/prog_tests/btf.c

index 8a9ba42921092c4e9af0eb3f6ec9b88debf05c72..054ecb6b1e9f1b8c6c0ef0bdaaabfa8e980d0ae7 100644 (file)
@@ -7495,6 +7495,71 @@ static struct btf_dedup_test dedup_tests[] = {
                BTF_STR_SEC("\0t\0m1\0m2\0tag1\0tag2\0tag3"),
        },
 },
+{
+       .descr = "dedup: recursive typedef",
+       /*
+        * This test simulates a recursive typedef, which in GO is defined as such:
+        *
+        *   type Foo func() Foo
+        *
+        * In BTF terms, this is represented as a TYPEDEF referencing
+        * a FUNC_PROTO that returns the same TYPEDEF.
+        */
+       .input = {
+               .raw_types = {
+                       /*
+                        * [1] typedef Foo -> func() Foo
+                        * [2] func_proto() -> Foo
+                        * [3] typedef Foo -> func() Foo
+                        * [4] func_proto() -> Foo
+                        */
+                       BTF_TYPEDEF_ENC(NAME_NTH(1), 2),        /* [1] */
+                       BTF_FUNC_PROTO_ENC(1, 0),               /* [2] */
+                       BTF_TYPEDEF_ENC(NAME_NTH(1), 4),        /* [3] */
+                       BTF_FUNC_PROTO_ENC(3, 0),               /* [4] */
+                       BTF_END_RAW,
+               },
+               BTF_STR_SEC("\0Foo"),
+       },
+       .expect = {
+               .raw_types = {
+                       BTF_TYPEDEF_ENC(NAME_NTH(1), 2),        /* [1] */
+                       BTF_FUNC_PROTO_ENC(1, 0),               /* [2] */
+                       BTF_END_RAW,
+               },
+               BTF_STR_SEC("\0Foo"),
+       },
+},
+{
+       .descr = "dedup: typedef",
+    /*
+     * // CU 1:
+     * typedef int foo;
+     *
+     * // CU 2:
+     * typedef int foo;
+     */
+       .input = {
+               .raw_types = {
+                       /* CU 1 */
+                       BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
+                       BTF_TYPEDEF_ENC(NAME_NTH(1), 1),                /* [2] */
+                       /* CU 2 */
+                       BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [3] */
+                       BTF_TYPEDEF_ENC(NAME_NTH(1), 3),                /* [4] */
+                       BTF_END_RAW,
+               },
+               BTF_STR_SEC("\0foo"),
+       },
+       .expect = {
+               .raw_types = {
+                       BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
+                       BTF_TYPEDEF_ENC(NAME_NTH(1), 1),                /* [2] */
+                       BTF_END_RAW,
+               },
+               BTF_STR_SEC("\0foo"),
+       },
+},
 {
        .descr = "dedup: typedef tags",
        .input = {