Skip to content

Commit f00bb75

Browse files
eddyz87Alexei Starovoitov
authored and
Alexei Starovoitov
committed
selftests/bpf: fix to avoid __msg tag de-duplication by clang
__msg, __regex and __xlated tags are based on __attribute__((btf_decl_tag("..."))) annotations. Clang de-duplicates such annotations, e.g. the following two sequences of tags are identical in final BTF: /* seq A */ /* seq B */ __tag("foo") __tag("foo") __tag("bar") __tag("bar") __tag("foo") Fix this by adding a unique suffix for each tag using __COUNTER__ pre-processor macro. E.g. here is a new definition for __msg: #define __msg(msg) \ __attribute__((btf_decl_tag("comment:test_expect_msg=" XSTR(__COUNTER__) "=" msg))) Using this definition the "seq A" from example above is translated to BTF as follows: [..] DECL_TAG 'comment:test_expect_msg=0=foo' type_id=X component_idx=-1 [..] DECL_TAG 'comment:test_expect_msg=1=bar' type_id=X component_idx=-1 [..] DECL_TAG 'comment:test_expect_msg=2=foo' type_id=X component_idx=-1 Surprisingly, this bug affects a single existing test: verifier_spill_fill/old_stack_misc_vs_cur_ctx_ptr, where sequence of identical messages was expected in the log. Fixes: 537c3f6 ("selftests/bpf: add generic BPF program tester-loader") Signed-off-by: Eduard Zingerman <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent d0a29cd commit f00bb75

File tree

3 files changed

+48
-22
lines changed

3 files changed

+48
-22
lines changed

tools/testing/selftests/bpf/progs/bpf_misc.h

+9-6
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
#ifndef __BPF_MISC_H__
33
#define __BPF_MISC_H__
44

5+
#define XSTR(s) STR(s)
6+
#define STR(s) #s
7+
58
/* This set of attributes controls behavior of the
69
* test_loader.c:test_loader__run_subtests().
710
*
@@ -68,15 +71,15 @@
6871
* Several __arch_* annotations could be specified at once.
6972
* When test case is not run on current arch it is marked as skipped.
7073
*/
71-
#define __msg(msg) __attribute__((btf_decl_tag("comment:test_expect_msg=" msg)))
72-
#define __regex(regex) __attribute__((btf_decl_tag("comment:test_expect_regex=" regex)))
73-
#define __xlated(msg) __attribute__((btf_decl_tag("comment:test_expect_xlated=" msg)))
74+
#define __msg(msg) __attribute__((btf_decl_tag("comment:test_expect_msg=" XSTR(__COUNTER__) "=" msg)))
75+
#define __regex(regex) __attribute__((btf_decl_tag("comment:test_expect_regex=" XSTR(__COUNTER__) "=" regex)))
76+
#define __xlated(msg) __attribute__((btf_decl_tag("comment:test_expect_xlated=" XSTR(__COUNTER__) "=" msg)))
7477
#define __failure __attribute__((btf_decl_tag("comment:test_expect_failure")))
7578
#define __success __attribute__((btf_decl_tag("comment:test_expect_success")))
7679
#define __description(desc) __attribute__((btf_decl_tag("comment:test_description=" desc)))
77-
#define __msg_unpriv(msg) __attribute__((btf_decl_tag("comment:test_expect_msg_unpriv=" msg)))
78-
#define __regex_unpriv(regex) __attribute__((btf_decl_tag("comment:test_expect_regex_unpriv=" regex)))
79-
#define __xlated_unpriv(msg) __attribute__((btf_decl_tag("comment:test_expect_xlated_unpriv=" msg)))
80+
#define __msg_unpriv(msg) __attribute__((btf_decl_tag("comment:test_expect_msg_unpriv=" XSTR(__COUNTER__) "=" msg)))
81+
#define __regex_unpriv(regex) __attribute__((btf_decl_tag("comment:test_expect_regex_unpriv=" XSTR(__COUNTER__) "=" regex)))
82+
#define __xlated_unpriv(msg) __attribute__((btf_decl_tag("comment:test_expect_xlated_unpriv=" XSTR(__COUNTER__) "=" msg)))
8083
#define __failure_unpriv __attribute__((btf_decl_tag("comment:test_expect_failure_unpriv")))
8184
#define __success_unpriv __attribute__((btf_decl_tag("comment:test_expect_success_unpriv")))
8285
#define __log_level(lvl) __attribute__((btf_decl_tag("comment:test_log_level="#lvl)))

tools/testing/selftests/bpf/progs/verifier_spill_fill.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -1213,10 +1213,10 @@ __success __log_level(2)
12131213
* - once for path entry - label 2;
12141214
* - once for path entry - label 1 - label 2.
12151215
*/
1216-
__msg("r1 = *(u64 *)(r10 -8)")
1217-
__msg("exit")
1218-
__msg("r1 = *(u64 *)(r10 -8)")
1219-
__msg("exit")
1216+
__msg("8: (79) r1 = *(u64 *)(r10 -8)")
1217+
__msg("9: (95) exit")
1218+
__msg("from 2 to 7")
1219+
__msg("8: safe")
12201220
__msg("processed 11 insns")
12211221
__flag(BPF_F_TEST_STATE_FREQ)
12221222
__naked void old_stack_misc_vs_cur_ctx_ptr(void)

