The old method for computing a member index for a CO-RE relocation relied on a name comparison, which could SEGV if the member in question is itself part of an anonymous inner struct or union.
This patch changes the index computation to not rely on a name, while maintaining the ability to account for other sibling fields which may not have a representation in BTF. Tested in bpf-unknown-none, no known regressions. OK? Thanks. gcc/ChangeLog: PR target/106745 * config/bpf/coreout.cc (bpf_core_get_sou_member_index): Fix computation of index for anonymous members. gcc/testsuite/ChangeLog: PR target/106745 * gcc.target/bpf/core-pr106745.c: New test. --- gcc/config/bpf/coreout.cc | 19 +++++++++---- gcc/testsuite/gcc.target/bpf/core-pr106745.c | 30 ++++++++++++++++++++ 2 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.target/bpf/core-pr106745.c diff --git a/gcc/config/bpf/coreout.cc b/gcc/config/bpf/coreout.cc index cceaaa969cc..caad4380fa1 100644 --- a/gcc/config/bpf/coreout.cc +++ b/gcc/config/bpf/coreout.cc @@ -207,7 +207,6 @@ bpf_core_get_sou_member_index (ctf_container_ref ctfc, const tree node) if (TREE_CODE (node) == FIELD_DECL) { const tree container = DECL_CONTEXT (node); - const char * name = IDENTIFIER_POINTER (DECL_NAME (node)); /* Lookup the CTF type info for the containing type. */ dw_die_ref die = lookup_type_die (container); @@ -222,16 +221,26 @@ bpf_core_get_sou_member_index (ctf_container_ref ctfc, const tree node) if (kind != CTF_K_STRUCT && kind != CTF_K_UNION) return -1; + tree field = TYPE_FIELDS (container); int i = 0; ctf_dmdef_t * dmd; for (dmd = dtd->dtd_u.dtu_members; dmd != NULL; dmd = (ctf_dmdef_t *) ctf_dmd_list_next (dmd)) { if (get_btf_id (dmd->dmd_type) > BTF_MAX_TYPE) - continue; - if (strcmp (dmd->dmd_name, name) == 0) - return i; - i++; + { + /* This field does not have a BTF representation. */ + if (field == node) + return -1; + } + else + { + if (field == node) + return i; + i++; + } + + field = DECL_CHAIN (field); } } return -1; diff --git a/gcc/testsuite/gcc.target/bpf/core-pr106745.c b/gcc/testsuite/gcc.target/bpf/core-pr106745.c new file mode 100644 index 00000000000..9d347006a69 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/core-pr106745.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-O0 -gbtf -dA -mco-re" } */ + +struct weird +{ + struct + { + int b; + }; + + char x; + + union + { + int a; + int c; + }; +}; + + +int test (struct weird *arg) { + int *x = __builtin_preserve_access_index (&arg->b); + int *y = __builtin_preserve_access_index (&arg->c); + + return *x + *y; +} + + +/* { dg-final { scan-assembler-times "ascii \"0:0:0.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"0:2:1.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */ -- 2.36.1