All of lore.kernel.org
 help / color / mirror / Atom feed
From: Delyan Kratunov <delyank@fb.com>
To: "daniel@iogearbox.net" <daniel@iogearbox.net>,
	"ast@kernel.org" <ast@kernel.org>,
	"andrii@kernel.org" <andrii@kernel.org>,
	"bpf@vger.kernel.org" <bpf@vger.kernel.org>
Subject: [PATCH bpf-next 3/4] libbpf: add subskeleton scaffolding
Date: Wed, 2 Mar 2022 02:48:46 +0000	[thread overview]
Message-ID: <13cba9e1c39e999e7bfb14f1f986b76d13e150b3.1646188795.git.delyank@fb.com> (raw)
In-Reply-To: <cover.1646188795.git.delyank@fb.com>

In symmetry with bpf_object__open_skeleton(),
bpf_object__open_subskeleton() performs the actual walking and linking
of symbols described by bpf_sym_skeleton objects.

Signed-off-by: Delyan Kratunov <delyank@fb.com>
---
 tools/lib/bpf/libbpf.c   | 76 ++++++++++++++++++++++++++++++++++++++++
 tools/lib/bpf/libbpf.h   | 21 +++++++++++
 tools/lib/bpf/libbpf.map |  2 ++
 3 files changed, 99 insertions(+)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index d20ae8f225ee..e6c27f4b9dea 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -11748,6 +11748,82 @@ int bpf_object__open_skeleton(struct bpf_object_skeleton *s,
 	return 0;
 }
 
