> On Jan 16, 2025, at 17:29, Bill Wendling <[email protected]> wrote:
>
> On Thu, Jan 16, 2025 at 1:19 PM Qing Zhao <[email protected]> wrote:
>>
>> Hi,
>>
>> This is the patch set to extend "counted_by" attribute to pointer fields of
>> structures.
>>
>> For example:
>>
>> struct PP {
>> size_t count2;
>> char other1;
>> char *array2 __attribute__ ((counted_by (count2)));
>> int other2;
>> } *pp;
>>
>> specifies that the "array2" is an array that is pointed by the
>> pointer field, and its number of elements is given by the field
>> "count2" in the same structure.
>>
>> Per the previous discussion with Martin and Bill
>> (https://gcc.gnu.org/pipermail/gcc-patches/2024-November/669320.html)
>>
>> there are the following importand facts about "counted_by" on pointer fields
>> compared
>> to the "counted_by" on FAM fields:
>>
>> 1. one more new requirement for pointer fields with "counted_by" attribute:
>> pp->array2 and pp->count2 can ONLY be changed by changing the whole
>> structure
>> at the same time.
>>
>> 2. the following feature for FAM field with "counted_by" attribute is NOT
>> valid for the pointer field any more:
>>
>> " One important feature of the attribute is, a reference to the
>> flexible array member field uses the latest value assigned to the
>> field that represents the number of the elements before that
>> reference. For example,
>>
>> p->count = val1;
>> p->array[20] = 0; // ref1 to p->array
>> p->count = val2;
>> p->array[30] = 0; // ref2 to p->array
>>
>> in the above, 'ref1' uses 'val1' as the number of the elements in
>> 'p->array', and 'ref2' uses 'val2' as the number of elements in
>> 'p->array'. "
>>
>> Although in the previous discussion, I agreed with Martin that we should use
>> the
>> designator syntax (i.e, counted_by (.n) instead of counted_by (n)) for the
>> counted_by attribute for pointer fields, after more consideration and
>> discussion
>> with Bill Wendling (who is working on the same work for CLANG), we decided to
>> keep the current syntax of FAM for pointer fields. And leave the new syntax
>> (.n)
>> and more complicate expressions to a later work.
>>
>> This patch set includes 3 parts:
>>
>> 1.Extend "counted_by" attribute to pointer fields of structures.
>> 2.Convert a pointer reference with counted_by attribute to .ACCESS_WITH_SIZE
>> and use it in builtinin-object-size.
>> 3.Use the counted_by attribute of pointers in array bound checker.
>>
>> In which, the patch 1 and 2 are simple and straightforward, however, the
>> patch 3
>> is a little complicate due to the following reason:
>>
>> Current array bound checker only instruments ARRAY_REF, and the INDEX
>> information is the 2nd operand of the ARRAY_REF.
>>
>> When extending the array bound checker to pointer references with
>> counted_by attributes, the hardest part is to get the INDEX of the
>> corresponding array ref from the offset computation expression of
>> the pointer ref.
>>
>> The whole patch set has been bootstrapped and regression tested on both
>> aarch64
>> and x86.
>>
>> Let me know any comments and suggestions.
>>
>> Thanks.
>>
>> Qing
>>
>> Qing Zhao (3):
>> Extend "counted_by" attribute to pointer fields of structures.
>> Convert a pointer reference with counted_by attribute to
>> .ACCESS_WITH_SIZE and use it in builtinin-object-size.
>> Use the counted_by attribute of pointers in array bound checker.
>>
>> gcc/c-family/c-attribs.cc | 15 +-
>> gcc/c-family/c-gimplify.cc | 7 +
>> gcc/c-family/c-ubsan.cc | 264 ++++++++++++++++--
>> gcc/c/c-decl.cc | 91 +++---
>> gcc/c/c-typeck.cc | 41 +--
>> gcc/doc/extend.texi | 37 ++-
>> gcc/testsuite/gcc.dg/flex-array-counted-by.c | 2 +-
>> gcc/testsuite/gcc.dg/pointer-counted-by-2.c | 8 +
>> gcc/testsuite/gcc.dg/pointer-counted-by-3.c | 127 +++++++++
>> gcc/testsuite/gcc.dg/pointer-counted-by-4.c | 63 +++++
>> gcc/testsuite/gcc.dg/pointer-counted-by-5.c | 48 ++++
>> gcc/testsuite/gcc.dg/pointer-counted-by-6.c | 47 ++++
>> gcc/testsuite/gcc.dg/pointer-counted-by-7.c | 30 ++
>> gcc/testsuite/gcc.dg/pointer-counted-by-8.c | 30 ++
>> gcc/testsuite/gcc.dg/pointer-counted-by.c | 70 +++++
>
> Do you have any tests where the 'count' field is after the pointer field?
Yes.
In /gcc/testsuite/gcc.dg/pointer-counted-by.c
struct mixed_array_2 {
float *array_1 __attribute ((counted_by (count1)));
int count1;
float *array_2 __attribute ((counted_by (count1)));
long *array_3 __attribute ((counted_by (count2)));
int count2;
long array_4[] __attribute ((counted_by (count2)));
};
count2 is After array_3.
Though I might need to add more such cases. Will do that.
Qing
> -bw
>
>> .../ubsan/pointer-counted-by-bounds-2.c | 47 ++++
>> .../ubsan/pointer-counted-by-bounds-3.c | 35 +++
>> .../ubsan/pointer-counted-by-bounds-4.c | 35 +++
>> .../ubsan/pointer-counted-by-bounds-5.c | 46 +++
>> .../ubsan/pointer-counted-by-bounds-6.c | 33 +++
>> .../gcc.dg/ubsan/pointer-counted-by-bounds.c | 46 +++
>> gcc/tree-object-size.cc | 11 +-
>> 22 files changed, 1045 insertions(+), 88 deletions(-)
>> create mode 100644 gcc/testsuite/gcc.dg/pointer-counted-by-2.c
>> create mode 100644 gcc/testsuite/gcc.dg/pointer-counted-by-3.c
>> create mode 100644 gcc/testsuite/gcc.dg/pointer-counted-by-4.c
>> create mode 100644 gcc/testsuite/gcc.dg/pointer-counted-by-5.c
>> create mode 100644 gcc/testsuite/gcc.dg/pointer-counted-by-6.c
>> create mode 100644 gcc/testsuite/gcc.dg/pointer-counted-by-7.c
>> create mode 100644 gcc/testsuite/gcc.dg/pointer-counted-by-8.c
>> create mode 100644 gcc/testsuite/gcc.dg/pointer-counted-by.c
>> create mode 100644 gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-2.c
>> create mode 100644 gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-3.c
>> create mode 100644 gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-4.c
>> create mode 100644 gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-5.c
>> create mode 100644 gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds-6.c
>> create mode 100644 gcc/testsuite/gcc.dg/ubsan/pointer-counted-by-bounds.c
>>
>> --
>> 2.31.1