summaryrefslogtreecommitdiffstats
path: root/compiler-rt/lib/asan/output_tests
diff options
context:
space:
mode:
Diffstat (limited to 'compiler-rt/lib/asan/output_tests')
-rw-r--r--compiler-rt/lib/asan/output_tests/clone_test.cc33
-rw-r--r--compiler-rt/lib/asan/output_tests/clone_test.tmpl1
-rw-r--r--compiler-rt/lib/asan/output_tests/deep_tail_call.cc13
-rw-r--r--compiler-rt/lib/asan/output_tests/deep_tail_call.tmpl6
-rw-r--r--compiler-rt/lib/asan/output_tests/dlclose-test-so.cc33
-rw-r--r--compiler-rt/lib/asan/output_tests/dlclose-test.cc73
-rw-r--r--compiler-rt/lib/asan/output_tests/dlclose-test.tmpl1
-rw-r--r--compiler-rt/lib/asan/output_tests/global-overflow.cc12
-rw-r--r--compiler-rt/lib/asan/output_tests/global-overflow.tmpl3
-rw-r--r--compiler-rt/lib/asan/output_tests/heap-overflow.cc9
-rw-r--r--compiler-rt/lib/asan/output_tests/heap-overflow.tmpl6
-rw-r--r--compiler-rt/lib/asan/output_tests/heap-overflow.tmpl.Darwin8
-rw-r--r--compiler-rt/lib/asan/output_tests/large_func_test.cc33
-rw-r--r--compiler-rt/lib/asan/output_tests/large_func_test.tmpl8
-rwxr-xr-xcompiler-rt/lib/asan/output_tests/match_output.py35
-rw-r--r--compiler-rt/lib/asan/output_tests/null_deref.cc7
-rw-r--r--compiler-rt/lib/asan/output_tests/null_deref.tmpl4
-rw-r--r--compiler-rt/lib/asan/output_tests/null_deref.tmpl.Darwin5
-rw-r--r--compiler-rt/lib/asan/output_tests/shared-lib-test-so.cc21
-rw-r--r--compiler-rt/lib/asan/output_tests/shared-lib-test.cc37
-rw-r--r--compiler-rt/lib/asan/output_tests/shared-lib-test.tmpl7
-rw-r--r--compiler-rt/lib/asan/output_tests/stack-overflow.cc7
-rw-r--r--compiler-rt/lib/asan/output_tests/stack-overflow.tmpl3
-rw-r--r--compiler-rt/lib/asan/output_tests/stack-use-after-return.cc24
-rw-r--r--compiler-rt/lib/asan/output_tests/stack-use-after-return.disabled3
-rw-r--r--compiler-rt/lib/asan/output_tests/strncpy-overflow.cc9
-rw-r--r--compiler-rt/lib/asan/output_tests/strncpy-overflow.tmpl7
-rw-r--r--compiler-rt/lib/asan/output_tests/strncpy-overflow.tmpl.Darwin9
-rwxr-xr-xcompiler-rt/lib/asan/output_tests/test_output.sh69
-rw-r--r--compiler-rt/lib/asan/output_tests/use-after-free.c9
-rw-r--r--compiler-rt/lib/asan/output_tests/use-after-free.cc6
-rw-r--r--compiler-rt/lib/asan/output_tests/use-after-free.tmpl10
-rw-r--r--compiler-rt/lib/asan/output_tests/use-after-free.tmpl.Darwin14
33 files changed, 525 insertions, 0 deletions
diff --git a/compiler-rt/lib/asan/output_tests/clone_test.cc b/compiler-rt/lib/asan/output_tests/clone_test.cc
new file mode 100644
index 00000000000..6a615acd014
--- /dev/null
+++ b/compiler-rt/lib/asan/output_tests/clone_test.cc
@@ -0,0 +1,33 @@
+#ifdef __linux__
+#include <stdio.h>
+#include <sched.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+int Child(void *arg) {
+ char x[32] = {0}; // Stack gets poisoned.
+ printf("Child: %p\n", x);
+ _exit(1); // NoReturn, stack will remain unpoisoned unless we do something.
+}
+
+int main(int argc, char **argv) {
+ const int kStackSize = 1 << 20;
+ char child_stack[kStackSize + 1];
+ char *sp = child_stack + kStackSize; // Stack grows down.
+ printf("Parent: %p\n", sp);
+ pid_t clone_pid = clone(Child, sp, CLONE_FILES | CLONE_VM, NULL, 0, 0, 0);
+ waitpid(clone_pid, NULL, 0);
+ for (int i = 0; i < kStackSize; i++)
+ child_stack[i] = i;
+ int ret = child_stack[argc - 1];
+ printf("PASSED\n");
+ return ret;
+}
+#else // not __linux__
+#include <stdio.h>
+int main() {
+ printf("PASSED\n");
+}
+#endif
diff --git a/compiler-rt/lib/asan/output_tests/clone_test.tmpl b/compiler-rt/lib/asan/output_tests/clone_test.tmpl
new file mode 100644
index 00000000000..53cdf1e9393
--- /dev/null
+++ b/compiler-rt/lib/asan/output_tests/clone_test.tmpl
@@ -0,0 +1 @@
+PASSED
diff --git a/compiler-rt/lib/asan/output_tests/deep_tail_call.cc b/compiler-rt/lib/asan/output_tests/deep_tail_call.cc
new file mode 100644
index 00000000000..bf6225e2580
--- /dev/null
+++ b/compiler-rt/lib/asan/output_tests/deep_tail_call.cc
@@ -0,0 +1,13 @@
+int global[10];
+__attribute__((noinline))
+void call4(int i) { global[i+10]++; }
+__attribute__((noinline))
+void call3(int i) { call4(i); }
+__attribute__((noinline))
+void call2(int i) { call3(i); }
+__attribute__((noinline))
+void call1(int i) { call2(i); }
+int main(int argc, char **argv) {
+ call1(argc);
+ return global[0];
+}
diff --git a/compiler-rt/lib/asan/output_tests/deep_tail_call.tmpl b/compiler-rt/lib/asan/output_tests/deep_tail_call.tmpl
new file mode 100644
index 00000000000..8a31d932232
--- /dev/null
+++ b/compiler-rt/lib/asan/output_tests/deep_tail_call.tmpl
@@ -0,0 +1,6 @@
+AddressSanitizer global-buffer-overflow
+ #0.*call4
+ #1.*call3
+ #2.*call2
+ #3.*call1
+ #4.*main
diff --git a/compiler-rt/lib/asan/output_tests/dlclose-test-so.cc b/compiler-rt/lib/asan/output_tests/dlclose-test-so.cc
new file mode 100644
index 00000000000..fae2f813abb
--- /dev/null
+++ b/compiler-rt/lib/asan/output_tests/dlclose-test-so.cc
@@ -0,0 +1,33 @@
+//===-- asan_rtl.cc ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of AddressSanitizer, an address sanity checker.
+//
+// Regression test for
+// http://code.google.com/p/address-sanitizer/issues/detail?id=19
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+
+static int pad1;
+static int static_var;
+static int pad2;
+
+extern "C"
+int *get_address_of_static_var() {
+ return &static_var;
+}
+
+__attribute__((constructor))
+void at_dlopen() {
+ printf("%s: I am being dlopened\n", __FILE__);
+}
+__attribute__((destructor))
+void at_dlclose() {
+ printf("%s: I am being dlclosed\n", __FILE__);
+}
diff --git a/compiler-rt/lib/asan/output_tests/dlclose-test.cc b/compiler-rt/lib/asan/output_tests/dlclose-test.cc
new file mode 100644
index 00000000000..307886667b1
--- /dev/null
+++ b/compiler-rt/lib/asan/output_tests/dlclose-test.cc
@@ -0,0 +1,73 @@
+//===-- asan_rtl.cc ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of AddressSanitizer, an address sanity checker.
+//
+// Regression test for
+// http://code.google.com/p/address-sanitizer/issues/detail?id=19
+// Bug description:
+// 1. application dlopens foo.so
+// 2. asan registers all globals from foo.so
+// 3. application dlcloses foo.so
+// 4. application mmaps some memory to the location where foo.so was before
+// 5. application starts using this mmaped memory, but asan still thinks there
+// are globals.
+// 6. BOOM
+//===----------------------------------------------------------------------===//
+#include <assert.h>
+#include <dlfcn.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/mman.h>
+
+#include <string>
+
+using std::string;
+
+static const int kPageSize = 4096;
+
+typedef int *(fun_t)();
+
+int main(int argc, char *argv[]) {
+ string path = string(argv[0]) + "-so.so";
+ printf("opening %s ... \n", path.c_str());
+ void *lib = dlopen(path.c_str(), RTLD_NOW);
+ if (!lib) {
+ printf("error in dlopen(): %s\n", dlerror());
+ return 1;
+ }
+ fun_t *get = (fun_t*)dlsym(lib, "get_address_of_static_var");
+ if (!get) {
+ printf("failed dlsym\n");
+ return 1;
+ }
+ int *addr = get();
+ assert(((size_t)addr % 32) == 0); // should be 32-byte aligned.
+ printf("addr: %p\n", addr);
+ addr[0] = 1; // make sure we can write there.
+
+ // Now dlclose the shared library.
+ printf("attempting to dlclose\n");
+ if (dlclose(lib)) {
+ printf("failed to dlclose\n");
+ return 1;
+ }
+ // Now, the page where 'addr' is unmapped. Map it.
+ size_t page_beg = ((size_t)addr) & ~(kPageSize - 1);
+ void *res = mmap((void*)(page_beg), kPageSize,
+ PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANON | MAP_FIXED | MAP_NORESERVE, 0, 0);
+ if (res == (char*)-1L) {
+ printf("failed to mmap\n");
+ return 1;
+ }
+ addr[1] = 2; // BOOM (if the bug is not fixed).
+ printf("PASS\n");
+ return 0;
+}
diff --git a/compiler-rt/lib/asan/output_tests/dlclose-test.tmpl b/compiler-rt/lib/asan/output_tests/dlclose-test.tmpl
new file mode 100644
index 00000000000..7ef22e9a431
--- /dev/null
+++ b/compiler-rt/lib/asan/output_tests/dlclose-test.tmpl
@@ -0,0 +1 @@
+PASS
diff --git a/compiler-rt/lib/asan/output_tests/global-overflow.cc b/compiler-rt/lib/asan/output_tests/global-overflow.cc
new file mode 100644
index 00000000000..b85c4d2a18b
--- /dev/null
+++ b/compiler-rt/lib/asan/output_tests/global-overflow.cc
@@ -0,0 +1,12 @@
+#include <string.h>
+int main(int argc, char **argv) {
+ static char XXX[10];
+ static char YYY[10];
+ static char ZZZ[10];
+ memset(XXX, 0, 10);
+ memset(YYY, 0, 10);
+ memset(ZZZ, 0, 10);
+ int res = YYY[argc * 10]; // BOOOM
+ res += XXX[argc] + ZZZ[argc];
+ return res;
+}
diff --git a/compiler-rt/lib/asan/output_tests/global-overflow.tmpl b/compiler-rt/lib/asan/output_tests/global-overflow.tmpl
new file mode 100644
index 00000000000..c5d54428143
--- /dev/null
+++ b/compiler-rt/lib/asan/output_tests/global-overflow.tmpl
@@ -0,0 +1,3 @@
+READ of size 1 at 0x.* thread T0
+ #0 0x.* in main .*global-overflow.cc:9
+0x.* is located 0 bytes to the right of global variable .*YYY.* of size 10
diff --git a/compiler-rt/lib/asan/output_tests/heap-overflow.cc b/compiler-rt/lib/asan/output_tests/heap-overflow.cc
new file mode 100644
index 00000000000..475d1637385
--- /dev/null
+++ b/compiler-rt/lib/asan/output_tests/heap-overflow.cc
@@ -0,0 +1,9 @@
+#include <stdlib.h>
+#include <string.h>
+int main(int argc, char **argv) {
+ char *x = (char*)malloc(10 * sizeof(char));
+ memset(x, 0, 10);
+ int res = x[argc * 10]; // BOOOM
+ free(x);
+ return res;
+}
diff --git a/compiler-rt/lib/asan/output_tests/heap-overflow.tmpl b/compiler-rt/lib/asan/output_tests/heap-overflow.tmpl
new file mode 100644
index 00000000000..e2ab65f17d8
--- /dev/null
+++ b/compiler-rt/lib/asan/output_tests/heap-overflow.tmpl
@@ -0,0 +1,6 @@
+READ of size 1 at 0x.* thread T0
+ #0 0x.* in main .*heap-overflow.cc:6
+0x.* is located 0 bytes to the right of 10-byte region
+allocated by thread T0 here:
+ #0 0x.* in malloc
+ #1 0x.* in main .*heap-overflow.cc:[45]
diff --git a/compiler-rt/lib/asan/output_tests/heap-overflow.tmpl.Darwin b/compiler-rt/lib/asan/output_tests/heap-overflow.tmpl.Darwin
new file mode 100644
index 00000000000..cb76269d7f7
--- /dev/null
+++ b/compiler-rt/lib/asan/output_tests/heap-overflow.tmpl.Darwin
@@ -0,0 +1,8 @@
+READ of size 1 at 0x.* thread T0
+ #0 0x.* in main .*heap-overflow.cc:6
+0x.* is located 0 bytes to the right of 10-byte region
+allocated by thread T0 here:
+ #0 0x.* in .*mz_malloc.*
+ #1 0x.* in malloc_zone_malloc.*
+ #2 0x.* in malloc.*
+ #3 0x.* in main heap-overflow.cc:[45]
diff --git a/compiler-rt/lib/asan/output_tests/large_func_test.cc b/compiler-rt/lib/asan/output_tests/large_func_test.cc
new file mode 100644
index 00000000000..70bc36f40b8
--- /dev/null
+++ b/compiler-rt/lib/asan/output_tests/large_func_test.cc
@@ -0,0 +1,33 @@
+#include <stdlib.h>
+__attribute__((noinline))
+static void LargeFunction(int *x, int zero) {
+ x[0]++;
+ x[1]++;
+ x[2]++;
+ x[3]++;
+ x[4]++;
+ x[5]++;
+ x[6]++;
+ x[7]++;
+ x[8]++;
+ x[9]++;
+
+ x[zero + 111]++; // we should report this exact line
+
+ x[10]++;
+ x[11]++;
+ x[12]++;
+ x[13]++;
+ x[14]++;
+ x[15]++;
+ x[16]++;
+ x[17]++;
+ x[18]++;
+ x[19]++;
+}
+
+int main(int argc, char **argv) {
+ int *x = new int[100];
+ LargeFunction(x, argc - 1);
+ delete x;
+}
diff --git a/compiler-rt/lib/asan/output_tests/large_func_test.tmpl b/compiler-rt/lib/asan/output_tests/large_func_test.tmpl
new file mode 100644
index 00000000000..45a13d0bc5b
--- /dev/null
+++ b/compiler-rt/lib/asan/output_tests/large_func_test.tmpl
@@ -0,0 +1,8 @@
+.*ERROR: AddressSanitizer heap-buffer-overflow on address 0x.* at pc 0x.* bp 0x.* sp 0x.*
+READ of size 4 at 0x.* thread T0
+ #0 0x.* in LargeFunction .*large_func_test.cc:15
+ #1 0x.* in main .*large_func_test.cc:3[012]
+0x.* is located 44 bytes to the right of 400-byte region
+allocated by thread T0 here:
+ #0 0x.* in operator new.*
+ #1 0x.* in main .*large_func_test.cc:30
diff --git a/compiler-rt/lib/asan/output_tests/match_output.py b/compiler-rt/lib/asan/output_tests/match_output.py
new file mode 100755
index 00000000000..31095f3f62f
--- /dev/null
+++ b/compiler-rt/lib/asan/output_tests/match_output.py
@@ -0,0 +1,35 @@
+#!/usr/bin/python
+
+import re
+import sys
+
+def matchFile(f, f_re):
+ for line_re in f_re:
+ line_re = line_re.rstrip()
+ if not line_re:
+ continue
+ if line_re[0] == '#':
+ continue
+ match = False
+ for line in f:
+ line = line.rstrip()
+ # print line
+ if re.search(line_re, line):
+ match = True
+ #print 'match: %s =~ %s' % (line, line_re)
+ break
+ if not match:
+ print 'no match for: %s' % (line_re)
+ return False
+ return True
+
+if len(sys.argv) != 2:
+ print >>sys.stderr, 'Usage: %s <template file>'
+ sys.exit(1)
+
+f = sys.stdin
+f_re = open(sys.argv[1])
+
+if not matchFile(f, f_re):
+ print >>sys.stderr, 'File does not match the template'
+ sys.exit(1)
diff --git a/compiler-rt/lib/asan/output_tests/null_deref.cc b/compiler-rt/lib/asan/output_tests/null_deref.cc
new file mode 100644
index 00000000000..f7ba4dd5f63
--- /dev/null
+++ b/compiler-rt/lib/asan/output_tests/null_deref.cc
@@ -0,0 +1,7 @@
+__attribute__((noinline))
+static void NullDeref(int *ptr) {
+ ptr[10]++;
+}
+int main() {
+ NullDeref((int*)0);
+}
diff --git a/compiler-rt/lib/asan/output_tests/null_deref.tmpl b/compiler-rt/lib/asan/output_tests/null_deref.tmpl
new file mode 100644
index 00000000000..d27cccc06bc
--- /dev/null
+++ b/compiler-rt/lib/asan/output_tests/null_deref.tmpl
@@ -0,0 +1,4 @@
+.*ERROR: AddressSanitizer crashed on unknown address 0x0*00028 .*pc 0x.*
+AddressSanitizer can not provide additional info. ABORTING
+ #0 0x.* in NullDeref.*null_deref.cc:3
+ #1 0x.* in main.*null_deref.cc:[67]
diff --git a/compiler-rt/lib/asan/output_tests/null_deref.tmpl.Darwin b/compiler-rt/lib/asan/output_tests/null_deref.tmpl.Darwin
new file mode 100644
index 00000000000..8c121431ec5
--- /dev/null
+++ b/compiler-rt/lib/asan/output_tests/null_deref.tmpl.Darwin
@@ -0,0 +1,5 @@
+.*ERROR: AddressSanitizer crashed on unknown address 0x0*00028 .*pc 0x.*
+AddressSanitizer can not provide additional info. ABORTING
+# atos cannot resolve the file:line info for frame 0 on the O1 level
+ #0 0x.* in NullDeref.*
+ #1 0x.* in main.*null_deref.cc:[67]
diff --git a/compiler-rt/lib/asan/output_tests/shared-lib-test-so.cc b/compiler-rt/lib/asan/output_tests/shared-lib-test-so.cc
new file mode 100644
index 00000000000..c3b3bc22aed
--- /dev/null
+++ b/compiler-rt/lib/asan/output_tests/shared-lib-test-so.cc
@@ -0,0 +1,21 @@
+//===-- asan_rtl.cc ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of AddressSanitizer, an address sanity checker.
+//
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+
+int pad[10];
+int GLOB[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+extern "C"
+void inc(int index) {
+ GLOB[index]++;
+}
diff --git a/compiler-rt/lib/asan/output_tests/shared-lib-test.cc b/compiler-rt/lib/asan/output_tests/shared-lib-test.cc
new file mode 100644
index 00000000000..e492572c728
--- /dev/null
+++ b/compiler-rt/lib/asan/output_tests/shared-lib-test.cc
@@ -0,0 +1,37 @@
+//===-- asan_rtl.cc ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of AddressSanitizer, an address sanity checker.
+//
+//===----------------------------------------------------------------------===//
+#include <dlfcn.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <string>
+
+using std::string;
+
+typedef void (fun_t)(int x);
+
+int main(int argc, char *argv[]) {
+ string path = string(argv[0]) + "-so.so";
+ printf("opening %s ... \n", path.c_str());
+ void *lib = dlopen(path.c_str(), RTLD_NOW);
+ if (!lib) {
+ printf("error in dlopen(): %s\n", dlerror());
+ return 1;
+ }
+ fun_t *inc = (fun_t*)dlsym(lib, "inc");
+ if (!inc) return 1;
+ printf("ok\n");
+ inc(1);
+ inc(-1);
+ return 0;
+}
diff --git a/compiler-rt/lib/asan/output_tests/shared-lib-test.tmpl b/compiler-rt/lib/asan/output_tests/shared-lib-test.tmpl
new file mode 100644
index 00000000000..564e3eb5cb8
--- /dev/null
+++ b/compiler-rt/lib/asan/output_tests/shared-lib-test.tmpl
@@ -0,0 +1,7 @@
+#.*ERROR: AddressSanitizer global-buffer-overflow on address 0x.* at pc 0x.* bp 0x.* sp 0x.*
+#READ of size 4 at 0x.* thread T0
+# #0 0x.* in inc .*shared-lib-test-so.cc:11
+# #1 0x.* in main .*shared-lib-test.cc:33
+# #2 0x.* in __libc_start_main.*
+#0x.* is located 4 bytes to the left of global variable 'GLOB' (.*) of size 40
+#0x.* is located 52 bytes to the right of global variable 'pad' (.*) of size 40
diff --git a/compiler-rt/lib/asan/output_tests/stack-overflow.cc b/compiler-rt/lib/asan/output_tests/stack-overflow.cc
new file mode 100644
index 00000000000..dd86aa32514
--- /dev/null
+++ b/compiler-rt/lib/asan/output_tests/stack-overflow.cc
@@ -0,0 +1,7 @@
+#include <string.h>
+int main(int argc, char **argv) {
+ char x[10];
+ memset(x, 0, 10);
+ int res = x[argc * 10]; // BOOOM
+ return res;
+}
diff --git a/compiler-rt/lib/asan/output_tests/stack-overflow.tmpl b/compiler-rt/lib/asan/output_tests/stack-overflow.tmpl
new file mode 100644
index 00000000000..6aa717a82b2
--- /dev/null
+++ b/compiler-rt/lib/asan/output_tests/stack-overflow.tmpl
@@ -0,0 +1,3 @@
+READ of size 1 at 0x.* thread T0
+ #0 0x.* in main .*stack-overflow.cc:5
+Address 0x.* is .* frame <main>
diff --git a/compiler-rt/lib/asan/output_tests/stack-use-after-return.cc b/compiler-rt/lib/asan/output_tests/stack-use-after-return.cc
new file mode 100644
index 00000000000..9098edf0adb
--- /dev/null
+++ b/compiler-rt/lib/asan/output_tests/stack-use-after-return.cc
@@ -0,0 +1,24 @@
+#include <stdio.h>
+
+__attribute__((noinline))
+char *Ident(char *x) {
+ fprintf(stderr, "1: %p\n", x);
+ return x;
+}
+
+__attribute__((noinline))
+char *Func1() {
+ char local;
+ return Ident(&local);
+}
+
+__attribute__((noinline))
+void Func2(char *x) {
+ fprintf(stderr, "2: %p\n", x);
+ *x = 1;
+}
+
+int main(int argc, char **argv) {
+ Func2(Func1());
+ return 0;
+}
diff --git a/compiler-rt/lib/asan/output_tests/stack-use-after-return.disabled b/compiler-rt/lib/asan/output_tests/stack-use-after-return.disabled
new file mode 100644
index 00000000000..02729bc43a7
--- /dev/null
+++ b/compiler-rt/lib/asan/output_tests/stack-use-after-return.disabled
@@ -0,0 +1,3 @@
+WRITE of size 1 .* thread T0
+#0.*Func2.*stack-use-after-return.cc:18
+is located in frame <.*Func1.*> of T0's stack
diff --git a/compiler-rt/lib/asan/output_tests/strncpy-overflow.cc b/compiler-rt/lib/asan/output_tests/strncpy-overflow.cc
new file mode 100644
index 00000000000..044f6494bfa
--- /dev/null
+++ b/compiler-rt/lib/asan/output_tests/strncpy-overflow.cc
@@ -0,0 +1,9 @@
+#include <string.h>
+#include <stdlib.h>
+int main(int argc, char **argv) {
+ char *hello = (char*)malloc(6);
+ strcpy(hello, "hello");
+ char *short_buffer = (char*)malloc(9);
+ strncpy(short_buffer, hello, 10); // BOOM
+ return short_buffer[8];
+}
diff --git a/compiler-rt/lib/asan/output_tests/strncpy-overflow.tmpl b/compiler-rt/lib/asan/output_tests/strncpy-overflow.tmpl
new file mode 100644
index 00000000000..3780aa81921
--- /dev/null
+++ b/compiler-rt/lib/asan/output_tests/strncpy-overflow.tmpl
@@ -0,0 +1,7 @@
+WRITE of size 1 at 0x.* thread T0
+ #0 0x.* in strncpy
+ #1 0x.* in main .*strncpy-overflow.cc:[78]
+0x.* is located 0 bytes to the right of 9-byte region
+allocated by thread T0 here:
+ #0 0x.* in malloc
+ #1 0x.* in main .*strncpy-overflow.cc:6
diff --git a/compiler-rt/lib/asan/output_tests/strncpy-overflow.tmpl.Darwin b/compiler-rt/lib/asan/output_tests/strncpy-overflow.tmpl.Darwin
new file mode 100644
index 00000000000..80919e6c519
--- /dev/null
+++ b/compiler-rt/lib/asan/output_tests/strncpy-overflow.tmpl.Darwin
@@ -0,0 +1,9 @@
+WRITE of size 1 at 0x.* thread T0
+ #0 0x.* in wrap_strncpy
+ #1 0x.* in main .*strncpy-overflow.cc:[78]
+0x.* is located 0 bytes to the right of 9-byte region
+allocated by thread T0 here:
+ #0 0x.* in .*mz_malloc.*
+ #1 0x.* in malloc_zone_malloc.*
+ #2 0x.* in malloc.*
+ #3 0x.* in main .*strncpy-overflow.cc:6
diff --git a/compiler-rt/lib/asan/output_tests/test_output.sh b/compiler-rt/lib/asan/output_tests/test_output.sh
new file mode 100755
index 00000000000..f619244b46b
--- /dev/null
+++ b/compiler-rt/lib/asan/output_tests/test_output.sh
@@ -0,0 +1,69 @@
+#!/bin/bash
+
+set -e # fail on any error
+
+OS=`uname`
+CXX=$1
+CC=$2
+CXXFLAGS="-mno-omit-leaf-frame-pointer -fno-omit-frame-pointer -fno-optimize-sibling-calls"
+SYMBOLIZER=../scripts/asan_symbolize.py
+FILE_CHECK=../../../../../build/Release+Asserts/bin/FileCheck
+
+# check_program exe_file src_file [check_prefix]
+check_program() {
+ exe=$1
+ src=$2
+ prefix="CHECK"
+ if [ "z$3" != "z" ] ; then
+ prefix=$3
+ fi
+ ./$exe 2>&1 | $SYMBOLIZER 2> /dev/null | c++filt | \
+ $FILE_CHECK $src --check-prefix=$prefix
+}
+
+C_TEST=use-after-free
+echo "Sanity checking a test in pure C"
+$CC -g -faddress-sanitizer -O2 $C_TEST.c
+check_program a.out $C_TEST.c
+rm ./a.out
+
+echo "Sanity checking a test in pure C with -pie"
+$CC -g -faddress-sanitizer -O2 $C_TEST.c -pie
+check_program a.out $C_TEST.c
+rm ./a.out
+
+echo "Testing sleep_before_dying"
+$CC -g -faddress-sanitizer -O2 $C_TEST.c
+export ASAN_OPTIONS="sleep_before_dying=1"
+check_program a.out $C_TEST.c CHECKSLEEP
+export ASAN_OPTIONS=""
+rm ./a.out
+
+for t in *.tmpl; do
+ for b in 32 64; do
+ for O in 0 1 2 3; do
+ c=`basename $t .tmpl`
+ c_so=$c-so
+ exe=$c.$b.O$O
+ so=$c.$b.O$O-so.so
+ echo testing $exe
+ build_command="$CXX $CXXFLAGS -g -m$b -faddress-sanitizer -O$O $c.cc -o $exe"
+ [ "$DEBUG" == "1" ] && echo $build_command
+ $build_command
+ [ -e "$c_so.cc" ] && $CXX $CXXFLAGS -g -m$b -faddress-sanitizer -O$O $c_so.cc -fPIC -shared -o $so
+ # If there's an OS-specific template, use it.
+ # Please minimize the use of OS-specific templates.
+ if [ -e "$t.$OS" ]
+ then
+ actual_t="$t.$OS"
+ else
+ actual_t="$t"
+ fi
+ ./$exe 2>&1 | $SYMBOLIZER 2> /dev/null | c++filt | ./match_output.py $actual_t
+ rm ./$exe
+ [ -e "$so" ] && rm ./$so
+ done
+ done
+done
+
+exit 0
diff --git a/compiler-rt/lib/asan/output_tests/use-after-free.c b/compiler-rt/lib/asan/output_tests/use-after-free.c
new file mode 100644
index 00000000000..801d3f68a46
--- /dev/null
+++ b/compiler-rt/lib/asan/output_tests/use-after-free.c
@@ -0,0 +1,9 @@
+#include <stdlib.h>
+int main() {
+ char *x = (char*)malloc(10 * sizeof(char));
+ free(x);
+ return x[5];
+}
+
+// CHECK: heap-use-after-free
+// CHECKSLEEP: Sleeping for 1 second
diff --git a/compiler-rt/lib/asan/output_tests/use-after-free.cc b/compiler-rt/lib/asan/output_tests/use-after-free.cc
new file mode 100644
index 00000000000..60626bff778
--- /dev/null
+++ b/compiler-rt/lib/asan/output_tests/use-after-free.cc
@@ -0,0 +1,6 @@
+#include <stdlib.h>
+int main() {
+ char *x = (char*)malloc(10 * sizeof(char));
+ free(x);
+ return x[5];
+}
diff --git a/compiler-rt/lib/asan/output_tests/use-after-free.tmpl b/compiler-rt/lib/asan/output_tests/use-after-free.tmpl
new file mode 100644
index 00000000000..c4b5c74d988
--- /dev/null
+++ b/compiler-rt/lib/asan/output_tests/use-after-free.tmpl
@@ -0,0 +1,10 @@
+.*ERROR: AddressSanitizer heap-use-after-free on address 0x.* at pc 0x.* bp 0x.* sp 0x.*
+READ of size 1 at 0x.* thread T0
+ #0 0x.* in main .*use-after-free.cc:5
+0x.* is located 5 bytes inside of 10-byte region .0x.*,0x.*
+freed by thread T0 here:
+ #0 0x.* in free
+ #1 0x.* in main .*use-after-free.cc:[45]
+previously allocated by thread T0 here:
+ #0 0x.* in malloc
+ #1 0x.* in main .*use-after-free.cc:3
diff --git a/compiler-rt/lib/asan/output_tests/use-after-free.tmpl.Darwin b/compiler-rt/lib/asan/output_tests/use-after-free.tmpl.Darwin
new file mode 100644
index 00000000000..f4f66cd8e18
--- /dev/null
+++ b/compiler-rt/lib/asan/output_tests/use-after-free.tmpl.Darwin
@@ -0,0 +1,14 @@
+.*ERROR: AddressSanitizer heap-use-after-free on address 0x.* at pc 0x.* bp 0x.* sp 0x.*
+READ of size 1 at 0x.* thread T0
+ #0 0x.* in main .*use-after-free.cc:5
+0x.* is located 5 bytes inside of 10-byte region .0x.*,0x.*
+freed by thread T0 here:
+ #0 0x.* in .*mz_free.*
+# We override free() on Darwin, thus no malloc_zone_free
+ #1 0x.* in free
+ #2 0x.* in main .*use-after-free.cc:[45]
+previously allocated by thread T0 here:
+ #0 0x.* in .*mz_malloc.*
+ #1 0x.* in malloc_zone_malloc.*
+ #2 0x.* in malloc.*
+ #3 0x.* in main .*use-after-free.cc:3
OpenPOWER on IntegriCloud