Messages in this thread Patch in this message | | | Date | Wed, 4 Nov 1998 16:36:27 +0100 | From | Alain RICHARD <> | Subject | NIPQUAD endian problem solved (patch included) |
| |
The NIPQUAD macro in the linux/kernel.h header that is faulty on big endian machines (PPC, Sparcs, m68k). It is used mainly in the firewalling code to print TCP/IP address in the form 192.9.200.1 in debugging messages (kernel messages). I don't know if it is used for other purpose. On big endian machines, the above address is badly printed as 1.200.9.192.
It seems there was several attempts to correct this beavior that were removed because Linus don't agree with the bad code generated on little endian machines. The patch I propose is working both on little and big endian machines and also seems to produce better code on i386 processor that the original macro.
I suggest the following new NIPQUADok macro to replace the broken NIPQUAD macro :
#define NIPQUAD(addr) \ ((unsigned char *)&addr)[0], \ ((unsigned char *)&addr)[1], \ ((unsigned char *)&addr)[2], \ ((unsigned char *)&addr)[3]
At the assembly level produced (using -O3) on the intel machine :
# # code generated by the current macro #
movl %edx,%eax shrl $24,%eax pushl %eax movl %edx,%eax shrl $16,%eax andl $255,%eax pushl %eax movl %edx,%eax shrl $8,%eax andl $255,%eax pushl %eax movzbl %dl,%edx pushl %edx pushl $.LC1 call printf
# # code generated by the new macro #
movzbl -1(%ebp),%eax pushl %eax movzbl -2(%ebp),%eax pushl %eax movzbl -3(%ebp),%eax pushl %eax movzbl -4(%ebp),%eax pushl %eax pushl $.LC1 call printf
This shows that the new macro is also better when looking at the generated code.
I hope this will be included in the next kernel sub-release.
Regards,
diff -u linux-2.1.126/include/linux/kernel.h linux/include/linux/kernel.h --- linux-2.1.126/include/linux/kernel.h Wed Oct 14 10:47:52 1998 +++ linux/include/linux/kernel.h Wed Oct 28 19:07:31 1998 @@ -69,10 +69,10 @@ */
#define NIPQUAD(addr) \ - (int)(((addr) >> 0) & 0xff), \ - (int)(((addr) >> 8) & 0xff), \ - (int)(((addr) >> 16) & 0xff), \ - (int)(((addr) >> 24) & 0xff) + ((unsigned char *)&addr)[0], \ + ((unsigned char *)&addr)[1], \ + ((unsigned char *)&addr)[2], \ + ((unsigned char *)&addr)[3]
#endif /* __KERNEL__ */
------------------------------------------------ Alain RICHARD <mailto:alain_richard@equation.fr> EQUATION SA <http://www.equation.fr> - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |