Hi, 

After some more studying and consideration, the following is my thoughts:

For a structure with FMA annotated with counted_by attribute: (the following 
small example)

====
struct annotated {
        size_t foo;
        char b;
        char array[] __attribute__((counted_by (foo)));
};

#define noinline __attribute__((__noinline__))
#define MAX(a, b)  ((a) > (b) ? (a) :  (b))

static struct annotated * noinline alloc_buf (size_t length)
{
  struct annotated *p;
  p = (struct annotated *) malloc (MAX (sizeof (struct annotated),
                                                                (offsetof 
(struct annotated, array[0])
                                                                + (length) * 
sizeof (char)))); 
  p->foo = length;
  return p;
}

int main ()
{
  struct annotated *p = alloc_buf (10);
  printf("the__bdos of max p->array whole is %d \n", 
__builtin_dynamic_object_size(p->array, 0)); 
  printf("the__bdos of max p->array sub is %d \n", 
__builtin_dynamic_object_size(p->array, 1));
  printf("the__bdos of min p->array whole is %d \n", 
__builtin_dynamic_object_size(p->array, 2));
  printf("the__bdos of min p->array sub is %d \n", 
__builtin_dynamic_object_size(p->array, 3));   
}

=====

 The actual allocation of the structure and the layout of the structure p is 
fixed at compilation time,
    A. We know the offsetof (p->array) during compilation time, (it’s 9)
    B. We also know the size of the p->array though the counted_by attribute, 
it’s p->foo * sizeof (char).

  1.  for subobject size (1/3 modes), Both A and B are know at compilation 
time, whatever it’s MAX or MIN, we 
    can determine  the size of the subobject p->array is:  p->foo * 
sizeof(char) without estimation. 

  2.  for whole object size (0/2 modes), since we don’t have any info on the 
actual allocation or structure 
    Initialization, we don’t know the size for the whole object whatever it’s 
MAX or MIN. 

So, the problem to decide which formula to use ((sizeof (x) + N * sizeof(elt), 
or offsetof + N * sizeof(elt)) is actually
the programmer’s job when allocating memory for the structure with FMA. (It’s 
not compiler’s job).  

Since this size computation is really confusing for the structure with FMA, I 
think that adding some clarification in
the documentation might be necessary to provide more details and guidance to 
the end-users.

Let me know if I miss anything here.

Thanks a lot.

Qing




> On Aug 10, 2023, at 11:18 AM, Martin Uecker <muec...@gwdg.de> wrote:
> The access attribute gives the size directly. The counted_by gives
> a length for the array which needs to be translated into a size
> via a formula. There are different formulas in use. The question 
> is which formula should bdos trust?
> 
> Whatever you pick, if this is not consistent with the actual
> allocation or use, then it will cause problems either by
> breaking code or not detecting buffer overruns.
> 
> So it needs to be consistent with what GCC allocates for a
> var with FAM and initialization and also the user needs to 
> be told what the right choice is so that he can use the right
> size for allocation and argument to memcpy / memset etc.

> On Aug 10, 2023, at 1:06 PM, Siddhesh Poyarekar <siddh...@gotplt.org> wrote:
> 
> On 2023-08-10 12:39, Jakub Jelinek wrote:
>> On Thu, Aug 10, 2023 at 12:30:06PM -0400, Siddhesh Poyarekar wrote:
>>> The definition of __bos/__bdos allows us the freedom to *estimate* rather
>>> than be precise, so I'd go for sizeof(x) + N * sizeof(*x.a) since it's bound
>>> to give the more conservative answer of the two.
>> To be precise, we have the 0/1 modes vs. 2/3.  So, when not determining
>> __bos/__bdos from actual allocation size or size of an stack object or
>> size of data section object but something else (say counted_by), perhaps
>> 0/1 modes should give the upper estimate of sizeof (x) + N * sizeof(elt)
>> and 2/3 modes should give a lower estimate, so offsetof + N * sizeof(elt),
>> then user code can continue testing if both modes are equal to have
>> exact number.
> 
> Ack, that's fair.
> 
> Thanks,
> Sid

Reply via email to