Fix format_number.

I broke this the other day when silencing x86 gcc warnings.

Bug: 7904160
Change-Id: I8e60cc1f8cbaff95248c8738d84e515413d839e4
diff --git a/linker/linker_format.cpp b/linker/linker_format.cpp
index c56d8a1..e631ca1 100644
--- a/linker/linker_format.cpp
+++ b/linker/linker_format.cpp
@@ -30,14 +30,16 @@
 // compile under GCC 4.7
 #undef _FORTIFY_SOURCE
 
-#include <assert.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <stdint.h>
-#include <stddef.h>
 #include "linker_format.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
 #include "linker_debug.h"
 
 /* define UNIT_TESTS to build this file as a single executable that runs
@@ -357,49 +359,49 @@
     return result;
 }
 
-/* write an octal/decimal/number into a bounded buffer.
- * assumes that bufsize > 0, and 'digits' is a string of
- * digits of at least 'base' values.
- */
-static void
-format_number(char *buffer, size_t bufsize, uint64_t value, int base, const char *digits)
-{
-    char *pos = buffer;
-    char *end = buffer + bufsize - 1;
+// Writes number 'value' in base 'base' into buffer 'buf' of size 'buf_size' bytes.
+// Assumes that buf_size > 0.
+static void format_number(char* buf, size_t buf_size, uint64_t value, int base, bool caps) {
+  char* p = buf;
+  char* end = buf + buf_size - 1;
 
-    /* generate digit string in reverse order */
-    while (value) {
-        unsigned d = value % base;
-        value /= base;
-        if (pos != end) {
-            *pos++ = digits[d];
-        }
+  // Generate digit string in reverse order.
+  while (value) {
+    unsigned d = value % base;
+    value /= base;
+    if (p != end) {
+      char ch;
+      if (d < 10) {
+        ch = '0' + d;
+      } else {
+        ch = (caps ? 'A' : 'a') + (d - 10);
+      }
+      *p++ = ch;
     }
+  }
 
-    /* special case for 0 */
-    if (pos == buffer) {
-        if (pos != end) {
-            *pos++ = '0';
-        }
+  // Special case for 0.
+  if (p == buf) {
+    if (p != end) {
+      *p++ = '0';
     }
-    pos[0] = '\0';
+  }
+  *p = '\0';
 
-    /* now reverse digit string in-place */
-    end = pos - 1;
-    pos = buffer;
-    while (pos != end) {
-        int ch = pos[0];
-        pos[0] = end[0];
-        end[0] = (char) ch;
-        pos++;
-        end--;
-    }
+  // Reverse digit string in-place.
+  size_t length = p - buf;
+  for (size_t i = 0, j = length - 1; i < j; ++i, --j) {
+    char ch = buf[i];
+    buf[i] = buf[j];
+    buf[j] = ch;
+  }
 }
 
 /* Write an integer (octal or decimal) into a buffer, assumes buffsize > 2 */
 static void
 format_integer(char *buffer, size_t buffsize, uint64_t value, int base, int isSigned)
 {
+    // TODO: this is incorrect for MIN_INT.
     if (isSigned && (int64_t)value < 0) {
         buffer[0] = '-';
         buffer += 1;
@@ -407,17 +409,12 @@
         value = (uint64_t)(-(int64_t)value);
     }
 
-    format_number(buffer, buffsize, value, base, "0123456789");
+    format_number(buffer, buffsize, value, base, false);
 }
 
-/* Write an hexadecimal into a buffer, isCap is true for capital alphas.
- * Assumes bufsize > 2 */
-static void
-format_hex(char *buffer, size_t buffsize, uint64_t value, int isCap)
-{
-    const char *digits = isCap ? "0123456789ABCDEF" : "0123456789abcdef";
-
-    format_number(buffer, buffsize, value, 16, digits);
+// Assumes buf_size > 2.
+static void format_hex(char* buf, size_t buf_size, uint64_t value, bool caps) {
+  format_number(buf, buf_size, value, 16, caps);
 }
 
 
@@ -543,7 +540,7 @@
             uint64_t  value = (uintptr_t) va_arg(args, void*);
             buffer[0] = '0';
             buffer[1] = 'x';
-            format_hex(buffer + 2, sizeof buffer-2, value, 0);
+            format_hex(buffer + 2, sizeof buffer-2, value, false);
             str = buffer;
         } else {
             /* integers - first read value from stack */