Hi Jan, Jan Rinze wrote: > Hi all, > > I am a bit worried and confused about this patch: > >
This patch made the way we align and size structs and bitfields match the way MSFT does with their tools. That is part of the ABI we must match. I'll give you an example where this was failing before the patch. Take an dll built with ex MSVC, with contents like this: struct my_struct { size_t size_of_my_struct; /* This technique is very common in Win32 world. It is mostly used to check the version of my_struct being used */ char v1_field; /* char v2_field; Field would be added in v2 of the dll.*/ }; /* only showing v1 of the dll. */ __declspec(dllexport) BOOL my_funct(struct my_struct* s) { if (s->size_of_my_struct != sizeof (struct my_struct)) { return FALSE; } /* do actual work. */ return TRUE; } And then called by an app built with mingw32ce, would never work correctly, since the sizeofs wouldn't match. Or imagine compiling a dll with a MSFT compiler that takes a foo4 pointer as a parameter in one of its exported functions. Then imagine you built an app in cegcc or mingw32ce, that uses that dll. Accessing the y member on the app and on the dll would access different offsets! Bang! Or this: In a MSVC compiled dll: struct small { char a; }; __declspec(dllexport) struct small* alloc_small(void) { return malloc (sizeof (struct small)); /* mallocs 1 byte. */ } In a mingw32ce app using the above dll: __declspec(dllimport) struct small* alloc_small(void); int main() { struct small* sm = alloc_small(); memset (sm, 0, sizeof (struct small)); /* clears 4 bytes, outch! */ } > Op di 31-10-2006, om 00:59 schreef Pedro Alves: > >> Hi all, >> >> I am commiting this patch that cleans up gcc's support of Windows CE for >> arm. >> >> This patch fixes some major bugs/annoyances we had: >> >> - __declspec(dllexport/dllimport) was so broken that it was hurting. >> We weren't passing -export= in .drectve properly, >> so the linker would default to exporting everything. If you used .def >> files, this would go unnoticed. >> >> - We had some major violations of WinCE's ABI: >> >> Currently this test gives wrong results: >> struct abi_check_doubles { char a; double d; }; >> struct foo0 { char x; }; >> struct foo1 { char x;char :0; char y; }; >> struct foo2 { char x; int :0; int :0; int :0; int :0; char y; }; >> struct foo3 { char x; char :1; char y; }; >> struct foo4 { char x; int :1; char y; }; >> >> int main() >> { >> printf ("Size of foo0 is %d, should be 1\n", sizeof (struct foo0)); >> printf ("Size of foo1 is %d, should be 2\n", sizeof (struct foo1)); >> printf ("Size of foo2 is %d, should be 2\n", sizeof (struct foo2)); >> printf ("Size of foo3 is %d, should be 3\n", sizeof (struct foo3)); >> printf ("Size of foo4 is %d, should be 12\n", sizeof (struct foo4)); >> return 0; >> } >> >> The right results where taken from compiling the test case with MSVC. >> Note that this is a simplified test case. >> If you where experiencing weird crashes before while calling/interfacing >> MSVC/eVC compiled code, >> including the system dlls, this may very well be the reason. >> >> This patch also brings gcc support very close to what should be >> submitted upstream. >> > > compiling the above on an ARM-Linux box yields: > > $> ./test > Size of foo0 is 4, should be 1 > Size of foo1 is 4, should be 2 > Size of foo2 is 8, should be 2 > Size of foo3 is 4, should be 3 > Size of foo4 is 4, should be 12 > > This is with > > $> gcc --version > gcc (GCC) 3.4.3 > Copyright (C) 2004 Free Software Foundation, Inc. > This is free software; see the source for copying conditions. There is > NO > warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR > PURPOSE. > > We should note that this can break a lot of other stuff. We had rather > be using the __packed__ attributed here. > > But WinCE is not arm-linux. Arm-linux uses it's own ABI (or ABIs for the matter, AAPCS, EABI, EEABI-linux, etc.) We must follow the ABI WinCE uses. For instance, All linux ABIs let small structs be passed in registers, while WinCE mandates that *all* structs be passed through the stack. > struct abi_check_doubles { char a; double d; }; > struct __attribute__((__packed__)) foo0 { char x; }; > struct __attribute__((__packed__)) foo1 { char x;char :0; char y; }; > struct __attribute__((__packed__)) foo2 { char x; int :0; int :0; int > :0; int :0; char y; }; > struct __attribute__((__packed__)) foo3 { char x; char :1; char y; }; > struct __attribute__((__packed__)) foo4 { char x; int :1; char y; }; > > > int main() > { > printf ("Size of foo0 is %d, should be 1\n", sizeof (struct foo0)); > printf ("Size of foo1 is %d, should be 2\n", sizeof (struct foo1)); > printf ("Size of foo2 is %d, should be 2\n", sizeof (struct foo2)); > printf ("Size of foo3 is %d, should be 3\n", sizeof (struct foo3)); > printf ("Size of foo4 is %d, should be 12\n", sizeof (struct foo4)); > return 0; > } > > Will yield: > > ./test > Size of foo0 is 1, should be 1 > Size of foo1 is 2, should be 2 > Size of foo2 is 2, should be 2 > Size of foo3 is 3, should be 3 > Size of foo4 is 3, should be 12 > > Where the foo4 is 3 in my opinion is fully correct.. 12 is pretty large > for 2 chars and 1 bit... > > Again it is the WinCE's ABI. Not my fault. :) Notice that the difference between foo3 and foo4 is the type of the bitfield. On windows targets, the type matters. So on those cases you get: struct foo3 { char x; /* 1 == sizeof (char) */ char :1; /* 1 == sizeof (char) */ char y; /* 1 == sizeof (char) */ }; struct foo4 { char x; /* 1 == sizeof (char) */ /* 3 == pad to align the next field, which has a 4 byte natural alignment. */ int :1; /* 4 == sizeof (int) */ char y; /* 1 == sizeof (char) */ /* 3 == pad to align the struct size to the maximum alignment of all the members, which is 4 (int) */ }; On the other cases, a special rule about zero sized bitfields enter the game. > The compiler can do this behaviour on all structs when we have > -fpack-struct when invoking gcc. The manual of gcc however warns about > the behaviour and the resulting binary incompatibilities. > > When you use -fpack-struct, you are effectively changing the ABI (Aplication Binary Interface). You must never match two different ABI's in the same program, hence the warning. In embedded apps where you have control over everything, you can get away with -fpack-struct, but only if you compile everything with it, else, you have the same ABI mismatch problems. > I am not sure about the behaviour of eVC in this respect but the packing > of integers on an ARM processor is pretty much going to slowdown memory > access by a factor of at least four! (each byte is read separately when > unaligned memory access is done.) > > That's a bit of a simplification :) Optimization also has it's saying here. > I will need to do some more checking on this in respect to eVC. > > I tested this on MSVC 2005, and I would be very surprised if eVC gave different results, but I would be very interested in confirming this. You can get a lot more info on this by googling for "-ms-bitfields" option. Here is a link the patch that introduced support for it in gcc, if you are interested. http://gcc.gnu.org/ml/gcc-patches/1999-06n/msg00702.html Hope this helps, Cheers, Pedro Alves ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ Cegcc-devel mailing list Cegcc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/cegcc-devel