Re: Alignment issues with Sun C Compiler
From: Seongbae Park (Seongbae.Park_at_sun.com)
Date: 03/02/04
- Next message: Logan Shaw: "Re: / & /usr separate?"
- Previous message: Darren Dunham: "Re: Can't run an init 6 on an E450."
- In reply to: Jogchem: "Alignment issues with Sun C Compiler"
- Next in thread: Joerg Schilling: "Re: Alignment issues with Sun C Compiler"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Tue, 2 Mar 2004 22:01:15 +0000 (UTC)
Jogchem <toorged.j.e.r@student.utwente.nl> wrote:
> Hello,
>
>
> I have some serious problems with the pack() pragma with sun cc:
>
> I'd like to have the members of a few structures packed. That is without
> any additional (compiler-dependent) padding between the members so that
> it can be used for binary communication with other systems. To
> accomplish this i surrounded the declaration of my structure with the
> pack pragma:
>
> int main() {
> #pragma pack(1)
> struct { short x; long y; char z; } blah;
> #pragma pack()
> blah.x = blah.y = blah.z = 1;
>
> return 0;
> }
>
> This indeed seems to pack the structure, however accessing the members
> generates a misalignment exception (SIGBUS):
>
> (from dbx)
>
> signal BUS (invalid address alignment) in main at line 6 in file "k.c"
> 6 blah.x = blah.y = blah.z = 1;
>
>
> Ok, i would have expected the compiler to schedule (synthesized,
> consisting out of 2 loads/stores + shift + or to load/store from an
> abitrary address) unaligned load/store instructions to access the fields
> of this packed structure.. Well, i thought, there would be an easy
> solution: By providing a different structure layout where the members
> requiring the highest alignment are placed first and in order this
> problem could be solved:
>
> int main() {
> #pragma pack(1)
> struct { long y; short x; char z; } blah;
> #pragma pack()
> blah.x = blah.y = blah.z = 1;
>
> return 0;
> }
>
> Sadly this does not solve the problem, i get again a SIGBUS, some closer
> inspection with dbx shows that the starting address of 'blah' is
> misaligned itself.. I would have expected the compiler to align the
> whole structure at least on the natural alignment of the first member
> which would in this case be sizeof(long):
>
> signal BUS (invalid address alignment) in main at line 5 in file "k.c"
> 5 blah.x = blah.y = blah.z = 1;
> (dbx) print &blah
> &blah = 0xffbff37d
>
> Obviously as you can see the address of blah is not aligned on a 4-byte
> (sizeof(long) == 4 on sparcv8) alignment and this is causing the
> alignment exception.
>
> My third attempt is to explicitly tell the compiler what alignment i want:
>
> int main() {
> #pragma align 4 (blah)
> #pragma pack(1)
> /* i also tried putting the align pragma at this place */
> struct { long y; short x; char z; } blah;
> #pragma pack()
> blah.x = blah.y = blah.z = 1;
>
> return 0;
> }
>
> This has absolutely no effect, sun cc is ignoring whatever alignment i
> request and keep placing blah at a 2-byte aligned address and not at a
> properly aligned address.
>From Sun ONE Studio 8 C User's Guide:
...
Note that when you use #pragma pack, the alignment of the packed
structure or union itself is the same as its more strictly
aligned member. Therefore any declaration of that struct or union
will be at the pack alignment.
> At this point i think it's about getting time looking through the sun
> forte manuals, and i do indeed find something interesting in the forte 7
> developer c++ users guide:
>
> "When using #pragma pack on a SPARC platform to pack denser than the
> type's default alignment, the -misalign option must be specified for
> both the compilation and the linking of the application. The following
> table shows the storage sizes and default alignments of the integral
> data types."
>
> So i compile my little test program with -misalign and yes, it runs
> properly now. Glad as i am i look up the description for the -misalign
> switch and while reading it i'm stunned. -misalign is an absolutely
> horrible solution to this problem. It turns out that -misalign is equal
> to -xmemalign=1i and the meaning of this option is that an exception
> handler for misalignment exceptions is to be installed which does
> interpretes the access of the misaligned address in software and let's
> the program continue as if nothing happened.
> Obviously this is *horribly* inefficient, this takes orders of
> magnitudes more cycles than simply using unaligned load/store sequences
> to access the packed structure in the first place. This is the worst
> possible solution one can possibly think of in dealing with misaligned
> access for this particular case.
You can use -xmemalign=1s which will force the compiler
to use byte load/store.
> So i found one more solution which does the trick, but which is really
> really ugly:
>
> int main() {
> union {
> long align;
> #pragma pack(1)
> struct { long y; short x; char z; } a;
> #pragma pack()
> } blah;
>
> blah.a.x = blah.a.y = blah.a.z = 1;
> return 0;
> }
>
> the 'long align' in the union guarantees that the blah structure is
> properly aligned to the natural alignment of long (this is guaranteed by
> the ansi c standard). However, this is not an acceptable solution really.
>
> So my question is, are there any better ways to deal with this? Any
> things i'm overlooking?
The current best bet is to have all functions that access packed structure
to be compiled with -xmemalign=1s.
Seongbae
- Next message: Logan Shaw: "Re: / & /usr separate?"
- Previous message: Darren Dunham: "Re: Can't run an init 6 on an E450."
- In reply to: Jogchem: "Alignment issues with Sun C Compiler"
- Next in thread: Joerg Schilling: "Re: Alignment issues with Sun C Compiler"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|