Thread (37 messages) 37 messages, 9 authors, 2012-10-23

alignment faults in 3.6

flat view

From: Mans Rullgard <hidden>
Date: 2012-10-05 22:37:40

On 5 October 2012 17:01, Rob Herring [off-list ref] wrote:
Here's a testcase. Compiled on ubuntu precise with
"arm-linux-gnueabihf-gcc -O2 -marm -march=armv7-a test.c".

typedef unsigned short u16;
typedef unsigned short __sum16;
typedef unsigned int __u32;
typedef unsigned char __u8;
typedef __u32 __be32;
typedef u16 __be16;

struct iphdr {
        __u8    ihl:4,
                version:4;
        __u8    tos;
        __be16  tot_len;
        __be16  id;
        __be16  frag_off;
        __u8    ttl;
        __u8    protocol;
        __sum16 check;
        __be32  saddr;
        __be32  daddr;
        /*The options start here. */
};

#define ntohl(x) __swab32((__u32)(__be32)(x))
#define IP_DF           0x4000          /* Flag: "Don't Fragment"       */

static inline __attribute__((const)) __u32 __swab32(__u32 x)
{
        __asm__ ("rev %0, %1" : "=r" (x) : "r" (x));
        return x;
}

int main(void * buffer, unsigned int *p_id)
{
        unsigned int id;
        int flush = 1;
        const struct iphdr *iph = buffer;
        __u32 len = *p_id;

        id = ntohl(*(__be32 *)&iph->id);
        flush = (u16)((ntohl(*(__be32 *)iph) ^ len) | (id ^ IP_DF));
        id >>= 16;

        *p_id = id;
        return flush;
}
The problem is the (__be32 *) casts.  This is a normal pointer to a 32-bit,
which is assumed to be aligned, and the cast overrides the packed attribute
from the struct.  Dereferencing these cast expressions must be done with the
macros from asm/unaligned.h

-- 
Mans Rullgard / mru
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help