1 // SPDX-License-Identifier: GPL-2.0
2 #include <test_progs.h>
5 static int duration
= 0;
7 void btf_dump_printf(void *ctx
, const char *fmt
, va_list args
)
9 vfprintf(ctx
, fmt
, args
);
12 static struct btf_dump_test_case
{
15 struct btf_dump_opts opts
;
16 } btf_dump_test_cases
[] = {
17 {"btf_dump: syntax", "btf_dump_test_case_syntax", {}},
18 {"btf_dump: ordering", "btf_dump_test_case_ordering", {}},
19 {"btf_dump: padding", "btf_dump_test_case_padding", {}},
20 {"btf_dump: packing", "btf_dump_test_case_packing", {}},
21 {"btf_dump: bitfields", "btf_dump_test_case_bitfields", {}},
22 {"btf_dump: multidim", "btf_dump_test_case_multidim", {}},
23 {"btf_dump: namespacing", "btf_dump_test_case_namespacing", {}},
26 static int btf_dump_all_types(const struct btf
*btf
,
27 const struct btf_dump_opts
*opts
)
29 size_t type_cnt
= btf__get_nr_types(btf
);
33 d
= btf_dump__new(btf
, NULL
, opts
, btf_dump_printf
);
37 for (id
= 1; id
<= type_cnt
; id
++) {
38 err
= btf_dump__dump_type(d
, id
);
48 static int test_btf_dump_case(int n
, struct btf_dump_test_case
*t
)
50 char test_file
[256], out_file
[256], diff_cmd
[1024];
51 struct btf
*btf
= NULL
;
55 snprintf(test_file
, sizeof(test_file
), "%s.o", t
->file
);
57 btf
= btf__parse_elf(test_file
, NULL
);
58 if (CHECK(IS_ERR(btf
), "btf_parse_elf",
59 "failed to load test BTF: %ld\n", PTR_ERR(btf
))) {
65 snprintf(out_file
, sizeof(out_file
), "/tmp/%s.output.XXXXXX", t
->file
);
66 fd
= mkstemp(out_file
);
67 if (CHECK(fd
< 0, "create_tmp", "failed to create file: %d\n", fd
)) {
72 if (CHECK(f
== NULL
, "open_tmp", "failed to open file: %s(%d)\n",
73 strerror(errno
), errno
)) {
79 err
= btf_dump_all_types(btf
, &t
->opts
);
82 if (CHECK(err
, "btf_dump", "failure during C dumping: %d\n", err
)) {
86 snprintf(test_file
, sizeof(test_file
), "progs/%s.c", t
->file
);
87 if (access(test_file
, R_OK
) == -1)
89 * When the test is run with O=, kselftest copies TEST_FILES
90 * without preserving the directory structure.
92 snprintf(test_file
, sizeof(test_file
), "%s.c", t
->file
);
94 * Diff test output and expected test output, contained between
95 * START-EXPECTED-OUTPUT and END-EXPECTED-OUTPUT lines in test case.
96 * For expected output lines, everything before '*' is stripped out.
97 * Also lines containing comment start and comment end markers are
100 snprintf(diff_cmd
, sizeof(diff_cmd
),
101 "awk '/START-EXPECTED-OUTPUT/{out=1;next} "
102 "/END-EXPECTED-OUTPUT/{out=0} "
103 "/\\/\\*|\\*\\//{next} " /* ignore comment start/end lines */
104 "out {sub(/^[ \\t]*\\*/, \"\"); print}' '%s' | diff -u - '%s'",
105 test_file
, out_file
);
106 err
= system(diff_cmd
);
107 if (CHECK(err
, "diff",
108 "differing test output, output=%s, err=%d, diff cmd:\n%s\n",
109 out_file
, err
, diff_cmd
))
119 void test_btf_dump() {
122 for (i
= 0; i
< ARRAY_SIZE(btf_dump_test_cases
); i
++) {
123 struct btf_dump_test_case
*t
= &btf_dump_test_cases
[i
];
125 if (!test__start_subtest(t
->name
))
128 test_btf_dump_case(i
, &btf_dump_test_cases
[i
]);