From: Yonghong Song <y...@fb.com>

The function get_btf() is implemented in tools/bpf/bpftool/map.c
to get a btf structure given a map_info. This patch
refactored this function to be function btf_get_from_id()
in tools/lib/bpf so that it can be used later.

Signed-off-by: Yonghong Song <y...@fb.com>
Signed-off-by: Martin KaFai Lau <ka...@fb.com>
---
 tools/bpf/bpftool/map.c | 68 ++--------------------------------------
 tools/lib/bpf/btf.c     | 69 +++++++++++++++++++++++++++++++++++++++++
 tools/lib/bpf/btf.h     |  1 +
 3 files changed, 72 insertions(+), 66 deletions(-)

diff --git a/tools/bpf/bpftool/map.c b/tools/bpf/bpftool/map.c
index dc9a8967ab8c..a1ae2a3e9fef 100644
--- a/tools/bpf/bpftool/map.c
+++ b/tools/bpf/bpftool/map.c
@@ -215,70 +215,6 @@ static int do_dump_btf(const struct btf_dumper *d,
        return ret;
 }
 
-static int get_btf(struct bpf_map_info *map_info, struct btf **btf)
-{
-       struct bpf_btf_info btf_info = { 0 };
-       __u32 len = sizeof(btf_info);
-       __u32 last_size;
-       int btf_fd;
-       void *ptr;
-       int err;
-
-       err = 0;
-       *btf = NULL;
-       btf_fd = bpf_btf_get_fd_by_id(map_info->btf_id);
-       if (btf_fd < 0)
-               return 0;
-
-       /* we won't know btf_size until we call bpf_obj_get_info_by_fd(). so
-        * let's start with a sane default - 4KiB here - and resize it only if
-        * bpf_obj_get_info_by_fd() needs a bigger buffer.
-        */
-       btf_info.btf_size = 4096;
-       last_size = btf_info.btf_size;
-       ptr = malloc(last_size);
-       if (!ptr) {
-               err = -ENOMEM;
-               goto exit_free;
-       }
-
-       bzero(ptr, last_size);
-       btf_info.btf = ptr_to_u64(ptr);
-       err = bpf_obj_get_info_by_fd(btf_fd, &btf_info, &len);
-
-       if (!err && btf_info.btf_size > last_size) {
-               void *temp_ptr;
-
-               last_size = btf_info.btf_size;
-               temp_ptr = realloc(ptr, last_size);
-               if (!temp_ptr) {
-                       err = -ENOMEM;
-                       goto exit_free;
-               }
-               ptr = temp_ptr;
-               bzero(ptr, last_size);
-               btf_info.btf = ptr_to_u64(ptr);
-               err = bpf_obj_get_info_by_fd(btf_fd, &btf_info, &len);
-       }
-
-       if (err || btf_info.btf_size > last_size) {
-               err = errno;
-               goto exit_free;
-       }
-
-       *btf = btf__new((__u8 *)btf_info.btf, btf_info.btf_size, NULL);
-       if (IS_ERR(*btf)) {
-               err = PTR_ERR(*btf);
-               *btf = NULL;
-       }
-
-exit_free:
-       close(btf_fd);
-       free(ptr);
-
-       return err;
-}
-
 static json_writer_t *get_btf_writer(void)
 {
        json_writer_t *jw = jsonw_new(stdout);
@@ -775,7 +711,7 @@ static int do_dump(int argc, char **argv)
 
        prev_key = NULL;
 
-       err = get_btf(&info, &btf);
+       err = btf_get_from_id(info.btf_id, &btf);
        if (err) {
                p_err("failed to get btf");
                goto exit_free;
@@ -919,7 +855,7 @@ static int do_lookup(int argc, char **argv)
        }
 
        /* here means bpf_map_lookup_elem() succeeded */
-       err = get_btf(&info, &btf);
+       err = btf_get_from_id(info.btf_id, &btf);
        if (err) {
                p_err("failed to get btf");
                goto exit_free;
diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
index fe87cb48a6a9..13ddc4bd24ee 100644
--- a/tools/lib/bpf/btf.c
+++ b/tools/lib/bpf/btf.c
@@ -49,6 +49,11 @@ struct bpf_func_info_min {
        __u32   type_id;
 };
 
+static inline __u64 ptr_to_u64(const void *ptr)
+{
+       return (__u64) (unsigned long) ptr;
+}
+
 static int btf_add_type(struct btf *btf, struct btf_type *t)
 {
        if (btf->types_size - btf->nr_types < 2) {
@@ -410,6 +415,70 @@ const char *btf__name_by_offset(const struct btf *btf, 
__u32 offset)
                return NULL;
 }
 
+int btf_get_from_id(__u32 id, struct btf **btf)
+{
+       struct bpf_btf_info btf_info = { 0 };
+       __u32 len = sizeof(btf_info);
+       __u32 last_size;
+       int btf_fd;
+       void *ptr;
+       int err;
+
+       err = 0;
+       *btf = NULL;
+       btf_fd = bpf_btf_get_fd_by_id(id);
+       if (btf_fd < 0)
+               return 0;
+
+       /* we won't know btf_size until we call bpf_obj_get_info_by_fd(). so
+        * let's start with a sane default - 4KiB here - and resize it only if
+        * bpf_obj_get_info_by_fd() needs a bigger buffer.
+        */
+       btf_info.btf_size = 4096;
+       last_size = btf_info.btf_size;
+       ptr = malloc(last_size);
+       if (!ptr) {
+               err = -ENOMEM;
+               goto exit_free;
+       }
+
+       bzero(ptr, last_size);
+       btf_info.btf = ptr_to_u64(ptr);
+       err = bpf_obj_get_info_by_fd(btf_fd, &btf_info, &len);
+
+       if (!err && btf_info.btf_size > last_size) {
+               void *temp_ptr;
+
+               last_size = btf_info.btf_size;
+               temp_ptr = realloc(ptr, last_size);
+               if (!temp_ptr) {
+                       err = -ENOMEM;
+                       goto exit_free;
+               }
+               ptr = temp_ptr;
+               bzero(ptr, last_size);
+               btf_info.btf = ptr_to_u64(ptr);
+               err = bpf_obj_get_info_by_fd(btf_fd, &btf_info, &len);
+       }
+
+       if (err || btf_info.btf_size > last_size) {
+               err = errno;
+               goto exit_free;
+       }
+
+       *btf = btf__new((__u8 *)btf_info.btf, btf_info.btf_size, NULL);
+       if (IS_ERR(*btf)) {
+               err = PTR_ERR(*btf);
+               *btf = NULL;
+       }
+
+exit_free:
+       close(btf_fd);
+       free(ptr);
+
+       return err;
+}
+
 static int btf_ext_validate_func_info(const void *finfo, __u32 size,
                                      btf_print_fn_t err_log)
 {
diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h
index 578171e8cb26..386b2ffc32a3 100644
--- a/tools/lib/bpf/btf.h
+++ b/tools/lib/bpf/btf.h
@@ -69,6 +69,7 @@ LIBBPF_API __s64 btf__resolve_size(const struct btf *btf, 
__u32 type_id);
 LIBBPF_API int btf__resolve_type(const struct btf *btf, __u32 type_id);
 LIBBPF_API int btf__fd(const struct btf *btf);
 LIBBPF_API const char *btf__name_by_offset(const struct btf *btf, __u32 
offset);
+LIBBPF_API int btf_get_from_id(__u32 id, struct btf **btf);
 
 struct btf_ext *btf_ext__new(__u8 *data, __u32 size, btf_print_fn_t err_log);
 void btf_ext__free(struct btf_ext *btf_ext);
-- 
2.17.1

Reply via email to