lwip-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lwip-users] Struct packing/alignment problems


From: K.J. Mansley
Subject: Re: [lwip-users] Struct packing/alignment problems
Date: 04 May 2004 16:07:57 +0100

On Tue, 2004-05-04 at 15:41, address@hidden wrote:
> > On Tue, 2004-05-04 at 01:04, Timmy Brolin wrote:
> > > Mandatory 
> > > alignment would render all those STRUCT_PACK macros unnecessary, 
> > > resulting in cleaner code, and significantly increased portability (ANSI 
> > > C conformant, no alignment problem, and no need to define architecture 
> > > specific struct packing macros)
> > 
> > Padding of the start of the struct does not guarantee the alignment of
> > subsequent elements in that struct, so the packing is still required.
> > 
> > Kieran
> 
> Oh but it does.
> The fields in the IP and TCP headers are properly aligned relative to the 
> start 
> of the headers by design. The problem is that the ethernet header is 14 bytes 
> which is not a factor of four, so the starting address of the subsequent IP 
> and 
> TCP structs become unaligned.
> A compiler normaly fix struct alignment problems by silently inserting 
> padding 
> between the fields in the struct (this is of course not acceptable). In order 
> to keep the compiler from doing so, there are struct packing compiler 
> directives in the lwip code. Theese compiler directives tell the compiler to 
> pack the structs even if they are unaligned. Not all compilers and processors 
> support this, it is not ANSI C, and the implementation is highly compiler 
> specific.
> 
> By padding the ethernet header to 16 bytes, we ensure that the IP and TCP 
> structs are correctly aligned. And since there are no alignment problems, the 
> compiler will not add any padding. Thus, we don't need the struct packing 
> directives.

There are two issues here which you seem to be confusing:

1) Ensuring that the IP header is aligned on a 32bit boundary.  The
standard way to do this is to reserve two bytes before the ethernet
header (if you happen to be using Ethernet) so that the following IP
header is 32 bit aligned.  I think we agree on this: you certainly have
no argument from me that this is a good thing, and I thought the
Ethernet driver already supported this.

2) Ensuring that the structs do not have gaps between fields.  This is
independent of anything to do with Ethernet having 14 byte headers, or
the alignment of the network headers.  It is simply ensuring that all
the elements are sequential in memory with no gaps.  Just making sure
the start of the struct is 32bit aligned will not guarantee this.  On
64bit alpha architectures for example I've run into problems where a
non-packed struct would have padding inserted *in the middle* of the
struct, as the compiler could access it more efficiently that way.  I
know the GCC pack directives are not ANSI C, but there is no other way
that I am aware of, other than not using structs at all, to ensure this.
That is why we use the packed struct directives.  If you know of an
alternative that is more standards compliant, please let us know.

Hope that clarifies the reasons why we need both padding and packing!

Kieran





reply via email to

[Prev in Thread] Current Thread [Next in Thread]