summaryrefslogtreecommitdiffstats
path: root/compiler-rt
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2013-11-28 14:14:48 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2013-11-28 14:14:48 +0000
commit9c1f8323ae537bf3a84a6f00ce3b15d99bacc124 (patch)
tree3afcc2b4048ce2df816e5ddf0c05d6b0dda64512 /compiler-rt
parent25ecfcf00cc1c06a3c4743b29dc0ea6749adabc1 (diff)
downloadbcm5719-llvm-9c1f8323ae537bf3a84a6f00ce3b15d99bacc124.tar.gz
bcm5719-llvm-9c1f8323ae537bf3a84a6f00ce3b15d99bacc124.zip
[sanitizer] Intercept iconv.
llvm-svn: 195917
Diffstat (limited to 'compiler-rt')
-rw-r--r--compiler-rt/lib/msan/lit_tests/iconv.cc48
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc26
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h1
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_stat.cc1
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_stat.h1
5 files changed, 77 insertions, 0 deletions
diff --git a/compiler-rt/lib/msan/lit_tests/iconv.cc b/compiler-rt/lib/msan/lit_tests/iconv.cc
new file mode 100644
index 00000000000..e7c30edd985
--- /dev/null
+++ b/compiler-rt/lib/msan/lit_tests/iconv.cc
@@ -0,0 +1,48 @@
+// RUN: %clangxx_msan -m64 -O0 -g %s -o %t && %t
+// RUN: %clangxx_msan -m64 -O0 -g -DPOSITIVE %s -o %t && not %t |& FileCheck %s
+
+#include <assert.h>
+#include <iconv.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+
+int main(void) {
+ iconv_t cd = iconv_open("ASCII", "ASCII");
+ assert(cd != (iconv_t)-1);
+
+ char inbuf_[100];
+ strcpy(inbuf_, "sample text");
+ char outbuf_[100];
+ char *inbuf = inbuf_;
+ char *outbuf = outbuf_;
+ size_t inbytesleft = strlen(inbuf_);
+ size_t outbytesleft = sizeof(outbuf_);
+
+#ifdef POSITIVE
+ {
+ char u;
+ char *volatile p = &u;
+ inbuf_[5] = *p;
+ }
+#endif
+
+ size_t res;
+ res = iconv(cd, 0, 0, 0, 0);
+ assert(res != (size_t)-1);
+
+ res = iconv(cd, 0, 0, &outbuf, &outbytesleft);
+ assert(res != (size_t)-1);
+
+ res = iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
+ // CHECK: MemorySanitizer: use-of-uninitialized-value
+ // CHECK: #0 {{.*}} in main {{.*}}iconv.cc:[[@LINE-2]]
+ assert(res != (size_t)-1);
+ assert(inbytesleft == 0);
+
+ assert(memcmp(inbuf_, outbuf_, strlen(inbuf_)) == 0);
+
+ iconv_close(cd);
+ return 0;
+}
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 1668bb0fa84..61bc06cf513 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -2853,6 +2853,31 @@ INTERCEPTOR(SSIZE_T, getdelim, char **lineptr, SIZE_T *n, int delim,
#define INIT_GETLINE
#endif
+#if SANITIZER_INTERCEPT_ICONV
+INTERCEPTOR(SIZE_T, iconv, void *cd, char **inbuf, SIZE_T *inbytesleft,
+ char **outbuf, SIZE_T *outbytesleft) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, iconv, cd, inbuf, inbytesleft, outbuf,
+ outbytesleft);
+ if (inbytesleft)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, inbytesleft, sizeof(*inbytesleft));
+ if (inbuf && inbytesleft)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, *inbuf, *inbytesleft);
+ if (outbytesleft)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, outbytesleft, sizeof(*outbytesleft));
+ void *outbuf_orig = outbuf ? *outbuf : 0;
+ SIZE_T res = REAL(iconv)(cd, inbuf, inbytesleft, outbuf, outbytesleft);
+ if (res != (SIZE_T) - 1 && outbuf && *outbuf > outbuf_orig) {
+ SIZE_T sz = (char *)*outbuf - (char *)outbuf_orig;
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, outbuf_orig, sz);
+ }
+ return res;
+}
+#define INIT_ICONV COMMON_INTERCEPT_FUNCTION(iconv);
+#else
+#define INIT_ICONV
+#endif
+
#define SANITIZER_COMMON_INTERCEPTORS_INIT \
INIT_STRCMP; \
INIT_STRNCMP; \
@@ -2963,4 +2988,5 @@ INTERCEPTOR(SSIZE_T, getdelim, char **lineptr, SIZE_T *n, int delim,
INIT_LGAMMA_R; \
INIT_DRAND48_R; \
INIT_GETLINE; \
+ INIT_ICONV; \
/**/
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
index e79b8c83e13..0db69021d22 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
@@ -158,6 +158,7 @@
# define SANITIZER_INTERCEPT_LGAMMA SI_NOT_WINDOWS
# define SANITIZER_INTERCEPT_LGAMMA_R SI_LINUX
# define SANITIZER_INTERCEPT_DRAND48_R SI_LINUX_NOT_ANDROID
+# define SANITIZER_INTERCEPT_ICONV SI_MAC || SI_LINUX_NOT_ANDROID
// FIXME: getline seems to be available on OSX 10.7
# define SANITIZER_INTERCEPT_GETLINE SI_LINUX_NOT_ANDROID
diff --git a/compiler-rt/lib/tsan/rtl/tsan_stat.cc b/compiler-rt/lib/tsan/rtl/tsan_stat.cc
index dcf28c8d49b..256ae835a11 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_stat.cc
+++ b/compiler-rt/lib/tsan/rtl/tsan_stat.cc
@@ -416,6 +416,7 @@ void StatOutput(u64 *stat) {
name[StatInt_lrand48_r] = " lrand48_r ";
name[StatInt_getline] = " getline ";
name[StatInt_getdelim] = " getdelim ";
+ name[StatInt_iconv] = " iconv ";
name[StatInt_pthread_attr_getdetachstate] = " pthread_addr_getdetachstate "; // NOLINT
name[StatInt_pthread_attr_getguardsize] = " pthread_addr_getguardsize "; // NOLINT
diff --git a/compiler-rt/lib/tsan/rtl/tsan_stat.h b/compiler-rt/lib/tsan/rtl/tsan_stat.h
index 1869c9d1fd8..afb3c22d6d5 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_stat.h
+++ b/compiler-rt/lib/tsan/rtl/tsan_stat.h
@@ -411,6 +411,7 @@ enum StatType {
StatInt_lrand48_r,
StatInt_getline,
StatInt_getdelim,
+ StatInt_iconv,
StatInt_pthread_attr_getdetachstate,
StatInt_pthread_attr_getguardsize,
OpenPOWER on IntegriCloud