[U-Boot] packed attribute problem

Balau balau at users.sourceforge.net
Mon Oct 11 15:22:54 CEST 2010


Dear all,

I wanted to point out clues about why GCC manages the packed attribute
in this way.

The behavior is suspiciously similar to what the ARM RVDS compiler
(armcc) does with the __packed qualifier:

> [...]
> Thus if you wish to define a pointer to a word that can be at any address (i.e. that can be at a non-natural
> alignment) then you must specify this using the __packed qualifier when defining the pointer:
>
>    __packed int *pi; // pointer to unaligned int
>
> The ARM compilers will not then use an LDR, but instead generate code which correctly accesses the value
> regardless of the alignment of the pointer. This code generated will be a sequence of byte accesses, or
> variable alignment-dependent shifting and masking (depending on the compile options) and will therefore
> incur a performance and code size penalty.
> [...]
( From http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka3544.html
)

I am starting to suspect that the "feature" was copied from the armcc
compiler, even though there shouldn't be any reason to do that.

I can picture someone translating C code from armcc to GCC and
changing the __packed qualifier with the packed attribute, and then
obtaining undesired 32-bit accesses when he wanted 8-bit accesses.
Maybe the fact that GCC packed attribute did not map globals to
unaligned addresses was listed as a "bug" by someone who was more
familiar with armcc, and the developers who "fixed" it were uncertain
about GCC specifications. Maybe the modification was part of a big
changeset and went overlooked, and changing it back now would break so
much code it's better to leave it so. But these are only speculations.

The file "gcc/config/arm/arm.h" inside GCC source contains possibly
useful information:
> /* Setting STRUCTURE_SIZE_BOUNDARY to 32 produces more efficient code, but the
> value set in previous versions of this toolchain was 8, which produces more
> compact structures.  The command line option -mstructure_size_boundary=<n>
> can be used to change this value.  For compatibility with the ARM SDK
> however the value should be left at 32.  ARM SDT Reference Manual (ARM DUI
> 0020D) page 2-20 says "Structures are aligned on word boundaries".
> The AAPCS specifies a value of 8.  */

It seems, though, that using -mstructure-size-boundary=8 or 32 with a
4.4.1-based toolchain has no difference on the managing of packed
structs.

Another interesting scenario is the access of arrays of packed
structs. If a struct is packed but not aligned(4), its sizeof() could
be a number that is not a multiple of the alignment (in the case of
ARM targets). Even if the first element of the array is aligned, the
second element has an unaligned address.

Hope it rings some bells.

Regards,
Francesco


More information about the U-Boot mailing list