From: Eduard Zingerman <eddyz87@gmail.com>
To: bpf@vger.kernel.org, ast@kernel.org
Cc: andrii@kernel.org, daniel@iogearbox.net, kernel-team@fb.com,
yhs@fb.com, Eduard Zingerman <eddyz87@gmail.com>
Subject: [PATCH bpf-next v3 3/3] selftests/bpf: Tests for BTF_KIND_DECL_TAG dump in C format
Date: Thu, 10 Nov 2022 16:43:20 +0200 [thread overview]
Message-ID: <20221110144320.1075367-4-eddyz87@gmail.com> (raw)
In-Reply-To: <20221110144320.1075367-1-eddyz87@gmail.com>
Covers the following cases:
- `__atribute__((btf_decl_tag("...")))` could be applied to structs
and unions;
- decl tag applied to an empty struct is printed on a single line;
- decl tags with the same name could be applied to several structs;
- several decl tags could be applied to the same struct;
- attribute `packed` works fine with decl tags (it is a separate
branch in `tools/lib/bpf/btf_dump.c:btf_dump_emit_attributes`;
- decl tag could be attached to typedef;
- decl tag could be attached to a struct field;
- decl tag could be attached to a struct field and a struct itself
simultaneously;
- decl tag could be attached to a global variable;
- decl tag could be attached to a func proto parameter;
- btf__add_decl_tag could be interleaved with btf_dump__dump_type calls.
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
---
.../selftests/bpf/prog_tests/btf_dump.c | 79 +++++++++++++++++++
.../bpf/progs/btf_dump_test_case_decl_tag.c | 65 +++++++++++++++
2 files changed, 144 insertions(+)
create mode 100644 tools/testing/selftests/bpf/progs/btf_dump_test_case_decl_tag.c
diff --git a/tools/testing/selftests/bpf/prog_tests/btf_dump.c b/tools/testing/selftests/bpf/prog_tests/btf_dump.c
index a0bdfc45660d..2e6135a555e3 100644
--- a/tools/testing/selftests/bpf/prog_tests/btf_dump.c
+++ b/tools/testing/selftests/bpf/prog_tests/btf_dump.c
@@ -23,6 +23,7 @@ static struct btf_dump_test_case {
{"btf_dump: bitfields", "btf_dump_test_case_bitfields", true},
{"btf_dump: multidim", "btf_dump_test_case_multidim", false},
{"btf_dump: namespacing", "btf_dump_test_case_namespacing", false},
+ {"btf_dump: decl_tag", "btf_dump_test_case_decl_tag", true},
};
static int btf_dump_all_types(const struct btf *btf, struct btf_dump *d)
@@ -345,6 +346,82 @@ static void test_btf_dump_incremental(void)
btf__free(btf);
}
+static void test_btf_dump_func_proto_decl_tag(void)
+{
+ struct btf *btf = NULL;
+ struct btf_dump *d = NULL;
+ int id, err;
+
+ dump_buf_file = open_memstream(&dump_buf, &dump_buf_sz);
+ if (!ASSERT_OK_PTR(dump_buf_file, "dump_memstream"))
+ return;
+ btf = btf__new_empty();
+ if (!ASSERT_OK_PTR(btf, "new_empty"))
+ goto err_out;
+ d = btf_dump__new(btf, btf_dump_printf, dump_buf_file, NULL);
+ if (!ASSERT_OK(libbpf_get_error(d), "btf_dump__new"))
+ goto err_out;
+
+ /* First, BTF corresponding to the following C code:
+ *
+ * typedef void (*fn)(int a __btf_decl_tag("a_tag"));
+ *
+ */
+ id = btf__add_int(btf, "int", 4, BTF_INT_SIGNED);
+ ASSERT_EQ(id, 1, "int_id");
+ id = btf__add_func_proto(btf, 0);
+ ASSERT_EQ(id, 2, "func_proto_id");
+ err = btf__add_func_param(btf, "a", 1);
+ ASSERT_OK(err, "func_param_ok");
+ id = btf__add_decl_tag(btf, "a_tag", 2, 0);
+ ASSERT_EQ(id, 3, "decl_tag_a");
+ id = btf__add_ptr(btf, 2);
+ ASSERT_EQ(id, 4, "proto_ptr");
+ id = btf__add_typedef(btf, "fn", 4);
+ ASSERT_EQ(id, 5, "typedef");
+
+ err = btf_dump_all_types(btf, d);
+ ASSERT_OK(err, "btf_dump_all_types #1");
+ fflush(dump_buf_file);
+ dump_buf[dump_buf_sz] = 0; /* some libc implementations don't do this */
+
+ ASSERT_STREQ(dump_buf,
+ "#if __has_attribute(btf_decl_tag)\n"
+ "#define __btf_decl_tag(x) __attribute__((btf_decl_tag(x)))\n"
+ "#else\n"
+ "#define __btf_decl_tag(x)\n"
+ "#endif\n"
+ "\n"
+ "typedef void (*fn)(int a __btf_decl_tag(\"a_tag\"));\n\n",
+ "decl tags for fn");
+
+ /* Next, add BTF corresponding to the following C code:
+ *
+ * typedef int foo __btf_decl_tag("foo_tag");
+ *
+ * To verify that decl_tag's table is updated incrementally.
+ */
+ id = btf__add_typedef(btf, "foo", 1);
+ ASSERT_EQ(id, 6, "typedef");
+ id = btf__add_decl_tag(btf, "foo_tag", 6, -1);
+ ASSERT_EQ(id, 7, "decl_tag_foo");
+
+ fseek(dump_buf_file, 0, SEEK_SET);
+ err = btf_dump_all_types(btf, d);
+ ASSERT_OK(err, "btf_dump_all_types #2");
+ fflush(dump_buf_file);
+ dump_buf[dump_buf_sz] = 0; /* some libc implementations don't do this */
+
+ ASSERT_STREQ(dump_buf,
+ "typedef int foo __btf_decl_tag(\"foo_tag\");\n\n",
+ "decl tags for foo");
+err_out:
+ fclose(dump_buf_file);
+ free(dump_buf);
+ btf_dump__free(d);
+ btf__free(btf);
+}
+
#define STRSIZE 4096
static void btf_dump_snprintf(void *ctx, const char *fmt, va_list args)
@@ -963,6 +1040,8 @@ void test_btf_dump() {
}
if (test__start_subtest("btf_dump: incremental"))
test_btf_dump_incremental();
+ if (test__start_subtest("btf_dump: func arg decl_tag"))
+ test_btf_dump_func_proto_decl_tag();
btf = libbpf_find_kernel_btf();
if (!ASSERT_OK_PTR(btf, "no kernel BTF found"))
diff --git a/tools/testing/selftests/bpf/progs/btf_dump_test_case_decl_tag.c b/tools/testing/selftests/bpf/progs/btf_dump_test_case_decl_tag.c
new file mode 100644
index 000000000000..1205351e9a68
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/btf_dump_test_case_decl_tag.c
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
+
+/*
+ * BTF-to-C dumper test for __atribute__((btf_decl_tag("..."))).
+ */
+
+#define SEC(x) __attribute__((section(x)))
+
+/* ----- START-EXPECTED-OUTPUT ----- */
+#if __has_attribute(btf_decl_tag)
+#define __btf_decl_tag(x) __attribute__((btf_decl_tag(x)))
+#else
+#define __btf_decl_tag(x)
+#endif
+
+struct empty_with_tag {} __btf_decl_tag("a");
+
+struct one_tag {
+ int x;
+} __btf_decl_tag("b");
+
+struct same_tag {
+ int x;
+} __btf_decl_tag("b");
+
+struct two_tags {
+ int x;
+} __btf_decl_tag("a") __btf_decl_tag("b");
+
+struct packed {
+ int x;
+ short y;
+} __attribute__((packed)) __btf_decl_tag("another_name");
+
+typedef int td_with_tag __btf_decl_tag("td");
+
+struct tags_on_fields {
+ int x __btf_decl_tag("t1");
+ int y;
+ int z __btf_decl_tag("t2") __btf_decl_tag("t3");
+};
+
+struct tag_on_field_and_struct {
+ int x __btf_decl_tag("t1");
+} __btf_decl_tag("t2");
+
+struct root_struct {
+ struct empty_with_tag a;
+ struct one_tag b;
+ struct same_tag c;
+ struct two_tags d;
+ struct packed e;
+ td_with_tag f;
+ struct tags_on_fields g;
+ struct tag_on_field_and_struct h;
+};
+
+SEC(".data") int global_var __btf_decl_tag("var_tag") = (int)777;
+
+/* ------ END-EXPECTED-OUTPUT ------ */
+
+int f(struct root_struct *s)
+{
+ return 0;
+}
--
2.34.1
next prev parent reply other threads:[~2022-11-10 14:43 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-11-10 14:43 [PATCH bpf-next v3 0/3] libbpf: btf_decl_tag attribute for btf dump in C format Eduard Zingerman
2022-11-10 14:43 ` [PATCH bpf-next v3 1/3] libbpf: __attribute__((btf_decl_tag("..."))) " Eduard Zingerman
2022-11-11 18:58 ` Andrii Nakryiko
2022-11-11 21:30 ` Eduard Zingerman
2022-11-14 19:56 ` Andrii Nakryiko
2022-11-16 1:51 ` Eduard Zingerman
2022-11-18 0:21 ` Andrii Nakryiko
2022-11-15 20:45 ` Yonghong Song
2022-11-15 20:48 ` Yonghong Song
2022-11-10 14:43 ` [PATCH bpf-next v3 2/3] selftests/bpf: Dump data sections as part of btf_dump_test_case tests Eduard Zingerman
2022-11-11 19:07 ` Andrii Nakryiko
2022-11-10 14:43 ` Eduard Zingerman [this message]
2022-11-11 19:07 ` [PATCH bpf-next v3 3/3] selftests/bpf: Tests for BTF_KIND_DECL_TAG dump in C format Andrii Nakryiko
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=20221110144320.1075367-4-eddyz87@gmail.com \
--to=eddyz87@gmail.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=kernel-team@fb.com \
--cc=yhs@fb.com \
/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 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.