[asan] get rid of libc's sscanf as it causes infinite recursion on Fedora.  

git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@159424 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/sanitizer_common/sanitizer_libc.h b/lib/sanitizer_common/sanitizer_libc.h
index a388005..8da4286 100644
--- a/lib/sanitizer_common/sanitizer_libc.h
+++ b/lib/sanitizer_common/sanitizer_libc.h
@@ -60,7 +60,6 @@
 uptr internal_filesize(fd_t fd);  // -1 on error.
 int internal_dup2(int oldfd, int newfd);
 int internal_snprintf(char *buffer, uptr length, const char *format, ...);
-int internal_sscanf(const char *str, const char *format, ...);
 
 // Threading
 int internal_sched_yield();
diff --git a/lib/sanitizer_common/sanitizer_linux.cc b/lib/sanitizer_common/sanitizer_linux.cc
index 8b2c67b..00363d0 100644
--- a/lib/sanitizer_common/sanitizer_linux.cc
+++ b/lib/sanitizer_common/sanitizer_linux.cc
@@ -171,14 +171,39 @@
   current_ = proc_self_maps_buff_;
 }
 
+// Parse a hex value in str and update str.
+static uptr ParseHex(char **str) {
+  uptr x = 0;
+  char *s;
+  for (s = *str; ; s++) {
+    char c = *s;
+    uptr v = 0;
+    if (c >= '0' && c <= '9')
+      v = c - '0';
+    else if (c >= 'a' && c <= 'f')
+      v = c - 'a' + 10;
+    else if (c >= 'A' && c <= 'F')
+      v = c - 'A' + 10;
+    else
+      break;
+    x = x * 16 + v;
+  }
+  *str = s;
+  return x;
+}
+
+static bool IsOnOf(char c, char c1, char c2) {
+  return c == c1 || c == c2;
+}
+
+static bool IsDecimal(char c) {
+  return c >= '0' && c <= '9';
+}
+
 bool ProcessMaps::Next(uptr *start, uptr *end, uptr *offset,
                        char filename[], uptr filename_size) {
   char *last = proc_self_maps_buff_ + proc_self_maps_buff_len_;
   if (current_ >= last) return false;
-  int consumed = 0;
-  char flags[10];
-  int major, minor;
-  uptr inode;
   uptr dummy;
   if (!start) start = &dummy;
   if (!end) end = &dummy;
@@ -186,11 +211,25 @@
   char *next_line = (char*)internal_memchr(current_, '\n', last - current_);
   if (next_line == 0)
     next_line = last;
-  if (internal_sscanf(current_, "%lx-%lx %4s %lx %x:%x %ld %n",
-                      start, end, flags, offset, &major, &minor,
-                      &inode, &consumed) != 7)
-    return false;
-  current_ += consumed;
+  // Example: 08048000-08056000 r-xp 00000000 03:0c 64593   /foo/bar
+  *start = ParseHex(&current_);
+  CHECK(*current_++ == '-');
+  *end = ParseHex(&current_);
+  CHECK(*current_++ == ' ');
+  CHECK(IsOnOf(*current_++, '-', 'r'));
+  CHECK(IsOnOf(*current_++, '-', 'w'));
+  CHECK(IsOnOf(*current_++, '-', 'x'));
+  CHECK(IsOnOf(*current_++, 's', 'p'));
+  CHECK(*current_++ == ' ');
+  *offset = ParseHex(&current_);
+  CHECK(*current_++ == ' ');
+  ParseHex(&current_);
+  CHECK(*current_++ == ':');
+  ParseHex(&current_);
+  CHECK(*current_++ == ' ');
+  while (IsDecimal(*current_))
+    current_++;
+  CHECK(*current_++ == ' ');
   // Skip spaces.
   while (current_ < next_line && *current_ == ' ')
     current_++;
diff --git a/lib/sanitizer_common/sanitizer_posix.cc b/lib/sanitizer_common/sanitizer_posix.cc
index d9cc9b0..d8d01a1 100644
--- a/lib/sanitizer_common/sanitizer_posix.cc
+++ b/lib/sanitizer_common/sanitizer_posix.cc
@@ -163,16 +163,6 @@
   return __sync_lock_test_and_set(a, new_val);
 }
 
-// -------------- sanitizer_libc.h
-
-int internal_sscanf(const char *str, const char *format, ...) {
-  va_list args;
-  va_start(args, format);
-  int res = vsscanf(str, format, args);
-  va_end(args);
-  return res;
-}
-
 }  // namespace __sanitizer
 
 #endif  // __linux__ || __APPLE_
diff --git a/lib/sanitizer_common/sanitizer_win.cc b/lib/sanitizer_common/sanitizer_win.cc
index fc5c93a..1ebb719 100644
--- a/lib/sanitizer_common/sanitizer_win.cc
+++ b/lib/sanitizer_common/sanitizer_win.cc
@@ -194,10 +194,6 @@
   UNIMPLEMENTED();
 }
 
-int internal_sscanf(const char *str, const char *format, ...) {
-  UNIMPLEMENTED();
-}
-
 }  // namespace __sanitizer
 
 #endif  // _WIN32