From: Viktor Malik <vmalik@redhat.com>
To: bpf@vger.kernel.org
Cc: Andrii Nakryiko <andrii@kernel.org>,
Eduard Zingerman <eddyz87@gmail.com>,
Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Martin KaFai Lau <martin.lau@linux.dev>,
Song Liu <song@kernel.org>,
Yonghong Song <yonghong.song@linux.dev>,
John Fastabend <john.fastabend@gmail.com>,
KP Singh <kpsingh@kernel.org>,
Stanislav Fomichev <sdf@fomichev.me>, Hao Luo <haoluo@google.com>,
Jiri Olsa <jolsa@kernel.org>, Viktor Malik <vmalik@redhat.com>
Subject: [RFC bpf-next 1/3] libbpf: Support aliased symbols in linker
Date: Mon, 2 Sep 2024 08:58:01 +0200 [thread overview]
Message-ID: <87e9970b63dede4a19ec62ec572e224eecc26fa3.1725016029.git.vmalik@redhat.com> (raw)
In-Reply-To: <cover.1725016029.git.vmalik@redhat.com>
It is possible to create multiple BPF programs sharing the same
instructions using the compiler `__attribute__((alias("...")))`:
int BPF_PROG(prog)
{
[...]
}
int prog_alias() __attribute__((alias("prog")));
This may be convenient when creating multiple programs with the same
instruction set attached to different events (such as bpftrace does).
One problem in this situation is that Clang doesn't generate a BTF entry
for `prog_alias` which makes libbpf linker fail when processing such a
BPF object.
This commits adds support for that by finding another symbol at the same
address for which a BTF entry exists and using that entry in the linker.
This allows to use the linker (e.g. via `bpftool gen object ...`) on BPF
objects containing aliases.
Note that this won't be sufficient for most programs as we also need to
add support for handling relocations in the aliased programs. This will
be added by the following commit.
Signed-off-by: Viktor Malik <vmalik@redhat.com>
---
tools/lib/bpf/linker.c | 68 +++++++++++++++++++++++-------------------
1 file changed, 38 insertions(+), 30 deletions(-)
diff --git a/tools/lib/bpf/linker.c b/tools/lib/bpf/linker.c
index 9cd3d4109788..5ebc9ff1246e 100644
--- a/tools/lib/bpf/linker.c
+++ b/tools/lib/bpf/linker.c
@@ -1688,6 +1688,34 @@ static bool btf_is_non_static(const struct btf_type *t)
|| (btf_is_func(t) && btf_func_linkage(t) != BTF_FUNC_STATIC);
}
+static Elf64_Sym *find_sym_by_name(struct src_obj *obj, size_t sec_idx,
+ int sym_type, const char *sym_name)
+{
+ struct src_sec *symtab = &obj->secs[obj->symtab_sec_idx];
+ Elf64_Sym *sym = symtab->data->d_buf;
+ int i, n = symtab->shdr->sh_size / symtab->shdr->sh_entsize;
+ int str_sec_idx = symtab->shdr->sh_link;
+ const char *name;
+
+ for (i = 0; i < n; i++, sym++) {
+ if (sym->st_shndx != sec_idx)
+ continue;
+ if (ELF64_ST_TYPE(sym->st_info) != sym_type)
+ continue;
+
+ name = elf_strptr(obj->elf, str_sec_idx, sym->st_name);
+ if (!name)
+ return NULL;
+
+ if (strcmp(sym_name, name) != 0)
+ continue;
+
+ return sym;
+ }
+
+ return NULL;
+}
+
static int find_glob_sym_btf(struct src_obj *obj, Elf64_Sym *sym, const char *sym_name,
int *out_btf_sec_id, int *out_btf_id)
{
@@ -1695,6 +1723,7 @@ static int find_glob_sym_btf(struct src_obj *obj, Elf64_Sym *sym, const char *sy
const struct btf_type *t;
const struct btf_var_secinfo *vi;
const char *name;
+ Elf64_Sym *s;
if (!obj->btf) {
pr_warn("failed to find BTF info for object '%s'\n", obj->filename);
@@ -1710,8 +1739,15 @@ static int find_glob_sym_btf(struct src_obj *obj, Elf64_Sym *sym, const char *sy
*/
if (btf_is_non_static(t)) {
name = btf__str_by_offset(obj->btf, t->name_off);
- if (strcmp(name, sym_name) != 0)
- continue;
+ if (strcmp(name, sym_name) != 0) {
+ /* the symbol that we look for may not have BTF as it may
+ * be an alias of another symbol; we check if this is
+ * the original symbol and if so, we use its BTF id
+ */
+ s = find_sym_by_name(obj, sym->st_shndx, STT_FUNC, name);
+ if (!s || s->st_value != sym->st_value)
+ continue;
+ }
/* remember and still try to find DATASEC */
btf_id = i;
@@ -2132,34 +2168,6 @@ static int linker_append_elf_relos(struct bpf_linker *linker, struct src_obj *ob
return 0;
}
-static Elf64_Sym *find_sym_by_name(struct src_obj *obj, size_t sec_idx,
- int sym_type, const char *sym_name)
-{
- struct src_sec *symtab = &obj->secs[obj->symtab_sec_idx];
- Elf64_Sym *sym = symtab->data->d_buf;
- int i, n = symtab->shdr->sh_size / symtab->shdr->sh_entsize;
- int str_sec_idx = symtab->shdr->sh_link;
- const char *name;
-
- for (i = 0; i < n; i++, sym++) {
- if (sym->st_shndx != sec_idx)
- continue;
- if (ELF64_ST_TYPE(sym->st_info) != sym_type)
- continue;
-
- name = elf_strptr(obj->elf, str_sec_idx, sym->st_name);
- if (!name)
- return NULL;
-
- if (strcmp(sym_name, name) != 0)
- continue;
-
- return sym;
- }
-
- return NULL;
-}
-
static int linker_fixup_btf(struct src_obj *obj)
{
const char *sec_name;
--
2.46.0
next prev parent reply other threads:[~2024-09-02 6:58 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-02 6:58 [RFC bpf-next 0/3] libbpf: Add support for aliased BPF programs Viktor Malik
2024-09-02 6:58 ` Viktor Malik [this message]
2024-09-03 11:16 ` [RFC bpf-next 1/3] libbpf: Support aliased symbols in linker Jiri Olsa
2024-09-03 13:08 ` Viktor Malik
2024-09-03 14:08 ` Arnaldo Carvalho de Melo
2024-09-04 5:46 ` Viktor Malik
2024-09-03 14:53 ` Jiri Olsa
2024-09-02 6:58 ` [RFC bpf-next 2/3] libbpf: Handle relocations in aliased symbols Viktor Malik
2024-09-02 6:58 ` [RFC bpf-next 3/3] selftests/bpf: Add tests for aliased programs Viktor Malik
2024-09-02 17:01 ` [RFC bpf-next 0/3] libbpf: Add support for aliased BPF programs Alan Maguire
2024-09-03 5:57 ` Viktor Malik
2024-09-03 20:19 ` Alexei Starovoitov
2024-09-04 19:07 ` Andrii Nakryiko
2024-09-06 5:04 ` Viktor Malik
2024-09-06 15:15 ` Alexei Starovoitov
2024-09-06 17:37 ` 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=87e9970b63dede4a19ec62ec572e224eecc26fa3.1725016029.git.vmalik@redhat.com \
--to=vmalik@redhat.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=haoluo@google.com \
--cc=john.fastabend@gmail.com \
--cc=jolsa@kernel.org \
--cc=kpsingh@kernel.org \
--cc=martin.lau@linux.dev \
--cc=sdf@fomichev.me \
--cc=song@kernel.org \
--cc=yonghong.song@linux.dev \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox