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 ---