This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c/20546] New: Loading and storing of packed structure elements uses wrong endian for PPC EABI Little Endian
- From: "aweiner at lsil dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 19 Mar 2005 01:21:23 -0000
- Subject: [Bug c/20546] New: Loading and storing of packed structure elements uses wrong endian for PPC EABI Little Endian
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
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