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: Timmy Brolin
Subject: Re: [lwip-users] Struct packing/alignment problems
Date: Thu, 06 May 2004 02:09:09 +0200
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.4) Gecko/20030624 Netscape/7.1 (ax)

I just ran nested struct tests on gcc+arm. And unfourtunately, it did not turn out very well. gcc+arm does indeed pad structs so that nested structs align to a 4 byte boundary. Also, it pads structs at the end to ensure the struct size is a factor of 4.
This causes problems in both etharp and eth_hdr.
The eth_addr struct is nested in the etharp struct and the eth_hdr struct. Size of the eth_addr struct is obviously 6, so this struct will be padded to 8 by gcc. In etharp there is also the nested "sipaddr" struct. This nested struct is not on a 4 byte boundary, so there will be 2 bytes of padding before it.

I see two solutions.
1: Remove the nested ip_addr2 and eth_addr structs, and use the arrays directly.
2: Put the PACK_STRUCT directives back in etharp .

I can see a potential problem with the second solution if there is a ARM compiler out there who does not support pack directives.
I guess the decision is up to you Leon?

Stupid thing of me not to consider the nested structs in the first place.
Timmy

Leon Woestenberg wrote:

Hello Jani,

could you please test run the program below to see how the nested struct is aligned under arm-gcc?


Actually, I think you are on to something here... Someone said that gcc for arm puts all structs on 4 byte boundarys in order to use the efficient load and store multiple instructions... I have not considered this. It would surely break the etharp struct.


This piece of code should show the actual alignments under GCC when using nested structs.

#include <stdio.h>
#include <stddef.h>

#if 1
#define PACKED __attribute__ ((packed))
#else
#define PACKED
#endif

struct A {
    u16_t x[2];
} PACKED;

struct B {
    u16_t p;
    struct A q;
    u16_t r;
} PACKED;

int main ()
{
        printf ("offsetof(p) = %d\n", offsetof(p));
        printf ("offsetof(q.x[0]) = %d\n", offsetof(q.x[0]));
        printf ("offsetof(q.x[1]) = %d\n", offsetof(q.x[1]));
        printf ("offsetof(r) = %d\n", offsetof(r));
        printf ("sizeof(struct B) = %d\n", sizeof(struct B));
        return 0;
}

/*
Hopefully:

offsetof(p) is 0
offsetof(q.x[0]) is 2
offsetof(q.x[1]) is 4
offsetof(r) is 6
sizeof(struct B) is 8
*/



Thanks, Leon.


_______________________________________________
lwip-users mailing list
address@hidden
http://mail.gnu.org/mailman/listinfo/lwip-users







reply via email to

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