Add %m and %#x support for async_safe logging

Bugs: None
Test: None
Change-Id: I889015b89b85e222e26f8aa20e35d46a86a0cb7c
diff --git a/libc/async_safe/async_safe_log.cpp b/libc/async_safe/async_safe_log.cpp
index 8b2a32b..2380e68 100644
--- a/libc/async_safe/async_safe_log.cpp
+++ b/libc/async_safe/async_safe_log.cpp
@@ -251,6 +251,7 @@
     char sign = '\0';
     int width = -1;
     int prec = -1;
+    bool alternate = false;
     size_t bytelen = sizeof(int);
     int slen;
     char buffer[32]; /* temporary buffer used to format numbers */
@@ -293,6 +294,9 @@
       } else if (c == ' ' || c == '+') {
         sign = c;
         continue;
+      } else if (c == '#') {
+        alternate = true;
+        continue;
       }
       break;
     }
@@ -344,9 +348,6 @@
     if (c == 's') {
       /* string */
       str = va_arg(args, const char*);
-      if (str == nullptr) {
-        str = "(null)";
-      }
     } else if (c == 'c') {
       /* character */
       /* NOTE: char is promoted to int when passed through the stack */
@@ -357,6 +358,9 @@
       buffer[0] = '0';
       buffer[1] = 'x';
       format_integer(buffer + 2, sizeof(buffer) - 2, value, 'x');
+    } else if (c == 'm') {
+      char buf[256];
+      str = strerror_r(errno, buf, sizeof(buf));
     } else if (c == 'd' || c == 'i' || c == 'o' || c == 'u' || c == 'x' || c == 'X') {
       /* integers - first read value from stack */
       uint64_t value;
@@ -388,8 +392,19 @@
         value = static_cast<uint64_t>((static_cast<int64_t>(value << shift)) >> shift);
       }
 
-      /* format the number properly into our buffer */
-      format_integer(buffer, sizeof(buffer), value, c);
+      if (alternate && value != 0 && (c == 'x' || c == 'o')) {
+        if (c == 'x') {
+          buffer[0] = '0';
+          buffer[1] = 'x';
+          format_integer(buffer + 2, sizeof(buffer) - 2, value, c);
+        } else {
+          buffer[0] = '0';
+          format_integer(buffer + 1, sizeof(buffer) - 1, value, c);
+        }
+      } else {
+        /* format the number properly into our buffer */
+        format_integer(buffer, sizeof(buffer), value, c);
+      }
     } else if (c == '%') {
       buffer[0] = '%';
       buffer[1] = '\0';
@@ -397,6 +412,10 @@
       __assert(__FILE__, __LINE__, "conversion specifier unsupported");
     }
 
+    if (str == nullptr) {
+      str = "(null)";
+    }
+
     /* if we are here, 'str' points to the content that must be
      * outputted. handle padding and alignment now */