diff options
author | Okash Khawaja <osk@fb.com> | 2018-07-14 00:57:02 -0400 |
---|---|---|
committer | Daniel Borkmann <daniel@iogearbox.net> | 2018-07-14 07:00:40 -0400 |
commit | 92b57121ca79b286bef4f304e887272f3f2d86bb (patch) | |
tree | f8890e7c3f08e4796dbeaa8e0592fc4394c3672d /tools/lib/bpf/btf.c | |
parent | db42a21a1e8d11a30a06050281c2723ec78b63a7 (diff) |
bpf: btf: export btf types and name by offset from lib
This patch introduces btf__resolve_type() function and exports two
existing functions from libbpf. btf__resolve_type follows modifier
types like const and typedef until it hits a type which actually takes
up memory, and then returns it. This function follows similar pattern
to btf__resolve_size but instead of computing size, it just returns
the type.
These functions will be used in the followig patch which parses
information inside array of `struct btf_type *`. btf_name_by_offset is
used for printing variable names.
Signed-off-by: Okash Khawaja <osk@fb.com>
Acked-by: Martin KaFai Lau <kafai@fb.com>
Acked-by: Song Liu <songliubraving@fb.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Diffstat (limited to 'tools/lib/bpf/btf.c')
-rw-r--r-- | tools/lib/bpf/btf.c | 65 |
1 files changed, 45 insertions, 20 deletions
diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c index 8c54a4b6f187..03161be094b4 100644 --- a/tools/lib/bpf/btf.c +++ b/tools/lib/bpf/btf.c | |||
@@ -17,6 +17,11 @@ | |||
17 | 17 | ||
18 | #define BTF_MAX_NR_TYPES 65535 | 18 | #define BTF_MAX_NR_TYPES 65535 |
19 | 19 | ||
20 | #define IS_MODIFIER(k) (((k) == BTF_KIND_TYPEDEF) || \ | ||
21 | ((k) == BTF_KIND_VOLATILE) || \ | ||
22 | ((k) == BTF_KIND_CONST) || \ | ||
23 | ((k) == BTF_KIND_RESTRICT)) | ||
24 | |||
20 | static struct btf_type btf_void; | 25 | static struct btf_type btf_void; |
21 | 26 | ||
22 | struct btf { | 27 | struct btf { |
@@ -33,14 +38,6 @@ struct btf { | |||
33 | int fd; | 38 | int fd; |
34 | }; | 39 | }; |
35 | 40 | ||
36 | static const char *btf_name_by_offset(const struct btf *btf, uint32_t offset) | ||
37 | { | ||
38 | if (offset < btf->hdr->str_len) | ||
39 | return &btf->strings[offset]; | ||
40 | else | ||
41 | return NULL; | ||
42 | } | ||
43 | |||
44 | static int btf_add_type(struct btf *btf, struct btf_type *t) | 41 | static int btf_add_type(struct btf *btf, struct btf_type *t) |
45 | { | 42 | { |
46 | if (btf->types_size - btf->nr_types < 2) { | 43 | if (btf->types_size - btf->nr_types < 2) { |
@@ -190,15 +187,6 @@ static int btf_parse_type_sec(struct btf *btf, btf_print_fn_t err_log) | |||
190 | return 0; | 187 | return 0; |
191 | } | 188 | } |
192 | 189 | ||
193 | static const struct btf_type *btf_type_by_id(const struct btf *btf, | ||
194 | uint32_t type_id) | ||
195 | { | ||
196 | if (type_id > btf->nr_types) | ||
197 | return NULL; | ||
198 | |||
199 | return btf->types[type_id]; | ||
200 | } | ||
201 | |||
202 | static bool btf_type_is_void(const struct btf_type *t) | 190 | static bool btf_type_is_void(const struct btf_type *t) |
203 | { | 191 | { |
204 | return t == &btf_void || BTF_INFO_KIND(t->info) == BTF_KIND_FWD; | 192 | return t == &btf_void || BTF_INFO_KIND(t->info) == BTF_KIND_FWD; |
@@ -234,7 +222,7 @@ int64_t btf__resolve_size(const struct btf *btf, uint32_t type_id) | |||
234 | int64_t size = -1; | 222 | int64_t size = -1; |
235 | int i; | 223 | int i; |
236 | 224 | ||
237 | t = btf_type_by_id(btf, type_id); | 225 | t = btf__type_by_id(btf, type_id); |
238 | for (i = 0; i < MAX_RESOLVE_DEPTH && !btf_type_is_void_or_null(t); | 226 | for (i = 0; i < MAX_RESOLVE_DEPTH && !btf_type_is_void_or_null(t); |
239 | i++) { | 227 | i++) { |
240 | size = btf_type_size(t); | 228 | size = btf_type_size(t); |
@@ -259,7 +247,7 @@ int64_t btf__resolve_size(const struct btf *btf, uint32_t type_id) | |||
259 | return -EINVAL; | 247 | return -EINVAL; |
260 | } | 248 | } |
261 | 249 | ||
262 | t = btf_type_by_id(btf, type_id); | 250 | t = btf__type_by_id(btf, type_id); |
263 | } | 251 | } |
264 | 252 | ||
265 | if (size < 0) | 253 | if (size < 0) |
@@ -271,6 +259,26 @@ int64_t btf__resolve_size(const struct btf *btf, uint32_t type_id) | |||
271 | return nelems * size; | 259 | return nelems * size; |
272 | } | 260 | } |
273 | 261 | ||
262 | int btf__resolve_type(const struct btf *btf, __u32 type_id) | ||
263 | { | ||
264 | const struct btf_type *t; | ||
265 | int depth = 0; | ||
266 | |||
267 | t = btf__type_by_id(btf, type_id); | ||
268 | while (depth < MAX_RESOLVE_DEPTH && | ||
269 | !btf_type_is_void_or_null(t) && | ||
270 | IS_MODIFIER(BTF_INFO_KIND(t->info))) { | ||
271 | type_id = t->type; | ||
272 | t = btf__type_by_id(btf, type_id); | ||
273 | depth++; | ||
274 | } | ||
275 | |||
276 | if (depth == MAX_RESOLVE_DEPTH || btf_type_is_void_or_null(t)) | ||
277 | return -EINVAL; | ||
278 | |||
279 | return type_id; | ||
280 | } | ||
281 | |||
274 | int32_t btf__find_by_name(const struct btf *btf, const char *type_name) | 282 | int32_t btf__find_by_name(const struct btf *btf, const char *type_name) |
275 | { | 283 | { |
276 | uint32_t i; | 284 | uint32_t i; |
@@ -280,7 +288,7 @@ int32_t btf__find_by_name(const struct btf *btf, const char *type_name) | |||
280 | 288 | ||
281 | for (i = 1; i <= btf->nr_types; i++) { | 289 | for (i = 1; i <= btf->nr_types; i++) { |
282 | const struct btf_type *t = btf->types[i]; | 290 | const struct btf_type *t = btf->types[i]; |
283 | const char *name = btf_name_by_offset(btf, t->name_off); | 291 | const char *name = btf__name_by_offset(btf, t->name_off); |
284 | 292 | ||
285 | if (name && !strcmp(type_name, name)) | 293 | if (name && !strcmp(type_name, name)) |
286 | return i; | 294 | return i; |
@@ -371,3 +379,20 @@ int btf__fd(const struct btf *btf) | |||
371 | { | 379 | { |
372 | return btf->fd; | 380 | return btf->fd; |
373 | } | 381 | } |
382 | |||
383 | const char *btf__name_by_offset(const struct btf *btf, __u32 offset) | ||
384 | { | ||
385 | if (offset < btf->hdr->str_len) | ||
386 | return &btf->strings[offset]; | ||
387 | else | ||
388 | return NULL; | ||
389 | } | ||
390 | |||
391 | const struct btf_type *btf__type_by_id(const struct btf *btf, | ||
392 | __u32 type_id) | ||
393 | { | ||
394 | if (type_id > btf->nr_types) | ||
395 | return NULL; | ||
396 | |||
397 | return btf->types[type_id]; | ||
398 | } | ||