gcc miscompiles csum_tcpudp_magic() on ARMv5
Russell King - ARM Linux
linux at arm.linux.org.uk
Thu Dec 12 07:40:15 EST 2013
On Thu, Dec 12, 2013 at 01:14:04PM +0100, Maxime Bizon wrote:
>
> Hello,
>
> I tried using csum_tcpudp_magic() like this:
>
> csum_tcpudp_magic(src, dst, ntohs(udph->len), IPPROTO_UDP, csum);
>
> instead of the more common:
>
> len = ntohs(udhp->len);
> [...]
> csum_tcpudp_magic(src, dst, len, IPPROTO_UDP, csum);
>
> the first one gives a bad checksum while the second one is ok.
>
>
> I've tracked down the problem to csum_tcpudp_nofold(), which uses inline
> asm and an unsigned short for len.
>
> If the len value is say 0x3412, and I pass ntohs(len), then the assigned
> register for len contains 0x00341234 instead of the expected 0x1234.
>
> The ntohs() expand to a dumb swab16 on my arch, and gcc does the swap
> but does not clear the high nibble, I guess it expects the assembly code
> to only use the low 16 bits.
>
> Is there a missing constraint or gcc is doing something wrong here ?
Depends which swab16 you mean by "dumb swab16". If it is a gcc bug then
you need to submit a bug report to gcc people.
More information about the linux-arm-kernel
mailing list