• Yonghong Song's avatar
    libbpf: Add new BPF_PROG2 macro · 34586d29
    Yonghong Song authored
    To support struct arguments in trampoline based programs,
    existing BPF_PROG doesn't work any more since
    the type size is needed to find whether a parameter
    takes one or two registers. So this patch added a new
    BPF_PROG2 macro to support such trampoline programs.
    
    The idea is suggested by Andrii. For example, if the
    to-be-traced function has signature like
      typedef struct {
           void *x;
           int t;
      } sockptr;
      int blah(sockptr x, char y);
    
    In the new BPF_PROG2 macro, the argument can be
    represented as
      __bpf_prog_call(
         ({ union {
              struct { __u64 x, y; } ___z;
              sockptr x;
            } ___tmp = { .___z = { ctx[0], ctx[1] }};
            ___tmp.x;
         }),
         ({ union {
              struct { __u8 x; } ___z;
              char y;
            } ___tmp = { .___z = { ctx[2] }};
            ___tmp.y;
         }));
    In the above, the values stored on the stack are properly
    assigned to the actual argument type value by using 'union'
    magic. Note that the macro also works even if no arguments
    are with struct types.
    
    Note that new BPF_PROG2 works for both llvm16 and pre-llvm16
    compilers where llvm16 supports bpf target passing value
    with struct up to 16 byte size and pre-llvm16 will pass
    by reference by storing values on the stack. With static functions
    with struct argument as always inline, the compiler is able
    to optimize and remove additional stack saving of struct values.
    Signed-off-by: default avatarYonghong Song <yhs@fb.com>
    Link: https://lore.kernel.org/r/20220831152707.2079473-1-yhs@fb.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
    34586d29
bpf_tracing.h 26.9 KB