lkml.org 
[lkml]   [1998]   [Nov]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectNIPQUAD 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/

\
 
 \ /
  Last update: 2005-03-22 13:45    [W:0.044 / U:0.240 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site