Message ID | 20220829201827.7419-1-david.faust@oracle.com |
---|---|
State | New |
Headers | show |
Series | [v2] bpf: handle anonymous members in CO-RE reloc [PR106745] | expand |
> [changes from v1: simplify the new conditional logic as suggested.] > > 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? OK, thank you. > 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 | 16 +++++++---- > gcc/testsuite/gcc.target/bpf/core-pr106745.c | 30 ++++++++++++++++++++ > 2 files changed, 40 insertions(+), 6 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..8897a045ea1 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,21 @@ 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++; > + bool field_has_btf = get_btf_id (dmd->dmd_type) <= BTF_MAX_TYPE; > + > + if (field == node) > + return field_has_btf ? i : -1; > + > + if (field_has_btf) > + 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 } } */
diff --git a/gcc/config/bpf/coreout.cc b/gcc/config/bpf/coreout.cc index cceaaa969cc..8897a045ea1 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,21 @@ 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++; + bool field_has_btf = get_btf_id (dmd->dmd_type) <= BTF_MAX_TYPE; + + if (field == node) + return field_has_btf ? i : -1; + + if (field_has_btf) + 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 } } */