diff options
author | David Faust <david.faust@oracle.com> | 2022-08-29 11:21:52 -0700 |
---|---|---|
committer | David Faust <david.faust@oracle.com> | 2022-08-29 13:45:47 -0700 |
commit | b504149d2c92ddfcfab62ea6d1ed49ae72493e38 (patch) | |
tree | 1e3fd59944faf25342b64c82e0621dcf90df7540 | |
parent | c68b5c078bbf167e6ab84fc230a53580dcc651db (diff) | |
download | gcc-b504149d2c92ddfcfab62ea6d1ed49ae72493e38.zip gcc-b504149d2c92ddfcfab62ea6d1ed49ae72493e38.tar.gz gcc-b504149d2c92ddfcfab62ea6d1ed49ae72493e38.tar.bz2 |
bpf: handle anonymous members in CO-RE reloc [PR106745]
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.
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.
-rw-r--r-- | gcc/config/bpf/coreout.cc | 16 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/bpf/core-pr106745.c | 30 |
2 files changed, 40 insertions, 6 deletions
diff --git a/gcc/config/bpf/coreout.cc b/gcc/config/bpf/coreout.cc index cceaaa9..8897a04 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 0000000..9d34700 --- /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 } } */ |