[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20210826193922.66204-21-jolsa@kernel.org>
Date: Thu, 26 Aug 2021 21:39:15 +0200
From: Jiri Olsa <jolsa@...hat.com>
To: Alexei Starovoitov <ast@...nel.org>,
Daniel Borkmann <daniel@...earbox.net>,
Andrii Nakryiko <andriin@...com>,
"Steven Rostedt (VMware)" <rostedt@...dmis.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>, Daniel Xu <dxu@...uu.xyz>,
Viktor Malik <vmalik@...hat.com>
Subject: [PATCH bpf-next v4 20/27] 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 | 80 +++++++++++++++++++++++++++++++++++++++++++++
tools/lib/bpf/btf.h | 3 ++
2 files changed, 83 insertions(+)
diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
index 77dc24d58302..5baaca6c3134 100644
--- a/tools/lib/bpf/btf.c
+++ b/tools/lib/bpf/btf.c
@@ -711,6 +711,86 @@ __s32 btf__find_by_name_kind(const struct btf *btf, const char *type_name,
return libbpf_err(-ENOENT);
}
+/* '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);
+ bool match = false;
+ const char *name;
+ __u32 *p;
+
+ if (btf_kind(t) != kind)
+ continue;
+ name = btf__name_by_offset(btf, t->name_off);
+ if (!name)
+ continue;
+
+ if (allow_pattern && glob_matches(allow_pattern, name))
+ match = true;
+ if (deny_pattern && !glob_matches(deny_pattern, name))
+ match = true;
+ if (!match)
+ continue;
+
+ if (cnt == alloc) {
+ alloc = max(100, alloc * 3 / 2);
+ p = realloc(ids, alloc * sizeof(__u32));
+ if (!p) {
+ free(ids);
+ return -ENOMEM;
+ }
+ ids = p;
+ }
+ ids[cnt] = i;
+ cnt++;
+ }
+
+ *__ids = ids;
+ return cnt ?: -ENOENT;
+}
+
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 4a711f990904..b288211770c3 100644
--- a/tools/lib/bpf/btf.h
+++ b/tools/lib/bpf/btf.h
@@ -396,6 +396,9 @@ btf_var_secinfos(const struct btf_type *t)
return (struct btf_var_secinfo *)(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