BPF List
 help / color / mirror / Atom feed
From: Jiri Olsa <olsajiri@gmail.com>
To: Viktor Malik <vmalik@redhat.com>
Cc: bpf@vger.kernel.org, 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>,
	Arnaldo Carvalho de Melo <acme@kernel.org>
Subject: Re: [RFC bpf-next 1/3] libbpf: Support aliased symbols in linker
Date: Tue, 3 Sep 2024 14:16:20 +0300	[thread overview]
Message-ID: <ZtbwBA8CG8s--8dt@krava> (raw)
In-Reply-To: <87e9970b63dede4a19ec62ec572e224eecc26fa3.1725016029.git.vmalik@redhat.com>

On Mon, Sep 02, 2024 at 08:58:01AM +0200, Viktor Malik wrote:
> 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 might not solve all the issues, but could we change pahole to
generate BTF FUNC for alias function symbols?

jirka

> 
> 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
> 

  reply	other threads:[~2024-09-03 11:16 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 ` [RFC bpf-next 1/3] libbpf: Support aliased symbols in linker Viktor Malik
2024-09-03 11:16   ` Jiri Olsa [this message]
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=ZtbwBA8CG8s--8dt@krava \
    --to=olsajiri@gmail.com \
    --cc=acme@kernel.org \
    --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=kpsingh@kernel.org \
    --cc=martin.lau@linux.dev \
    --cc=sdf@fomichev.me \
    --cc=song@kernel.org \
    --cc=vmalik@redhat.com \
    --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