1 //===-- sanitizer_libc.cc -------------------------------------------------===//
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
6 //===----------------------------------------------------------------------===//
8 // This file is shared between AddressSanitizer and ThreadSanitizer
9 // run-time libraries. See sanitizer_libc.h for details.
10 //===----------------------------------------------------------------------===//
11 #include "sanitizer_common.h"
12 #include "sanitizer_libc.h"
14 namespace __sanitizer
{
16 s64
internal_atoll(const char *nptr
) {
17 return internal_simple_strtoll(nptr
, (char**)0, 10);
20 void *internal_memchr(const void *s
, int c
, uptr n
) {
21 const char* t
= (char*)s
;
22 for (uptr i
= 0; i
< n
; ++i
, ++t
)
28 int internal_memcmp(const void* s1
, const void* s2
, uptr n
) {
29 const char* t1
= (char*)s1
;
30 const char* t2
= (char*)s2
;
31 for (uptr i
= 0; i
< n
; ++i
, ++t1
, ++t2
)
33 return *t1
< *t2
? -1 : 1;
37 void *internal_memcpy(void *dest
, const void *src
, uptr n
) {
38 char *d
= (char*)dest
;
40 for (uptr i
= 0; i
< n
; ++i
)
45 void *internal_memset(void* s
, int c
, uptr n
) {
46 // The next line prevents Clang from making a call to memset() instead of the
48 // FIXME: building the runtime with -ffreestanding is a better idea. However
49 // there currently are linktime problems due to PR12396.
50 char volatile *t
= (char*)s
;
51 for (uptr i
= 0; i
< n
; ++i
, ++t
) {
57 uptr
internal_strcspn(const char *s
, const char *reject
) {
59 for (i
= 0; s
[i
]; i
++) {
60 if (internal_strchr(reject
, s
[i
]) != 0)
66 char* internal_strdup(const char *s
) {
67 uptr len
= internal_strlen(s
);
68 char *s2
= (char*)InternalAlloc(len
+ 1);
69 internal_memcpy(s2
, s
, len
);
74 int internal_strcmp(const char *s1
, const char *s2
) {
78 if (c1
!= c2
) return (c1
< c2
) ? -1 : 1;
86 int internal_strncmp(const char *s1
, const char *s2
, uptr n
) {
87 for (uptr i
= 0; i
< n
; i
++) {
90 if (c1
!= c2
) return (c1
< c2
) ? -1 : 1;
98 char* internal_strchr(const char *s
, int c
) {
108 char *internal_strrchr(const char *s
, int c
) {
110 for (uptr i
= 0; s
[i
]; i
++) {
111 if (s
[i
] == c
) res
= s
+ i
;
116 uptr
internal_strlen(const char *s
) {
122 char *internal_strncat(char *dst
, const char *src
, uptr n
) {
123 uptr len
= internal_strlen(dst
);
125 for (i
= 0; i
< n
&& src
[i
]; i
++)
126 dst
[len
+ i
] = src
[i
];
131 char *internal_strncpy(char *dst
, const char *src
, uptr n
) {
133 for (i
= 0; i
< n
&& src
[i
]; i
++)
140 uptr
internal_strnlen(const char *s
, uptr maxlen
) {
142 while (i
< maxlen
&& s
[i
]) i
++;
146 char *internal_strstr(const char *haystack
, const char *needle
) {
147 // This is O(N^2), but we are not using it in hot places.
148 uptr len1
= internal_strlen(haystack
);
149 uptr len2
= internal_strlen(needle
);
150 if (len1
< len2
) return 0;
151 for (uptr pos
= 0; pos
<= len1
- len2
; pos
++) {
152 if (internal_memcmp(haystack
+ pos
, needle
, len2
) == 0)
153 return (char*)haystack
+ pos
;
158 s64
internal_simple_strtoll(const char *nptr
, char **endptr
, int base
) {
160 while (IsSpace(*nptr
)) nptr
++;
163 bool have_digits
= false;
164 char *old_nptr
= (char*)nptr
;
168 } else if (*nptr
== '-') {
172 while (IsDigit(*nptr
)) {
173 res
= (res
<= UINT64_MAX
/ 10) ? res
* 10 : UINT64_MAX
;
174 int digit
= ((*nptr
) - '0');
175 res
= (res
<= UINT64_MAX
- digit
) ? res
+ digit
: UINT64_MAX
;
180 *endptr
= (have_digits
) ? (char*)nptr
: old_nptr
;
183 return (s64
)(Min((u64
)INT64_MAX
, res
));
185 return (res
> INT64_MAX
) ? INT64_MIN
: ((s64
)res
* -1);
189 } // namespace __sanitizer