https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107844

--- Comment #1 from David Faust <david.faust at oracle dot com> ---
Looks like this is a result of the combination of how the bpf_core_field_exists
macro is defined and some sort of optimization(?) happening in the C frontend.

Consider:

  struct S {
    unsigned short x;
    char c[12];
  };

  int foo () {
    int has_c = bpf_core_field_exists (struct S, c);
    return has_c;
  }

The bpf_core_field_exists macro expands to:

  int has_c =
    __builtin_preserve_field_info((((typeof(struct S) *)0)->c),
BPF_RELO_FIELD_EXISTS);

For some reason, for array members specifically, this construction results in
the tree for the parameter when resolving the builtin being simply:

  (gdb) pt param
   <integer_cst 0x7ffff7531b88 type <pointer_type 0x7ffff741bc78> constant 2>

i.e. a pointer to 0x2, the offset of 'c' in a 'struct S' mapped at 0x0. For
non-array members, 'param' is some kind of <component_ref> as I'd expect.

This gives us two problems:
 a) We cannot distinguish an array member from a non-member constant-value
    pointer.
 b) We cannot correctly compute information for the CO-RE relocation.
    For example, in this case BPF_RELO_FIELD_BYTE_SIZE will be calculated as 8
    (size of pointer), not 12 (size of the array).

I'm not sure how to resolve this and support the existing helper macros in the
kernel/libbpf. Might need some change in the C frontend, or to somehow pass
more
information to the target_resolve_overloaded_builtin hook...

Reply via email to