[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(¤t_);
+ CHECK(*current_++ == '-');
+ *end = ParseHex(¤t_);
+ CHECK(*current_++ == ' ');
+ CHECK(IsOnOf(*current_++, '-', 'r'));
+ CHECK(IsOnOf(*current_++, '-', 'w'));
+ CHECK(IsOnOf(*current_++, '-', 'x'));
+ CHECK(IsOnOf(*current_++, 's', 'p'));
+ CHECK(*current_++ == ' ');
+ *offset = ParseHex(¤t_);
+ CHECK(*current_++ == ' ');
+ ParseHex(¤t_);
+ CHECK(*current_++ == ':');
+ ParseHex(¤t_);
+ 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