OK.

Thanks for the patch!

> The existing BTF pruning logic meant that an anonymous struct or
> union type hidden behind a typedef, such as in the common construct:
>
>   typedef struct { ... } my_struct_type;
>
> could be pruned if 'my_struct_type' was only ever referenced via pointer
> members in other structs/unions types used in the program.
>
> The result of pruning is to skip emitting full type information for
> a struct or union type by replacing it with a BTF_KIND_FWD, indicating
> that it exists but its definition is omitted.  Any types used only by
> pruned types are fully omitted from the generated BTF.
>
> In cases like this where the struct/union type is anonymous, the result
> is an anonymous BTF_KIND_FWD, which is useless.  The presence of such a
> type record rightly causes complaints from BTF loaders.  Worse, since
> the TYPEDEF for 'my_struct_type' itself may _not_ be pruned, its type
> information will be incomplete.
>
> Change the BTF pruner so that we never consider pruning at a typedef,
> and always either keep or discard both the type and the typedef.
>
> Tested on x86_64-linux-gnu and that host for bpf-unknown-none target.
>
> gcc/
>
>       * btfout.cc (btf_add_used_type_1): Do not consider creating
>       fixups at typedefs.
>
> gcc/testsuite/
>
>       * gcc.dg/debug/btf/btf-prune-4.c: New.
> ---
>  gcc/btfout.cc                                |  3 +-
>  gcc/testsuite/gcc.dg/debug/btf/btf-prune-4.c | 61 ++++++++++++++++++++
>  2 files changed, 63 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-prune-4.c
>
> diff --git a/gcc/btfout.cc b/gcc/btfout.cc
> index 5a210cd51e6..eb794ff8694 100644
> --- a/gcc/btfout.cc
> +++ b/gcc/btfout.cc
> @@ -1138,7 +1138,8 @@ btf_add_used_type_1 (ctf_container_ref ctfc, 
> ctf_dtdef_ref dtd,
>  
>       /* Try to avoid chasing pointers to struct/union types if the
>          underlying type isn't used.  */
> -     if (check_ptr && seen_ptr && create_fixups)
> +     if (check_ptr && seen_ptr && create_fixups
> +         && kind != BTF_KIND_TYPEDEF)
>         {
>           ctf_dtdef_ref ref = dtd->ref_type;
>           uint32_t ref_kind = btf_dtd_kind (ref);
> diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-prune-4.c 
> b/gcc/testsuite/gcc.dg/debug/btf/btf-prune-4.c
> new file mode 100644
> index 00000000000..9274abf836e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-prune-4.c
> @@ -0,0 +1,61 @@
> +/* Test that -gprune-btf does not prune at typedefs.  */
> +
> +/* { dg-do compile } */
> +/* { dg-options "-gbtf -gprune-btf -dA" } */
> +
> +/* We must have the full definitions of td1 and td3.  Neither are pruned.
> +   td2 will be skipped entirely, only because the only reference to
> +   it is through struct inner, which is pruned because inner itself
> +   is only used as a pointer member.
> +
> +   In general, we must never get an anonymous FWD; the only FWD in this
> +   case will be for 'inner' */
> +
> +/* Exactly 1 FWD for inner and no anonymous FWD.  */
> +/* { dg-final { scan-assembler-times "TYPE \[0-9\]+ BTF_KIND_FWD" 1 } } */
> +/* { dg-final { scan-assembler-not   "TYPE \[0-9\]+ BTF_KIND_FWD ''" } } */
> +/* { dg-final { scan-assembler       " BTF_KIND_FWD 'inner'" } } */
> +
> +/* 1 anonymous struct for td1 and 1 anonymous union for td3 */
> +/* { dg-final { scan-assembler-times "TYPE \[0-9\]+ BTF_KIND_STRUCT ''" 1 } 
> } */
> +/* { dg-final { scan-assembler-times "TYPE \[0-9\]+ BTF_KIND_UNION ''" 1 } } 
> */
> +
> +/* The two remaining typedefs.  */
> +/* { dg-final { scan-assembler " BTF_KIND_TYPEDEF 'td1'" } } */
> +/* { dg-final { scan-assembler " BTF_KIND_TYPEDEF 'td3'" } } */
> +
> +typedef struct {
> +  int x;
> +  char c;
> +} td1;
> +
> +typedef struct {
> +  long l;
> +  char b[4];
> +} td2;
> +
> +typedef union {
> +  long l;
> +  unsigned short s[2];
> +} td3;
> +
> +struct inner {
> +  char a;
> +  td2 *ptd;
> +  long z;
> +};
> +
> +struct A {
> +  td1 *pt;
> +  struct inner *in;
> +  unsigned long l[4];
> +};
> +
> +struct A foo;
> +
> +struct B {
> +  int x;
> +  td3 **ppptd3;
> +};
> +
> +struct B bar;

Reply via email to