[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20211118112455.475349-22-jolsa@kernel.org>
Date: Thu, 18 Nov 2021 12:24:47 +0100
From: Jiri Olsa <jolsa@...hat.com>
To: Alexei Starovoitov <ast@...nel.org>,
Daniel Borkmann <daniel@...earbox.net>,
Andrii Nakryiko <andrii@...nel.org>
Cc: Andrii Nakryiko <andrii.nakryiko@...il.com>,
netdev@...r.kernel.org, bpf@...r.kernel.org,
Martin KaFai Lau <kafai@...com>,
Song Liu <songliubraving@...com>, Yonghong Song <yhs@...com>,
John Fastabend <john.fastabend@...il.com>,
KP Singh <kpsingh@...omium.org>
Subject: [PATCH bpf-next 21/29] libbpf: Add btf__find_by_glob_kind function
Adding btf__find_by_glob_kind function that returns array of
BTF ids that match given kind and allow/deny patterns.
int btf__find_by_glob_kind(const struct btf *btf, __u32 kind,
const char *allow_pattern,
const char *deny_pattern,
__u32 **__ids);
The __ids array is allocated and needs to be manually freed.
At the moment the supported pattern is '*' at the beginning or
the end of the pattern.
Kindly borrowed from retsnoop.
Suggested-by: Andrii Nakryiko <andrii.nakryiko@...il.com>
Signed-off-by: Jiri Olsa <jolsa@...nel.org>
---
tools/lib/bpf/btf.c | 77 +++++++++++++++++++++++++++++++++++++++++++++
tools/lib/bpf/btf.h | 3 ++
2 files changed, 80 insertions(+)
diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
index b6be579e0dc6..ebc02576390d 100644
--- a/tools/lib/bpf/btf.c
+++ b/tools/lib/bpf/btf.c
@@ -749,6 +749,83 @@ __s32 btf__find_by_name_kind(const struct btf *btf, const char *type_name,
return btf_find_by_name_kind(btf, 1, type_name, kind);
}
+/* 'borrowed' from retsnoop */
+static bool glob_matches(const char *glob, const char *s)
+{
+ int n = strlen(glob);
+
+ if (n == 1 && glob[0] == '*')
+ return true;
+
+ if (glob[0] == '*' && glob[n - 1] == '*') {
+ const char *subs;
+ /* substring match */
+
+ /* this is hacky, but we don't want to allocate for no good reason */
+ ((char *)glob)[n - 1] = '\0';
+ subs = strstr(s, glob + 1);
+ ((char *)glob)[n - 1] = '*';
+
+ return subs != NULL;
+ } else if (glob[0] == '*') {
+ size_t nn = strlen(s);
+ /* suffix match */
+
+ /* too short for a given suffix */
+ if (nn < n - 1)
+ return false;
+
+ return strcmp(s + nn - (n - 1), glob + 1) == 0;
+ } else if (glob[n - 1] == '*') {
+ /* prefix match */
+ return strncmp(s, glob, n - 1) == 0;
+ } else {
+ /* exact match */
+ return strcmp(glob, s) == 0;
+ }
+}
+
+int btf__find_by_glob_kind(const struct btf *btf, __u32 kind,
+ const char *allow_pattern, const char *deny_pattern,
+ __u32 **__ids)
+{
+ __u32 i, nr_types = btf__get_nr_types(btf);
+ int cnt = 0, alloc = 0;
+ __u32 *ids = NULL;
+
+ for (i = 1; i <= nr_types; i++) {
+ const struct btf_type *t = btf__type_by_id(btf, i);
+ const char *name;
+ __u32 *p;
+
+ if (btf_kind(t) != kind)
+ continue;
+ name = btf__name_by_offset(btf, t->name_off);
+ if (!name)
+ continue;
+
+ if (deny_pattern && glob_matches(deny_pattern, name))
+ continue;
+ if (allow_pattern && !glob_matches(allow_pattern, name))
+ continue;
+
+ if (cnt == alloc) {
+ alloc = max(16, alloc * 3 / 2);
+ p = libbpf_reallocarray(ids, alloc, sizeof(__u32));
+ if (!p) {
+ free(ids);
+ return -ENOMEM;
+ }
+ ids = p;
+ }
+ ids[cnt] = i;
+ cnt++;
+ }
+
+ *__ids = ids;
+ return cnt;
+}
+
static bool btf_is_modifiable(const struct btf *btf)
{
return (void *)btf->hdr != btf->raw_data;
diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h
index 5c73a5b0a044..408b8e6d913b 100644
--- a/tools/lib/bpf/btf.h
+++ b/tools/lib/bpf/btf.h
@@ -572,6 +572,9 @@ static inline struct btf_decl_tag *btf_decl_tag(const struct btf_type *t)
return (struct btf_decl_tag *)(t + 1);
}
+int btf__find_by_glob_kind(const struct btf *btf, __u32 kind,
+ const char *allow_pattern, const char *deny_pattern,
+ __u32 **__ids);
#ifdef __cplusplus
} /* extern "C" */
#endif
--
2.31.1
Powered by blists - more mailing lists