[Sanitizer] move all the rest re-implementations of libc functions from ASan runtime to common sanitizer runtime

llvm-svn: 158519
This commit is contained in:
Alexey Samsonov 2012-06-15 13:09:52 +00:00
parent 3efd6fc26c
commit 156958dd0c
9 changed files with 105 additions and 113 deletions

View File

@ -171,86 +171,13 @@ static inline bool RangesOverlap(const char *offset1, uptr length1,
} \
} while (0)
static inline bool IsSpace(int c) {
return (c == ' ') || (c == '\n') || (c == '\t') ||
(c == '\f') || (c == '\r') || (c == '\v');
}
static inline bool IsDigit(int c) {
return (c >= '0') && (c <= '9');
}
static inline int ToLower(int c) {
return (c >= 'A' && c <= 'Z') ? (c + 'a' - 'A') : c;
}
// ---------------------- Internal string functions ---------------- {{{1
s64 internal_simple_strtoll(const char *nptr, char **endptr, int base) {
CHECK(base == 10);
while (IsSpace(*nptr)) nptr++;
int sgn = 1;
u64 res = 0;
bool have_digits = false;
char *old_nptr = (char*)nptr;
if (*nptr == '+') {
sgn = 1;
nptr++;
} else if (*nptr == '-') {
sgn = -1;
nptr++;
}
while (IsDigit(*nptr)) {
res = (res <= UINT64_MAX / 10) ? res * 10 : UINT64_MAX;
int digit = ((*nptr) - '0');
res = (res <= UINT64_MAX - digit) ? res + digit : UINT64_MAX;
have_digits = true;
nptr++;
}
if (endptr != 0) {
*endptr = (have_digits) ? (char*)nptr : old_nptr;
}
if (sgn > 0) {
return (s64)(Min((u64)INT64_MAX, res));
} else {
return (res > INT64_MAX) ? INT64_MIN : ((s64)res * -1);
}
}
s64 internal_atoll(const char *nptr) {
return internal_simple_strtoll(nptr, (char**)0, 10);
}
uptr internal_strnlen(const char *s, uptr maxlen) {
static inline uptr MaybeRealStrnlen(const char *s, uptr maxlen) {
#if ASAN_INTERCEPT_STRNLEN
if (REAL(strnlen) != 0) {
return REAL(strnlen)(s, maxlen);
}
#endif
uptr i = 0;
while (i < maxlen && s[i]) i++;
return i;
}
char *internal_strstr(const char *haystack, const char *needle) {
// This is O(N^2), but we are not using it in hot places.
uptr len1 = internal_strlen(haystack);
uptr len2 = internal_strlen(needle);
if (len1 < len2) return 0;
for (uptr pos = 0; pos <= len1 - len2; pos++) {
if (internal_memcmp(haystack + pos, needle, len2) == 0)
return (char*)haystack + pos;
}
return 0;
}
char *internal_strncat(char *dst, const char *src, uptr n) {
uptr len = internal_strlen(dst);
uptr i;
for (i = 0; i < n && src[i]; i++)
dst[len + i] = src[i];
dst[len + i] = 0;
return dst;
return internal_strnlen(s, maxlen);
}
} // namespace __asan
@ -479,7 +406,7 @@ INTERCEPTOR(char*, strcat, char *to, const char *from) { // NOLINT
INTERCEPTOR(char*, strncat, char *to, const char *from, uptr size) {
ENSURE_ASAN_INITED();
if (FLAG_replace_str && size > 0) {
uptr from_length = internal_strnlen(from, size);
uptr from_length = MaybeRealStrnlen(from, size);
ASAN_READ_RANGE(from, Min(size, from_length + 1));
uptr to_length = REAL(strlen)(to);
ASAN_READ_RANGE(to, to_length);
@ -582,7 +509,7 @@ INTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) {
INTERCEPTOR(char*, strncpy, char *to, const char *from, uptr size) {
ENSURE_ASAN_INITED();
if (FLAG_replace_str) {
uptr from_size = Min(size, internal_strnlen(from, size) + 1);
uptr from_size = Min(size, MaybeRealStrnlen(from, size) + 1);
CHECK_RANGES_OVERLAP("strncpy", to, from_size, from, from_size);
ASAN_READ_RANGE(from, from_size);
ASAN_WRITE_RANGE(to, size);

View File

@ -30,16 +30,7 @@ DECLARE_REAL(int, sigaction, int signum, const struct sigaction *act,
namespace __asan {
// __asan::internal_X() is the implementation of X() for use in RTL.
s64 internal_atoll(const char *nptr);
uptr internal_strnlen(const char *s, uptr maxlen);
char *internal_strstr(const char *haystack, const char *needle);
char *internal_strncat(char *dst, const char *src, uptr n);
// Works only for base=10 and doesn't set errno.
s64 internal_simple_strtoll(const char *nptr, char **endptr, int base);
void InitializeAsanInterceptors();
#if defined(__APPLE__)
void InitializeMacInterceptors();
#endif // __APPLE__

View File

@ -27,28 +27,6 @@ extern "C" void* _ReturnAddress(void);
# pragma intrinsic(_ReturnAddress)
#endif // defined(_WIN32)
// Limits for integral types. We have to redefine it in case we don't
// have stdint.h (like in Visual Studio 9).
#if __WORDSIZE == 64
# define __INT64_C(c) c ## L
# define __UINT64_C(c) c ## UL
#else
# define __INT64_C(c) c ## LL
# define __UINT64_C(c) c ## ULL
#endif // __WORDSIZE == 64
#undef INT32_MIN
#define INT32_MIN (-2147483647-1)
#undef INT32_MAX
#define INT32_MAX (2147483647)
#undef UINT32_MAX
#define UINT32_MAX (4294967295U)
#undef INT64_MIN
#define INT64_MIN (-__INT64_C(9223372036854775807)-1)
#undef INT64_MAX
#define INT64_MAX (__INT64_C(9223372036854775807))
#undef UINT64_MAX
#define UINT64_MAX (__UINT64_C(18446744073709551615))
#define ASAN_DEFAULT_FAILURE_EXITCODE 1
#if defined(__linux__)

View File

@ -477,7 +477,6 @@ static void ParseAsanOptions(const char *options) {
void __asan_init() {
if (asan_inited) return;
MiniLibcStub(); // FIXME: remove me once mini libc build is tested properly.
asan_init_is_running = true;
// Make sure we are not statically linked.

View File

@ -89,6 +89,18 @@ inline uptr RoundUpTo(uptr size, uptr boundary) {
template<class T> T Min(T a, T b) { return a < b ? a : b; }
template<class T> T Max(T a, T b) { return a > b ? a : b; }
// Char handling
inline bool IsSpace(int c) {
return (c == ' ') || (c == '\n') || (c == '\t') ||
(c == '\f') || (c == '\r') || (c == '\v');
}
inline bool IsDigit(int c) {
return (c >= '0') && (c <= '9');
}
inline int ToLower(int c) {
return (c >= 'A' && c <= 'Z') ? (c + 'a' - 'A') : c;
}
#if __WORDSIZE == 64
# define FIRST_32_SECOND_64(a, b) (b)
#else

View File

@ -107,4 +107,26 @@ void NORETURN CheckFailed(const char *file, int line, const char *cond,
#define UNIMPLEMENTED() CHECK("unimplemented" && 0)
// Limits for integral types. We have to redefine it in case we don't
// have stdint.h (like in Visual Studio 9).
#if __WORDSIZE == 64
# define __INT64_C(c) c ## L
# define __UINT64_C(c) c ## UL
#else
# define __INT64_C(c) c ## LL
# define __UINT64_C(c) c ## ULL
#endif // __WORDSIZE == 64
#undef INT32_MIN
#define INT32_MIN (-2147483647-1)
#undef INT32_MAX
#define INT32_MAX (2147483647)
#undef UINT32_MAX
#define UINT32_MAX (4294967295U)
#undef INT64_MIN
#define INT64_MIN (-__INT64_C(9223372036854775807)-1)
#undef INT64_MAX
#define INT64_MAX (__INT64_C(9223372036854775807))
#undef UINT64_MAX
#define UINT64_MAX (__UINT64_C(18446744073709551615))
#endif // SANITIZER_DEFS_H

View File

@ -15,7 +15,8 @@
namespace __sanitizer {
void MiniLibcStub() {
s64 internal_atoll(const char *nptr) {
return internal_simple_strtoll(nptr, (char**)0, 10);
}
void *internal_memchr(const void *s, int c, uptr n) {
@ -99,6 +100,15 @@ uptr internal_strlen(const char *s) {
return i;
}
char *internal_strncat(char *dst, const char *src, uptr n) {
uptr len = internal_strlen(dst);
uptr i;
for (i = 0; i < n && src[i]; i++)
dst[len + i] = src[i];
dst[len + i] = 0;
return dst;
}
char *internal_strncpy(char *dst, const char *src, uptr n) {
uptr i;
for (i = 0; i < n && src[i]; i++)
@ -108,4 +118,53 @@ char *internal_strncpy(char *dst, const char *src, uptr n) {
return dst;
}
uptr internal_strnlen(const char *s, uptr maxlen) {
uptr i = 0;
while (i < maxlen && s[i]) i++;
return i;
}
char *internal_strstr(const char *haystack, const char *needle) {
// This is O(N^2), but we are not using it in hot places.
uptr len1 = internal_strlen(haystack);
uptr len2 = internal_strlen(needle);
if (len1 < len2) return 0;
for (uptr pos = 0; pos <= len1 - len2; pos++) {
if (internal_memcmp(haystack + pos, needle, len2) == 0)
return (char*)haystack + pos;
}
return 0;
}
s64 internal_simple_strtoll(const char *nptr, char **endptr, int base) {
CHECK(base == 10);
while (IsSpace(*nptr)) nptr++;
int sgn = 1;
u64 res = 0;
bool have_digits = false;
char *old_nptr = (char*)nptr;
if (*nptr == '+') {
sgn = 1;
nptr++;
} else if (*nptr == '-') {
sgn = -1;
nptr++;
}
while (IsDigit(*nptr)) {
res = (res <= UINT64_MAX / 10) ? res * 10 : UINT64_MAX;
int digit = ((*nptr) - '0');
res = (res <= UINT64_MAX - digit) ? res + digit : UINT64_MAX;
have_digits = true;
nptr++;
}
if (endptr != 0) {
*endptr = (have_digits) ? (char*)nptr : old_nptr;
}
if (sgn > 0) {
return (s64)(Min((u64)INT64_MAX, res));
} else {
return (res > INT64_MAX) ? INT64_MIN : ((s64)res * -1);
}
}
} // namespace __sanitizer

View File

@ -19,11 +19,10 @@
namespace __sanitizer {
void MiniLibcStub();
// internal_X() is a custom implementation of X() for use in RTL.
// String functions
s64 internal_atoll(const char *nptr);
void *internal_memchr(const void *s, int c, uptr n);
int internal_memcmp(const void* s1, const void* s2, uptr n);
void *internal_memcpy(void *dest, const void *src, uptr n);
@ -33,8 +32,14 @@ char* internal_strchr(const char *s, int c);
int internal_strcmp(const char *s1, const char *s2);
char *internal_strdup(const char *s);
uptr internal_strlen(const char *s);
char *internal_strncat(char *dst, const char *src, uptr n);
char *internal_strncpy(char *dst, const char *src, uptr n);
uptr internal_strnlen(const char *s, uptr maxlen);
char *internal_strrchr(const char *s, int c);
// This is O(N^2), but we are not using it in hot places.
char *internal_strstr(const char *haystack, const char *needle);
// Works only for base=10 and doesn't set errno.
s64 internal_simple_strtoll(const char *nptr, char **endptr, int base);
// Memory
void *internal_mmap(void *addr, uptr length, int prot, int flags,

View File

@ -155,7 +155,6 @@ static void InitializeMemoryFlush() {
}
void Initialize(ThreadState *thr) {
MiniLibcStub();
// Thread safe because done before all threads exist.
static bool is_initialized = false;
if (is_initialized)