[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH 4/4] xen/arm: correctly handle an empty array of platform descs.



>>> On 17.05.13 at 19:03, Ian Campbell <ian.campbell@xxxxxxxxxx> wrote:
> On Fri, 2013-05-17 at 16:34 +0100, Jan Beulich wrote:
>> >>> On 17.05.13 at 16:34, Ian Campbell <ian.campbell@xxxxxxxxxx> wrote:
>> > Is there a requirement (e.g. from the C standard) that an empty struct
>> > take at least one byte, or more likely I suppose something about
>> > different instances having different addresses which sort of implies it?
>> 
>> Yes: "Two pointers compare equal if and only if both are null pointers,
>> both are pointers to the same object (including a pointer to an object
>> and a subobject at its beginning) or function, both are pointers to one
>> past the last element of the same array object, or one is a pointer to
>> one past the end of one array object and the other is a pointer to the
>> start of a different array object that happens to immediately follow
>> the first array object in the address space."
> 
> Right, that rings a bell, thanks.
> 
> Even on x86 I see this:
> 
>         struct foo { };
>         static struct foo a, b;
>         int main(void)
>         {
>               printf("a %p %lx\n", &a, (unsigned long)&a);
>               printf("b %p %lx\n", &b, (unsigned long)&b);
>               printf("a and b are %s\n", &a == &b ? "equal" : "distinct");
>               printf("ulong a and b are %s\n", (unsigned long)&a == (unsigned 
> long)&b ? "equal" : "distinct");
>         }
> 
>         $ gcc --version
>         gcc (Debian 4.7.2-5) 4.7.2
>         $ gcc -O2 t.c
>         $ ./a.out
>         a 0x60094c 60094c
>         b 0x60094c 60094c
>         a and b are distinct
>         ulong a and b are distinct
>         
> and I see the same thing on arm32 and visibility has no affect.
> 
> This seems to conform to what you quote above even though the addresses
> appear equal.

This is overly simplified (as the compiler eliminates the comparisons).
Try this

#include <stdio.h>

struct foo { };
extern struct foo a, b;

int main(void) {
        printf("a %p %lx\n", &a, (unsigned long)&a);
        printf("b %p %lx\n", &b, (unsigned long)&b);
        printf("a and b are %s\n", &a == &b ? "equal" : "distinct");
        printf("ulong a and b are %s\n", (unsigned long)&a == (unsigned long)&b 
? "equal" : "distinct");
        return 0;
}

once with this as second source file

struct foo { };
struct foo a = { }, b = { };

and a second time with another second source file

struct foo { };
struct foo a, b;

The initializers already make a difference (also on x86). This is yet
another bug then (apparently architecture independent).

If you then take the earlier of the "second" source files and build it
for ARM32, you'll see different behavior from x86 (identical to that
with the latter "second" source file).

And if you then change the declarations in the first source file to

extern struct foo __attribute__((__visibility__("hidden"))) a;
extern struct foo __attribute__((__visibility__("hidden"))) b;

and compare the disassembly here with the original one, you'll see
that the compiler eliminates the pointer comparison, but retains the
comparison of the casts to unsigned long (the effect isn't visible in
the output of the executable).

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.