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 /gcc/config | |
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.
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/bpf/coreout.cc | 16 |
1 files changed, 10 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; |