Re: [PATCH bpf-next 1/2] tools/lib/bpf: bpf_program__insns allow to retrieve insns in libbpf

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Jul 13, 2021 at 11:34 AM Lorenzo Fontana
<fontanalorenz@xxxxxxxxx> wrote:
>
> This allows consumers of libbpf to iterate trough the insns
> of a program without loading it first directly after the ELF parsing.
>
> Being able to do that is useful to create tooling that can show
> the structure of a BPF program using libbpf without having to
> parse the ELF separately.
>

So I wonder how useful is getting raw BPF instructions before libbpf
processed them and resolved map references, subprogram calls, etc?
You'll have lots of zeroes or meaningless constants in ldimm64
instructions, etc. I always felt that being able to get instructions
after libbpf processed them is more useful. The problem is that
currently libbpf frees prog->insns after successful bpf_program__load.
There is one extra (advanced) scenario where having those instructions
preserved after load would be really nice -- cloning BPF program (I
had use case for fentry/fexit). So the question is whether we should
just leave those prog->insns around until the object is closed or not?
And if we do, should bpftool dump instructions before or after load?
Let's see what folks think.

> Usage:
>   struct bpf_insn *insn;
>   insn = bpf_program__insns(prog);
>
> Signed-off-by: Lorenzo Fontana <fontanalorenz@xxxxxxxxx>
> ---
>  tools/lib/bpf/libbpf.c | 5 +++++
>  tools/lib/bpf/libbpf.h | 1 +
>  2 files changed, 6 insertions(+)
>
> diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
> index 1e04ce724240..67d51531f6b6 100644
> --- a/tools/lib/bpf/libbpf.c
> +++ b/tools/lib/bpf/libbpf.c
> @@ -8866,6 +8866,11 @@ void *bpf_program__priv(const struct bpf_program *prog)
>         return prog ? prog->priv : libbpf_err_ptr(-EINVAL);
>  }
>
> +struct bpf_insn *bpf_program__insns(const struct bpf_program *prog)

Definitely needs to be const, we don't want anyone accidentally to
modify it (though it's C and they can always force they way, but
that's a separate issue)

> +{
> +       return prog ? prog->insns : libbpf_err_ptr(-EINVAL);
> +}
> +
>  void bpf_program__set_ifindex(struct bpf_program *prog, __u32 ifindex)
>  {
>         prog->prog_ifindex = ifindex;
> diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
> index 6e61342ba56c..e4a1c98ae6d9 100644
> --- a/tools/lib/bpf/libbpf.h
> +++ b/tools/lib/bpf/libbpf.h
> @@ -195,6 +195,7 @@ typedef void (*bpf_program_clear_priv_t)(struct bpf_program *, void *);
>  LIBBPF_API int bpf_program__set_priv(struct bpf_program *prog, void *priv,
>                                      bpf_program_clear_priv_t clear_priv);
>
> +LIBBPF_API struct bpf_insn *bpf_program__insns(const struct bpf_program *prog);

BTW, I find bpf_program__size() is very ambiguous (is it number of
bytes or number of instructions)? I'd also add bpf_program__insn_cnt()
in the same patch.

And as Quentin mentioned, you need to update libbpf.map (and please
keep everything alphabetically sorted).

>  LIBBPF_API void *bpf_program__priv(const struct bpf_program *prog);
>  LIBBPF_API void bpf_program__set_ifindex(struct bpf_program *prog,
>                                          __u32 ifindex);
> --
> 2.32.0
>



[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux