Commit 85153ac0 authored by Jiri Olsa's avatar Jiri Olsa Committed by Alexei Starovoitov

libbpf: Add libbpf_kallsyms_parse function

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: default avatarJiri Olsa <jolsa@kernel.org>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
Acked-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20220316122419.933957-8-jolsa@kernel.org
parent ca74823c
...@@ -7171,12 +7171,10 @@ static int bpf_object__sanitize_maps(struct bpf_object *obj) ...@@ -7171,12 +7171,10 @@ static int bpf_object__sanitize_maps(struct bpf_object *obj)
return 0; 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]; char sym_type, sym_name[500];
unsigned long long sym_addr; unsigned long long sym_addr;
const struct btf_type *t;
struct extern_desc *ext;
int ret, err = 0; int ret, err = 0;
FILE *f; FILE *f;
...@@ -7195,33 +7193,49 @@ static int bpf_object__read_kallsyms_file(struct bpf_object *obj) ...@@ -7195,33 +7193,49 @@ static int bpf_object__read_kallsyms_file(struct bpf_object *obj)
if (ret != 3) { if (ret != 3) {
pr_warn("failed to read kallsyms entry: %d\n", ret); pr_warn("failed to read kallsyms entry: %d\n", ret);
err = -EINVAL; err = -EINVAL;
goto out; break;
}
err = cb(sym_addr, sym_type, sym_name, ctx);
if (err)
break;
} }
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); ext = find_extern_by_name(obj, sym_name);
if (!ext || ext->type != EXT_KSYM) if (!ext || ext->type != EXT_KSYM)
continue; return 0;
t = btf__type_by_id(obj->btf, ext->btf_id); t = btf__type_by_id(obj->btf, ext->btf_id);
if (!btf_is_var(t)) if (!btf_is_var(t))
continue; return 0;
if (ext->is_set && ext->ksym.addr != sym_addr) { if (ext->is_set && ext->ksym.addr != sym_addr) {
pr_warn("extern (ksym) '%s' resolution is ambiguous: 0x%llx or 0x%llx\n", pr_warn("extern (ksym) '%s' resolution is ambiguous: 0x%llx or 0x%llx\n",
sym_name, ext->ksym.addr, sym_addr); sym_name, ext->ksym.addr, sym_addr);
err = -EINVAL; return -EINVAL;
goto out;
} }
if (!ext->is_set) { if (!ext->is_set) {
ext->is_set = true; ext->is_set = true;
ext->ksym.addr = sym_addr; ext->ksym.addr = sym_addr;
pr_debug("extern (ksym) %s=0x%llx\n", sym_name, sym_addr); pr_debug("extern (ksym) %s=0x%llx\n", sym_name, sym_addr);
} }
} return 0;
}
out: static int bpf_object__read_kallsyms_file(struct bpf_object *obj)
fclose(f); {
return err; return libbpf_kallsyms_parse(kallsyms_cb, obj);
} }
static int find_ksym_btf_id(struct bpf_object *obj, const char *ksym_name, static int find_ksym_btf_id(struct bpf_object *obj, const char *ksym_name,
......
...@@ -449,6 +449,11 @@ __s32 btf__find_by_name_kind_own(const struct btf *btf, const char *type_name, ...@@ -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; 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 */ /* handle direct returned errors */
static inline int libbpf_err(int ret) static inline int libbpf_err(int ret)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment