libbpf: Add libbpf_kallsyms_parse function
authorJiri Olsa <jolsa@kernel.org>
Wed, 16 Mar 2022 12:24:13 +0000 (13:24 +0100)
committerAlexei Starovoitov <ast@kernel.org>
Fri, 18 Mar 2022 03:17:19 +0000 (20:17 -0700)
Move the kallsyms parsing in internal libbpf_kallsyms_parse
function, so it can be used from other places.

It will be used in following changes.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20220316122419.933957-8-jolsa@kernel.org
tools/lib/bpf/libbpf.c
tools/lib/bpf/libbpf_internal.h

index 43161fd..1ca520a 100644 (file)
@@ -7171,12 +7171,10 @@ static int bpf_object__sanitize_maps(struct bpf_object *obj)
        return 0;
 }
 
-static int bpf_object__read_kallsyms_file(struct bpf_object *obj)
+int libbpf_kallsyms_parse(kallsyms_cb_t cb, void *ctx)
 {
        char sym_type, sym_name[500];
        unsigned long long sym_addr;
-       const struct btf_type *t;
-       struct extern_desc *ext;
        int ret, err = 0;
        FILE *f;
 
@@ -7195,35 +7193,51 @@ static int bpf_object__read_kallsyms_file(struct bpf_object *obj)
                if (ret != 3) {
                        pr_warn("failed to read kallsyms entry: %d\n", ret);
                        err = -EINVAL;
-                       goto out;
+                       break;
                }
 
-               ext = find_extern_by_name(obj, sym_name);
-               if (!ext || ext->type != EXT_KSYM)
-                       continue;
-
-               t = btf__type_by_id(obj->btf, ext->btf_id);
-               if (!btf_is_var(t))
-                       continue;
-
-               if (ext->is_set && ext->ksym.addr != sym_addr) {
-                       pr_warn("extern (ksym) '%s' resolution is ambiguous: 0x%llx or 0x%llx\n",
-                               sym_name, ext->ksym.addr, sym_addr);
-                       err = -EINVAL;
-                       goto out;
-               }
-               if (!ext->is_set) {
-                       ext->is_set = true;
-                       ext->ksym.addr = sym_addr;
-                       pr_debug("extern (ksym) %s=0x%llx\n", sym_name, sym_addr);
-               }
+               err = cb(sym_addr, sym_type, sym_name, ctx);
+               if (err)
+                       break;
        }
 
-out:
        fclose(f);
        return err;
 }
 
+static int kallsyms_cb(unsigned long long sym_addr, char sym_type,
+                      const char *sym_name, void *ctx)
+{
+       struct bpf_object *obj = ctx;
+       const struct btf_type *t;
+       struct extern_desc *ext;
+
+       ext = find_extern_by_name(obj, sym_name);
+       if (!ext || ext->type != EXT_KSYM)
+               return 0;
+
+       t = btf__type_by_id(obj->btf, ext->btf_id);
+       if (!btf_is_var(t))
+               return 0;
+
+       if (ext->is_set && ext->ksym.addr != sym_addr) {
+               pr_warn("extern (ksym) '%s' resolution is ambiguous: 0x%llx or 0x%llx\n",
+                       sym_name, ext->ksym.addr, sym_addr);
+               return -EINVAL;
+       }
+       if (!ext->is_set) {
+               ext->is_set = true;
+               ext->ksym.addr = sym_addr;
+               pr_debug("extern (ksym) %s=0x%llx\n", sym_name, sym_addr);
+       }
+       return 0;
+}
+
+static int bpf_object__read_kallsyms_file(struct bpf_object *obj)
+{
+       return libbpf_kallsyms_parse(kallsyms_cb, obj);
+}
+
 static int find_ksym_btf_id(struct bpf_object *obj, const char *ksym_name,
                            __u16 kind, struct btf **res_btf,
                            struct module_btf **res_mod_btf)
index 4fda8bd..b6247dc 100644 (file)
@@ -449,6 +449,11 @@ __s32 btf__find_by_name_kind_own(const struct btf *btf, const char *type_name,
 
 extern enum libbpf_strict_mode libbpf_mode;
 
+typedef int (*kallsyms_cb_t)(unsigned long long sym_addr, char sym_type,
+                            const char *sym_name, void *ctx);
+
+int libbpf_kallsyms_parse(kallsyms_cb_t cb, void *arg);
+
 /* handle direct returned errors */
 static inline int libbpf_err(int ret)
 {