* gcc-4.3.3 arm-linux-gnueabi pointer to packed struct field align problem
@ 2009-03-12 2:05 john.philip
2009-03-12 5:59 ` [solved] " john.philip
0 siblings, 1 reply; 2+ messages in thread
From: john.philip @ 2009-03-12 2:05 UTC (permalink / raw)
To: gcc-help
[-- Attachment #1: Type: text/plain, Size: 1968 bytes --]
test.c below shows example of a problem seen in a larger code base.
happens when access 16bit & 32bit uints inside struct (or byte array)
via pointers to struct fields rather than the struct itself
expect val to be same in all tests. & for example TESTA is so with
gcc-3.4.6 i486-slackwaere-linux little-end:
ptr 0xbf81bec0 0xbf81bec1 0xbf81bec3, val 1 302 7060504
ptr 0xbf81bec0 0xbf81bec1 0xbf81bec3, val 1 302 7060504
ptr 0xbf81bec0 0xbf81bec1 0xbf81bec3, val 1 302 7060504
ptr 0xbf81beb0 0xbf81beb1 0xbf81beb3, val 1 302 7060504
& gcc-3.4.2 mips-linux-uclibc big-end (cross compile):
ptr 0x7fff7da0 0x7fff7da1 0x7fff7da3, val 1 203 4050607
ptr 0x7fff7da0 0x7fff7da1 0x7fff7da3, val 1 203 4050607
ptr 0x7fff7da0 0x7fff7da1 0x7fff7da3, val 1 203 4050607
ptr 0x7fff7da8 0x7fff7da9 0x7fff7dab, val 1 203 4050607
but have problems with gcc-4.3.3 arm-linux-gnueabi little-end:
TESTA:
ptr 0xbe93f8db 0xbe93f8dc 0xbe93f8de, val 1 302 7060504
ptr 0xbe93f8db 0xbe93f8dc 0xbe93f8de, val 1 302 7060504
ptr 0xbe93f8db 0xbe93f8dc 0xbe93f8de, val 1 302 3020504 <<< u32 nok
ptr 0xbe93f8d4 0xbe93f8d5 0xbe93f8d7, val 1 201 3020104 <<< u16 nok
TESTB:
ptr 0xbee018dc 0xbee018dd 0xbee018df, val 1 302 7060504
ptr 0xbee018dc 0xbee018dd 0xbee018df, val 1 302 7060504
ptr 0xbee018dc 0xbee018dd 0xbee018df, val 1 201 3020104 <<< u16 nok
ptr 0xbee018d5 0xbee018d6 0xbee018d8, val 1 302 7060504 <<< u32 nok
- removing packed & 'char c' (TESTC) so us_t.u16 & us_t.u32 both at even
address gets around problem. so looks like an alignment issue
- but accessing via a pointer to entire struct (us_p) is always ok. so
looks like alignment not an issue
questions:
- is use of pointer to struct fields (@ [1]) non-portable?
- is there compiler config &/or options to fix this? (specs attached)
- a blue moon case of 'compiler did it wrong' being fact rather than too
quick excuse for own buggy code? (gotta be so 1 day)
############################
[-- Attachment #2: test.c --]
[-- Type: text/plain, Size: 1599 bytes --]
#include <stdint.h>
#include <stdio.h>
#define TESTA 1
#define TESTB 0
#define TESTC 0
#if !defined(offsetof)
#define offsetof(x, y) __builtin_offsetof(x, y)
#endif
#if TESTC
typedef struct
#else
typedef struct __attribute__ ((packed))
#endif
{
uint8_t u8;
uint16_t u16;
uint32_t u32;
} us_t;
int main()
{
#if TESTA
char c;
// dummy
c = 1;
#endif
// struct
us_t us;
// byte array
uint8_t ua[7];
uint8_t i;
uint8_t * j;
// fill us & ua 1,2,3..
for (i = 0, j = (uint8_t *)&us; i < sizeof(us); i++, j++)
{
*j = i + 1;
ua[i] = i + 1;
}
#if 0
printf("%d %d %d\n",
offsetof(us_t, u8), offsetof(us_t, u16), offsetof(us_t, u32));
#endif
// via struct, all ok
printf("ptr %p %p %p, val %x %x %x\n",
&us.u8, &us.u16, &us.u32, us.u8, us.u16, us.u32);
// via ptr to whole struct, all ok
us_t * us_p = &us;
printf("ptr %p %p %p, val %x %x %x\n",
&us_p->u8, &us_p->u16, &us_p->u32, us_p->u8, us_p->u16, us_p->u32);
// [1] via ptr to packed struct fields, armv5tel nok
uint8_t * u8_p = &us.u8;
uint16_t * u16_p = &us.u16;
uint32_t * u32_p = &us.u32;
printf("ptr %p %p %p, val %x %x %x\n",
u8_p, u16_p, u32_p, *u8_p, *u16_p, *u32_p);
#if !TESTC
// [2] via ptr to equivalent byte array locations, amv5tel nok
u8_p = &ua[0];
u16_p = (uint16_t *)&ua[1];
u32_p = (uint32_t *)&ua[3];
printf("ptr %p %p %p, val %x %x %x\n",
u8_p, u16_p, u32_p, *u8_p, *u16_p, *u32_p);
#endif
return 0;
}
[-- Attachment #3: Type: text/plain, Size: 31 bytes --]
############################
[-- Attachment #4: gcc.arm.specs --]
[-- Type: text/plain, Size: 6221 bytes --]
$ uname -a
Linux xxxx 2.6.26-1-orion5x #1 Sun Jan 11 17:19:11 UTC 2009 armv5tel GNU/Linux
#################################
$ gcc -v
Using built-in specs.
Target: arm-linux-gnueabi
Configured with: ../src/configure -v --with-pkgversion='Debian 4.3.3-4' --with-bugurl=file:///usr/share/doc/gcc-4.3/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.3 --program-suffix=-4.3 --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr --disable-libssp --disable-sjlj-exceptions --enable-checking=release --build=arm-linux-gnueabi --host=arm-linux-gnueabi --target=arm-linux-gnueabi
Thread model: posix
gcc version 4.3.3 (Debian 4.3.3-4)
#################################
$ gcc -dumpspecs
*asm:
%{mbig-endian:-EB} %{mlittle-endian:-EL} %{mcpu=*:-mcpu=%*} %{march=*:-march=%*} %{mapcs-*:-mapcs-%*} %(subtarget_asm_float_spec) %{mthumb-interwork:-mthumb-interwork} %{msoft-float:-mfloat-abi=soft} %{mhard-float:-mfloat-abi=hard} %{mfloat-abi=*} %{mfpu=*} %(subtarget_extra_asm_spec)
*asm_debug:
%{gstabs*:--gstabs}%{!gstabs*:%{g*:--gdwarf2}} %{fdebug-prefix-map=*:--debug-prefix-map %*}
*asm_final:
*asm_options:
%{--target-help:%:print-asm-header()} %a %Y %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}
*invoke_as:
%{!S:-o %|.s |
as %(asm_options) %m.s %A }
*cpp:
%(subtarget_cpp_spec) %{msoft-float:%{mhard-float: %e-msoft-float and -mhard_float may not be used together}} %{mbig-endian:%{mlittle-endian: %e-mbig-endian and -mlittle-endian may not be used together}}
*cpp_options:
%(cpp_unique_options) %1 %{m*} %{std*&ansi&trigraphs} %{W*&pedantic*} %{w} %{f*} %{g*:%{!g0:%{!fno-working-directory:-fworking-directory}}} %{O*} %{undef} %{save-temps:-fpch-preprocess}
*cpp_debug_options:
%{d*}
*cpp_unique_options:
%{C|CC:%{!E:%eGCC does not support -C or -CC without -E}} %{!Q:-quiet} %{nostdinc*} %{C} %{CC} %{v} %{I*&F*} %{P} %I %{MD:-MD %{!o:%b.d}%{o*:%.d%*}} %{MMD:-MMD %{!o:%b.d}%{o*:%.d%*}} %{M} %{MM} %{MF*} %{MG} %{MP} %{MQ*} %{MT*} %{!E:%{!M:%{!MM:%{!MT:%{!MQ:%{MD|MMD:%{o*:-MQ %*}}}}}}} %{remap} %{g3|ggdb3|gstabs3|gcoff3|gxcoff3|gvms3:-dD} %{H} %C %{D*&U*&A*} %{i*} %Z %i %{fmudflap:-D_MUDFLAP -include mf-runtime.h} %{fmudflapth:-D_MUDFLAP -D_MUDFLAPTH -include mf-runtime.h} %{E|M|MM:%W{o*}}
*trad_capable_cpp:
cc1 -E %{traditional|ftraditional|traditional-cpp:-traditional-cpp}
*cc1:
%{profile:-p}
*cc1_options:
%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}} %1 %{!Q:-quiet} -dumpbase %B %{d*} %{m*} %{a*} %{c|S:%{o*:-auxbase-strip %*}%{!o*:-auxbase %b}}%{!c:%{!S:-auxbase %b}} %{g*} %{O*} %{W*&pedantic*} %{w} %{std*&ansi&trigraphs} %{v:-version} %{pg:-p} %{p} %{f*} %{undef} %{Qn:-fno-ident} %{--help:--help} %{--target-help:--target-help} %{--help=*:--help=%(VALUE)} %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}} %{fsyntax-only:-o %j} %{-param*} %{fmudflap|fmudflapth:-fno-builtin -fno-merge-constants} %{coverage:-fprofile-arcs -ftest-coverage}
*cc1plus:
*link_gcc_c_sequence:
%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}
*link_ssp:
%{fstack-protector:}
*endfile:
%{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s
*link:
%{!static:--eh-frame-hdr} %{h*} %{version:-v} %{b} %{static:-Bstatic} %{shared:-shared} %{symbolic:-Bsymbolic} %{rdynamic:-export-dynamic} %{!dynamic-linker:-dynamic-linker %{muclibc:%{mglibc:%e-mglibc and -muclibc used together}/lib/ld-uClibc.so.0;:/lib/ld-linux.so.3}} -X %{mbig-endian:-EB} %{mlittle-endian:-EL} -m armelf_linux_eabi
*lib:
%{pthread:-lpthread} %{shared:-lc} %{!shared:%{profile:-lc_p}%{!profile:-lc}}
*mfwrap:
%{static: %{fmudflap|fmudflapth: --wrap=malloc --wrap=free --wrap=calloc --wrap=realloc --wrap=mmap --wrap=munmap --wrap=alloca} %{fmudflapth: --wrap=pthread_create}} %{fmudflap|fmudflapth: --wrap=main}
*mflib:
%{fmudflap|fmudflapth: -export-dynamic}
*link_gomp:
*libgcc:
%{static|static-libgcc:-lgcc -lgcc_eh}%{!static:%{!static-libgcc:%{!shared-libgcc:-lgcc --as-needed -lgcc_s --no-as-needed}%{shared-libgcc:-lgcc_s%{!shared: -lgcc}}}}
*startfile:
%{!shared: %{pg|p|profile:gcrt1.o%s;pie:Scrt1.o%s;:crt1.o%s}} crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}
*switches_need_spaces:
*cross_compile:
0
*version:
4.3.3
*multilib:
. ;
*multilib_defaults:
marm mlittle-endian mhard-float mno-thumb-interwork
*multilib_extra:
*multilib_matches:
*multilib_exclusions:
*multilib_options:
*linker:
collect2
*link_libgcc:
%D
*md_exec_prefix:
*md_startfile_prefix:
*md_startfile_prefix_1:
*startfile_prefix_spec:
*sysroot_spec:
--sysroot=%R
*sysroot_suffix_spec:
*sysroot_hdrs_suffix_spec:
*subtarget_cpp_spec:
%{posix:-D_POSIX_SOURCE} %{pthread:-D_REENTRANT}
*subtarget_extra_asm_spec:
%{mabi=apcs-gnu|mabi=atpcs:-meabi=gnu;:-meabi=4}
*subtarget_asm_float_spec:
%{mapcs-float:-mfloat}
*link_command:
%{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S: %(linker) %l %{pie:-pie} %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r} %{s} %{t} %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}} %{static:} %{L*} %(mfwrap) %(link_libgcc) %o %{fopenmp|ftree-parallelize-loops=*:%:include(libgomp.spec)%(link_gomp)} %(mflib) %{fprofile-arcs|fprofile-generate|coverage:-lgcov} %{!nostdlib:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}} %{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*} }}}}}}
#################################
$ cat /proc/cpuinfo
Processor : Feroceon rev 0 (v5l)
BogoMIPS : 332.59
Features : swp half thumb fastmult edsp
CPU implementer : 0x41
CPU architecture: 5TEJ
CPU variant : 0x0
CPU part : 0x926
CPU revision : 0
Cache type : write-back
Cache clean : cp15 c7 ops
Cache lockdown : format C
Cache format : Harvard
I size : 32768
I assoc : 1
I line length : 32
I sets : 1024
D size : 32768
D assoc : 1
D line length : 32
D sets : 1024
[-- Attachment #5: Type: text/plain, Size: 4 bytes --]
--
^ permalink raw reply [flat|nested] 2+ messages in thread
* [solved] Re: gcc-4.3.3 arm-linux-gnueabi pointer to packed struct field align problem
2009-03-12 2:05 gcc-4.3.3 arm-linux-gnueabi pointer to packed struct field align problem john.philip
@ 2009-03-12 5:59 ` john.philip
0 siblings, 0 replies; 2+ messages in thread
From: john.philip @ 2009-03-12 5:59 UTC (permalink / raw)
To: gcc-help
just needed to ask right person
john.philip@uhssystems.com writes:
] - is use of pointer to struct fields (@ [1]) non-portable?
yes. because of diff alignment restrictions on diff CPUs
for ways to find such code, or even do see-no-evil & have linux kernel
fix them at run time, see http://wiki.debian.org/ArmEabiFixes &
http://lecs.cs.ucla.edu/wiki/index.php/XScale_alignment
--
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2009-03-12 5:59 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-03-12 2:05 gcc-4.3.3 arm-linux-gnueabi pointer to packed struct field align problem john.philip
2009-03-12 5:59 ` [solved] " john.philip
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).