Subject: gcc4 lossage on mips kernels with semi-packed struct
To: None <tech-toolchain@netbsd.org>
From: Simon Burge <simonb@wasabisystems.com>
List: tech-toolchain
Date: 05/16/2006 12:22:01
Hi folks,
In nfs/nfs_bootdhcp.c we have struct bootpcontext which is:
struct bootpcontext {
int xid;
u_char *haddr;
u_char halen;
struct bootp *replybuf;
int replylen;
#ifdef NFS_BOOT_DHCP
char expected_dhcpmsgtype, dhcp_ok;
struct in_addr dhcp_serverip;
#endif
};
where struct in_addr is effectively:
struct in_addr {
uint32_t s_addr;
} __attribute__((__packed__));
Under both gcc3 and gcc4, dhcp_serverip is at offset 22 in struct
bootpcontext.
In bootpcheck() there is:
memcpy(&bpc->dhcp_serverip.s_addr, p,
sizeof(bpc->dhcp_serverip.s_addr));
On gcc3 this generates:
lwl $2,3($4)
lwr $2,0($4)
swl $2,25($18)
swr $2,22($18)
where swl and swr are unaligned stores. Life is good.
On gcc4 this generates:
lwl $2,3($4)
lwr $2,0($4)
sw $2,22($17)
where sw is an aligned store, which promptly panics when it tries
to store at an unaligned address.
A workaround is to simply reverse the last two lines in struct
bootpcontext, so that dhcp_serverip is aligned nicely.
Is gcc4 doing something wrong here, or is it a problem with the
structure definitions? I don't want to just swap the lines around
in the struct without understanding what's at fault here.
Simon.
--
Simon Burge <simonb@wasabisystems.com>
NetBSD Development, Support and Service: http://www.wasabisystems.com/