]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commit
libbpf: Fix BTF dump of pointer-to-array-of-struct
authorJean-Philippe Brucker <jean-philippe@linaro.org>
Fri, 19 Mar 2021 11:25:54 +0000 (12:25 +0100)
committerSeth Forshee <seth.forshee@canonical.com>
Thu, 8 Apr 2021 20:42:37 +0000 (15:42 -0500)
commite71f629a18e20ac875e741241ba2f23e232f7f73
tree9a6d1d594bcb1475db58b498adc9c60cd249649f
parent9d8f6f019a867cf25dcfce2ceeb26b1c87b0848a
libbpf: Fix BTF dump of pointer-to-array-of-struct

BugLink: https://bugs.launchpad.net/bugs/1922601
[ Upstream commit 901ee1d750f29a335423eeb9463c3ca461ca18c2 ]

The vmlinux.h generated from BTF is invalid when building
drivers/phy/ti/phy-gmii-sel.c with clang:

vmlinux.h:61702:27: error: array type has incomplete element type ‘struct reg_field’
61702 |  const struct reg_field (*regfields)[3];
      |                           ^~~~~~~~~

bpftool generates a forward declaration for this struct regfield, which
compilers aren't happy about. Here's a simplified reproducer:

struct inner {
int val;
};
struct outer {
struct inner (*ptr_to_array)[2];
} A;

After build with clang -> bpftool btf dump c -> clang/gcc:
./def-clang.h:11:23: error: array has incomplete element type 'struct inner'
        struct inner (*ptr_to_array)[2];

Member ptr_to_array of struct outer is a pointer to an array of struct
inner. In the DWARF generated by clang, struct outer appears before
struct inner, so when converting BTF of struct outer into C, bpftool
issues a forward declaration to struct inner. With GCC the DWARF info is
reversed so struct inner gets fully defined.

That forward declaration is not sufficient when compilers handle an
array of the struct, even when it's only used through a pointer. Note
that we can trigger the same issue with an intermediate typedef:

struct inner {
        int val;
};
typedef struct inner inner2_t[2];
struct outer {
        inner2_t *ptr_to_array;
} A;

Becomes:

struct inner;
typedef struct inner inner2_t[2];

And causes:

./def-clang.h:10:30: error: array has incomplete element type 'struct inner'
typedef struct inner inner2_t[2];

To fix this, clear through_ptr whenever we encounter an intermediate
array, to make the inner struct part of a strong link and force full
declaration.

Fixes: 351131b51c7a ("libbpf: add btf_dump API for BTF-to-C conversion")
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20210319112554.794552-2-jean-philippe@linaro.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
tools/lib/bpf/btf_dump.c