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