1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2020 Facebook */
6 #include <test_progs.h>
9 static int duration
= 0;
11 void test_btf_endian() {
12 #if __BYTE_ORDER == __LITTLE_ENDIAN
13 enum btf_endianness endian
= BTF_LITTLE_ENDIAN
;
14 #elif __BYTE_ORDER == __BIG_ENDIAN
15 enum btf_endianness endian
= BTF_BIG_ENDIAN
;
17 #error "Unrecognized __BYTE_ORDER"
19 enum btf_endianness swap_endian
= 1 - endian
;
20 struct btf
*btf
= NULL
, *swap_btf
= NULL
;
21 const void *raw_data
, *swap_raw_data
;
22 const struct btf_type
*t
;
23 const struct btf_header
*hdr
;
24 __u32 raw_sz
, swap_raw_sz
;
27 /* Load BTF in native endianness */
28 btf
= btf__parse_elf("btf_dump_test_case_syntax.o", NULL
);
29 if (!ASSERT_OK_PTR(btf
, "parse_native_btf"))
32 ASSERT_EQ(btf__endianness(btf
), endian
, "endian");
33 btf__set_endianness(btf
, swap_endian
);
34 ASSERT_EQ(btf__endianness(btf
), swap_endian
, "endian");
36 /* Get raw BTF data in non-native endianness... */
37 raw_data
= btf__get_raw_data(btf
, &raw_sz
);
38 if (!ASSERT_OK_PTR(raw_data
, "raw_data_inverted"))
41 /* ...and open it as a new BTF instance */
42 swap_btf
= btf__new(raw_data
, raw_sz
);
43 if (!ASSERT_OK_PTR(swap_btf
, "parse_swap_btf"))
46 ASSERT_EQ(btf__endianness(swap_btf
), swap_endian
, "endian");
47 ASSERT_EQ(btf__get_nr_types(swap_btf
), btf__get_nr_types(btf
), "nr_types");
49 swap_raw_data
= btf__get_raw_data(swap_btf
, &swap_raw_sz
);
50 if (!ASSERT_OK_PTR(swap_raw_data
, "swap_raw_data"))
53 /* both raw data should be identical (with non-native endianness) */
54 ASSERT_OK(memcmp(raw_data
, swap_raw_data
, raw_sz
), "mem_identical");
56 /* make sure that at least BTF header data is really swapped */
58 ASSERT_EQ(bswap_16(hdr
->magic
), BTF_MAGIC
, "btf_magic_swapped");
59 ASSERT_EQ(raw_sz
, swap_raw_sz
, "raw_sizes");
61 /* swap it back to native endianness */
62 btf__set_endianness(swap_btf
, endian
);
63 swap_raw_data
= btf__get_raw_data(swap_btf
, &swap_raw_sz
);
64 if (!ASSERT_OK_PTR(swap_raw_data
, "swap_raw_data"))
67 /* now header should have native BTF_MAGIC */
69 ASSERT_EQ(hdr
->magic
, BTF_MAGIC
, "btf_magic_native");
70 ASSERT_EQ(raw_sz
, swap_raw_sz
, "raw_sizes");
72 /* now modify original BTF */
73 var_id
= btf__add_var(btf
, "some_var", BTF_VAR_GLOBAL_ALLOCATED
, 1);
74 CHECK(var_id
<= 0, "var_id", "failed %d\n", var_id
);
79 btf__set_endianness(btf
, swap_endian
);
80 raw_data
= btf__get_raw_data(btf
, &raw_sz
);
81 if (!ASSERT_OK_PTR(raw_data
, "raw_data_inverted"))
84 /* and re-open swapped raw data again */
85 swap_btf
= btf__new(raw_data
, raw_sz
);
86 if (!ASSERT_OK_PTR(swap_btf
, "parse_swap_btf"))
89 ASSERT_EQ(btf__endianness(swap_btf
), swap_endian
, "endian");
90 ASSERT_EQ(btf__get_nr_types(swap_btf
), btf__get_nr_types(btf
), "nr_types");
92 /* the type should appear as if it was stored in native endianness */
93 t
= btf__type_by_id(swap_btf
, var_id
);
94 ASSERT_STREQ(btf__str_by_offset(swap_btf
, t
->name_off
), "some_var", "var_name");
95 ASSERT_EQ(btf_var(t
)->linkage
, BTF_VAR_GLOBAL_ALLOCATED
, "var_linkage");
96 ASSERT_EQ(t
->type
, 1, "var_type");