grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH]: grub: Fix handling of long printf arguments on 64-bit.


From: Pavel Roskin
Subject: Re: [PATCH]: grub: Fix handling of long printf arguments on 64-bit.
Date: Sun, 12 Apr 2009 17:51:47 -0400

On Sun, 2009-04-12 at 17:33 -0400, Pavel Roskin wrote:

> If the type is going to be converted, we need to treat signed and
> unsigned values separately.

This is compile tested only, to show what I mean.  The size of
kernel.img is reduced from 31220 to 31124.  The code looks long, but I'm
sure an optimizing compiler can simplify it well.  Variable names are
changed for readability.

Index: kern/misc.c
===================================================================
--- kern/misc.c (revision 2087)
+++ kern/misc.c (working copy)
@@ -565,56 +565,6 @@
     }
 }
 
-static char *
-grub_itoa (char *str, int c, unsigned n)
-{
-  unsigned base = (c == 'x') ? 16 : 10;
-  char *p;
-  
-  if ((int) n < 0 && c == 'd')
-    {
-      n = (unsigned) (-((int) n));
-      *str++ = '-';
-    }
-
-  p = str;
-  do
-    {
-      unsigned d = n % base;
-      *p++ = (d > 9) ? d + 'a' - 10 : d + '0';
-    }
-  while (n /= base);
-  *p = 0;
-
-  grub_reverse (str);
-  return p;
-}
-
-static char *
-grub_ltoa (char *str, int c, unsigned long n)
-{
-  unsigned long base = (c == 'x') ? 16 : 10;
-  char *p;
-
-  if ((long) n < 0 && c == 'd')
-    {
-      n = (unsigned long) (-((long) n));
-      *str++ = '-';
-    }
-
-  p = str;
-  do
-    {
-      unsigned long d = n % base;
-      *p++ = (d > 9) ? d + 'a' - 10 : d + '0';
-    }
-  while (n /= base);
-  *p = 0;
-
-  grub_reverse (str);
-  return p;
-}
-
 /* Divide N by D, return the quotient, and store the remainder in *R.  */
 grub_uint64_t
 grub_divmod64 (grub_uint64_t n, grub_uint32_t d, grub_uint32_t *r)
@@ -807,23 +757,36 @@
              /* fall through */
            case 'x':
            case 'u':
+             if (longlongfmt)
+               {
+                 unsigned long long ull = va_arg (args, unsigned long long);
+                 grub_lltoa (tmp, c, ull);
+               }
+             else if (longfmt)
+               {
+                 unsigned long ul = va_arg (args, unsigned long);
+                 grub_lltoa (tmp, c, ul);
+               }
+             else
+               {
+                 unsigned int ui = va_arg (args, unsigned int);
+                 grub_lltoa (tmp, c, ui);
+               }
            case 'd':
              if (longlongfmt)
                {
-                 long long ll;
-
-                 ll = va_arg (args, long long);
-                 grub_lltoa (tmp, c, ll);
+                 long long sll = va_arg (args, long long);
+                 grub_lltoa (tmp, c, sll);
                }
              else if (longfmt)
                {
-                 long l = va_arg (args, long);
-                 grub_ltoa (tmp, c, l);
+                 long sl = va_arg (args, long);
+                 grub_lltoa (tmp, c, sl);
                }
              else
                {
-                 n = va_arg (args, int);
-                 grub_itoa (tmp, c, n);
+                 int si = va_arg (args, int);
+                 grub_lltoa (tmp, c, si);
                }
              if (! rightfill && grub_strlen (tmp) < format1)
                write_fill (zerofill, format1 - grub_strlen (tmp));


-- 
Regards,
Pavel Roskin




reply via email to

[Prev in Thread] Current Thread [Next in Thread]