public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* 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).