Using GCC 3.4 3.4.0 20040225 (prerelease) PPC EABI Little-Endian. For packed structure element read/writes, compiler is loading/storing data as big-endian instead of little-endian. Seen with all optimization levels, including off. Phenomena not seen with unpacked structures.
Source: typedef struct _FOO { unsigned short a; } __attribute((packed)) FOO; FOO foo; void test_case(void) { foo.a = 0x2233; } Generated assembly: packed_bug.o: file format elf32-powerpcle Disassembly of section .text: 00000000 <test_case>: 0: e8 ff 21 94 stwu r1,-24(r1) 4: 14 00 e1 93 stw r31,20(r1) 8: 78 0b 3f 7c mr r31,r1 c: 00 00 20 3d lis r9,0 10: 00 00 29 39 addi r9,r9,0 14: 00 00 09 88 lbz r0,0(r9) ; superfluous read (optimizaions off) 18: 00 00 00 70 andi. r0,r0,0 1c: 22 00 00 60 ori r0,r0,0x22 20: 00 00 09 98 stb r0,0(r9) ; should be at 1(r9) not 0(r9) 24: 01 00 09 88 lbz r0,1(r9) ; superfluous read (optimizations off) 28: 00 00 00 70 andi. r0,r0,0 2c: 33 00 00 60 ori r0,r0,0x33 30: 01 00 09 98 stb r0,1(r9) ; should be at 0(r9) not 1(r9) 34: 00 00 61 81 lwz r11,0(r1) 38: fc ff eb 83 lwz r31,-4(r11) 3c: 78 5b 61 7d mr r1,r11 40: 20 00 80 4e blr Offset 20: storing the upper 8-bits (0x22) into byte #0 instead of byte #1 Offset 30: storing the lower 8-bits (0x33) into byte #1 instead of byte #0 Result: Memory location contains 0x3322 instead of 0x2233. Here is a disassembly of the same function but with the packed attribute removed: packed_bug.o: file format elf32-powerpcle Disassembly of section .text: 00000000 <test_case>: 0: e8 ff 21 94 stwu r1,-24(r1) 4: 14 00 e1 93 stw r31,20(r1) 8: 78 0b 3f 7c mr r31,r1 c: 00 00 20 3d lis r9,0 10: 33 22 00 38 li r0,0x2233 ; correct little-endian value 14: 00 00 09 b0 sth r0,0(r9) ; correct, stored as little-endian 18: 00 00 61 81 lwz r11,0(r1) 1c: fc ff eb 83 lwz r31,-4(r11) 20: 78 5b 61 7d mr r1,r11 24: 20 00 80 4e blr ------------------------------- Compiler output (-v -save-temps): c:\test>powerpcle-440-eabi-gcc -v -save-temps @options.cl packed_bug.c > t.txt Reading specs from /cygdrive/c/gcc_3.4_ppc_440/bin/../lib/gcc/powerpcle-440-eabi /3.4.0/specs Configured with: : (reconfigured) Thread model: single gcc version 3.4.0 20040225 (prerelease) /cygdrive/c/gcc_3.4_ppc_440/bin/../libexec/gcc/powerpcle-440-eabi/3.4.0/cc1.exe -E -quiet -v -I../../inc -I../.. -iprefix /cygdri ve/c/gcc_3.4_ppc_440/bin/../lib/gcc/powerpcle-440-eabi/3.4.0/ -DVE NDOR_GEN packed_bug.c -mstrict-align -m cpu=440 -mno-sched-prolog -W -Wall -Wno-parentheses -Wno-unused -Wno-uninitializ ed -Wno-format -finline-limit=200 -fworking-directory -o packed_bug.i ignoring nonexistent directory "/cygdrive/c/gcc_3.4_ppc_440/bin/../lib/gcc/power pcle-440-eabi/3.4.0/../../../../powerpcle-440-eabi/sys-include" ignoring nonexistent directory "/cygdrive/e/gcc_3.4_ppc_440/lib/gcc/powerpcle-44 0-eabi/3.4.0/include" ignoring nonexistent directory "/cygdrive/e/gcc_3.4_ppc_440/powerpcle-440-eabi/s ys-include" ignoring nonexistent directory "/cygdrive/e/gcc_3.4_ppc_440/powerpcle-440-eabi/i nclude" #include "..." search starts here: #include <...> search starts here: ../../inc ../.. /cygdrive/c/gcc_3.4_ppc_440/bin/../lib/gcc/powerpcle-440-eabi/3.4.0/include /cygdrive/c/gcc_3.4_ppc_440/bin/../lib/gcc/powerpcle-440-eabi/3.4.0/../../../.. /powerpcle-440-eabi/include End of search list. /cygdrive/c/gcc_3.4_ppc_440/bin/../libexec/gcc/powerpcle-440-eabi/3.4.0/cc1.exe -fpreprocessed packed_bug.i -mstrict-align -quiet -dumpbase packed_bug.c -mcpu= 440 -mno-sched-prolog -auxbase packed_bug -g -W -Wall -Wno-parentheses -Wno-unus ed -Wno-uninitialized -Wno-format -version -finline-limit=200 -o packed_bug.s GNU C version 3.4.0 20040225 (prerelease) (powerpcle-440-eabi) compiled by GNU C version 3.3.1 (cygming special). GGC heuristics: --param ggc-min-expand=64 --param ggc-min-heapsize=65463 /cygdrive/c/gcc_3.4_ppc_440/bin/../lib/gcc/powerpcle-440-eabi/3.4.0/../../../.. /powerpcle-440-eabi/bin/as.exe -m440 -V -Qy -mregnames -m440 -o packed_bug.o pac ked_bug.s GNU assembler version 2.14 (powerpcle-440-eabi) using BFD version 2.14 20030612 /cygdrive/c/gcc_3.4_ppc_440/bin/../libexec/gcc/powerpcle-440-eabi/3.4.0/collect 2.exe -V -Qy -dn -Bstatic -L/cygdrive/c/gcc_3.4_ppc_440/bin/../lib/gcc/powerpcle -440-eabi/3.4.0 -L/cygdrive/c/gcc_3.4_ppc_440/bin/../lib/gcc -L/cygdrive/c/gcc_3 .4_ppc_440/bin/../lib/gcc/powerpcle-440-eabi/3.4.0/../../../../powerpcle-440-eab i/lib packed_bug.o -lgcc -lgcc /cygdrive/c/gcc_3.4_ppc_440/bin/../lib/gcc/powerp cle-440-eabi/3.4.0/crtsavres.o /cygdrive/c/gcc_3.4_ppc_440/bin/../lib/gcc/powerpcle-440-eabi/3.4.0/../../../../ powerpcle-440-eabi/bin/ld: warning: cannot find entry symbol _start; defaulting to 01800074 GNU ld version 2.14 20030612 Supported emulations: elf32lppc elf32ppcsim -- Summary: Loading and storing of packed structure elements uses wrong endian for PPC EABI Little Endian Product: gcc Version: 3.4.0 Status: UNCONFIRMED Severity: critical Priority: P1 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: aweiner at lsil dot com CC: gcc-bugs at gcc dot gnu dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20546