tools/testing/selftests/bpf/test_loader.c

+35-12
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,35 @@ static void update_flags(int *flags, int flag, bool clear)
215215
*flags |= flag;
216216
}
217217

218+
/* Matches a string of form '<pfx>[^=]=.*' and returns it's suffix.
219+
* Used to parse btf_decl_tag values.
220+
* Such values require unique prefix because compiler does not add
221+
* same __attribute__((btf_decl_tag(...))) twice.
222+
* Test suite uses two-component tags for such cases:
223+
*
224+
* <pfx> __COUNTER__ '='
225+
*
226+
* For example, two consecutive __msg tags '__msg("foo") __msg("foo")'
227+
* would be encoded as:
228+
*
229+
* [18] DECL_TAG 'comment:test_expect_msg=0=foo' type_id=15 component_idx=-1
230+
* [19] DECL_TAG 'comment:test_expect_msg=1=foo' type_id=15 component_idx=-1
231+
*
232+
* And the purpose of this function is to extract 'foo' from the above.
233+
*/
234+
static const char *skip_dynamic_pfx(const char *s, const char *pfx)
235+
{
236+
const char *msg;
237+
238+
if (strncmp(s, pfx, strlen(pfx)) != 0)
239+
return NULL;
240+
msg = s + strlen(pfx);
241+
msg = strchr(msg, '=');
242+
if (!msg)
243+
return NULL;
244+
return msg + 1;
245+
}
246+
218247
enum arch {
219248
ARCH_X86_64 = 0x1,
220249
ARCH_ARM64 = 0x2,
@@ -290,38 +319,32 @@ static int parse_test_spec(struct test_loader *tester,
290319
} else if (strcmp(s, TEST_TAG_AUXILIARY_UNPRIV) == 0) {
291320
spec->auxiliary = true;
292321
spec->mode_mask |= UNPRIV;
293-
} else if (str_has_pfx(s, TEST_TAG_EXPECT_MSG_PFX)) {
294-
msg = s + sizeof(TEST_TAG_EXPECT_MSG_PFX) - 1;
322+
} else if ((msg = skip_dynamic_pfx(s, TEST_TAG_EXPECT_MSG_PFX))) {
295323
err = push_msg(msg, NULL, &spec->priv.expect_msgs);
296324
if (err)
297325
goto cleanup;
298326
spec->mode_mask |= PRIV;
299-
} else if (str_has_pfx(s, TEST_TAG_EXPECT_MSG_PFX_UNPRIV)) {
300-
msg = s + sizeof(TEST_TAG_EXPECT_MSG_PFX_UNPRIV) - 1;
327+
} else if ((msg = skip_dynamic_pfx(s, TEST_TAG_EXPECT_MSG_PFX_UNPRIV))) {
301328
err = push_msg(msg, NULL, &spec->unpriv.expect_msgs);
302329
if (err)
303330
goto cleanup;
304331
spec->mode_mask |= UNPRIV;
305-
} else if (str_has_pfx(s, TEST_TAG_EXPECT_REGEX_PFX)) {
306-
msg = s + sizeof(TEST_TAG_EXPECT_REGEX_PFX) - 1;
332+
} else if ((msg = skip_dynamic_pfx(s, TEST_TAG_EXPECT_REGEX_PFX))) {
307333
err = push_msg(NULL, msg, &spec->priv.expect_msgs);
308334
if (err)
309335
goto cleanup;
310336
spec->mode_mask |= PRIV;
311-
} else if (str_has_pfx(s, TEST_TAG_EXPECT_REGEX_PFX_UNPRIV)) {
312-
msg = s + sizeof(TEST_TAG_EXPECT_REGEX_PFX_UNPRIV) - 1;
337+
} else if ((msg = skip_dynamic_pfx(s, TEST_TAG_EXPECT_REGEX_PFX_UNPRIV))) {
313338
err = push_msg(NULL, msg, &spec->unpriv.expect_msgs);
314339
if (err)
315340
goto cleanup;
316341
spec->mode_mask |= UNPRIV;
317-
} else if (str_has_pfx(s, TEST_TAG_EXPECT_XLATED_PFX)) {
318-
msg = s + sizeof(TEST_TAG_EXPECT_XLATED_PFX) - 1;
342+
} else if ((msg = skip_dynamic_pfx(s, TEST_TAG_EXPECT_XLATED_PFX))) {
319343
err = push_msg(msg, NULL, &spec->priv.expect_xlated);
320344
if (err)
321345
goto cleanup;
322346
spec->mode_mask |= PRIV;
323-
} else if (str_has_pfx(s, TEST_TAG_EXPECT_XLATED_PFX_UNPRIV)) {
324-
msg = s + sizeof(TEST_TAG_EXPECT_XLATED_PFX_UNPRIV) - 1;
347+
} else if ((msg = skip_dynamic_pfx(s, TEST_TAG_EXPECT_XLATED_PFX_UNPRIV))) {
325348
err = push_msg(msg, NULL, &spec->unpriv.expect_xlated);
326349
if (err)
327350
goto cleanup;

0 commit comments

Comments
 (0)