[PATCH] fix printf "%p" output on 64-bit platform

Roman Kononov roman at xtremedatainc.com
Sat Jan 27 16:56:23 UTC 2007


On Sat, 27 Jan 2007 23:10:22 +0900 (JST) Atsushi Nemoto <anemo at mba.ocn.ne.jp> wrote:
> First, your mailer still break your patch.  It seems your mailer
> insert an additional space character on every line staring with a
> space.  I have seen someone blame "format=flowed", but not sure what
> to do.  Anyway, sending patches in attachment would be better since
> Mike Frysinger told me to do so some time ago.

Sorry about the mailer and the spaces. I attached the result of
"svn diff >printf.patch". In ~/.subversion/config, I have diff-cmd option to
invoke "/usr/bin/diff -upb ...". The result has a space in the beginning of
every line, which does not have '+' or '-'. I think this is all right.

> For the patch itself, I do not think we should care
> "sizeof(long)!=sizeof(void *)" case.

This is work for the compiler; no run-time overhead. If sizeof(int)==sizeof(void*)
the compiler should remove everything inside the if () {}, and PA_FLAG_PTR case
will be handled as if no PA_FLAG_XXX is set. You can remove the case, it will
not change too much.

> I'm not sure the magic typedef
> do not confuse any compiler, so I think the magic typedef check is not
> needed at all.

The typedef is purely compile-time check that sizeof(void*)<=sizeof(uintmax_t).
Theoretically, this condition does not have to be true. In such case the
compiled code would be wrong at run-time. The typedef prevents the compiler
to produce wrong code. AFAIK all modern compilers work fine with this typedef.
You can remove the typedef, in practice it will not change too much.

> Also, type_codes[1] in _vprintf.c should be changed to
> PA_POINTER|PA_FLAG_PTR too, no?  (not tested yet)
Yes. I added this and tested.

Regards, Roman
-------------------------------------------
Index: libc/stdio/_load_inttype.c
===================================================================
--- libc/stdio/_load_inttype.c	(revision 17475)
+++ libc/stdio/_load_inttype.c	(working copy)
@@ -11,6 +11,12 @@
 uintmax_t _load_inttype(int desttype, register const void *src, int uflag) attribute_hidden;
 uintmax_t _load_inttype(int desttype, register const void *src, int uflag)
 {
+	if (sizeof(void*)!=sizeof(int) && (desttype&PA_FLAG_PTR)) {
+		/* if this test fails you are in trouble */
+		typedef char test_t[sizeof(void*)<sizeof(uintmax_t)?-1:1];
+		return (uintmax_t)*(void**)src;
+	}
+
 	if (uflag >= 0) {			/* unsigned */
 #if LONG_MAX != INT_MAX
 		if (desttype & (PA_FLAG_LONG|PA_FLAG_LONG_LONG)) {
Index: libc/stdio/_vfprintf.c
===================================================================
--- libc/stdio/_vfprintf.c	(revision 17475)
+++ libc/stdio/_vfprintf.c	(working copy)
@@ -269,7 +269,7 @@ enum {
 
 #define SPEC_OR_MASK		 { \
 	/* n */			(PA_FLAG_PTR|PA_INT), \
-	/* p */			PA_POINTER, \
+	/* p */			PA_POINTER | PA_FLAG_PTR, \
 	/* oxXudi */	PA_INT, \
 	/* fFeEgGaA */	PA_DOUBLE, \
 	/* C */			PA_WCHAR, \
@@ -280,7 +280,7 @@ enum {
 
 #define SPEC_AND_MASK		{ \
 	/* n */			(PA_FLAG_PTR|__PA_INTMASK), \
-	/* p */			PA_POINTER, \
+	/* p */			PA_POINTER | PA_FLAG_PTR, \
 	/* oxXudi */	(__PA_INTMASK), \
 	/* fFeEgGaA */	(PA_FLAG_LONG_DOUBLE|PA_DOUBLE), \
 	/* C */			(PA_WCHAR), \
@@ -758,7 +758,7 @@ libc_hidden_proto(__ctype_b)
 
 static const short int type_codes[] = {
 	__PA_NOARG,					/* must be first entry */
-	PA_POINTER,
+	PA_POINTER|PA_FLAG_PTR,
 	PA_STRING,
 	PA_WSTRING,
 	PA_CHAR,
@@ -1566,7 +1566,7 @@ static int _do_one_spec(FILE * __restric
 #endif /* __UCLIBC_MJN3_ONLY__ */
 			s = _uintmaxtostr(buf + sizeof(buf) - 1,
 							  (uintmax_t)
-							  _load_inttype(*argtype & __PA_INTMASK,
+							  _load_inttype(*argtype & (__PA_INTMASK | PA_FLAG_PTR),
 											*argptr, base), base, alphacase);
 			if (ppfs->conv_num > CONV_u) { /* signed int */
 				if (*s == '-') {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: printf.patch
Type: text/x-patch
Size: 2027 bytes
Desc: not available
Url : http://lists.busybox.net/pipermail/uclibc/attachments/20070127/ccf09f86/attachment-0002.bin 


More information about the uClibc mailing list