forked from OSchip/llvm-project
[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:
parent
3efd6fc26c
commit
156958dd0c
|
@ -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);
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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__)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue