1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2024, Oracle and/or its affiliates. */ 3 4 #include <test_progs.h> 5 #include <bpf/btf.h> 6 #include "btf_helpers.h" 7 8 /* Fabricate base, split BTF with references to base types needed; then create 9 * split BTF with distilled base BTF and ensure expectations are met: 10 * - only referenced base types from split BTF are present 11 * - struct/union/enum are represented as empty unless anonymous, when they 12 * are represented in full in split BTF 13 */ 14 static void test_distilled_base(void) 15 { 16 struct btf *btf1 = NULL, *btf2 = NULL, *btf3 = NULL, *btf4 = NULL; 17 18 btf1 = btf__new_empty(); 19 if (!ASSERT_OK_PTR(btf1, "empty_main_btf")) 20 return; 21 22 btf__add_int(btf1, "int", 4, BTF_INT_SIGNED); /* [1] int */ 23 btf__add_ptr(btf1, 1); /* [2] ptr to int */ 24 btf__add_struct(btf1, "s1", 8); /* [3] struct s1 { */ 25 btf__add_field(btf1, "f1", 2, 0, 0); /* int *f1; */ 26 /* } */ 27 btf__add_struct(btf1, "", 12); /* [4] struct { */ 28 btf__add_field(btf1, "f1", 1, 0, 0); /* int f1; */ 29 btf__add_field(btf1, "f2", 3, 32, 0); /* struct s1 f2; */ 30 /* } */ 31 btf__add_int(btf1, "unsigned int", 4, 0); /* [5] unsigned int */ 32 btf__add_union(btf1, "u1", 12); /* [6] union u1 { */ 33 btf__add_field(btf1, "f1", 1, 0, 0); /* int f1; */ 34 btf__add_field(btf1, "f2", 2, 0, 0); /* int *f2; */ 35 /* } */ 36 btf__add_union(btf1, "", 4); /* [7] union { */ 37 btf__add_field(btf1, "f1", 1, 0, 0); /* int f1; */ 38 /* } */ 39 btf__add_enum(btf1, "e1", 4); /* [8] enum e1 { */ 40 btf__add_enum_value(btf1, "v1", 1); /* v1 = 1; */ 41 /* } */ 42 btf__add_enum(btf1, "", 4); /* [9] enum { */ 43 btf__add_enum_value(btf1, "av1", 2); /* av1 = 2; */ 44 /* } */ 45 btf__add_enum64(btf1, "e641", 8, true); /* [10] enum64 { */ 46 btf__add_enum64_value(btf1, "v1", 1024); /* v1 = 1024; */ 47 /* } */ 48 btf__add_enum64(btf1, "", 8, true); /* [11] enum64 { */ 49 btf__add_enum64_value(btf1, "v1", 1025); /* v1 = 1025; */ 50 /* } */ 51 btf__add_struct(btf1, "unneeded", 4); /* [12] struct unneeded { */ 52 btf__add_field(btf1, "f1", 1, 0, 0); /* int f1; */ 53 /* } */ 54 btf__add_struct(btf1, "embedded", 4); /* [13] struct embedded { */ 55 btf__add_field(btf1, "f1", 1, 0, 0); /* int f1; */ 56 /* } */ 57 btf__add_func_proto(btf1, 1); /* [14] int (*)(int *p1); */ 58 btf__add_func_param(btf1, "p1", 1); 59 60 btf__add_array(btf1, 1, 1, 3); /* [15] int [3]; */ 61 62 btf__add_struct(btf1, "from_proto", 4); /* [16] struct from_proto { */ 63 btf__add_field(btf1, "f1", 1, 0, 0); /* int f1; */ 64 /* } */ 65 btf__add_union(btf1, "u1", 4); /* [17] union u1 { */ 66 btf__add_field(btf1, "f1", 1, 0, 0); /* int f1; */ 67 /* } */ 68 VALIDATE_RAW_BTF( 69 btf1, 70 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED", 71 "[2] PTR '(anon)' type_id=1", 72 "[3] STRUCT 's1' size=8 vlen=1\n" 73 "\t'f1' type_id=2 bits_offset=0", 74 "[4] STRUCT '(anon)' size=12 vlen=2\n" 75 "\t'f1' type_id=1 bits_offset=0\n" 76 "\t'f2' type_id=3 bits_offset=32", 77 "[5] INT 'unsigned int' size=4 bits_offset=0 nr_bits=32 encoding=(none)", 78 "[6] UNION 'u1' size=12 vlen=2\n" 79 "\t'f1' type_id=1 bits_offset=0\n" 80 "\t'f2' type_id=2 bits_offset=0", 81 "[7] UNION '(anon)' size=4 vlen=1\n" 82 "\t'f1' type_id=1 bits_offset=0", 83 "[8] ENUM 'e1' encoding=UNSIGNED size=4 vlen=1\n" 84 "\t'v1' val=1", 85 "[9] ENUM '(anon)' encoding=UNSIGNED size=4 vlen=1\n" 86 "\t'av1' val=2", 87 "[10] ENUM64 'e641' encoding=SIGNED size=8 vlen=1\n" 88 "\t'v1' val=1024", 89 "[11] ENUM64 '(anon)' encoding=SIGNED size=8 vlen=1\n" 90 "\t'v1' val=1025", 91 "[12] STRUCT 'unneeded' size=4 vlen=1\n" 92 "\t'f1' type_id=1 bits_offset=0", 93 "[13] STRUCT 'embedded' size=4 vlen=1\n" 94 "\t'f1' type_id=1 bits_offset=0", 95 "[14] FUNC_PROTO '(anon)' ret_type_id=1 vlen=1\n" 96 "\t'p1' type_id=1", 97 "[15] ARRAY '(anon)' type_id=1 index_type_id=1 nr_elems=3", 98 "[16] STRUCT 'from_proto' size=4 vlen=1\n" 99 "\t'f1' type_id=1 bits_offset=0", 100 "[17] UNION 'u1' size=4 vlen=1\n" 101 "\t'f1' type_id=1 bits_offset=0"); 102 103 btf2 = btf__new_empty_split(btf1); 104 if (!ASSERT_OK_PTR(btf2, "empty_split_btf")) 105 goto cleanup; 106 107 btf__add_ptr(btf2, 3); /* [18] ptr to struct s1 */ 108 /* add ptr to struct anon */ 109 btf__add_ptr(btf2, 4); /* [19] ptr to struct (anon) */ 110 btf__add_const(btf2, 6); /* [20] const union u1 */ 111 btf__add_restrict(btf2, 7); /* [21] restrict union (anon) */ 112 btf__add_volatile(btf2, 8); /* [22] volatile enum e1 */ 113 btf__add_typedef(btf2, "et", 9); /* [23] typedef enum (anon) */ 114 btf__add_const(btf2, 10); /* [24] const enum64 e641 */ 115 btf__add_ptr(btf2, 11); /* [25] restrict enum64 (anon) */ 116 btf__add_struct(btf2, "with_embedded", 4); /* [26] struct with_embedded { */ 117 btf__add_field(btf2, "f1", 13, 0, 0); /* struct embedded f1; */ 118 /* } */ 119 btf__add_func(btf2, "fn", BTF_FUNC_STATIC, 14); /* [27] int fn(int p1); */ 120 btf__add_typedef(btf2, "arraytype", 15); /* [28] typedef int[3] foo; */ 121 btf__add_func_proto(btf2, 1); /* [29] int (*)(struct from proto p1); */ 122 btf__add_func_param(btf2, "p1", 16); 123 124 VALIDATE_RAW_BTF( 125 btf2, 126 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED", 127 "[2] PTR '(anon)' type_id=1", 128 "[3] STRUCT 's1' size=8 vlen=1\n" 129 "\t'f1' type_id=2 bits_offset=0", 130 "[4] STRUCT '(anon)' size=12 vlen=2\n" 131 "\t'f1' type_id=1 bits_offset=0\n" 132 "\t'f2' type_id=3 bits_offset=32", 133 "[5] INT 'unsigned int' size=4 bits_offset=0 nr_bits=32 encoding=(none)", 134 "[6] UNION 'u1' size=12 vlen=2\n" 135 "\t'f1' type_id=1 bits_offset=0\n" 136 "\t'f2' type_id=2 bits_offset=0", 137 "[7] UNION '(anon)' size=4 vlen=1\n" 138 "\t'f1' type_id=1 bits_offset=0", 139 "[8] ENUM 'e1' encoding=UNSIGNED size=4 vlen=1\n" 140 "\t'v1' val=1", 141 "[9] ENUM '(anon)' encoding=UNSIGNED size=4 vlen=1\n" 142 "\t'av1' val=2", 143 "[10] ENUM64 'e641' encoding=SIGNED size=8 vlen=1\n" 144 "\t'v1' val=1024", 145 "[11] ENUM64 '(anon)' encoding=SIGNED size=8 vlen=1\n" 146 "\t'v1' val=1025", 147 "[12] STRUCT 'unneeded' size=4 vlen=1\n" 148 "\t'f1' type_id=1 bits_offset=0", 149 "[13] STRUCT 'embedded' size=4 vlen=1\n" 150 "\t'f1' type_id=1 bits_offset=0", 151 "[14] FUNC_PROTO '(anon)' ret_type_id=1 vlen=1\n" 152 "\t'p1' type_id=1", 153 "[15] ARRAY '(anon)' type_id=1 index_type_id=1 nr_elems=3", 154 "[16] STRUCT 'from_proto' size=4 vlen=1\n" 155 "\t'f1' type_id=1 bits_offset=0", 156 "[17] UNION 'u1' size=4 vlen=1\n" 157 "\t'f1' type_id=1 bits_offset=0", 158 "[18] PTR '(anon)' type_id=3", 159 "[19] PTR '(anon)' type_id=4", 160 "[20] CONST '(anon)' type_id=6", 161 "[21] RESTRICT '(anon)' type_id=7", 162 "[22] VOLATILE '(anon)' type_id=8", 163 "[23] TYPEDEF 'et' type_id=9", 164 "[24] CONST '(anon)' type_id=10", 165 "[25] PTR '(anon)' type_id=11", 166 "[26] STRUCT 'with_embedded' size=4 vlen=1\n" 167 "\t'f1' type_id=13 bits_offset=0", 168 "[27] FUNC 'fn' type_id=14 linkage=static", 169 "[28] TYPEDEF 'arraytype' type_id=15", 170 "[29] FUNC_PROTO '(anon)' ret_type_id=1 vlen=1\n" 171 "\t'p1' type_id=16"); 172 173 if (!ASSERT_EQ(0, btf__distill_base(btf2, &btf3, &btf4), 174 "distilled_base") || 175 !ASSERT_OK_PTR(btf3, "distilled_base") || 176 !ASSERT_OK_PTR(btf4, "distilled_split") || 177 !ASSERT_EQ(8, btf__type_cnt(btf3), "distilled_base_type_cnt")) 178 goto cleanup; 179 180 VALIDATE_RAW_BTF( 181 btf4, 182 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED", 183 "[2] STRUCT 's1' size=8 vlen=0", 184 "[3] UNION 'u1' size=12 vlen=0", 185 "[4] ENUM 'e1' encoding=UNSIGNED size=4 vlen=0", 186 "[5] ENUM 'e641' encoding=UNSIGNED size=8 vlen=0", 187 "[6] STRUCT 'embedded' size=4 vlen=0", 188 "[7] STRUCT 'from_proto' size=4 vlen=0", 189 /* split BTF; these types should match split BTF above from 17-28, with 190 * updated type id references 191 */ 192 "[8] PTR '(anon)' type_id=2", 193 "[9] PTR '(anon)' type_id=20", 194 "[10] CONST '(anon)' type_id=3", 195 "[11] RESTRICT '(anon)' type_id=21", 196 "[12] VOLATILE '(anon)' type_id=4", 197 "[13] TYPEDEF 'et' type_id=22", 198 "[14] CONST '(anon)' type_id=5", 199 "[15] PTR '(anon)' type_id=23", 200 "[16] STRUCT 'with_embedded' size=4 vlen=1\n" 201 "\t'f1' type_id=6 bits_offset=0", 202 "[17] FUNC 'fn' type_id=24 linkage=static", 203 "[18] TYPEDEF 'arraytype' type_id=25", 204 "[19] FUNC_PROTO '(anon)' ret_type_id=1 vlen=1\n" 205 "\t'p1' type_id=7", 206 /* split BTF types added from original base BTF below */ 207 "[20] STRUCT '(anon)' size=12 vlen=2\n" 208 "\t'f1' type_id=1 bits_offset=0\n" 209 "\t'f2' type_id=2 bits_offset=32", 210 "[21] UNION '(anon)' size=4 vlen=1\n" 211 "\t'f1' type_id=1 bits_offset=0", 212 "[22] ENUM '(anon)' encoding=UNSIGNED size=4 vlen=1\n" 213 "\t'av1' val=2", 214 "[23] ENUM64 '(anon)' encoding=SIGNED size=8 vlen=1\n" 215 "\t'v1' val=1025", 216 "[24] FUNC_PROTO '(anon)' ret_type_id=1 vlen=1\n" 217 "\t'p1' type_id=1", 218 "[25] ARRAY '(anon)' type_id=1 index_type_id=1 nr_elems=3"); 219 220 if (!ASSERT_EQ(btf__relocate(btf4, btf1), 0, "relocate_split")) 221 goto cleanup; 222 223 VALIDATE_RAW_BTF( 224 btf4, 225 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED", 226 "[2] PTR '(anon)' type_id=1", 227 "[3] STRUCT 's1' size=8 vlen=1\n" 228 "\t'f1' type_id=2 bits_offset=0", 229 "[4] STRUCT '(anon)' size=12 vlen=2\n" 230 "\t'f1' type_id=1 bits_offset=0\n" 231 "\t'f2' type_id=3 bits_offset=32", 232 "[5] INT 'unsigned int' size=4 bits_offset=0 nr_bits=32 encoding=(none)", 233 "[6] UNION 'u1' size=12 vlen=2\n" 234 "\t'f1' type_id=1 bits_offset=0\n" 235 "\t'f2' type_id=2 bits_offset=0", 236 "[7] UNION '(anon)' size=4 vlen=1\n" 237 "\t'f1' type_id=1 bits_offset=0", 238 "[8] ENUM 'e1' encoding=UNSIGNED size=4 vlen=1\n" 239 "\t'v1' val=1", 240 "[9] ENUM '(anon)' encoding=UNSIGNED size=4 vlen=1\n" 241 "\t'av1' val=2", 242 "[10] ENUM64 'e641' encoding=SIGNED size=8 vlen=1\n" 243 "\t'v1' val=1024", 244 "[11] ENUM64 '(anon)' encoding=SIGNED size=8 vlen=1\n" 245 "\t'v1' val=1025", 246 "[12] STRUCT 'unneeded' size=4 vlen=1\n" 247 "\t'f1' type_id=1 bits_offset=0", 248 "[13] STRUCT 'embedded' size=4 vlen=1\n" 249 "\t'f1' type_id=1 bits_offset=0", 250 "[14] FUNC_PROTO '(anon)' ret_type_id=1 vlen=1\n" 251 "\t'p1' type_id=1", 252 "[15] ARRAY '(anon)' type_id=1 index_type_id=1 nr_elems=3", 253 "[16] STRUCT 'from_proto' size=4 vlen=1\n" 254 "\t'f1' type_id=1 bits_offset=0", 255 "[17] UNION 'u1' size=4 vlen=1\n" 256 "\t'f1' type_id=1 bits_offset=0", 257 "[18] PTR '(anon)' type_id=3", 258 "[19] PTR '(anon)' type_id=30", 259 "[20] CONST '(anon)' type_id=6", 260 "[21] RESTRICT '(anon)' type_id=31", 261 "[22] VOLATILE '(anon)' type_id=8", 262 "[23] TYPEDEF 'et' type_id=32", 263 "[24] CONST '(anon)' type_id=10", 264 "[25] PTR '(anon)' type_id=33", 265 "[26] STRUCT 'with_embedded' size=4 vlen=1\n" 266 "\t'f1' type_id=13 bits_offset=0", 267 "[27] FUNC 'fn' type_id=34 linkage=static", 268 "[28] TYPEDEF 'arraytype' type_id=35", 269 "[29] FUNC_PROTO '(anon)' ret_type_id=1 vlen=1\n" 270 "\t'p1' type_id=16", 271 /* below here are (duplicate) anon base types added by distill 272 * process to split BTF. 273 */ 274 "[30] STRUCT '(anon)' size=12 vlen=2\n" 275 "\t'f1' type_id=1 bits_offset=0\n" 276 "\t'f2' type_id=3 bits_offset=32", 277 "[31] UNION '(anon)' size=4 vlen=1\n" 278 "\t'f1' type_id=1 bits_offset=0", 279 "[32] ENUM '(anon)' encoding=UNSIGNED size=4 vlen=1\n" 280 "\t'av1' val=2", 281 "[33] ENUM64 '(anon)' encoding=SIGNED size=8 vlen=1\n" 282 "\t'v1' val=1025", 283 "[34] FUNC_PROTO '(anon)' ret_type_id=1 vlen=1\n" 284 "\t'p1' type_id=1", 285 "[35] ARRAY '(anon)' type_id=1 index_type_id=1 nr_elems=3"); 286 287 cleanup: 288 btf__free(btf4); 289 btf__free(btf3); 290 btf__free(btf2); 291 btf__free(btf1); 292 } 293 294 /* ensure we can cope with multiple types with the same name in 295 * distilled base BTF. In this case because sizes are different, 296 * we can still disambiguate them. 297 */ 298 static void test_distilled_base_multi(void) 299 { 300 struct btf *btf1 = NULL, *btf2 = NULL, *btf3 = NULL, *btf4 = NULL; 301 302 btf1 = btf__new_empty(); 303 if (!ASSERT_OK_PTR(btf1, "empty_main_btf")) 304 return; 305 btf__add_int(btf1, "int", 4, BTF_INT_SIGNED); /* [1] int */ 306 btf__add_int(btf1, "int", 8, BTF_INT_SIGNED); /* [2] int */ 307 VALIDATE_RAW_BTF( 308 btf1, 309 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED", 310 "[2] INT 'int' size=8 bits_offset=0 nr_bits=64 encoding=SIGNED"); 311 btf2 = btf__new_empty_split(btf1); 312 if (!ASSERT_OK_PTR(btf2, "empty_split_btf")) 313 goto cleanup; 314 btf__add_ptr(btf2, 1); 315 btf__add_const(btf2, 2); 316 VALIDATE_RAW_BTF( 317 btf2, 318 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED", 319 "[2] INT 'int' size=8 bits_offset=0 nr_bits=64 encoding=SIGNED", 320 "[3] PTR '(anon)' type_id=1", 321 "[4] CONST '(anon)' type_id=2"); 322 if (!ASSERT_EQ(0, btf__distill_base(btf2, &btf3, &btf4), 323 "distilled_base") || 324 !ASSERT_OK_PTR(btf3, "distilled_base") || 325 !ASSERT_OK_PTR(btf4, "distilled_split") || 326 !ASSERT_EQ(3, btf__type_cnt(btf3), "distilled_base_type_cnt")) 327 goto cleanup; 328 VALIDATE_RAW_BTF( 329 btf3, 330 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED", 331 "[2] INT 'int' size=8 bits_offset=0 nr_bits=64 encoding=SIGNED"); 332 if (!ASSERT_EQ(btf__relocate(btf4, btf1), 0, "relocate_split")) 333 goto cleanup; 334 335 VALIDATE_RAW_BTF( 336 btf4, 337 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED", 338 "[2] INT 'int' size=8 bits_offset=0 nr_bits=64 encoding=SIGNED", 339 "[3] PTR '(anon)' type_id=1", 340 "[4] CONST '(anon)' type_id=2"); 341 342 cleanup: 343 btf__free(btf4); 344 btf__free(btf3); 345 btf__free(btf2); 346 btf__free(btf1); 347 } 348 349 /* If a needed type is not present in the base BTF we wish to relocate 350 * with, btf__relocate() should error our. 351 */ 352 static void test_distilled_base_missing_err(void) 353 { 354 struct btf *btf1 = NULL, *btf2 = NULL, *btf3 = NULL, *btf4 = NULL, *btf5 = NULL; 355 356 btf1 = btf__new_empty(); 357 if (!ASSERT_OK_PTR(btf1, "empty_main_btf")) 358 return; 359 btf__add_int(btf1, "int", 4, BTF_INT_SIGNED); /* [1] int */ 360 btf__add_int(btf1, "int", 8, BTF_INT_SIGNED); /* [2] int */ 361 VALIDATE_RAW_BTF( 362 btf1, 363 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED", 364 "[2] INT 'int' size=8 bits_offset=0 nr_bits=64 encoding=SIGNED"); 365 btf2 = btf__new_empty_split(btf1); 366 if (!ASSERT_OK_PTR(btf2, "empty_split_btf")) 367 goto cleanup; 368 btf__add_ptr(btf2, 1); 369 btf__add_const(btf2, 2); 370 VALIDATE_RAW_BTF( 371 btf2, 372 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED", 373 "[2] INT 'int' size=8 bits_offset=0 nr_bits=64 encoding=SIGNED", 374 "[3] PTR '(anon)' type_id=1", 375 "[4] CONST '(anon)' type_id=2"); 376 if (!ASSERT_EQ(0, btf__distill_base(btf2, &btf3, &btf4), 377 "distilled_base") || 378 !ASSERT_OK_PTR(btf3, "distilled_base") || 379 !ASSERT_OK_PTR(btf4, "distilled_split") || 380 !ASSERT_EQ(3, btf__type_cnt(btf3), "distilled_base_type_cnt")) 381 goto cleanup; 382 VALIDATE_RAW_BTF( 383 btf3, 384 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED", 385 "[2] INT 'int' size=8 bits_offset=0 nr_bits=64 encoding=SIGNED"); 386 btf5 = btf__new_empty(); 387 if (!ASSERT_OK_PTR(btf5, "empty_reloc_btf")) 388 return; 389 btf__add_int(btf5, "int", 4, BTF_INT_SIGNED); /* [1] int */ 390 VALIDATE_RAW_BTF( 391 btf5, 392 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED"); 393 ASSERT_EQ(btf__relocate(btf4, btf5), -EINVAL, "relocate_split"); 394 395 cleanup: 396 btf__free(btf5); 397 btf__free(btf4); 398 btf__free(btf3); 399 btf__free(btf2); 400 btf__free(btf1); 401 } 402 403 /* With 2 types of same size in distilled base BTF, relocation should 404 * fail as we have no means to choose between them. 405 */ 406 static void test_distilled_base_multi_err(void) 407 { 408 struct btf *btf1 = NULL, *btf2 = NULL, *btf3 = NULL, *btf4 = NULL; 409 410 btf1 = btf__new_empty(); 411 if (!ASSERT_OK_PTR(btf1, "empty_main_btf")) 412 return; 413 btf__add_int(btf1, "int", 4, BTF_INT_SIGNED); /* [1] int */ 414 btf__add_int(btf1, "int", 4, BTF_INT_SIGNED); /* [2] int */ 415 VALIDATE_RAW_BTF( 416 btf1, 417 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED", 418 "[2] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED"); 419 btf2 = btf__new_empty_split(btf1); 420 if (!ASSERT_OK_PTR(btf2, "empty_split_btf")) 421 goto cleanup; 422 btf__add_ptr(btf2, 1); 423 btf__add_const(btf2, 2); 424 VALIDATE_RAW_BTF( 425 btf2, 426 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED", 427 "[2] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED", 428 "[3] PTR '(anon)' type_id=1", 429 "[4] CONST '(anon)' type_id=2"); 430 if (!ASSERT_EQ(0, btf__distill_base(btf2, &btf3, &btf4), 431 "distilled_base") || 432 !ASSERT_OK_PTR(btf3, "distilled_base") || 433 !ASSERT_OK_PTR(btf4, "distilled_split") || 434 !ASSERT_EQ(3, btf__type_cnt(btf3), "distilled_base_type_cnt")) 435 goto cleanup; 436 VALIDATE_RAW_BTF( 437 btf3, 438 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED", 439 "[2] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED"); 440 ASSERT_EQ(btf__relocate(btf4, btf1), -EINVAL, "relocate_split"); 441 cleanup: 442 btf__free(btf4); 443 btf__free(btf3); 444 btf__free(btf2); 445 btf__free(btf1); 446 } 447 448 /* With 2 types of same size in base BTF, relocation should 449 * fail as we have no means to choose between them. 450 */ 451 static void test_distilled_base_multi_err2(void) 452 { 453 struct btf *btf1 = NULL, *btf2 = NULL, *btf3 = NULL, *btf4 = NULL, *btf5 = NULL; 454 455 btf1 = btf__new_empty(); 456 if (!ASSERT_OK_PTR(btf1, "empty_main_btf")) 457 return; 458 btf__add_int(btf1, "int", 4, BTF_INT_SIGNED); /* [1] int */ 459 VALIDATE_RAW_BTF( 460 btf1, 461 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED"); 462 btf2 = btf__new_empty_split(btf1); 463 if (!ASSERT_OK_PTR(btf2, "empty_split_btf")) 464 goto cleanup; 465 btf__add_ptr(btf2, 1); 466 VALIDATE_RAW_BTF( 467 btf2, 468 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED", 469 "[2] PTR '(anon)' type_id=1"); 470 if (!ASSERT_EQ(0, btf__distill_base(btf2, &btf3, &btf4), 471 "distilled_base") || 472 !ASSERT_OK_PTR(btf3, "distilled_base") || 473 !ASSERT_OK_PTR(btf4, "distilled_split") || 474 !ASSERT_EQ(2, btf__type_cnt(btf3), "distilled_base_type_cnt")) 475 goto cleanup; 476 VALIDATE_RAW_BTF( 477 btf3, 478 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED"); 479 btf5 = btf__new_empty(); 480 if (!ASSERT_OK_PTR(btf5, "empty_reloc_btf")) 481 return; 482 btf__add_int(btf5, "int", 4, BTF_INT_SIGNED); /* [1] int */ 483 btf__add_int(btf5, "int", 4, BTF_INT_SIGNED); /* [2] int */ 484 VALIDATE_RAW_BTF( 485 btf5, 486 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED", 487 "[2] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED"); 488 ASSERT_EQ(btf__relocate(btf4, btf5), -EINVAL, "relocate_split"); 489 cleanup: 490 btf__free(btf5); 491 btf__free(btf4); 492 btf__free(btf3); 493 btf__free(btf2); 494 btf__free(btf1); 495 } 496 497 /* create split reference BTF from vmlinux + split BTF with a few type references; 498 * ensure the resultant split reference BTF is as expected, containing only types 499 * needed to disambiguate references from split BTF. 500 */ 501 static void test_distilled_base_vmlinux(void) 502 { 503 struct btf *split_btf = NULL, *vmlinux_btf = btf__load_vmlinux_btf(); 504 struct btf *split_dist = NULL, *base_dist = NULL; 505 __s32 int_id, myint_id; 506 507 if (!ASSERT_OK_PTR(vmlinux_btf, "load_vmlinux")) 508 return; 509 int_id = btf__find_by_name_kind(vmlinux_btf, "int", BTF_KIND_INT); 510 if (!ASSERT_GT(int_id, 0, "find_int")) 511 goto cleanup; 512 split_btf = btf__new_empty_split(vmlinux_btf); 513 if (!ASSERT_OK_PTR(split_btf, "new_split")) 514 goto cleanup; 515 myint_id = btf__add_typedef(split_btf, "myint", int_id); 516 btf__add_ptr(split_btf, myint_id); 517 518 if (!ASSERT_EQ(btf__distill_base(split_btf, &base_dist, &split_dist), 0, 519 "distill_vmlinux_base")) 520 goto cleanup; 521 522 if (!ASSERT_OK_PTR(split_dist, "split_distilled") || 523 !ASSERT_OK_PTR(base_dist, "base_dist")) 524 goto cleanup; 525 VALIDATE_RAW_BTF( 526 split_dist, 527 "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED", 528 "[2] TYPEDEF 'myint' type_id=1", 529 "[3] PTR '(anon)' type_id=2"); 530 531 cleanup: 532 btf__free(split_dist); 533 btf__free(base_dist); 534 btf__free(split_btf); 535 btf__free(vmlinux_btf); 536 } 537 538 void test_btf_distill(void) 539 { 540 if (test__start_subtest("distilled_base")) 541 test_distilled_base(); 542 if (test__start_subtest("distilled_base_multi")) 543 test_distilled_base_multi(); 544 if (test__start_subtest("distilled_base_missing_err")) 545 test_distilled_base_missing_err(); 546 if (test__start_subtest("distilled_base_multi_err")) 547 test_distilled_base_multi_err(); 548 if (test__start_subtest("distilled_base_multi_err2")) 549 test_distilled_base_multi_err2(); 550 if (test__start_subtest("distilled_base_vmlinux")) 551 test_distilled_base_vmlinux(); 552 } 553
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.