cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

btf_dedup_split.c (13551B)


      1// SPDX-License-Identifier: GPL-2.0
      2/* Copyright (c) 2020 Facebook */
      3#include <test_progs.h>
      4#include <bpf/btf.h>
      5#include "btf_helpers.h"
      6
      7static void test_split_simple() {
      8	const struct btf_type *t;
      9	struct btf *btf1, *btf2;
     10	int str_off, err;
     11
     12	btf1 = btf__new_empty();
     13	if (!ASSERT_OK_PTR(btf1, "empty_main_btf"))
     14		return;
     15
     16	btf__set_pointer_size(btf1, 8); /* enforce 64-bit arch */
     17
     18	btf__add_int(btf1, "int", 4, BTF_INT_SIGNED);	/* [1] int */
     19	btf__add_ptr(btf1, 1);				/* [2] ptr to int */
     20	btf__add_struct(btf1, "s1", 4);			/* [3] struct s1 { */
     21	btf__add_field(btf1, "f1", 1, 0, 0);		/*      int f1; */
     22							/* } */
     23
     24	VALIDATE_RAW_BTF(
     25		btf1,
     26		"[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
     27		"[2] PTR '(anon)' type_id=1",
     28		"[3] STRUCT 's1' size=4 vlen=1\n"
     29		"\t'f1' type_id=1 bits_offset=0");
     30
     31	ASSERT_STREQ(btf_type_c_dump(btf1), "\
     32struct s1 {\n\
     33	int f1;\n\
     34};\n\n", "c_dump");
     35
     36	btf2 = btf__new_empty_split(btf1);
     37	if (!ASSERT_OK_PTR(btf2, "empty_split_btf"))
     38		goto cleanup;
     39
     40	/* pointer size should be "inherited" from main BTF */
     41	ASSERT_EQ(btf__pointer_size(btf2), 8, "inherit_ptr_sz");
     42
     43	str_off = btf__find_str(btf2, "int");
     44	ASSERT_NEQ(str_off, -ENOENT, "str_int_missing");
     45
     46	t = btf__type_by_id(btf2, 1);
     47	if (!ASSERT_OK_PTR(t, "int_type"))
     48		goto cleanup;
     49	ASSERT_EQ(btf_is_int(t), true, "int_kind");
     50	ASSERT_STREQ(btf__str_by_offset(btf2, t->name_off), "int", "int_name");
     51
     52	btf__add_struct(btf2, "s2", 16);		/* [4] struct s2 {	*/
     53	btf__add_field(btf2, "f1", 6, 0, 0);		/*      struct s1 f1;	*/
     54	btf__add_field(btf2, "f2", 5, 32, 0);		/*      int f2;		*/
     55	btf__add_field(btf2, "f3", 2, 64, 0);		/*      int *f3;	*/
     56							/* } */
     57
     58	/* duplicated int */
     59	btf__add_int(btf2, "int", 4, BTF_INT_SIGNED);	/* [5] int */
     60
     61	/* duplicated struct s1 */
     62	btf__add_struct(btf2, "s1", 4);			/* [6] struct s1 { */
     63	btf__add_field(btf2, "f1", 5, 0, 0);		/*      int f1; */
     64							/* } */
     65
     66	VALIDATE_RAW_BTF(
     67		btf2,
     68		"[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
     69		"[2] PTR '(anon)' type_id=1",
     70		"[3] STRUCT 's1' size=4 vlen=1\n"
     71		"\t'f1' type_id=1 bits_offset=0",
     72		"[4] STRUCT 's2' size=16 vlen=3\n"
     73		"\t'f1' type_id=6 bits_offset=0\n"
     74		"\t'f2' type_id=5 bits_offset=32\n"
     75		"\t'f3' type_id=2 bits_offset=64",
     76		"[5] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
     77		"[6] STRUCT 's1' size=4 vlen=1\n"
     78		"\t'f1' type_id=5 bits_offset=0");
     79
     80	ASSERT_STREQ(btf_type_c_dump(btf2), "\
     81struct s1 {\n\
     82	int f1;\n\
     83};\n\
     84\n\
     85struct s1___2 {\n\
     86	int f1;\n\
     87};\n\
     88\n\
     89struct s2 {\n\
     90	struct s1___2 f1;\n\
     91	int f2;\n\
     92	int *f3;\n\
     93};\n\n", "c_dump");
     94
     95	err = btf__dedup(btf2, NULL);
     96	if (!ASSERT_OK(err, "btf_dedup"))
     97		goto cleanup;
     98
     99	VALIDATE_RAW_BTF(
    100		btf2,
    101		"[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
    102		"[2] PTR '(anon)' type_id=1",
    103		"[3] STRUCT 's1' size=4 vlen=1\n"
    104		"\t'f1' type_id=1 bits_offset=0",
    105		"[4] STRUCT 's2' size=16 vlen=3\n"
    106		"\t'f1' type_id=3 bits_offset=0\n"
    107		"\t'f2' type_id=1 bits_offset=32\n"
    108		"\t'f3' type_id=2 bits_offset=64");
    109
    110	ASSERT_STREQ(btf_type_c_dump(btf2), "\
    111struct s1 {\n\
    112	int f1;\n\
    113};\n\
    114\n\
    115struct s2 {\n\
    116	struct s1 f1;\n\
    117	int f2;\n\
    118	int *f3;\n\
    119};\n\n", "c_dump");
    120
    121cleanup:
    122	btf__free(btf2);
    123	btf__free(btf1);
    124}
    125
    126static void test_split_fwd_resolve() {
    127	struct btf *btf1, *btf2;
    128	int err;
    129
    130	btf1 = btf__new_empty();
    131	if (!ASSERT_OK_PTR(btf1, "empty_main_btf"))
    132		return;
    133
    134	btf__set_pointer_size(btf1, 8); /* enforce 64-bit arch */
    135
    136	btf__add_int(btf1, "int", 4, BTF_INT_SIGNED);	/* [1] int */
    137	btf__add_ptr(btf1, 4);				/* [2] ptr to struct s1 */
    138	btf__add_ptr(btf1, 5);				/* [3] ptr to struct s2 */
    139	btf__add_struct(btf1, "s1", 16);		/* [4] struct s1 { */
    140	btf__add_field(btf1, "f1", 2, 0, 0);		/*      struct s1 *f1; */
    141	btf__add_field(btf1, "f2", 3, 64, 0);		/*      struct s2 *f2; */
    142							/* } */
    143	btf__add_struct(btf1, "s2", 4);			/* [5] struct s2 { */
    144	btf__add_field(btf1, "f1", 1, 0, 0);		/*      int f1; */
    145							/* } */
    146
    147	VALIDATE_RAW_BTF(
    148		btf1,
    149		"[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
    150		"[2] PTR '(anon)' type_id=4",
    151		"[3] PTR '(anon)' type_id=5",
    152		"[4] STRUCT 's1' size=16 vlen=2\n"
    153		"\t'f1' type_id=2 bits_offset=0\n"
    154		"\t'f2' type_id=3 bits_offset=64",
    155		"[5] STRUCT 's2' size=4 vlen=1\n"
    156		"\t'f1' type_id=1 bits_offset=0");
    157
    158	btf2 = btf__new_empty_split(btf1);
    159	if (!ASSERT_OK_PTR(btf2, "empty_split_btf"))
    160		goto cleanup;
    161
    162	btf__add_int(btf2, "int", 4, BTF_INT_SIGNED);	/* [6] int */
    163	btf__add_ptr(btf2, 10);				/* [7] ptr to struct s1 */
    164	btf__add_fwd(btf2, "s2", BTF_FWD_STRUCT);	/* [8] fwd for struct s2 */
    165	btf__add_ptr(btf2, 8);				/* [9] ptr to fwd struct s2 */
    166	btf__add_struct(btf2, "s1", 16);		/* [10] struct s1 { */
    167	btf__add_field(btf2, "f1", 7, 0, 0);		/*      struct s1 *f1; */
    168	btf__add_field(btf2, "f2", 9, 64, 0);		/*      struct s2 *f2; */
    169							/* } */
    170
    171	VALIDATE_RAW_BTF(
    172		btf2,
    173		"[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
    174		"[2] PTR '(anon)' type_id=4",
    175		"[3] PTR '(anon)' type_id=5",
    176		"[4] STRUCT 's1' size=16 vlen=2\n"
    177		"\t'f1' type_id=2 bits_offset=0\n"
    178		"\t'f2' type_id=3 bits_offset=64",
    179		"[5] STRUCT 's2' size=4 vlen=1\n"
    180		"\t'f1' type_id=1 bits_offset=0",
    181		"[6] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
    182		"[7] PTR '(anon)' type_id=10",
    183		"[8] FWD 's2' fwd_kind=struct",
    184		"[9] PTR '(anon)' type_id=8",
    185		"[10] STRUCT 's1' size=16 vlen=2\n"
    186		"\t'f1' type_id=7 bits_offset=0\n"
    187		"\t'f2' type_id=9 bits_offset=64");
    188
    189	err = btf__dedup(btf2, NULL);
    190	if (!ASSERT_OK(err, "btf_dedup"))
    191		goto cleanup;
    192
    193	VALIDATE_RAW_BTF(
    194		btf2,
    195		"[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
    196		"[2] PTR '(anon)' type_id=4",
    197		"[3] PTR '(anon)' type_id=5",
    198		"[4] STRUCT 's1' size=16 vlen=2\n"
    199		"\t'f1' type_id=2 bits_offset=0\n"
    200		"\t'f2' type_id=3 bits_offset=64",
    201		"[5] STRUCT 's2' size=4 vlen=1\n"
    202		"\t'f1' type_id=1 bits_offset=0");
    203
    204cleanup:
    205	btf__free(btf2);
    206	btf__free(btf1);
    207}
    208
    209static void test_split_struct_duped() {
    210	struct btf *btf1, *btf2;
    211	int err;
    212
    213	btf1 = btf__new_empty();
    214	if (!ASSERT_OK_PTR(btf1, "empty_main_btf"))
    215		return;
    216
    217	btf__set_pointer_size(btf1, 8); /* enforce 64-bit arch */
    218
    219	btf__add_int(btf1, "int", 4, BTF_INT_SIGNED);	/* [1] int */
    220	btf__add_ptr(btf1, 5);				/* [2] ptr to struct s1 */
    221	btf__add_fwd(btf1, "s2", BTF_FWD_STRUCT);	/* [3] fwd for struct s2 */
    222	btf__add_ptr(btf1, 3);				/* [4] ptr to fwd struct s2 */
    223	btf__add_struct(btf1, "s1", 16);		/* [5] struct s1 { */
    224	btf__add_field(btf1, "f1", 2, 0, 0);		/*      struct s1 *f1; */
    225	btf__add_field(btf1, "f2", 4, 64, 0);		/*      struct s2 *f2; */
    226							/* } */
    227
    228	VALIDATE_RAW_BTF(
    229		btf1,
    230		"[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
    231		"[2] PTR '(anon)' type_id=5",
    232		"[3] FWD 's2' fwd_kind=struct",
    233		"[4] PTR '(anon)' type_id=3",
    234		"[5] STRUCT 's1' size=16 vlen=2\n"
    235		"\t'f1' type_id=2 bits_offset=0\n"
    236		"\t'f2' type_id=4 bits_offset=64");
    237
    238	btf2 = btf__new_empty_split(btf1);
    239	if (!ASSERT_OK_PTR(btf2, "empty_split_btf"))
    240		goto cleanup;
    241
    242	btf__add_int(btf2, "int", 4, BTF_INT_SIGNED);	/* [6] int */
    243	btf__add_ptr(btf2, 10);				/* [7] ptr to struct s1 */
    244	btf__add_fwd(btf2, "s2", BTF_FWD_STRUCT);	/* [8] fwd for struct s2 */
    245	btf__add_ptr(btf2, 11);				/* [9] ptr to struct s2 */
    246	btf__add_struct(btf2, "s1", 16);		/* [10] struct s1 { */
    247	btf__add_field(btf2, "f1", 7, 0, 0);		/*      struct s1 *f1; */
    248	btf__add_field(btf2, "f2", 9, 64, 0);		/*      struct s2 *f2; */
    249							/* } */
    250	btf__add_struct(btf2, "s2", 40);		/* [11] struct s2 {	*/
    251	btf__add_field(btf2, "f1", 7, 0, 0);		/*      struct s1 *f1;	*/
    252	btf__add_field(btf2, "f2", 9, 64, 0);		/*      struct s2 *f2;	*/
    253	btf__add_field(btf2, "f3", 6, 128, 0);		/*      int f3;		*/
    254	btf__add_field(btf2, "f4", 10, 192, 0);		/*      struct s1 f4;	*/
    255							/* } */
    256	btf__add_ptr(btf2, 8);				/* [12] ptr to fwd struct s2 */
    257	btf__add_struct(btf2, "s3", 8);			/* [13] struct s3 { */
    258	btf__add_field(btf2, "f1", 12, 0, 0);		/*      struct s2 *f1; (fwd) */
    259							/* } */
    260
    261	VALIDATE_RAW_BTF(
    262		btf2,
    263		"[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
    264		"[2] PTR '(anon)' type_id=5",
    265		"[3] FWD 's2' fwd_kind=struct",
    266		"[4] PTR '(anon)' type_id=3",
    267		"[5] STRUCT 's1' size=16 vlen=2\n"
    268		"\t'f1' type_id=2 bits_offset=0\n"
    269		"\t'f2' type_id=4 bits_offset=64",
    270		"[6] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
    271		"[7] PTR '(anon)' type_id=10",
    272		"[8] FWD 's2' fwd_kind=struct",
    273		"[9] PTR '(anon)' type_id=11",
    274		"[10] STRUCT 's1' size=16 vlen=2\n"
    275		"\t'f1' type_id=7 bits_offset=0\n"
    276		"\t'f2' type_id=9 bits_offset=64",
    277		"[11] STRUCT 's2' size=40 vlen=4\n"
    278		"\t'f1' type_id=7 bits_offset=0\n"
    279		"\t'f2' type_id=9 bits_offset=64\n"
    280		"\t'f3' type_id=6 bits_offset=128\n"
    281		"\t'f4' type_id=10 bits_offset=192",
    282		"[12] PTR '(anon)' type_id=8",
    283		"[13] STRUCT 's3' size=8 vlen=1\n"
    284		"\t'f1' type_id=12 bits_offset=0");
    285
    286	err = btf__dedup(btf2, NULL);
    287	if (!ASSERT_OK(err, "btf_dedup"))
    288		goto cleanup;
    289
    290	VALIDATE_RAW_BTF(
    291		btf2,
    292		"[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
    293		"[2] PTR '(anon)' type_id=5",
    294		"[3] FWD 's2' fwd_kind=struct",
    295		"[4] PTR '(anon)' type_id=3",
    296		"[5] STRUCT 's1' size=16 vlen=2\n"
    297		"\t'f1' type_id=2 bits_offset=0\n"
    298		"\t'f2' type_id=4 bits_offset=64",
    299		"[6] PTR '(anon)' type_id=8",
    300		"[7] PTR '(anon)' type_id=9",
    301		"[8] STRUCT 's1' size=16 vlen=2\n"
    302		"\t'f1' type_id=6 bits_offset=0\n"
    303		"\t'f2' type_id=7 bits_offset=64",
    304		"[9] STRUCT 's2' size=40 vlen=4\n"
    305		"\t'f1' type_id=6 bits_offset=0\n"
    306		"\t'f2' type_id=7 bits_offset=64\n"
    307		"\t'f3' type_id=1 bits_offset=128\n"
    308		"\t'f4' type_id=8 bits_offset=192",
    309		"[10] STRUCT 's3' size=8 vlen=1\n"
    310		"\t'f1' type_id=7 bits_offset=0");
    311
    312cleanup:
    313	btf__free(btf2);
    314	btf__free(btf1);
    315}
    316
    317static void btf_add_dup_struct_in_cu(struct btf *btf, int start_id)
    318{
    319#define ID(n) (start_id + n)
    320	btf__set_pointer_size(btf, 8); /* enforce 64-bit arch */
    321
    322	btf__add_int(btf, "int", 4, BTF_INT_SIGNED);    /* [1] int */
    323
    324	btf__add_struct(btf, "s", 8);                   /* [2] struct s { */
    325	btf__add_field(btf, "a", ID(3), 0, 0);          /*      struct anon a; */
    326	btf__add_field(btf, "b", ID(4), 0, 0);          /*      struct anon b; */
    327							/* } */
    328
    329	btf__add_struct(btf, "(anon)", 8);              /* [3] struct anon { */
    330	btf__add_field(btf, "f1", ID(1), 0, 0);         /*      int f1; */
    331	btf__add_field(btf, "f2", ID(1), 32, 0);        /*      int f2; */
    332							/* } */
    333
    334	btf__add_struct(btf, "(anon)", 8);              /* [4] struct anon { */
    335	btf__add_field(btf, "f1", ID(1), 0, 0);         /*      int f1; */
    336	btf__add_field(btf, "f2", ID(1), 32, 0);        /*      int f2; */
    337							/* } */
    338#undef ID
    339}
    340
    341static void test_split_dup_struct_in_cu()
    342{
    343	struct btf *btf1, *btf2 = NULL;
    344	int err;
    345
    346	/* generate the base data.. */
    347	btf1 = btf__new_empty();
    348	if (!ASSERT_OK_PTR(btf1, "empty_main_btf"))
    349		return;
    350
    351	btf_add_dup_struct_in_cu(btf1, 0);
    352
    353	VALIDATE_RAW_BTF(
    354			btf1,
    355			"[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
    356			"[2] STRUCT 's' size=8 vlen=2\n"
    357			"\t'a' type_id=3 bits_offset=0\n"
    358			"\t'b' type_id=4 bits_offset=0",
    359			"[3] STRUCT '(anon)' size=8 vlen=2\n"
    360			"\t'f1' type_id=1 bits_offset=0\n"
    361			"\t'f2' type_id=1 bits_offset=32",
    362			"[4] STRUCT '(anon)' size=8 vlen=2\n"
    363			"\t'f1' type_id=1 bits_offset=0\n"
    364			"\t'f2' type_id=1 bits_offset=32");
    365
    366	/* ..dedup them... */
    367	err = btf__dedup(btf1, NULL);
    368	if (!ASSERT_OK(err, "btf_dedup"))
    369		goto cleanup;
    370
    371	VALIDATE_RAW_BTF(
    372			btf1,
    373			"[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
    374			"[2] STRUCT 's' size=8 vlen=2\n"
    375			"\t'a' type_id=3 bits_offset=0\n"
    376			"\t'b' type_id=3 bits_offset=0",
    377			"[3] STRUCT '(anon)' size=8 vlen=2\n"
    378			"\t'f1' type_id=1 bits_offset=0\n"
    379			"\t'f2' type_id=1 bits_offset=32");
    380
    381	/* and add the same data on top of it */
    382	btf2 = btf__new_empty_split(btf1);
    383	if (!ASSERT_OK_PTR(btf2, "empty_split_btf"))
    384		goto cleanup;
    385
    386	btf_add_dup_struct_in_cu(btf2, 3);
    387
    388	VALIDATE_RAW_BTF(
    389			btf2,
    390			"[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
    391			"[2] STRUCT 's' size=8 vlen=2\n"
    392			"\t'a' type_id=3 bits_offset=0\n"
    393			"\t'b' type_id=3 bits_offset=0",
    394			"[3] STRUCT '(anon)' size=8 vlen=2\n"
    395			"\t'f1' type_id=1 bits_offset=0\n"
    396			"\t'f2' type_id=1 bits_offset=32",
    397			"[4] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
    398			"[5] STRUCT 's' size=8 vlen=2\n"
    399			"\t'a' type_id=6 bits_offset=0\n"
    400			"\t'b' type_id=7 bits_offset=0",
    401			"[6] STRUCT '(anon)' size=8 vlen=2\n"
    402			"\t'f1' type_id=4 bits_offset=0\n"
    403			"\t'f2' type_id=4 bits_offset=32",
    404			"[7] STRUCT '(anon)' size=8 vlen=2\n"
    405			"\t'f1' type_id=4 bits_offset=0\n"
    406			"\t'f2' type_id=4 bits_offset=32");
    407
    408	err = btf__dedup(btf2, NULL);
    409	if (!ASSERT_OK(err, "btf_dedup"))
    410		goto cleanup;
    411
    412	/* after dedup it should match the original data */
    413	VALIDATE_RAW_BTF(
    414			btf2,
    415			"[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
    416			"[2] STRUCT 's' size=8 vlen=2\n"
    417			"\t'a' type_id=3 bits_offset=0\n"
    418			"\t'b' type_id=3 bits_offset=0",
    419			"[3] STRUCT '(anon)' size=8 vlen=2\n"
    420			"\t'f1' type_id=1 bits_offset=0\n"
    421			"\t'f2' type_id=1 bits_offset=32");
    422
    423cleanup:
    424	btf__free(btf2);
    425	btf__free(btf1);
    426}
    427
    428void test_btf_dedup_split()
    429{
    430	if (test__start_subtest("split_simple"))
    431		test_split_simple();
    432	if (test__start_subtest("split_struct_duped"))
    433		test_split_struct_duped();
    434	if (test__start_subtest("split_fwd_resolve"))
    435		test_split_fwd_resolve();
    436	if (test__start_subtest("split_dup_struct_in_cu"))
    437		test_split_dup_struct_in_cu();
    438}