+int bpf_object__open_subskeleton(struct bpf_object_subskeleton *s)
+{
+	int i, len, map_type_id, sym_idx;
+	const char *var_name;
+	struct bpf_map *map;
+	struct btf *btf;
+	const struct btf_type *map_type, *var_type;
+	const struct bpf_sym_skeleton *sym;
+	struct btf_var_secinfo *var;
+	struct bpf_map *last_map = NULL;
+	const struct btf_type *last_map_type = NULL;
+
+	if (!s->obj)
+		return libbpf_err(-EINVAL);
+
+	btf = bpf_object__btf(s->obj);
+	if (!btf)
+		return libbpf_err(errno);
+
+	for (sym_idx = 0; sym_idx < s->sym_cnt; sym_idx++) {
+		sym = &s->syms[sym_idx];
+		if (last_map && (strcmp(sym->section, bpf_map__section_name(last_map)) == 0)) {
+			map = last_map;
+			map_type = last_map_type;
+		} else {
+			map = bpf_object__find_map_by_name(s->obj, sym->section);
+			if (!map) {
+				pr_warn("Could not find map for section %1$s, symbol %2$s",
+					sym->section, s->syms[i].name);
+				return libbpf_err(-EINVAL);
+			}
+			map_type_id = btf__find_by_name_kind(btf, sym->section, BTF_KIND_DATASEC);
+			if (map_type_id < 0) {
+				pr_warn("Could not find map type in btf for section %1$s (due to symbol %2$s)",
+					sym->section, sym->name);
+				return libbpf_err(-EINVAL);
+			}
+			map_type = btf__type_by_id(btf, map_type_id);
+		}
+
+		/* We have a section and a corresponding type, now find the
+		 * symbol in the loaded map. This is clearly quadratic in the
+		 * number of symbols in the section, but that's easy to optimize
+		 * once the need arises.
+		 */
+
+		len = btf_vlen(map_type);
+		for (i = 0, var = btf_var_secinfos(map_type); i < len; i++, var++) {
+			var_type = btf__type_by_id(btf, var->type);
+			if (!var_type) {
+				pr_warn("Could not find var type for item %1$d in section %2$s",
+					i, sym->section);
+				return libbpf_err(-EINVAL);
+			}
+			var_name = btf__name_by_offset(btf, var_type->name_off);
+			if (strcmp(var_name, sym->name) == 0) {
+				*sym->addr = (char *) map->mmaped + var->offset;
+				break;
+			}
+		}
+
+		last_map = map;
+		last_map_type = map_type;
+	}
+	return 0;
+}
+
+void bpf_object__destroy_subskeleton(struct bpf_object_subskeleton *s)
+{
+	if (!s)
+		return;
+	if (s->syms)
+		free(s->syms);
+	free(s);
+}
+
 int bpf_object__load_skeleton(struct bpf_object_skeleton *s)
 {
 	int i, err;
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 7b66794f1c0a..915d59c31ad5 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -1291,6 +1291,27 @@ LIBBPF_API int bpf_object__attach_skeleton(struct bpf_object_skeleton *s);
 LIBBPF_API void bpf_object__detach_skeleton(struct bpf_object_skeleton *s);
 LIBBPF_API void bpf_object__destroy_skeleton(struct bpf_object_skeleton *s);
 
+struct bpf_sym_skeleton {
+	const char *name;
+	const char *section;
+	void **addr;
+};
+
+struct bpf_object_subskeleton {
+	size_t sz; /* size of this struct, for forward/backward compatibility */
+
+	const struct bpf_object *obj;
+
+	int sym_cnt;
+	int sym_skel_sz;
+	struct bpf_sym_skeleton *syms;
+};
+
+LIBBPF_API int
+bpf_object__open_subskeleton(struct bpf_object_subskeleton *s);
+LIBBPF_API void
+bpf_object__destroy_subskeleton(struct bpf_object_subskeleton *s);
+
 struct gen_loader_opts {
 	size_t sz; /* size of this struct, for forward/backward compatiblity */
 	const char *data;
diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map
index 5c85d297d955..81a1d0259866 100644
--- a/tools/lib/bpf/libbpf.map
+++ b/tools/lib/bpf/libbpf.map
@@ -443,4 +443,6 @@ LIBBPF_0.7.0 {
 LIBBPF_0.8.0 {
 	global:
     bpf_map__section_name;
+    bpf_object__open_subskeleton;
+    bpf_object__destroy_subskeleton;
 } LIBBPF_0.7.0;
-- 
2.34.1

  reply	other threads:[~2022-03-02  2:48 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-03-02  2:48 [PATCH bpf-next 0/4] Subskeleton support for BPF libraries Delyan Kratunov
2022-03-02  2:48 ` Delyan Kratunov [this message]
2022-03-02 21:43   ` [PATCH bpf-next 3/4] libbpf: add subskeleton scaffolding Daniel Borkmann
2022-03-03  0:20     ` Delyan Kratunov
2022-03-03  0:28       ` Andrii Nakryiko
2022-03-03  0:44         ` Delyan Kratunov
2022-03-03  4:33   ` Andrii Nakryiko
2022-03-03  4:34     ` Andrii Nakryiko
2022-03-03 19:09       ` Delyan Kratunov
2022-03-04 19:40         ` Andrii Nakryiko
2022-03-02  2:48 ` [PATCH bpf-next 4/4] selftests/bpf: test subskeleton functionality Delyan Kratunov
2022-03-02 22:30   ` Alexei Starovoitov
2022-03-03  0:06     ` Delyan Kratunov
2022-03-03  4:58   ` Andrii Nakryiko
2022-03-02  2:48 ` [PATCH bpf-next 1/4] libbpf: expose map elf section name Delyan Kratunov
2022-03-03  1:13   ` Andrii Nakryiko
2022-03-03 18:19     ` Delyan Kratunov
2022-03-02  2:48 ` [PATCH bpf-next 2/4] bpftool: add support for subskeletons Delyan Kratunov
2022-03-03  1:46   ` Andrii Nakryiko
2022-03-03 18:57     ` Delyan Kratunov
2022-03-03 20:54       ` Delyan Kratunov
2022-03-04 19:29         ` Andrii Nakryiko
2022-03-04 19:29       ` Andrii Nakryiko
2022-03-10  0:09         ` Delyan Kratunov
2022-03-10  0:38           ` Andrii Nakryiko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=13cba9e1c39e999e7bfb14f1f986b76d13e150b3.1646188795.git.delyank@fb.com \
    --to=delyank@fb.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.