• Andrii Nakryiko's avatar
    libbpf: Make RELO_CALL work for multi-prog sections and sub-program calls · c3c55696
    Andrii Nakryiko authored
    This patch implements general and correct logic for bpf-to-bpf sub-program
    calls. Only sub-programs used (called into) from entry-point (main) BPF
    program are going to be appended at the end of main BPF program. This ensures
    that BPF verifier won't encounter any dead code due to copying unreferenced
    sub-program. This change means that each entry-point (main) BPF program might
    have a different set of sub-programs appended to it and potentially in
    different order. This has implications on how sub-program call relocations
    need to be handled, described below.
    
    All relocations are now split into two categores: data references (maps and
    global variables) and code references (sub-program calls). This distinction is
    important because data references need to be relocated just once per each BPF
    program and sub-program. These relocation are agnostic to instruction
    locations, because they are not code-relative and they are relocating against
    static targets (maps, variables with fixes offsets, etc).
    
    Sub-program RELO_CALL relocations, on the other hand, are highly-dependent on
    code position, because they are recorded as instruction-relative offset. So
    BPF sub-programs (those that do calls into other sub-programs) can't be
    relocated once, they need to be relocated each time such a sub-program is
    appended at the end of the main entry-point BPF program. As mentioned above,
    each main BPF program might have different subset and differen order of
    sub-programs, so call relocations can't be done just once. Splitting data
    reference and calls relocations as described above allows to do this
    efficiently and cleanly.
    
    bpf_object__find_program_by_name() will now ignore non-entry BPF programs.
    Previously one could have looked up '.text' fake BPF program, but the
    existence of such BPF program was always an implementation detail and you
    can't do much useful with it. Now, though, all non-entry sub-programs get
    their own BPF program with name corresponding to a function name, so there is
    no more '.text' name for BPF program. This means there is no regression,
    effectively, w.r.t.  API behavior. But this is important aspect to highlight,
    because it's going to be critical once libbpf implements static linking of BPF
    programs. Non-entry static BPF programs will be allowed to have conflicting
    names, but global and main-entry BPF program names should be unique. Just like
    with normal user-space linking process. So it's important to restrict this
    aspect right now, keep static and non-entry functions as internal
    implementation details, and not have to deal with regressions in behavior
    later.
    
    This patch leaves .BTF.ext adjustment as is until next patch.
    Signed-off-by: default avatarAndrii Nakryiko <andriin@fb.com>
    Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
    Link: https://lore.kernel.org/bpf/20200903203542.15944-5-andriin@fb.com
    c3c55696
libbpf.c 269 KB