aboutsummaryrefslogtreecommitdiffstats
path: root/tools/lib/bpf/btf.c
diff options
context:
space:
mode:
authorYonghong Song <yhs@fb.com>2019-02-04 14:00:58 -0500
committerAlexei Starovoitov <ast@kernel.org>2019-02-04 15:48:36 -0500
commit96408c43447aff5091a6938f29d8b6f2d0aa2064 (patch)
treee59397b34c18fbca196e149502381e4efa1ad31c /tools/lib/bpf/btf.c
parentb8dcf8d149db5999d3db937822d3e374eca68b9f (diff)
tools/bpf: implement libbpf btf__get_map_kv_tids() API function
Currently, to get map key/value type id's, the macro BPF_ANNOTATE_KV_PAIR(<map_name>, <key_type>, <value_type>) needs to be defined in the bpf program for the corresponding map. During program/map loading time, the local static function bpf_map_find_btf_info() in libbpf.c is implemented to retrieve the key/value type ids given the map name. The patch refactored function bpf_map_find_btf_info() to create an API btf__get_map_kv_tids() which includes the bulk of implementation for the original function. The API btf__get_map_kv_tids() can be used by bcc, a JIT based bpf compilation system, which uses the same BPF_ANNOTATE_KV_PAIR to record map key/value types. Acked-by: Martin KaFai Lau <kafai@fb.com> Signed-off-by: Yonghong Song <yhs@fb.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Diffstat (limited to 'tools/lib/bpf/btf.c')
-rw-r--r--tools/lib/bpf/btf.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
index 51a0db05bf80..7ec0463354db 100644
--- a/tools/lib/bpf/btf.c
+++ b/tools/lib/bpf/btf.c
@@ -1,6 +1,7 @@
1// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) 1// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
2/* Copyright (c) 2018 Facebook */ 2/* Copyright (c) 2018 Facebook */
3 3
4#include <stdio.h>
4#include <stdlib.h> 5#include <stdlib.h>
5#include <string.h> 6#include <string.h>
6#include <unistd.h> 7#include <unistd.h>
@@ -504,6 +505,78 @@ exit_free:
504 return err; 505 return err;
505} 506}
506 507
508int btf__get_map_kv_tids(const struct btf *btf, char *map_name,
509 __u32 expected_key_size, __u32 expected_value_size,
510 __u32 *key_type_id, __u32 *value_type_id)
511{
512 const struct btf_type *container_type;
513 const struct btf_member *key, *value;
514 const size_t max_name = 256;
515 char container_name[max_name];
516 __s64 key_size, value_size;
517 __s32 container_id;
518
519 if (snprintf(container_name, max_name, "____btf_map_%s", map_name) ==
520 max_name) {
521 pr_warning("map:%s length of '____btf_map_%s' is too long\n",
522 map_name, map_name);
523 return -EINVAL;
524 }
525
526 container_id = btf__find_by_name(btf, container_name);
527 if (container_id < 0) {
528 pr_warning("map:%s container_name:%s cannot be found in BTF. Missing BPF_ANNOTATE_KV_PAIR?\n",
529 map_name, container_name);
530 return container_id;
531 }
532
533 container_type = btf__type_by_id(btf, container_id);
534 if (!container_type) {
535 pr_warning("map:%s cannot find BTF type for container_id:%u\n",
536 map_name, container_id);
537 return -EINVAL;
538 }
539
540 if (BTF_INFO_KIND(container_type->info) != BTF_KIND_STRUCT ||
541 BTF_INFO_VLEN(container_type->info) < 2) {
542 pr_warning("map:%s container_name:%s is an invalid container struct\n",
543 map_name, container_name);
544 return -EINVAL;
545 }
546
547 key = (struct btf_member *)(container_type + 1);
548 value = key + 1;
549
550 key_size = btf__resolve_size(btf, key->type);
551 if (key_size < 0) {
552 pr_warning("map:%s invalid BTF key_type_size\n", map_name);
553 return key_size;
554 }
555
556 if (expected_key_size != key_size) {
557 pr_warning("map:%s btf_key_type_size:%u != map_def_key_size:%u\n",
558 map_name, (__u32)key_size, expected_key_size);
559 return -EINVAL;
560 }
561
562 value_size = btf__resolve_size(btf, value->type);
563 if (value_size < 0) {
564 pr_warning("map:%s invalid BTF value_type_size\n", map_name);
565 return value_size;
566 }
567
568 if (expected_value_size != value_size) {
569 pr_warning("map:%s btf_value_type_size:%u != map_def_value_size:%u\n",
570 map_name, (__u32)value_size, expected_value_size);
571 return -EINVAL;
572 }
573
574 *key_type_id = key->type;
575 *value_type_id = value->type;
576
577 return 0;
578}
579
507struct btf_ext_sec_copy_param { 580struct btf_ext_sec_copy_param {
508 __u32 off; 581 __u32 off;
509 __u32 len; 582 __u32 len;