On 8/29/22 12:57, Jose E. Marchesi wrote:
>
> Hi David.
>
>> 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);
>> }
>
> I find the logic of the new conditional a little difficult to follow.
> What about something like this instead:
>
> for (dmd = dtd->dtd_u.dtu_members;
> dmd != NULL; dmd = (ctf_dmdef_t *) ctf_dmd_list_next (dmd))
> {
> 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);
> }
>
> WDYT?
Thanks, that is certainly easier to follow.
v2 coming shortly.
>
>> }
>> 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 } } */