libbpf.c (13dfb3fa494361ea9a5950f27c9cd8b06d28c04f) | libbpf.c (b03bc6853c0e0c97da842434e8056f1b9d9a1f4a) |
---|---|
1// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) 2 3/* 4 * Common eBPF ELF object loading operations. 5 * 6 * Copyright (C) 2013-2015 Alexei Starovoitov <ast@kernel.org> 7 * Copyright (C) 2015 Wang Nan <wangnan0@huawei.com> 8 * Copyright (C) 2015 Huawei Inc. --- 6 unchanged lines hidden (view full) --- 15#endif 16#include <stdlib.h> 17#include <stdio.h> 18#include <stdarg.h> 19#include <libgen.h> 20#include <inttypes.h> 21#include <string.h> 22#include <unistd.h> | 1// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) 2 3/* 4 * Common eBPF ELF object loading operations. 5 * 6 * Copyright (C) 2013-2015 Alexei Starovoitov <ast@kernel.org> 7 * Copyright (C) 2015 Wang Nan <wangnan0@huawei.com> 8 * Copyright (C) 2015 Huawei Inc. --- 6 unchanged lines hidden (view full) --- 15#endif 16#include <stdlib.h> 17#include <stdio.h> 18#include <stdarg.h> 19#include <libgen.h> 20#include <inttypes.h> 21#include <string.h> 22#include <unistd.h> |
23#include <endian.h> | |
24#include <fcntl.h> 25#include <errno.h> 26#include <asm/unistd.h> 27#include <linux/err.h> 28#include <linux/kernel.h> 29#include <linux/bpf.h> 30#include <linux/btf.h> 31#include <linux/filter.h> --- 38 unchanged lines hidden (view full) --- 70 if (level == LIBBPF_DEBUG) 71 return 0; 72 73 return vfprintf(stderr, format, args); 74} 75 76static libbpf_print_fn_t __libbpf_pr = __base_pr; 77 | 23#include <fcntl.h> 24#include <errno.h> 25#include <asm/unistd.h> 26#include <linux/err.h> 27#include <linux/kernel.h> 28#include <linux/bpf.h> 29#include <linux/btf.h> 30#include <linux/filter.h> --- 38 unchanged lines hidden (view full) --- 69 if (level == LIBBPF_DEBUG) 70 return 0; 71 72 return vfprintf(stderr, format, args); 73} 74 75static libbpf_print_fn_t __libbpf_pr = __base_pr; 76 |
78void libbpf_set_print(libbpf_print_fn_t fn) | 77libbpf_print_fn_t libbpf_set_print(libbpf_print_fn_t fn) |
79{ | 78{ |
79 libbpf_print_fn_t old_print_fn = __libbpf_pr; 80 |
|
80 __libbpf_pr = fn; | 81 __libbpf_pr = fn; |
82 return old_print_fn; |
|
81} 82 83__printf(2, 3) 84void libbpf_print(enum libbpf_print_level level, const char *format, ...) 85{ 86 va_list args; 87 88 if (!__libbpf_pr) --- 519 unchanged lines hidden (view full) --- 608 return 0; 609errout: 610 bpf_object__elf_finish(obj); 611 return err; 612} 613 614static int bpf_object__check_endianness(struct bpf_object *obj) 615{ | 83} 84 85__printf(2, 3) 86void libbpf_print(enum libbpf_print_level level, const char *format, ...) 87{ 88 va_list args; 89 90 if (!__libbpf_pr) --- 519 unchanged lines hidden (view full) --- 610 return 0; 611errout: 612 bpf_object__elf_finish(obj); 613 return err; 614} 615 616static int bpf_object__check_endianness(struct bpf_object *obj) 617{ |
616#if __BYTE_ORDER == __LITTLE_ENDIAN | 618#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ |
617 if (obj->efile.ehdr.e_ident[EI_DATA] == ELFDATA2LSB) 618 return 0; | 619 if (obj->efile.ehdr.e_ident[EI_DATA] == ELFDATA2LSB) 620 return 0; |
619#elif __BYTE_ORDER == __BIG_ENDIAN | 621#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ |
620 if (obj->efile.ehdr.e_ident[EI_DATA] == ELFDATA2MSB) 621 return 0; 622#else 623# error "Unrecognized __BYTE_ORDER__" 624#endif 625 pr_warning("endianness mismatch.\n"); 626 return -LIBBPF_ERRNO__ENDIAN; 627} --- 414 unchanged lines hidden (view full) --- 1042static bool get_map_field_int(const char *map_name, const struct btf *btf, 1043 const struct btf_type *def, 1044 const struct btf_member *m, __u32 *res) { 1045 const struct btf_type *t = skip_mods_and_typedefs(btf, m->type); 1046 const char *name = btf__name_by_offset(btf, m->name_off); 1047 const struct btf_array *arr_info; 1048 const struct btf_type *arr_t; 1049 | 622 if (obj->efile.ehdr.e_ident[EI_DATA] == ELFDATA2MSB) 623 return 0; 624#else 625# error "Unrecognized __BYTE_ORDER__" 626#endif 627 pr_warning("endianness mismatch.\n"); 628 return -LIBBPF_ERRNO__ENDIAN; 629} --- 414 unchanged lines hidden (view full) --- 1044static bool get_map_field_int(const char *map_name, const struct btf *btf, 1045 const struct btf_type *def, 1046 const struct btf_member *m, __u32 *res) { 1047 const struct btf_type *t = skip_mods_and_typedefs(btf, m->type); 1048 const char *name = btf__name_by_offset(btf, m->name_off); 1049 const struct btf_array *arr_info; 1050 const struct btf_type *arr_t; 1051 |
1050 if (BTF_INFO_KIND(t->info) != BTF_KIND_PTR) { | 1052 if (!btf_is_ptr(t)) { |
1051 pr_warning("map '%s': attr '%s': expected PTR, got %u.\n", | 1053 pr_warning("map '%s': attr '%s': expected PTR, got %u.\n", |
1052 map_name, name, BTF_INFO_KIND(t->info)); | 1054 map_name, name, btf_kind(t)); |
1053 return false; 1054 } 1055 1056 arr_t = btf__type_by_id(btf, t->type); 1057 if (!arr_t) { 1058 pr_warning("map '%s': attr '%s': type [%u] not found.\n", 1059 map_name, name, t->type); 1060 return false; 1061 } | 1055 return false; 1056 } 1057 1058 arr_t = btf__type_by_id(btf, t->type); 1059 if (!arr_t) { 1060 pr_warning("map '%s': attr '%s': type [%u] not found.\n", 1061 map_name, name, t->type); 1062 return false; 1063 } |
1062 if (BTF_INFO_KIND(arr_t->info) != BTF_KIND_ARRAY) { | 1064 if (!btf_is_array(arr_t)) { |
1063 pr_warning("map '%s': attr '%s': expected ARRAY, got %u.\n", | 1065 pr_warning("map '%s': attr '%s': expected ARRAY, got %u.\n", |
1064 map_name, name, BTF_INFO_KIND(arr_t->info)); | 1066 map_name, name, btf_kind(arr_t)); |
1065 return false; 1066 } | 1067 return false; 1068 } |
1067 arr_info = (const void *)(arr_t + 1); | 1069 arr_info = btf_array(arr_t); |
1068 *res = arr_info->nelems; 1069 return true; 1070} 1071 1072static int bpf_object__init_user_btf_map(struct bpf_object *obj, 1073 const struct btf_type *sec, 1074 int var_idx, int sec_idx, 1075 const Elf_Data *data, bool strict) 1076{ 1077 const struct btf_type *var, *def, *t; 1078 const struct btf_var_secinfo *vi; 1079 const struct btf_var *var_extra; 1080 const struct btf_member *m; 1081 const char *map_name; 1082 struct bpf_map *map; 1083 int vlen, i; 1084 | 1070 *res = arr_info->nelems; 1071 return true; 1072} 1073 1074static int bpf_object__init_user_btf_map(struct bpf_object *obj, 1075 const struct btf_type *sec, 1076 int var_idx, int sec_idx, 1077 const Elf_Data *data, bool strict) 1078{ 1079 const struct btf_type *var, *def, *t; 1080 const struct btf_var_secinfo *vi; 1081 const struct btf_var *var_extra; 1082 const struct btf_member *m; 1083 const char *map_name; 1084 struct bpf_map *map; 1085 int vlen, i; 1086 |
1085 vi = (const struct btf_var_secinfo *)(const void *)(sec + 1) + var_idx; | 1087 vi = btf_var_secinfos(sec) + var_idx; |
1086 var = btf__type_by_id(obj->btf, vi->type); | 1088 var = btf__type_by_id(obj->btf, vi->type); |
1087 var_extra = (const void *)(var + 1); | 1089 var_extra = btf_var(var); |
1088 map_name = btf__name_by_offset(obj->btf, var->name_off); | 1090 map_name = btf__name_by_offset(obj->btf, var->name_off); |
1089 vlen = BTF_INFO_VLEN(var->info); | 1091 vlen = btf_vlen(var); |
1090 1091 if (map_name == NULL || map_name[0] == '\0') { 1092 pr_warning("map #%d: empty name.\n", var_idx); 1093 return -EINVAL; 1094 } 1095 if ((__u64)vi->offset + vi->size > data->d_size) { 1096 pr_warning("map '%s' BTF data is corrupted.\n", map_name); 1097 return -EINVAL; 1098 } | 1092 1093 if (map_name == NULL || map_name[0] == '\0') { 1094 pr_warning("map #%d: empty name.\n", var_idx); 1095 return -EINVAL; 1096 } 1097 if ((__u64)vi->offset + vi->size > data->d_size) { 1098 pr_warning("map '%s' BTF data is corrupted.\n", map_name); 1099 return -EINVAL; 1100 } |
1099 if (BTF_INFO_KIND(var->info) != BTF_KIND_VAR) { | 1101 if (!btf_is_var(var)) { |
1100 pr_warning("map '%s': unexpected var kind %u.\n", | 1102 pr_warning("map '%s': unexpected var kind %u.\n", |
1101 map_name, BTF_INFO_KIND(var->info)); | 1103 map_name, btf_kind(var)); |
1102 return -EINVAL; 1103 } 1104 if (var_extra->linkage != BTF_VAR_GLOBAL_ALLOCATED && 1105 var_extra->linkage != BTF_VAR_STATIC) { 1106 pr_warning("map '%s': unsupported var linkage %u.\n", 1107 map_name, var_extra->linkage); 1108 return -EOPNOTSUPP; 1109 } 1110 1111 def = skip_mods_and_typedefs(obj->btf, var->type); | 1104 return -EINVAL; 1105 } 1106 if (var_extra->linkage != BTF_VAR_GLOBAL_ALLOCATED && 1107 var_extra->linkage != BTF_VAR_STATIC) { 1108 pr_warning("map '%s': unsupported var linkage %u.\n", 1109 map_name, var_extra->linkage); 1110 return -EOPNOTSUPP; 1111 } 1112 1113 def = skip_mods_and_typedefs(obj->btf, var->type); |
1112 if (BTF_INFO_KIND(def->info) != BTF_KIND_STRUCT) { | 1114 if (!btf_is_struct(def)) { |
1113 pr_warning("map '%s': unexpected def kind %u.\n", | 1115 pr_warning("map '%s': unexpected def kind %u.\n", |
1114 map_name, BTF_INFO_KIND(var->info)); | 1116 map_name, btf_kind(var)); |
1115 return -EINVAL; 1116 } 1117 if (def->size > vi->size) { 1118 pr_warning("map '%s': invalid def size.\n", map_name); 1119 return -EINVAL; 1120 } 1121 1122 map = bpf_object__add_map(obj); --- 6 unchanged lines hidden (view full) --- 1129 } 1130 map->libbpf_type = LIBBPF_MAP_UNSPEC; 1131 map->def.type = BPF_MAP_TYPE_UNSPEC; 1132 map->sec_idx = sec_idx; 1133 map->sec_offset = vi->offset; 1134 pr_debug("map '%s': at sec_idx %d, offset %zu.\n", 1135 map_name, map->sec_idx, map->sec_offset); 1136 | 1117 return -EINVAL; 1118 } 1119 if (def->size > vi->size) { 1120 pr_warning("map '%s': invalid def size.\n", map_name); 1121 return -EINVAL; 1122 } 1123 1124 map = bpf_object__add_map(obj); --- 6 unchanged lines hidden (view full) --- 1131 } 1132 map->libbpf_type = LIBBPF_MAP_UNSPEC; 1133 map->def.type = BPF_MAP_TYPE_UNSPEC; 1134 map->sec_idx = sec_idx; 1135 map->sec_offset = vi->offset; 1136 pr_debug("map '%s': at sec_idx %d, offset %zu.\n", 1137 map_name, map->sec_idx, map->sec_offset); 1138 |
1137 vlen = BTF_INFO_VLEN(def->info); 1138 m = (const void *)(def + 1); | 1139 vlen = btf_vlen(def); 1140 m = btf_members(def); |
1139 for (i = 0; i < vlen; i++, m++) { 1140 const char *name = btf__name_by_offset(obj->btf, m->name_off); 1141 1142 if (!name) { 1143 pr_warning("map '%s': invalid field #%d.\n", 1144 map_name, i); 1145 return -EINVAL; 1146 } --- 33 unchanged lines hidden (view full) --- 1180 __s64 sz; 1181 1182 t = btf__type_by_id(obj->btf, m->type); 1183 if (!t) { 1184 pr_warning("map '%s': key type [%d] not found.\n", 1185 map_name, m->type); 1186 return -EINVAL; 1187 } | 1141 for (i = 0; i < vlen; i++, m++) { 1142 const char *name = btf__name_by_offset(obj->btf, m->name_off); 1143 1144 if (!name) { 1145 pr_warning("map '%s': invalid field #%d.\n", 1146 map_name, i); 1147 return -EINVAL; 1148 } --- 33 unchanged lines hidden (view full) --- 1182 __s64 sz; 1183 1184 t = btf__type_by_id(obj->btf, m->type); 1185 if (!t) { 1186 pr_warning("map '%s': key type [%d] not found.\n", 1187 map_name, m->type); 1188 return -EINVAL; 1189 } |
1188 if (BTF_INFO_KIND(t->info) != BTF_KIND_PTR) { | 1190 if (!btf_is_ptr(t)) { |
1189 pr_warning("map '%s': key spec is not PTR: %u.\n", | 1191 pr_warning("map '%s': key spec is not PTR: %u.\n", |
1190 map_name, BTF_INFO_KIND(t->info)); | 1192 map_name, btf_kind(t)); |
1191 return -EINVAL; 1192 } 1193 sz = btf__resolve_size(obj->btf, t->type); 1194 if (sz < 0) { 1195 pr_warning("map '%s': can't determine key size for type [%u]: %lld.\n", 1196 map_name, t->type, sz); 1197 return sz; 1198 } --- 24 unchanged lines hidden (view full) --- 1223 __s64 sz; 1224 1225 t = btf__type_by_id(obj->btf, m->type); 1226 if (!t) { 1227 pr_warning("map '%s': value type [%d] not found.\n", 1228 map_name, m->type); 1229 return -EINVAL; 1230 } | 1193 return -EINVAL; 1194 } 1195 sz = btf__resolve_size(obj->btf, t->type); 1196 if (sz < 0) { 1197 pr_warning("map '%s': can't determine key size for type [%u]: %lld.\n", 1198 map_name, t->type, sz); 1199 return sz; 1200 } --- 24 unchanged lines hidden (view full) --- 1225 __s64 sz; 1226 1227 t = btf__type_by_id(obj->btf, m->type); 1228 if (!t) { 1229 pr_warning("map '%s': value type [%d] not found.\n", 1230 map_name, m->type); 1231 return -EINVAL; 1232 } |
1231 if (BTF_INFO_KIND(t->info) != BTF_KIND_PTR) { | 1233 if (!btf_is_ptr(t)) { |
1232 pr_warning("map '%s': value spec is not PTR: %u.\n", | 1234 pr_warning("map '%s': value spec is not PTR: %u.\n", |
1233 map_name, BTF_INFO_KIND(t->info)); | 1235 map_name, btf_kind(t)); |
1234 return -EINVAL; 1235 } 1236 sz = btf__resolve_size(obj->btf, t->type); 1237 if (sz < 0) { 1238 pr_warning("map '%s': can't determine value size for type [%u]: %lld.\n", 1239 map_name, t->type, sz); 1240 return sz; 1241 } --- 44 unchanged lines hidden (view full) --- 1286 pr_warning("failed to get Elf_Data from map section %d (%s)\n", 1287 obj->efile.maps_shndx, MAPS_ELF_SEC); 1288 return -EINVAL; 1289 } 1290 1291 nr_types = btf__get_nr_types(obj->btf); 1292 for (i = 1; i <= nr_types; i++) { 1293 t = btf__type_by_id(obj->btf, i); | 1236 return -EINVAL; 1237 } 1238 sz = btf__resolve_size(obj->btf, t->type); 1239 if (sz < 0) { 1240 pr_warning("map '%s': can't determine value size for type [%u]: %lld.\n", 1241 map_name, t->type, sz); 1242 return sz; 1243 } --- 44 unchanged lines hidden (view full) --- 1288 pr_warning("failed to get Elf_Data from map section %d (%s)\n", 1289 obj->efile.maps_shndx, MAPS_ELF_SEC); 1290 return -EINVAL; 1291 } 1292 1293 nr_types = btf__get_nr_types(obj->btf); 1294 for (i = 1; i <= nr_types; i++) { 1295 t = btf__type_by_id(obj->btf, i); |
1294 if (BTF_INFO_KIND(t->info) != BTF_KIND_DATASEC) | 1296 if (!btf_is_datasec(t)) |
1295 continue; 1296 name = btf__name_by_offset(obj->btf, t->name_off); 1297 if (strcmp(name, MAPS_ELF_SEC) == 0) { 1298 sec = t; 1299 break; 1300 } 1301 } 1302 1303 if (!sec) { 1304 pr_warning("DATASEC '%s' not found.\n", MAPS_ELF_SEC); 1305 return -ENOENT; 1306 } 1307 | 1297 continue; 1298 name = btf__name_by_offset(obj->btf, t->name_off); 1299 if (strcmp(name, MAPS_ELF_SEC) == 0) { 1300 sec = t; 1301 break; 1302 } 1303 } 1304 1305 if (!sec) { 1306 pr_warning("DATASEC '%s' not found.\n", MAPS_ELF_SEC); 1307 return -ENOENT; 1308 } 1309 |
1308 vlen = BTF_INFO_VLEN(sec->info); | 1310 vlen = btf_vlen(sec); |
1309 for (i = 0; i < vlen; i++) { 1310 err = bpf_object__init_user_btf_map(obj, sec, i, 1311 obj->efile.btf_maps_shndx, 1312 data, strict); 1313 if (err) 1314 return err; 1315 } 1316 --- 44 unchanged lines hidden (view full) --- 1361 1362static void bpf_object__sanitize_btf(struct bpf_object *obj) 1363{ 1364 bool has_datasec = obj->caps.btf_datasec; 1365 bool has_func = obj->caps.btf_func; 1366 struct btf *btf = obj->btf; 1367 struct btf_type *t; 1368 int i, j, vlen; | 1311 for (i = 0; i < vlen; i++) { 1312 err = bpf_object__init_user_btf_map(obj, sec, i, 1313 obj->efile.btf_maps_shndx, 1314 data, strict); 1315 if (err) 1316 return err; 1317 } 1318 --- 44 unchanged lines hidden (view full) --- 1363 1364static void bpf_object__sanitize_btf(struct bpf_object *obj) 1365{ 1366 bool has_datasec = obj->caps.btf_datasec; 1367 bool has_func = obj->caps.btf_func; 1368 struct btf *btf = obj->btf; 1369 struct btf_type *t; 1370 int i, j, vlen; |
1369 __u16 kind; | |
1370 1371 if (!obj->btf || (has_func && has_datasec)) 1372 return; 1373 1374 for (i = 1; i <= btf__get_nr_types(btf); i++) { 1375 t = (struct btf_type *)btf__type_by_id(btf, i); | 1371 1372 if (!obj->btf || (has_func && has_datasec)) 1373 return; 1374 1375 for (i = 1; i <= btf__get_nr_types(btf); i++) { 1376 t = (struct btf_type *)btf__type_by_id(btf, i); |
1376 kind = BTF_INFO_KIND(t->info); | |
1377 | 1377 |
1378 if (!has_datasec && kind == BTF_KIND_VAR) { | 1378 if (!has_datasec && btf_is_var(t)) { |
1379 /* replace VAR with INT */ 1380 t->info = BTF_INFO_ENC(BTF_KIND_INT, 0, 0); | 1379 /* replace VAR with INT */ 1380 t->info = BTF_INFO_ENC(BTF_KIND_INT, 0, 0); |
1381 /* 1382 * using size = 1 is the safest choice, 4 will be too 1383 * big and cause kernel BTF validation failure if 1384 * original variable took less than 4 bytes 1385 */ 1386 t->size = 1; 1387 *(int *)(t+1) = BTF_INT_ENC(0, 0, 8); 1388 } else if (!has_datasec && kind == BTF_KIND_DATASEC) { | 1381 t->size = sizeof(int); 1382 *(int *)(t + 1) = BTF_INT_ENC(0, 0, 32); 1383 } else if (!has_datasec && btf_is_datasec(t)) { |
1389 /* replace DATASEC with STRUCT */ | 1384 /* replace DATASEC with STRUCT */ |
1390 struct btf_var_secinfo *v = (void *)(t + 1); 1391 struct btf_member *m = (void *)(t + 1); | 1385 const struct btf_var_secinfo *v = btf_var_secinfos(t); 1386 struct btf_member *m = btf_members(t); |
1392 struct btf_type *vt; 1393 char *name; 1394 1395 name = (char *)btf__name_by_offset(btf, t->name_off); 1396 while (*name) { 1397 if (*name == '.') 1398 *name = '_'; 1399 name++; 1400 } 1401 | 1387 struct btf_type *vt; 1388 char *name; 1389 1390 name = (char *)btf__name_by_offset(btf, t->name_off); 1391 while (*name) { 1392 if (*name == '.') 1393 *name = '_'; 1394 name++; 1395 } 1396 |
1402 vlen = BTF_INFO_VLEN(t->info); | 1397 vlen = btf_vlen(t); |
1403 t->info = BTF_INFO_ENC(BTF_KIND_STRUCT, 0, vlen); 1404 for (j = 0; j < vlen; j++, v++, m++) { 1405 /* order of field assignments is important */ 1406 m->offset = v->offset * 8; 1407 m->type = v->type; 1408 /* preserve variable name as member name */ 1409 vt = (void *)btf__type_by_id(btf, v->type); 1410 m->name_off = vt->name_off; 1411 } | 1398 t->info = BTF_INFO_ENC(BTF_KIND_STRUCT, 0, vlen); 1399 for (j = 0; j < vlen; j++, v++, m++) { 1400 /* order of field assignments is important */ 1401 m->offset = v->offset * 8; 1402 m->type = v->type; 1403 /* preserve variable name as member name */ 1404 vt = (void *)btf__type_by_id(btf, v->type); 1405 m->name_off = vt->name_off; 1406 } |
1412 } else if (!has_func && kind == BTF_KIND_FUNC_PROTO) { | 1407 } else if (!has_func && btf_is_func_proto(t)) { |
1413 /* replace FUNC_PROTO with ENUM */ | 1408 /* replace FUNC_PROTO with ENUM */ |
1414 vlen = BTF_INFO_VLEN(t->info); | 1409 vlen = btf_vlen(t); |
1415 t->info = BTF_INFO_ENC(BTF_KIND_ENUM, 0, vlen); 1416 t->size = sizeof(__u32); /* kernel enforced */ | 1410 t->info = BTF_INFO_ENC(BTF_KIND_ENUM, 0, vlen); 1411 t->size = sizeof(__u32); /* kernel enforced */ |
1417 } else if (!has_func && kind == BTF_KIND_FUNC) { | 1412 } else if (!has_func && btf_is_func(t)) { |
1418 /* replace FUNC with TYPEDEF */ 1419 t->info = BTF_INFO_ENC(BTF_KIND_TYPEDEF, 0, 0); 1420 } 1421 } 1422} 1423 1424static void bpf_object__sanitize_btf_ext(struct bpf_object *obj) 1425{ --- 75 unchanged lines hidden (view full) --- 1501 bpf_object__sanitize_btf_ext(obj); 1502 1503 err = btf__load(obj->btf); 1504 if (err) { 1505 pr_warning("Error loading %s into kernel: %d.\n", 1506 BTF_ELF_SEC, err); 1507 btf__free(obj->btf); 1508 obj->btf = NULL; | 1413 /* replace FUNC with TYPEDEF */ 1414 t->info = BTF_INFO_ENC(BTF_KIND_TYPEDEF, 0, 0); 1415 } 1416 } 1417} 1418 1419static void bpf_object__sanitize_btf_ext(struct bpf_object *obj) 1420{ --- 75 unchanged lines hidden (view full) --- 1496 bpf_object__sanitize_btf_ext(obj); 1497 1498 err = btf__load(obj->btf); 1499 if (err) { 1500 pr_warning("Error loading %s into kernel: %d.\n", 1501 BTF_ELF_SEC, err); 1502 btf__free(obj->btf); 1503 obj->btf = NULL; |
1509 /* btf_ext can't exist without btf, so free it as well */ 1510 if (obj->btf_ext) { 1511 btf_ext__free(obj->btf_ext); 1512 obj->btf_ext = NULL; 1513 } 1514 | |
1515 if (bpf_object__is_btf_mandatory(obj)) 1516 return err; 1517 } 1518 return 0; 1519} 1520 1521static int bpf_object__elf_collect(struct bpf_object *obj, int flags) 1522{ --- 244 unchanged lines hidden (view full) --- 1767 name = elf_strptr(obj->efile.elf, obj->efile.strtabidx, 1768 sym.st_name) ? : "<?>"; 1769 1770 pr_debug("relo for %lld value %lld name %d (\'%s\')\n", 1771 (long long) (rel.r_info >> 32), 1772 (long long) sym.st_value, sym.st_name, name); 1773 1774 shdr_idx = sym.st_shndx; | 1504 if (bpf_object__is_btf_mandatory(obj)) 1505 return err; 1506 } 1507 return 0; 1508} 1509 1510static int bpf_object__elf_collect(struct bpf_object *obj, int flags) 1511{ --- 244 unchanged lines hidden (view full) --- 1756 name = elf_strptr(obj->efile.elf, obj->efile.strtabidx, 1757 sym.st_name) ? : "<?>"; 1758 1759 pr_debug("relo for %lld value %lld name %d (\'%s\')\n", 1760 (long long) (rel.r_info >> 32), 1761 (long long) sym.st_value, sym.st_name, name); 1762 1763 shdr_idx = sym.st_shndx; |
1764 insn_idx = rel.r_offset / sizeof(struct bpf_insn); 1765 pr_debug("relocation: insn_idx=%u, shdr_idx=%u\n", 1766 insn_idx, shdr_idx); 1767 1768 if (shdr_idx >= SHN_LORESERVE) { 1769 pr_warning("relocation: not yet supported relo for non-static global \'%s\' variable in special section (0x%x) found in insns[%d].code 0x%x\n", 1770 name, shdr_idx, insn_idx, 1771 insns[insn_idx].code); 1772 return -LIBBPF_ERRNO__RELOC; 1773 } |
|
1775 if (!bpf_object__relo_in_known_section(obj, shdr_idx)) { 1776 pr_warning("Program '%s' contains unrecognized relo data pointing to section %u\n", 1777 prog->section_name, shdr_idx); 1778 return -LIBBPF_ERRNO__RELOC; 1779 } 1780 | 1774 if (!bpf_object__relo_in_known_section(obj, shdr_idx)) { 1775 pr_warning("Program '%s' contains unrecognized relo data pointing to section %u\n", 1776 prog->section_name, shdr_idx); 1777 return -LIBBPF_ERRNO__RELOC; 1778 } 1779 |
1781 insn_idx = rel.r_offset / sizeof(struct bpf_insn); 1782 pr_debug("relocation: insn_idx=%u\n", insn_idx); 1783 | |
1784 if (insns[insn_idx].code == (BPF_JMP | BPF_CALL)) { 1785 if (insns[insn_idx].src_reg != BPF_PSEUDO_CALL) { 1786 pr_warning("incorrect bpf_call opcode\n"); 1787 return -LIBBPF_ERRNO__RELOC; 1788 } 1789 prog->reloc_desc[i].type = RELO_CALL; 1790 prog->reloc_desc[i].insn_idx = insn_idx; 1791 prog->reloc_desc[i].text_off = sym.st_value; --- 2722 unchanged lines hidden (view full) --- 4514 4515static struct perf_buffer *__perf_buffer__new(int map_fd, size_t page_cnt, 4516 struct perf_buffer_params *p); 4517 4518struct perf_buffer *perf_buffer__new(int map_fd, size_t page_cnt, 4519 const struct perf_buffer_opts *opts) 4520{ 4521 struct perf_buffer_params p = {}; | 1780 if (insns[insn_idx].code == (BPF_JMP | BPF_CALL)) { 1781 if (insns[insn_idx].src_reg != BPF_PSEUDO_CALL) { 1782 pr_warning("incorrect bpf_call opcode\n"); 1783 return -LIBBPF_ERRNO__RELOC; 1784 } 1785 prog->reloc_desc[i].type = RELO_CALL; 1786 prog->reloc_desc[i].insn_idx = insn_idx; 1787 prog->reloc_desc[i].text_off = sym.st_value; --- 2722 unchanged lines hidden (view full) --- 4510 4511static struct perf_buffer *__perf_buffer__new(int map_fd, size_t page_cnt, 4512 struct perf_buffer_params *p); 4513 4514struct perf_buffer *perf_buffer__new(int map_fd, size_t page_cnt, 4515 const struct perf_buffer_opts *opts) 4516{ 4517 struct perf_buffer_params p = {}; |
4522 struct perf_event_attr attr = { 0, }; | 4518 struct perf_event_attr attr = { 4519 .config = PERF_COUNT_SW_BPF_OUTPUT, 4520 .type = PERF_TYPE_SOFTWARE, 4521 .sample_type = PERF_SAMPLE_RAW, 4522 .sample_period = 1, 4523 .wakeup_events = 1, 4524 }; |
4523 | 4525 |
4524 attr.config = PERF_COUNT_SW_BPF_OUTPUT, 4525 attr.type = PERF_TYPE_SOFTWARE; 4526 attr.sample_type = PERF_SAMPLE_RAW; 4527 attr.sample_period = 1; 4528 attr.wakeup_events = 1; 4529 | |
4530 p.attr = &attr; 4531 p.sample_cb = opts ? opts->sample_cb : NULL; 4532 p.lost_cb = opts ? opts->lost_cb : NULL; 4533 p.ctx = opts ? opts->ctx : NULL; 4534 4535 return __perf_buffer__new(map_fd, page_cnt, &p); 4536} 4537 --- 516 unchanged lines hidden --- | 4526 p.attr = &attr; 4527 p.sample_cb = opts ? opts->sample_cb : NULL; 4528 p.lost_cb = opts ? opts->lost_cb : NULL; 4529 p.ctx = opts ? opts->ctx : NULL; 4530 4531 return __perf_buffer__new(map_fd, page_cnt, &p); 4532} 4533 --- 516 unchanged lines hidden --- |