Package: netdiag Version: 1.0-8 User: [EMAIL PROTECTED] Usertags: eabi Hi! Since etch at least, netwatch has not worked on arm: it reports lots of phantom accesses in the remote IP addresses composed of the high-order bytes of the local IP address in the low-order bytes and 16 bytes of garbage in the high-order bytes. This turns out to be entirely due to misaligned 32-bit memory accesses, which are easy to detect ehre as I have /proc/cpu/alignment set to cause bus errors. The attached patches fix the two issues. One is not really netwatch's fault: GCC spots a 16-byte memcpy of what looks to it from the type casts to be properly-aligned source and target structures, and uses 4-byte register copies to do a 16-byte copy - at runtime it turns out that one of the params is an array of shorts, so the nonaligned accesses do the usual ARM thing of rotating the words by (addr & 03) bytes. (Or giving bus error if you set ethe system that way) The easy workaround is to compile that file without using the builtin memcpy "optimisation". The other is the constructions of a 4-byte network-endian integer in a 4-char array and then accessing it as a longword, fixed in the source with __attribute__((aligned(32)))
I dunno if the other programs in the suite have similar issues, but this definitely affects and fixes netwatch on both arm and armel sid. It also works on arm-etch. Attached: - screen dump of garbage output (the machines' own IP address is 88.96.6.156 and the network is quiet) - patch -p1 file to ficx the two alignment issues in netwatch. M
<<attachment: netwatch-arm-alignment-bugs.png>>
--- netdiag-1.0-orig/netwatch-1.0c/Makefile 2008-10-08 18:33:22.000000000 +0100 +++ netdiag-1.0/netwatch-1.0c/Makefile 2008-10-08 18:31:42.000000000 +0100 @@ -35,6 +35,10 @@ clean: rm -f *~ *.o $(EXEC) config.h config.cache config.log config.status +# work round ARM GCC bug: builtin memcpy gets alignment wrong. +netwatch.o: netwatch.c + $(CC) $(XCFLAGS) -c $(OLDLINUX) -fno-builtin-memcpy $< + .c.o: $(CC) $(XCFLAGS) -c $(OLDLINUX) $< --- netdiag-1.0-orig/netwatch-1.0c/netwatch.c 2008-10-08 18:33:22.000000000 +0100 +++ netdiag-1.0/netwatch-1.0c/netwatch.c 2008-10-08 18:19:08.000000000 +0100 @@ -2483,7 +2483,7 @@ int tlocal (u_int32_t * addr) { - static unsigned char lhost[] = { 127, 0, 0, 1 }; + static unsigned char __attribute__((aligned(32))) lhost[] = { 127, 0, 0, 1 }; u_int32_t *k = (u_int32_t *) netmask; u_int32_t reslocal, restest; if (*addr == *(u_int32_t *) lhost)