Re: [PATCH v1 bpf-next 10/11] libbpf: support llvm-generated indirect jumps

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

 



On 25/08/20 05:20PM, Andrii Nakryiko wrote:
> On Sat, Aug 16, 2025 at 11:02 AM Anton Protopopov
> <a.s.protopopov@xxxxxxxxx> wrote:
> >
> > For v5 instruction set, LLVM now is allowed to generate indirect
> > jumps for switch statements and for 'goto *rX' assembly. Every such a
> > jump will be accompanied by necessary metadata, e.g. (`llvm-objdump
> > -Sr ...`):
> >
> >        0:       r2 = 0x0 ll
> >                 0000000000000030:  R_BPF_64_64  BPF.JT.0.0
> >
> > Here BPF.JT.1.0 is a symbol residing in the .jumptables section:
> >
> >     Symbol table:
> >        4: 0000000000000000   240 OBJECT  GLOBAL DEFAULT     4 BPF.JT.0.0
> >
> > The -bpf-min-jump-table-entries llvm option may be used to control
> > the minimal size of a switch which will be converted to an indirect
> > jumps.
> >
> > The code generated by LLVM for a switch will look, approximately,
> > like this:
> >
> >     0: rX <- jump_table_x[i]
> >     2: rX <<= 3
> >     3: gotox *rX
> >
> > Right now there is no robust way to associate the jump with the
> > corresponding map, so libbpf doesn't insert map file descriptor
> > inside the gotox instruction.
> 

[...]

> 
> > +               err = bpf_map_update_elem(map_fd, &i, &val, 0);
> > +               if (err) {
> > +                       close(map_fd);
> > +                       return err;
> > +               }
> > +       }
> > +
> > +       err = bpf_map_freeze(map_fd);
> > +       if (err) {
> > +               close(map_fd);
> > +               return err;
> > +       }
> > +
> > +       return map_fd;
> > +}
> > +
> > +static int subprog_insn_off(struct bpf_program *prog, int insn_idx)
> > +{
> > +       int i;
> > +
> > +       for (i = prog->subprog_cnt - 1; i >= 0; i--)
> > +               if (insn_idx >= prog->subprog_offset[i])
> > +                       return prog->subprog_offset[i] - prog->subprog_sec_offst[i];
> 
> I feel like this whole subprog_offset and subprog_sec_offst shouldn't
> be even necessary.
> 
> Check bpf_object__relocate(). I'm not sure why this was done this way
> that we go across all programs in phases, doing code relocation first,
> then data relocation later (across all programs again). I might be
> forgetting some details, but if we change this to do all the
> relocation for each program one at a time, then all this information
> that you explicitly record is already recorded in
> subprog->sub_insn_off and you can use it until we start relocating
> another entry-point program. Can you give it a try?
> 
> So basically the structure will be:
> 
> for (i = 0; i < obj->nr_programs; i++) {
>    prog = ...
>    if (prog_is_subprog(...))
>        continue;
>    if (!prog->autoload)
>        continue;
>    bpf_object__relocate_calls()
>    /* that exception callback handling */
>    bpf_object__relocate_data()
>    bpf_program_fixup_func_info()
> }
> 
> It feels like this should work because there cannot be
> interdependencies between entry programs.

So turns out that the reason why it is separate is given in the commit which
introduced this separation, see b12688267280b223256c8cf912486577d3adce25
(So I kept this part of my patch the same in v2.)

[...]




[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