From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Jan Beulich" Subject: Re: [PATCH 4/4] xen/arm: correctly handle an empty array of platform descs. Date: Tue, 21 May 2013 08:54:47 +0100 Message-ID: <519B446702000078000D7800@nat28.tlf.novell.com> References: <1368462160.537.125.camel@zakaz.uk.xensource.com> <1368462182-10317-4-git-send-email-ian.campbell@citrix.com> <1368523975.14264.22.camel@zakaz.uk.xensource.com> <5192248402000078000D5E7F@nat28.tlf.novell.com> <1368526880.14264.29.camel@zakaz.uk.xensource.com> <5192666A02000078000D60F8@nat28.tlf.novell.com> <1368543272.14264.41.camel@zakaz.uk.xensource.com> <1368543416.14264.42.camel@zakaz.uk.xensource.com> <1368544071.14264.46.camel@zakaz.uk.xensource.com> <5192787B02000078000D61D3@nat28.tlf.novell.com> <1368549665.14264.60.camel@zakaz.uk.xensource.com> <5193518E02000078000D647F@nat28.tlf.novell.com> <1368611254.11138.6.camel@hastur.hellion.org.uk> <5193995402000078000D6733@nat28.tlf.novell.com> <1368625620.11138.37.camel@hastur.hellion.org.uk> <5194CE7402000078000D6AF6@nat28.tlf.novell.com> <1368785245.24012.32.camel@hastur.hellion.org.uk> <519624EF02000078000D6F8F@nat28.tlf.novell.com> <1368801272.24012.49.camel@hastur.hellion.org.uk> <51966A2302000078000D710F@nat28.tlf.novell.com> <1368810229.24012.60.camel@hastur.hellion.org.uk> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1368810229.24012.60.camel@hastur.hellion.org.uk> Content-Disposition: inline List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: Ian Campbell Cc: "Keir (Xen.org)" , Stefano Stabellini , Ian Jackson , "Tim (Xen.org)" , "xen-devel@lists.xen.org" , Julien Grall List-Id: xen-devel@lists.xenproject.org >>> On 17.05.13 at 19:03, Ian Campbell wrote: > On Fri, 2013-05-17 at 16:34 +0100, Jan Beulich wrote: >> >>> On 17.05.13 at 16:34, Ian Campbell 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 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