Commit 933d1aa3 authored by Martin KaFai Lau's avatar Martin KaFai Lau Committed by Alexei Starovoitov

libbpf: Refactor bpf_object__resolve_ksyms_btf_id

This patch refactors most of the logic from
bpf_object__resolve_ksyms_btf_id() into a new function
bpf_object__resolve_ksym_var_btf_id().
It is to get ready for a later patch adding
bpf_object__resolve_ksym_func_btf_id() which resolves
a kernel function to the running kernel btf_id.
Signed-off-by: default avatarMartin KaFai Lau <kafai@fb.com>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
Acked-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20210325015207.1546749-1-kafai@fb.com
parent e78aea8b
...@@ -7395,75 +7395,85 @@ static int bpf_object__read_kallsyms_file(struct bpf_object *obj) ...@@ -7395,75 +7395,85 @@ static int bpf_object__read_kallsyms_file(struct bpf_object *obj)
return err; return err;
} }
static int bpf_object__resolve_ksyms_btf_id(struct bpf_object *obj) static int bpf_object__resolve_ksym_var_btf_id(struct bpf_object *obj,
struct extern_desc *ext)
{ {
struct extern_desc *ext; const struct btf_type *targ_var, *targ_type;
__u32 targ_type_id, local_type_id;
const char *targ_var_name;
int i, id, btf_fd, err;
struct btf *btf; struct btf *btf;
int i, j, id, btf_fd, err;
for (i = 0; i < obj->nr_extern; i++) { btf = obj->btf_vmlinux;
const struct btf_type *targ_var, *targ_type; btf_fd = 0;
__u32 targ_type_id, local_type_id; id = btf__find_by_name_kind(btf, ext->name, BTF_KIND_VAR);
const char *targ_var_name; if (id == -ENOENT) {
int ret; err = load_module_btfs(obj);
if (err)
return err;
ext = &obj->externs[i]; for (i = 0; i < obj->btf_module_cnt; i++) {
if (ext->type != EXT_KSYM || !ext->ksym.type_id) btf = obj->btf_modules[i].btf;
continue; /* we assume module BTF FD is always >0 */
btf_fd = obj->btf_modules[i].fd;
id = btf__find_by_name_kind(btf, ext->name, BTF_KIND_VAR);
if (id != -ENOENT)
break;
}
}
if (id <= 0) {
pr_warn("extern (var ksym) '%s': failed to find BTF ID in kernel BTF(s).\n",
ext->name);
return -ESRCH;
}
btf = obj->btf_vmlinux; /* find local type_id */
btf_fd = 0; local_type_id = ext->ksym.type_id;
id = btf__find_by_name_kind(btf, ext->name, BTF_KIND_VAR);
if (id == -ENOENT) {
err = load_module_btfs(obj);
if (err)
return err;
for (j = 0; j < obj->btf_module_cnt; j++) { /* find target type_id */
btf = obj->btf_modules[j].btf; targ_var = btf__type_by_id(btf, id);
/* we assume module BTF FD is always >0 */ targ_var_name = btf__name_by_offset(btf, targ_var->name_off);
btf_fd = obj->btf_modules[j].fd; targ_type = skip_mods_and_typedefs(btf, targ_var->type, &targ_type_id);
id = btf__find_by_name_kind(btf, ext->name, BTF_KIND_VAR);
if (id != -ENOENT)
break;
}
}
if (id <= 0) {
pr_warn("extern (ksym) '%s': failed to find BTF ID in kernel BTF(s).\n",
ext->name);
return -ESRCH;
}
/* find local type_id */ err = bpf_core_types_are_compat(obj->btf, local_type_id,
local_type_id = ext->ksym.type_id; btf, targ_type_id);
if (err <= 0) {
const struct btf_type *local_type;
const char *targ_name, *local_name;
/* find target type_id */ local_type = btf__type_by_id(obj->btf, local_type_id);
targ_var = btf__type_by_id(btf, id); local_name = btf__name_by_offset(obj->btf, local_type->name_off);
targ_var_name = btf__name_by_offset(btf, targ_var->name_off); targ_name = btf__name_by_offset(btf, targ_type->name_off);
targ_type = skip_mods_and_typedefs(btf, targ_var->type, &targ_type_id);
ret = bpf_core_types_are_compat(obj->btf, local_type_id, pr_warn("extern (var ksym) '%s': incompatible types, expected [%d] %s %s, but kernel has [%d] %s %s\n",
btf, targ_type_id); ext->name, local_type_id,
if (ret <= 0) { btf_kind_str(local_type), local_name, targ_type_id,
const struct btf_type *local_type; btf_kind_str(targ_type), targ_name);
const char *targ_name, *local_name; return -EINVAL;
}
local_type = btf__type_by_id(obj->btf, local_type_id); ext->is_set = true;
local_name = btf__name_by_offset(obj->btf, local_type->name_off); ext->ksym.kernel_btf_obj_fd = btf_fd;
targ_name = btf__name_by_offset(btf, targ_type->name_off); ext->ksym.kernel_btf_id = id;
pr_debug("extern (var ksym) '%s': resolved to [%d] %s %s\n",
ext->name, id, btf_kind_str(targ_var), targ_var_name);
pr_warn("extern (ksym) '%s': incompatible types, expected [%d] %s %s, but kernel has [%d] %s %s\n", return 0;
ext->name, local_type_id, }
btf_kind_str(local_type), local_name, targ_type_id,
btf_kind_str(targ_type), targ_name); static int bpf_object__resolve_ksyms_btf_id(struct bpf_object *obj)
return -EINVAL; {
} struct extern_desc *ext;
int i, err;
for (i = 0; i < obj->nr_extern; i++) {
ext = &obj->externs[i];
if (ext->type != EXT_KSYM || !ext->ksym.type_id)
continue;
ext->is_set = true; err = bpf_object__resolve_ksym_var_btf_id(obj, ext);
ext->ksym.kernel_btf_obj_fd = btf_fd; if (err)
ext->ksym.kernel_btf_id = id; return err;
pr_debug("extern (ksym) '%s': resolved to [%d] %s %s\n",
ext->name, id, btf_kind_str(targ_var), targ_var_name);
} }
return 0; return 0;
} }
......
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