[Bug target/28763] wrong size of struct with some bit-fields on ppc-eabi
--- Comment #9 from mcvick_e at iname dot com 2009-06-16 16:24 --- Similar behavior has been seen against version 4.3.2. Using the __attribute__ mechanism in the past has forced the hand of the alignment issue most all of the time. I say most all of the time because we have uncovered a case where the __attribute__ mechanism will NOT suffice to correct the alignment issue. As stated the ABI for the PPC Processor states what the alignment requirements are for bitfields, however here is a case that is only correctable by restructuring the bitfield. This in my opinion is poor coding practice as well (however the original developer has long since been gone). Code Snippet: enum Status { LOCKED = 1, UNLOCKED = 2 }; struct foo { Status lockStatus : 2; unsigned char id : 8; unsigned char rId: 8; unsigned short unused : 14; }; struct foo2 { Status lockStatus : 2; unsigned char id : 8; unsigned char rId: 8; unsigned short unused : 14; } __attribute__((aligned(4))) __attribute__((packed)); struct foo3 { Status lockStatus : 2; unsigned short id : 8; unsigned short rId: 8; unsigned short unused : 14; } __attribute__((aligned(4))) __attribute__((packed)); int main(void) { static foo bar = { LOCKED, 2, 10, 0 }; // Wrong alignment (64-bits) static foo1 bar1 = { LOCKED, 2, 10, 0 }; // Wrong alignment (64-bits) static foo2 bar2 = { LOCKED, 2, 10, 0 }; // Correct 32-bit alignment! // Do something so the compiler will not optimize the variables out in // gcc 4.3.2 bar.lockStatus = LOCKED; bar1.lockStatus = LOCKED; bar2.lockStatus = LOCKED; return 0; } -- mcvick_e at iname dot com changed: What|Removed |Added Severity|normal |major http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28763
[Bug target/28763] wrong size of struct with some bit-fields on ppc-eabi
--- Comment #10 from mcvick_e at iname dot com 2009-06-16 16:30 --- The __attribute__ mechanism works in 4.0.1, but was broken in the 4.3 series. I wanted to clarify this as I think it's an important hint as to the root cause of the problem. In 4.0.1, packing and aligning worked via __attribute__ in 4.3.2, packing and aligning is broken. -- mcvick_e at iname dot com changed: What|Removed |Added Severity|normal |major http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28763
[Bug target/28763] wrong size of struct with some bit-fields on ppc-eabi
--- Comment #12 from mcvick_e at iname dot com 2009-06-16 16:55 --- Can you be a bit more succinct here? Because the comment just made sounds like a bunch of foo foo stuff made up to ignore a genuine bug in the compiler. Type byte has a byte alignment. Type short has a 16-bit alignment. Type int has a 32-bit alignment. Especially in the case where strict-align is used. We have a processor/environment that requires strict alignment and we force it via the compiler flags. Furthermore, as stated numerous comments back with a link to the actual PPC ABI, bitfields are to have a 32-bit alignment period. Are you implying that the fields within the structure are considered variables? If so that statement is incorrect as they are fields of a type declaration, which sum total 32-bits (which match the alignment requirement of the ABI). The fact that it was working correctly in 4.0.1 (with the __attribute__ specifications) tells me that this is a bug introduced in the compiler following that release. I think the reason this bug has been ignored for a very long time (as in opened in June of 2006, so 3 years now), is that some core component of the compiler relies on the bug. Yes it's great to save space when possible, but not at the cost of incorrectly violating the ABI. I guess we will have to roll back to 4.0.1 because we can at least get the __CORRECT__ behavior out of the compiler. Which is a shame as the new compiler had features that we were hoping to utilize. This is a bug, a critical one at that, and needs to be fixed. If you don't know how to then just state that and stop hiding behind the ABI which worked against you, and some obtuse commentary that sounded like a politicians statement which meant nothing. -- mcvick_e at iname dot com changed: What|Removed |Added Severity|normal |major http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28763
[Bug target/28763] sizeof() and __attribute__ broken with bit-fields on ppc-eabi
--- Comment #14 from mcvick_e at iname dot com 2009-06-16 17:42 --- Thanks for the update. I finally feel as though this is getting some teeth. I don't know what the default behavior of the 4.3.2 compiler is, however the command line that I used to invoke this behavior excluded any bit-align directives to the compiler. the only flags specified were: -O2 -mtune=603 -mstrict-align -nostdlib -mcpu=603. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28763
[Bug c++/28763] New: sizeof macro appears broken when bitfields are in structures
I have compiled a sample application that demonstrates my problem (see below for the sample code). Basically when I have two structures, one that contains a bitfield and one that does not, the sizeof macro acts differently between the two structures. These structures are identical as far as content (size allocated), yet sizeof fails for the structure containing the bitfield. Accoding to the standards sizeof should report the total number of bytes within a structure (including pad bytes for alignment). However it appears as though when the bitfield mechanism is used, this fails. Here's a sample code specimen that duplicates the problem... sample app struct foo1 { unsigned int bar1 : 10; unsigned int bar2 : 16; unsigned int bar3 : 6; unsigned short bar4; }; struct foo2 { unsigned intbar1; unsigned short bar2; }; int main(void) { static foo1 fubar1 = { 1, 2, 3, 4 }; static foo2 fubar2 = { 1, 2 }; static intsizeofFubar1 = sizeof(foo1); static intsizeofFubar2 = sizeof(foo2); return 0; } end sample app --- Compile the application with: c++ -gstabs+ -O2 -mno-bit-align -mcpu=603 -mtune=603 -mstrict-align -nostdlib -fno-use-cxa-atexit -fcheck-new -fno-rtti -fno-exceptions -fsigned-char -c sampleApp.cc -o sampleApp.o if you run objdump -D -C -s -x -z sampleApp.o you will see that: sizeof(foo1) reports 6 sizeof(foo2) reports 8 even though the two structures are identical in size and alignment requirements. We have 6600 occurrances of the sizeof macro in our software, so manually padding or using the __attribute__((aligned(4))) isn't very tempting to overcome this problem. Thanks! -- Summary: sizeof macro appears broken when bitfields are in structures Product: gcc Version: 4.0.1 Status: UNCONFIRMED Severity: major Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: mcvick_e at iname dot com GCC build triplet: powerpc-eabi GCC host triplet: x86_64-redhat-linux GCC target triplet: powerpc-unknown-eabi http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28763
[Bug target/28763] sizeof macro appears broken when bitfields are in structures
--- Comment #3 from mcvick_e at iname dot com 2006-08-17 22:17 --- Are you telling me that if I put two of those structures side by side in memory that GNU will mis-align them even though I pass the flag -mstrict-align? That couldn't possibly be since the align flag states to use strict type alignment. The GNU documentation also states that it will align to the smallest base type of the bitfield. Thus an 8-bit bitfield has 8-bit alignment, a 16-bit has 16-bit alignment, and a 32-bit has 32-bit alignment. In the example I have shown, it clearly shows that a 32-bit bitfield is defaulting to byte alignment as far as size allocation is concerned. I've ran objdump on the file, and even though the size is reported as smaller, it ALLOCATES all 32-bits for alignment reasons. According to the C-Speficiation (which applies to C++ as well) ... The size of an object of a structure type is the amount of storage necessary to represent all components of that type, including any unused padding space between or after the components. The rule is that the structure will be padded out to the size the type would occupy as an element of array of such types. So if you had an array of foo1's and an array of foo2's you would see exactly the same alignment in memory. Just that sizeof reports something incorrect. Thus if you were wanting to walk the array by say a byte pointer, and then went to increment that byte pointer by the sizeof the structure, in one case you would get correct behavior, and in the other you would get undefined or incorrect behavior. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28763
[Bug target/28763] sizeof macro appears broken when bitfields are in structures
--- Comment #5 from mcvick_e at iname dot com 2006-08-17 22:28 --- Additional information, if you insist on having an ABI then please go to this link and look at pages 3-8 and 3-9. It states that bitfields have the same alignment restrictions as their base types (int for int) (short for short) etc. http://refspecs.freestandards.org/elf/elfspec_ppc.pdf#search=%22powerpc%20abi%22 -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28763
[Bug target/28763] sizeof macro appears broken when bitfields are in structures
--- Comment #6 from mcvick_e at iname dot com 2006-08-17 22:35 --- The spec also has multiple examples of big versus little endian layouts and how they map in memory and what their alignment is. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28763
[Bug target/28763] sizeof macro appears broken when bitfields are in structures
--- Comment #7 from mcvick_e at iname dot com 2006-08-18 00:03 --- (In reply to comment #4) > -mstrict-align does not do what you think it does. What it does is say the > alignment requirements for loads/stores cannot be violated. That's fine for the -mstrict-align, however as I stated in my last two comments the ABI for the Power PC state that this is clearly incorrect behavior. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28763
[Bug target/28763] sizeof macro appears broken when bitfields are in structures
--- Comment #8 from mcvick_e at iname dot com 2006-08-22 16:42 --- To try to be more helpful here, after doing a large amount of investigation into the signature of this problem, it's been observed that the GNU compiler simply defines (or appears to define) a bitfield (regardless of it's type (char, short, int)) as nothing more than a byte aligned entity. Now if the structure has a larger constituent primitive type (short, int) then the structure will align to the largest primitive type. For example. One of the tests that I performed was simply to define two structures. struct foo1 { unsigned intbar1 : 10; unsigned intbar2 : 10; unsigned intbar3 : 12; unsigned short bar4; unsigned char bar5; }; struct foo2 { unsigned intbar1 : 10; unsigned intbar2 : 10; unsigned intbar3 : 12; unsigned short bar4; unsigned char bar5; unsigned char bar6; }; foo1 will report the size as being 0x8 (which is correct), where as foo2 will report the size as 0xA which is incorrect. It's correct if the structure has short alignment, however according to the ABI the structure should align to a 32-bit alignment because of the unsigned int bitfield. Taking the same example above, if you substitute an unsigned int for the unsigned short, then you get the alignment that you expect across all situations. Merely because an integer primitive type is embedded within the structure. I hope this helps some. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28763
[Bug c++/23539] New: C & C++ compiler generating misaligned references regardless of compiler flags
108: b1 3f 00 11 sth r9,17(r31)<-- Again odd offsets 10c: 88 1f 00 10 lbz r0,16(r31) 110: a1 3f 00 11 lhz r9,17(r31) 114: 98 1f 00 30 stb r0,48(r31) 118: b1 3f 00 31 sth r9,49(r31) 11c: 38 1f 00 30 addir0,r31,48 120: 7c 03 03 78 mr r3,r0 124: 48 00 00 01 bl 124 128: 7c 60 1b 78 mr r0,r3 12c: 90 1f 00 0c stw r0,12(r31) 130: 80 1f 00 0c lwz r0,12(r31) 134: 2f 80 00 00 cmpwi cr7,r0,0 138: 40 9e 00 10 bne-cr7,148 13c: 80 1f 00 08 lwz r0,8(r31) 140: 2f 80 00 00 cmpwi cr7,r0,0 144: 41 9e 00 10 beq-cr7,154 148: 38 00 00 01 li r0,1 14c: 90 1f 00 40 stw r0,64(r31) 150: 48 00 00 0c b 15c 154: 38 00 00 00 li r0,0 158: 90 1f 00 40 stw r0,64(r31) 15c: 80 1f 00 40 lwz r0,64(r31) 160: 7c 03 03 78 mr r3,r0 164: 81 61 00 00 lwz r11,0(r1) 168: 80 0b 00 04 lwz r0,4(r11) 16c: 7c 08 03 a6 mtlrr0 170: 83 eb ff fc lwz r31,-4(r11) 174: 7d 61 5b 78 mr r1,r11 178: 4e 80 00 20 blr >From Section 3.3.1 Alignment and Misaligned Accesses The operand of a single-register memory access instruction has a natural alignment boundary equal to the operand length. The "natural" address of an operand is an integral multiple of the operand length, .. I can understand what the compiler is trying to achieve here in the sense of doing two loads/stores versus three, however it is performing misaligned loads/stores as a result. This optimization actually becomes a performance hit if the underlying system is forced to perform the exception handling and piece the parts together. Perhaps it's not a "real" bug, however not being able to override this behavior probably is. This behavior has been observed in 4.0.1, 4.0.0, 3.4.4 and 3.3.1 -- Summary: C & C++ compiler generating misaligned references regardless of compiler flags Product: gcc Version: 4.0.1 Status: UNCONFIRMED Severity: normal Priority: P2 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: mcvick_e at iname dot com CC: gcc-bugs at gcc dot gnu dot org GCC build triplet: i686-pc-linux-gnu GCC host triplet: i686-pc-linux-gnu GCC target triplet: powerpc-eabi http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23539
[Bug target/23539] C & C++ compiler generating misaligned references regardless of compiler flags
--- Additional Comments From mcvick_e at iname dot com 2005-08-23 21:44 --- I should also mention that the target processor for this is the 603, not 603e or otherwise. Even compiling with the -mtune=603 and -mcpu=603 gives the same output. And those old processors do not handle mis-aligned short references in hardware. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23539
[Bug target/23539] C & C++ compiler generating misaligned references regardless of compiler flags
--- Additional Comments From mcvick_e at iname dot com 2005-08-23 22:24 --- The data access exception is incorrect in this sense. The software developer had updated the status of this issue and states that this causes a Machine Check exception to occur on our current hardware. The observation made earlier that padding the structure with a byte clearing up the issue is still a factual statement. We will have to discuss this with our hardware engineers as to why this occurs, however the issue is the same, since this hardware cannot be modified. The software is for space based satellites which have already been launched. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23539
[Bug target/23539] C & C++ compiler generating misaligned references regardless of compiler flags
--- Additional Comments From mcvick_e at iname dot com 2005-08-23 23:47 --- Our Hardware engineers came back to us informing us as to why this _may_ be an issue. The hardware has a memory bus arbiter ASIC that does not handle mis- aligned references for 2-byte accesses ending on 1 or 5. So this construct will fail indeterminately. I passed on the information given us about the -mstrict-align and it appears to have cleared up the issue with odd alignment offsets. Thanks Much! -- What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution||INVALID http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23539
[Bug target/23539] C & C++ compiler generating misaligned references regardless of compiler flags
--- Additional Comments From mcvick_e at iname dot com 2005-08-24 00:20 --- Unfortunately this still appears to be some sort of bug. The solution given with the -mstrict-align worked for the test case, but in the specific case here, still fails. Attached is the output of the link command given. The compiler invocation for all of the associated files that make the libraries, and object files all contain the -mstrict-align. See the text below... (1)> ppcg++ -gstabs+ -O1 -fno-guess-branch-probability -mcpu=603e -mtune=603e - mstrict-align -nostdlib -DGH_COMPAT -DAVOID_EMPTY_CLASSES -DSVRT_TRACE -fno-use- cxa-atexit -fcheck-new -fno-rtti -fno-exceptions -Wabi - Wextra /export/GNU_port/MM.1/lib/sac/begin.o /export/GNU_port/MM.1/lib/sac/sysin it.o /export/GNU_port/MM.1/lib/sac/prepccfg.o /export/GNU_port/MM.1/lib/sac/psos cfg.o /export/GNU_port/MM.1/lib/sac/drv_conf.o --no-undefined -Bstatic --warn- section-align --demangle --warn-once --warn-common --sort-common -T sac.cmd - L /export/GNU_port/MM.1/lib -L /export/GNU_port/MM.1/lbcs/lib \ -o /export/GNU_port/MM.1/bins/sac.x --- (2)> ppcobjdump -C -S sac.x | grep sth | less 494108: b3 43 00 18 sth r26,24(r3) 49410c: b3 23 00 1a sth r25,26(r3) 494110: b3 03 00 1c sth r24,28(r3) 494c0c: b0 01 00 21 sth r0,33(r1) <-- Still ODD alignment 4954a0: b1 3a 30 ec sth r9,12524(r26) 4956ac: b1 23 00 04 sth r9,4(r3) 4957d4: b0 03 00 a4 sth r0,164(r3) 4959a8: b1 23 00 00 sth r9,0(r3) 495bac: b0 03 00 a4 sth r0,164(r3) 495ed0: b1 2a 30 e0 sth r9,12512(r10) (3)> -- What|Removed |Added Status|RESOLVED|UNCONFIRMED Resolution|INVALID | http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23539
[Bug target/23539] C & C++ compiler generating misaligned references regardless of compiler flags
--- Additional Comments From mcvick_e at iname dot com 2005-08-24 02:57 --- I understand this frustration. The source code is proprietary material so I cannot post it. However we are working on developing a sample case to demonstrate what is happening. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23539
[Bug target/23539] C & C++ compiler generating misaligned references regardless of compiler flags
--- Additional Comments From mcvick_e at iname dot com 2005-08-24 15:44 --- Here is a short program that duplicates the problem. -- test.cc struct foo { char bar1; char bar2; char bar3; }; class bar2 { private: static foo myFubarStruct; public: static void fbs(foo fubarStruct); }; foo bar2::myFubarStruct; class bar1 { private: int rVal1; int rVal2; public: void doFoo(void); }; void bar1::doFoo(void) { foo barStruct; barStruct.bar1 = 'A'; barStruct.bar2 = 'B'; barStruct.bar3 = 'C'; bar2::fbs(barStruct); } void bar2::fbs(foo fubarStruct) { myFubarStruct = fubarStruct; } int main(int argc, char **argv) { bar1 baar; baar.doFoo(); return (0); } -- end of test.cc -- The test app was just compiled to object code as shown below with the -mstrict- align option. (2)> ppcg++ -mstrict-align -c test.cc Then an objdump was done to dump the assembly (shown below) (3)> ppcobjdump -C -S test.o test.o: file format elf32-powerpc Disassembly of section .text: : 0: 94 21 ff f0 stwur1,-16(r1) 4: 93 e1 00 0c stw r31,12(r1) 8: 7c 3f 0b 78 mr r31,r1 c: 7c 6b 1b 78 mr r11,r3 10: 3d 20 00 00 lis r9,0 14: 39 29 00 00 addir9,r9,0 18: 88 0b 00 00 lbz r0,0(r11) 1c: 89 4b 00 01 lbz r10,1(r11) 20: 89 6b 00 02 lbz r11,2(r11) 24: 98 09 00 00 stb r0,0(r9) 28: 99 49 00 01 stb r10,1(r9) 2c: 99 69 00 02 stb r11,2(r9) 30: 81 61 00 00 lwz r11,0(r1) 34: 83 eb ff fc lwz r31,-4(r11) 38: 7d 61 5b 78 mr r1,r11 3c: 4e 80 00 20 blr 0040 : 40: 94 21 ff c8 stwur1,-56(r1) 44: 7c 08 02 a6 mflrr0 48: 93 e1 00 34 stw r31,52(r1) 4c: 90 01 00 3c stw r0,60(r1) 50: 7c 3f 0b 78 mr r31,r1 54: 90 7f 00 18 stw r3,24(r31) 58: 38 00 00 41 li r0,65 5c: 98 1f 00 0b stb r0,11(r31) 60: 38 00 00 42 li r0,66 64: 98 1f 00 0c stb r0,12(r31) 68: 38 00 00 43 li r0,67 6c: 98 1f 00 0d stb r0,13(r31) 70: 88 1f 00 0b lbz r0,11(r31) 74: 89 3f 00 0c lbz r9,12(r31) 78: 89 7f 00 0d lbz r11,13(r31) 7c: 98 1f 00 08 stb r0,8(r31) 80: 99 3f 00 09 stb r9,9(r31) 84: 99 7f 00 0a stb r11,10(r31) 88: 88 1f 00 08 lbz r0,8(r31) 8c: a1 3f 00 09 lhz r9,9(r31) <--- Odd alignment 90: 98 1f 00 20 stb r0,32(r31) 94: b1 3f 00 21 sth r9,33(r31) <--- Odd alignment 98: 38 1f 00 20 addir0,r31,32 9c: 7c 03 03 78 mr r3,r0 a0: 48 00 00 01 bl a0 a4: 81 61 00 00 lwz r11,0(r1) a8: 80 0b 00 04 lwz r0,4(r11) ac: 7c 08 03 a6 mtlrr0 b0: 83 eb ff fc lwz r31,-4(r11) b4: 7d 61 5b 78 mr r1,r11 b8: 4e 80 00 20 blr 00bc : bc: 94 21 ff d8 stwur1,-40(r1) c0: 7c 08 02 a6 mflrr0 c4: 93 e1 00 24 stw r31,36(r1) c8: 90 01 00 2c stw r0,44(r1) cc: 7c 3f 0b 78 mr r31,r1 d0: 90 7f 00 18 stw r3,24(r31) d4: 90 9f 00 1c stw r4,28(r31) d8: 48 00 00 01 bl d8 dc: 38 7f 00 08 addir3,r31,8 e0: 48 00 00 01 bl e0 e4: 38 00 00 00 li r0,0 e8: 7c 03 03 78 mr r3,r0 ec: 81 61 00 00 lwz r11,0(r1) f0: 80 0b 00 04 lwz r0,4(r11) f4: 7c 08 03 a6 mtlrr0 f8: 83 eb ff fc lwz r31,-4(r11) fc: 7d 61 5b 78 mr r1,r11 100: 4e 80 00 20 blr (4)> -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23539