[U-Boot] packed attribute problem
Reinhard Meyer
u-boot at emk-elektronik.de
Mon Oct 4 14:43:48 CEST 2010
Dear Wolfgang Denk,
> Dear Reinhard Meyer,
>
> In message <4CA9BE94.6000401 at emk-elektronik.de> you wrote:
>> Do you imply that the code is really different when the pointer gets
>> its value by assigning it NOT to a packed entity? Hard to believe.
>
> This is a special "feature" of GCC on ARM.
>
> -> cat foo.c
> #define writel(v,a) (*(volatile unsigned int *)(a) = (v))
>
> struct p {
> int n;
> } __attribute__ ((packed));
>
> struct q {
> int n;
> };
>
> void foo()
> {
> struct p *pp = (struct p *)0x1000;
>
> pp->n = 5;
> }
>
> void bar()
> {
> struct q *qq = (struct q *)0x1000;
>
> qq->n = 5;
> }
> -> arm-linux-gcc -O -S foo.c
> -> cat foo.s
> .file "foo.c"
> .text
> .align 2
> .global foo
> .type foo, %function
> foo:
> @ Function supports interworking.
> @ args = 0, pretend = 0, frame = 0
> @ frame_needed = 0, uses_anonymous_args = 0
> @ link register save eliminated.
> @ lr needed for prologue
> mov r3, #4096
> mov r2, #0
> orr r1, r2, #5
> strb r1, [r3, #0]
> strb r2, [r3, #1]
> strb r2, [r3, #2]
> strb r2, [r3, #3]
> bx lr
> .size foo, .-foo
> .align 2
> .global bar
> .type bar, %function
In a non-packed struct an int will never be unaligned
(unless you use an unaligned pointer to the whole struct)
In a packed struct an int might be unaligned, so it
_might_ make sense for the compiler to handle that
differently on ARM. Assume you overlay (bad idea anyway)
a packed structure over some communication data stream
thats is byte oriented. On most architectures that would
work (besides obvious endianess issues) but on ARM it would
(without raising an exception) malfunction.
[remember the "display_buffer issue"]
> bar:
> @ Function supports interworking.
> @ args = 0, pretend = 0, frame = 0
> @ frame_needed = 0, uses_anonymous_args = 0
> @ link register save eliminated.
> @ lr needed for prologue
> mov r2, #5
> mov r3, #4096
> str r2, [r3, #0]
> bx lr
> .size bar, .-bar
> .ident "GCC: (GNU) 4.2.2"
>
>
> Note that this is with GCC 4.2.2. Even GCC 4.0.0 behaves the same, so
> this is *not* an issue with very recent tool chains.
OK, for directly adressing elements inside a packed struct;
but the original post said:
"struct xyz {
int x;
int y;
int z[CONST];
} __attribute__ ((packed));
struct xyz *abc;
u32 * status_reg = (u32 *)&abc->z[0];
writel(status, status_reg);"
So the "status_reg" pointer is in a completely unrelated (to the packed struct)
"u32 *" and still the access is done like it was packed. If the
compiler silently drags that attribute along into the "u32 *"
THAT is really sick!
Reinhard
More information about the U-Boot
mailing list