1. 17 Jun, 2024 5 commits
    • Eduard Zingerman's avatar
      libbpf: Make btf_parse_elf process .BTF.base transparently · c86f180f
      Eduard Zingerman authored
      Update btf_parse_elf() to check if .BTF.base section is present.
      The logic is as follows:
      
        if .BTF.base section exists:
           distilled_base := btf_new(.BTF.base)
        if distilled_base:
           btf := btf_new(.BTF, .base_btf=distilled_base)
           if base_btf:
              btf_relocate(btf, base_btf)
        else:
           btf := btf_new(.BTF)
        return btf
      
      In other words:
      - if .BTF.base section exists, load BTF from it and use it as a base
        for .BTF load;
      - if base_btf is specified and .BTF.base section exist, relocate newly
        loaded .BTF against base_btf.
      Signed-off-by: default avatarEduard Zingerman <eddyz87@gmail.com>
      Signed-off-by: default avatarAlan Maguire <alan.maguire@oracle.com>
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Link: https://lore.kernel.org/bpf/20240613095014.357981-6-alan.maguire@oracle.com
      c86f180f
    • Alan Maguire's avatar
      selftests/bpf: Extend distilled BTF tests to cover BTF relocation · affdeb50
      Alan Maguire authored
      Ensure relocated BTF looks as expected; in this case identical to
      original split BTF, with a few duplicate anonymous types added to
      split BTF by the relocation process.  Also add relocation tests
      for edge cases like missing type in base BTF and multiple types
      of the same name.
      Signed-off-by: default avatarAlan Maguire <alan.maguire@oracle.com>
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Acked-by: default avatarEduard Zingerman <eddyz87@gmail.com>
      Link: https://lore.kernel.org/bpf/20240613095014.357981-5-alan.maguire@oracle.com
      affdeb50
    • Alan Maguire's avatar
      libbpf: Split BTF relocation · 19e00c89
      Alan Maguire authored
      Map distilled base BTF type ids referenced in split BTF and their
      references to the base BTF passed in, and if the mapping succeeds,
      reparent the split BTF to the base BTF.
      
      Relocation is done by first verifying that distilled base BTF
      only consists of named INT, FLOAT, ENUM, FWD, STRUCT and
      UNION kinds; then we sort these to speed lookups.  Once sorted,
      the base BTF is iterated, and for each relevant kind we check
      for an equivalent in distilled base BTF.  When found, the
      mapping from distilled -> base BTF id and string offset is recorded.
      In establishing mappings, we need to ensure we check STRUCT/UNION
      size when the STRUCT/UNION is embedded in a split BTF STRUCT/UNION,
      and when duplicate names exist for the same STRUCT/UNION.  Otherwise
      size is ignored in matching STRUCT/UNIONs.
      
      Once all mappings are established, we can update type ids
      and string offsets in split BTF and reparent it to the new base.
      Signed-off-by: default avatarAlan Maguire <alan.maguire@oracle.com>
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Acked-by: default avatarEduard Zingerman <eddyz87@gmail.com>
      Link: https://lore.kernel.org/bpf/20240613095014.357981-4-alan.maguire@oracle.com
      19e00c89
    • Alan Maguire's avatar
      selftests/bpf: Test distilled base, split BTF generation · eb20e727
      Alan Maguire authored
      Test generation of split+distilled base BTF, ensuring that
      
      - named base BTF STRUCTs and UNIONs are represented as 0-vlen sized
        STRUCT/UNIONs
      - named ENUM[64]s are represented as 0-vlen named ENUM[64]s
      - anonymous struct/unions are represented in full in split BTF
      - anonymous enums are represented in full in split BTF
      - types unreferenced from split BTF are not present in distilled
        base BTF
      
      Also test that with vmlinux BTF and split BTF based upon it,
      we only represent needed base types referenced from split BTF
      in distilled base.
      Signed-off-by: default avatarAlan Maguire <alan.maguire@oracle.com>
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Acked-by: default avatarEduard Zingerman <eddyz87@gmail.com>
      Link: https://lore.kernel.org/bpf/20240613095014.357981-3-alan.maguire@oracle.com
      eb20e727
    • Alan Maguire's avatar
      libbpf: Add btf__distill_base() creating split BTF with distilled base BTF · 58e185a0
      Alan Maguire authored
      To support more robust split BTF, adding supplemental context for the
      base BTF type ids that split BTF refers to is required.  Without such
      references, a simple shuffling of base BTF type ids (without any other
      significant change) invalidates the split BTF.  Here the attempt is made
      to store additional context to make split BTF more robust.
      
      This context comes in the form of distilled base BTF providing minimal
      information (name and - in some cases - size) for base INTs, FLOATs,
      STRUCTs, UNIONs, ENUMs and ENUM64s along with modified split BTF that
      points at that base and contains any additional types needed (such as
      TYPEDEF, PTR and anonymous STRUCT/UNION declarations).  This
      information constitutes the minimal BTF representation needed to
      disambiguate or remove split BTF references to base BTF.  The rules
      are as follows:
      
      - INT, FLOAT, FWD are recorded in full.
      - if a named base BTF STRUCT or UNION is referred to from split BTF, it
        will be encoded as a zero-member sized STRUCT/UNION (preserving
        size for later relocation checks).  Only base BTF STRUCT/UNIONs
        that are either embedded in split BTF STRUCT/UNIONs or that have
        multiple STRUCT/UNION instances of the same name will _need_ size
        checks at relocation time, but as it is possible a different set of
        types will be duplicates in the later to-be-resolved base BTF,
        we preserve size information for all named STRUCT/UNIONs.
      - if an ENUM[64] is named, a ENUM forward representation (an ENUM
        with no values) of the same size is used.
      - in all other cases, the type is added to the new split BTF.
      
      Avoiding struct/union/enum/enum64 expansion is important to keep the
      distilled base BTF representation to a minimum size.
      
      When successful, new representations of the distilled base BTF and new
      split BTF that refers to it are returned.  Both need to be freed by the
      caller.
      
      So to take a simple example, with split BTF with a type referring
      to "struct sk_buff", we will generate distilled base BTF with a
      0-member STRUCT sk_buff of the appropriate size, and the split BTF
      will refer to it instead.
      
      Tools like pahole can utilize such split BTF to populate the .BTF
      section (split BTF) and an additional .BTF.base section.  Then
      when the split BTF is loaded, the distilled base BTF can be used
      to relocate split BTF to reference the current (and possibly changed)
      base BTF.
      
      So for example if "struct sk_buff" was id 502 when the split BTF was
      originally generated,  we can use the distilled base BTF to see that
      id 502 refers to a "struct sk_buff" and replace instances of id 502
      with the current (relocated) base BTF sk_buff type id.
      
      Distilled base BTF is small; when building a kernel with all modules
      using distilled base BTF as a test, overall module size grew by only
      5.3Mb total across ~2700 modules.
      Signed-off-by: default avatarAlan Maguire <alan.maguire@oracle.com>
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Acked-by: default avatarEduard Zingerman <eddyz87@gmail.com>
      Link: https://lore.kernel.org/bpf/20240613095014.357981-2-alan.maguire@oracle.com
      58e185a0
  2. 14 Jun, 2024 4 commits
  3. 13 Jun, 2024 11 commits
  4. 12 Jun, 2024 13 commits
  5. 11 Jun, 2024 7 commits