mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
libbpf: Add btf_type_is_traceable_func function
Adding btf_type_is_traceable_func function to perform same checks as the kernel's btf_distill_func_proto function to prevent attachment on some of the functions. Exporting the function via libbpf_internal.h because it will be used by benchmark test in following changes. Signed-off-by: Jiri Olsa <jolsa@kernel.org> Link: https://lore.kernel.org/r/20260606123955.345967-20-jolsa@kernel.org Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
630e85a9f0
commit
616a93b473
|
|
@ -12450,6 +12450,85 @@ static int attach_uprobe_multi(const struct bpf_program *prog, long cookie, stru
|
|||
return ret;
|
||||
}
|
||||
|
||||
#define MAX_BPF_FUNC_ARGS 12
|
||||
|
||||
static bool btf_type_is_modifier(const struct btf_type *t)
|
||||
{
|
||||
switch (BTF_INFO_KIND(t->info)) {
|
||||
case BTF_KIND_TYPEDEF:
|
||||
case BTF_KIND_VOLATILE:
|
||||
case BTF_KIND_CONST:
|
||||
case BTF_KIND_RESTRICT:
|
||||
case BTF_KIND_TYPE_TAG:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#define MAX_RESOLVE_DEPTH 32
|
||||
|
||||
static int btf_get_type_size(const struct btf *btf, __u32 type_id,
|
||||
const struct btf_type **ret_type)
|
||||
{
|
||||
const struct btf_type *t;
|
||||
int i;
|
||||
|
||||
*ret_type = btf__type_by_id(btf, 0);
|
||||
if (!type_id)
|
||||
return 0;
|
||||
t = btf__type_by_id(btf, type_id);
|
||||
for (i = 0; i < MAX_RESOLVE_DEPTH && t && btf_type_is_modifier(t); i++)
|
||||
t = btf__type_by_id(btf, t->type);
|
||||
if (!t || i == MAX_RESOLVE_DEPTH)
|
||||
return -EINVAL;
|
||||
*ret_type = t;
|
||||
if (btf_is_ptr(t))
|
||||
return btf__pointer_size(btf);
|
||||
if (btf_is_int(t) || btf_is_any_enum(t) || btf_is_struct(t) || btf_is_union(t))
|
||||
return t->size;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
bool btf_type_is_traceable_func(const struct btf *btf, const struct btf_type *t)
|
||||
{
|
||||
const struct btf_param *args;
|
||||
const struct btf_type *proto;
|
||||
__u32 i, nargs;
|
||||
int ret;
|
||||
|
||||
if (!btf_is_func(t))
|
||||
return false;
|
||||
proto = btf__type_by_id(btf, t->type);
|
||||
if (!proto || !btf_is_func_proto(proto))
|
||||
return false;
|
||||
|
||||
args = (const struct btf_param *)(proto + 1);
|
||||
nargs = btf_vlen(proto);
|
||||
if (nargs > MAX_BPF_FUNC_ARGS)
|
||||
return false;
|
||||
|
||||
/* No support for struct return type. */
|
||||
ret = btf_get_type_size(btf, proto->type, &t);
|
||||
if (ret < 0 || btf_is_struct(t) || btf_is_union(t))
|
||||
return false;
|
||||
|
||||
for (i = 0; i < nargs; i++) {
|
||||
/* No support for variable args. */
|
||||
if (i == nargs - 1 && args[i].type == 0)
|
||||
return false;
|
||||
ret = btf_get_type_size(btf, args[i].type, &t);
|
||||
/* No support of struct argument size greater than 16 bytes. */
|
||||
if (ret < 0 || ret > 16)
|
||||
return false;
|
||||
/* No support for void argument. */
|
||||
if (ret == 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline int add_uprobe_event_legacy(const char *probe_name, bool retprobe,
|
||||
const char *binary_path, size_t offset)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -250,6 +250,7 @@ const struct btf_type *skip_mods_and_typedefs(const struct btf *btf, __u32 id, _
|
|||
const struct btf_header *btf_header(const struct btf *btf);
|
||||
void btf_set_base_btf(struct btf *btf, const struct btf *base_btf);
|
||||
int btf_relocate(struct btf *btf, const struct btf *base_btf, __u32 **id_map);
|
||||
bool btf_type_is_traceable_func(const struct btf *btf, const struct btf_type *t);
|
||||
|
||||
static inline enum btf_func_linkage btf_func_linkage(const struct btf_type *t)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user