diff options
Diffstat (limited to 'tools/lib/bpf/libbpf.c')
-rw-r--r-- | tools/lib/bpf/libbpf.c | 125 |
1 files changed, 32 insertions, 93 deletions
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 03bc01ca2577..47969aa0faf8 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include "bpf.h" | 42 | #include "bpf.h" |
43 | #include "btf.h" | 43 | #include "btf.h" |
44 | #include "str_error.h" | 44 | #include "str_error.h" |
45 | #include "libbpf_util.h" | ||
45 | 46 | ||
46 | #ifndef EM_BPF | 47 | #ifndef EM_BPF |
47 | #define EM_BPF 247 | 48 | #define EM_BPF 247 |
@@ -53,39 +54,33 @@ | |||
53 | 54 | ||
54 | #define __printf(a, b) __attribute__((format(printf, a, b))) | 55 | #define __printf(a, b) __attribute__((format(printf, a, b))) |
55 | 56 | ||
56 | __printf(1, 2) | 57 | static int __base_pr(enum libbpf_print_level level, const char *format, |
57 | static int __base_pr(const char *format, ...) | 58 | va_list args) |
58 | { | 59 | { |
59 | va_list args; | 60 | if (level == LIBBPF_DEBUG) |
60 | int err; | 61 | return 0; |
61 | 62 | ||
62 | va_start(args, format); | 63 | return vfprintf(stderr, format, args); |
63 | err = vfprintf(stderr, format, args); | ||
64 | va_end(args); | ||
65 | return err; | ||
66 | } | 64 | } |
67 | 65 | ||
68 | static __printf(1, 2) libbpf_print_fn_t __pr_warning = __base_pr; | 66 | static libbpf_print_fn_t __libbpf_pr = __base_pr; |
69 | static __printf(1, 2) libbpf_print_fn_t __pr_info = __base_pr; | ||
70 | static __printf(1, 2) libbpf_print_fn_t __pr_debug; | ||
71 | |||
72 | #define __pr(func, fmt, ...) \ | ||
73 | do { \ | ||
74 | if ((func)) \ | ||
75 | (func)("libbpf: " fmt, ##__VA_ARGS__); \ | ||
76 | } while (0) | ||
77 | 67 | ||
78 | #define pr_warning(fmt, ...) __pr(__pr_warning, fmt, ##__VA_ARGS__) | 68 | void libbpf_set_print(libbpf_print_fn_t fn) |
79 | #define pr_info(fmt, ...) __pr(__pr_info, fmt, ##__VA_ARGS__) | 69 | { |
80 | #define pr_debug(fmt, ...) __pr(__pr_debug, fmt, ##__VA_ARGS__) | 70 | __libbpf_pr = fn; |
71 | } | ||
81 | 72 | ||
82 | void libbpf_set_print(libbpf_print_fn_t warn, | 73 | __printf(2, 3) |
83 | libbpf_print_fn_t info, | 74 | void libbpf_print(enum libbpf_print_level level, const char *format, ...) |
84 | libbpf_print_fn_t debug) | ||
85 | { | 75 | { |
86 | __pr_warning = warn; | 76 | va_list args; |
87 | __pr_info = info; | 77 | |
88 | __pr_debug = debug; | 78 | if (!__libbpf_pr) |
79 | return; | ||
80 | |||
81 | va_start(args, format); | ||
82 | __libbpf_pr(level, format, args); | ||
83 | va_end(args); | ||
89 | } | 84 | } |
90 | 85 | ||
91 | #define STRERR_BUFSIZE 128 | 86 | #define STRERR_BUFSIZE 128 |
@@ -839,8 +834,7 @@ static int bpf_object__elf_collect(struct bpf_object *obj, int flags) | |||
839 | else if (strcmp(name, "maps") == 0) | 834 | else if (strcmp(name, "maps") == 0) |
840 | obj->efile.maps_shndx = idx; | 835 | obj->efile.maps_shndx = idx; |
841 | else if (strcmp(name, BTF_ELF_SEC) == 0) { | 836 | else if (strcmp(name, BTF_ELF_SEC) == 0) { |
842 | obj->btf = btf__new(data->d_buf, data->d_size, | 837 | obj->btf = btf__new(data->d_buf, data->d_size); |
843 | __pr_debug); | ||
844 | if (IS_ERR(obj->btf)) { | 838 | if (IS_ERR(obj->btf)) { |
845 | pr_warning("Error loading ELF section %s: %ld. Ignored and continue.\n", | 839 | pr_warning("Error loading ELF section %s: %ld. Ignored and continue.\n", |
846 | BTF_ELF_SEC, PTR_ERR(obj->btf)); | 840 | BTF_ELF_SEC, PTR_ERR(obj->btf)); |
@@ -915,8 +909,7 @@ static int bpf_object__elf_collect(struct bpf_object *obj, int flags) | |||
915 | BTF_EXT_ELF_SEC, BTF_ELF_SEC); | 909 | BTF_EXT_ELF_SEC, BTF_ELF_SEC); |
916 | } else { | 910 | } else { |
917 | obj->btf_ext = btf_ext__new(btf_ext_data->d_buf, | 911 | obj->btf_ext = btf_ext__new(btf_ext_data->d_buf, |
918 | btf_ext_data->d_size, | 912 | btf_ext_data->d_size); |
919 | __pr_debug); | ||
920 | if (IS_ERR(obj->btf_ext)) { | 913 | if (IS_ERR(obj->btf_ext)) { |
921 | pr_warning("Error loading ELF section %s: %ld. Ignored and continue.\n", | 914 | pr_warning("Error loading ELF section %s: %ld. Ignored and continue.\n", |
922 | BTF_EXT_ELF_SEC, | 915 | BTF_EXT_ELF_SEC, |
@@ -1057,72 +1050,18 @@ bpf_program__collect_reloc(struct bpf_program *prog, GElf_Shdr *shdr, | |||
1057 | 1050 | ||
1058 | static int bpf_map_find_btf_info(struct bpf_map *map, const struct btf *btf) | 1051 | static int bpf_map_find_btf_info(struct bpf_map *map, const struct btf *btf) |
1059 | { | 1052 | { |
1060 | const struct btf_type *container_type; | ||
1061 | const struct btf_member *key, *value; | ||
1062 | struct bpf_map_def *def = &map->def; | 1053 | struct bpf_map_def *def = &map->def; |
1063 | const size_t max_name = 256; | 1054 | __u32 key_type_id, value_type_id; |
1064 | char container_name[max_name]; | 1055 | int ret; |
1065 | __s64 key_size, value_size; | ||
1066 | __s32 container_id; | ||
1067 | |||
1068 | if (snprintf(container_name, max_name, "____btf_map_%s", map->name) == | ||
1069 | max_name) { | ||
1070 | pr_warning("map:%s length of '____btf_map_%s' is too long\n", | ||
1071 | map->name, map->name); | ||
1072 | return -EINVAL; | ||
1073 | } | ||
1074 | |||
1075 | container_id = btf__find_by_name(btf, container_name); | ||
1076 | if (container_id < 0) { | ||
1077 | pr_debug("map:%s container_name:%s cannot be found in BTF. Missing BPF_ANNOTATE_KV_PAIR?\n", | ||
1078 | map->name, container_name); | ||
1079 | return container_id; | ||
1080 | } | ||
1081 | |||
1082 | container_type = btf__type_by_id(btf, container_id); | ||
1083 | if (!container_type) { | ||
1084 | pr_warning("map:%s cannot find BTF type for container_id:%u\n", | ||
1085 | map->name, container_id); | ||
1086 | return -EINVAL; | ||
1087 | } | ||
1088 | |||
1089 | if (BTF_INFO_KIND(container_type->info) != BTF_KIND_STRUCT || | ||
1090 | BTF_INFO_VLEN(container_type->info) < 2) { | ||
1091 | pr_warning("map:%s container_name:%s is an invalid container struct\n", | ||
1092 | map->name, container_name); | ||
1093 | return -EINVAL; | ||
1094 | } | ||
1095 | |||
1096 | key = (struct btf_member *)(container_type + 1); | ||
1097 | value = key + 1; | ||
1098 | |||
1099 | key_size = btf__resolve_size(btf, key->type); | ||
1100 | if (key_size < 0) { | ||
1101 | pr_warning("map:%s invalid BTF key_type_size\n", | ||
1102 | map->name); | ||
1103 | return key_size; | ||
1104 | } | ||
1105 | |||
1106 | if (def->key_size != key_size) { | ||
1107 | pr_warning("map:%s btf_key_type_size:%u != map_def_key_size:%u\n", | ||
1108 | map->name, (__u32)key_size, def->key_size); | ||
1109 | return -EINVAL; | ||
1110 | } | ||
1111 | |||
1112 | value_size = btf__resolve_size(btf, value->type); | ||
1113 | if (value_size < 0) { | ||
1114 | pr_warning("map:%s invalid BTF value_type_size\n", map->name); | ||
1115 | return value_size; | ||
1116 | } | ||
1117 | 1056 | ||
1118 | if (def->value_size != value_size) { | 1057 | ret = btf__get_map_kv_tids(btf, map->name, def->key_size, |
1119 | pr_warning("map:%s btf_value_type_size:%u != map_def_value_size:%u\n", | 1058 | def->value_size, &key_type_id, |
1120 | map->name, (__u32)value_size, def->value_size); | 1059 | &value_type_id); |
1121 | return -EINVAL; | 1060 | if (ret) |
1122 | } | 1061 | return ret; |
1123 | 1062 | ||
1124 | map->btf_key_type_id = key->type; | 1063 | map->btf_key_type_id = key_type_id; |
1125 | map->btf_value_type_id = value->type; | 1064 | map->btf_value_type_id = value_type_id; |
1126 | 1065 | ||
1127 | return 0; | 1066 | return 0; |
1128 | } | 1067 | } |