msan_test.cc revision e03345ba3da0450f7ff1410de6a2a00fd304089d
1//===-- msan_test.cc ------------------------------------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file is a part of MemorySanitizer.
11//
12// MemorySanitizer unit tests.
13//===----------------------------------------------------------------------===//
14
15#include "sanitizer/msan_interface.h"
16#include "msandr_test_so.h"
17#include "gtest/gtest.h"
18
19#include <stdlib.h>
20#include <stdarg.h>
21#include <stdio.h>
22#include <assert.h>
23#include <wchar.h>
24
25#include <dlfcn.h>
26#include <unistd.h>
27#include <limits.h>
28#include <sys/time.h>
29#include <sys/types.h>
30#include <sys/stat.h>
31#include <fcntl.h>
32#include <sys/resource.h>
33#include <sys/ioctl.h>
34#include <sys/utsname.h>
35#include <sys/mman.h>
36#include <sys/vfs.h>
37
38#if defined(__i386__) || defined(__x86_64__)
39# include <emmintrin.h>
40# define MSAN_HAS_M128 1
41#else
42# define MSAN_HAS_M128 0
43#endif
44
45typedef unsigned char      U1;
46typedef unsigned short     U2;  // NOLINT
47typedef unsigned int       U4;
48typedef unsigned long long U8;  // NOLINT
49typedef   signed char      S1;
50typedef   signed short     S2;  // NOLINT
51typedef   signed int       S4;
52typedef   signed long long S8;  // NOLINT
53#define NOINLINE      __attribute__((noinline))
54#define INLINE      __attribute__((always_inline))
55
56
57#define EXPECT_POISONED(action) \
58    do {                        \
59      __msan_set_expect_umr(1); \
60      action;                   \
61      __msan_set_expect_umr(0); \
62    } while (0)
63
64#define EXPECT_POISONED_O(action, origin) \
65    do {                                            \
66      __msan_set_expect_umr(1);                     \
67      action;                                       \
68      __msan_set_expect_umr(0);                     \
69      if (TrackingOrigins())                        \
70        EXPECT_EQ(origin, __msan_get_origin_tls()); \
71    } while (0)
72
73#define EXPECT_POISONED_S(action, stack_origin) \
74    do {                                            \
75      __msan_set_expect_umr(1);                     \
76      action;                                       \
77      __msan_set_expect_umr(0);                     \
78      u32 id = __msan_get_origin_tls();             \
79      const char *str = __msan_get_origin_descr_if_stack(id); \
80      if (!str || strcmp(str, stack_origin)) {      \
81        fprintf(stderr, "EXPECT_POISONED_S: id=%u %s, %s", \
82                id, stack_origin, str);  \
83        EXPECT_EQ(1, 0);                            \
84      }                                             \
85    } while (0)
86
87
88static U8 poisoned_array[100];
89template<class T>
90T *GetPoisoned(int i = 0, T val = 0) {
91  T *res = (T*)&poisoned_array[i];
92  *res = val;
93  __msan_poison(&poisoned_array[i], sizeof(T));
94  return res;
95}
96
97template<class T>
98T *GetPoisonedO(int i, u32 origin, T val = 0) {
99  T *res = (T*)&poisoned_array[i];
100  *res = val;
101  __msan_poison(&poisoned_array[i], sizeof(T));
102  __msan_set_origin(&poisoned_array[i], sizeof(T), origin);
103  return res;
104}
105
106// This function returns its parameter but in such a way that compiler
107// can not prove it.
108template<class T>
109NOINLINE
110static T Ident(T t) {
111  volatile T ret = t;
112  return ret;
113}
114
115static bool TrackingOrigins() {
116  S8 x;
117  __msan_set_origin(&x, sizeof(x), 0x1234);
118  u32 origin = __msan_get_origin(&x);
119  __msan_set_origin(&x, sizeof(x), 0);
120  return origin == 0x1234;
121}
122
123template<class T> NOINLINE T ReturnPoisoned() { return *GetPoisoned<T>(); }
124
125static volatile S1 v_s1;
126static volatile S2 v_s2;
127static volatile S4 v_s4;
128static volatile S8 v_s8;
129static volatile U1 v_u1;
130static volatile U2 v_u2;
131static volatile U4 v_u4;
132static volatile U8 v_u8;
133static void* volatile v_p;
134static volatile double v_d;
135static volatile int g_one = 1;
136static volatile int g_zero = 0;
137static volatile int g_0 = 0;
138static volatile int g_1 = 1;
139
140#if MSAN_HAS_M128
141static volatile __m128i v_m128;
142#endif
143
144S4 a_s4[100];
145S8 a_s8[100];
146
147TEST(MemorySanitizer, NegativeTest1) {
148  S4 *x = GetPoisoned<S4>();
149  if (g_one)
150    *x = 0;
151  v_s4 = *x;
152}
153
154TEST(MemorySanitizer, PositiveTest1) {
155  // Load to store.
156  EXPECT_POISONED(v_s1 = *GetPoisoned<S1>());
157  EXPECT_POISONED(v_s2 = *GetPoisoned<S2>());
158  EXPECT_POISONED(v_s4 = *GetPoisoned<S4>());
159  EXPECT_POISONED(v_s8 = *GetPoisoned<S8>());
160
161  // S->S conversions.
162  EXPECT_POISONED(v_s2 = *GetPoisoned<S1>());
163  EXPECT_POISONED(v_s4 = *GetPoisoned<S1>());
164  EXPECT_POISONED(v_s8 = *GetPoisoned<S1>());
165
166  EXPECT_POISONED(v_s1 = *GetPoisoned<S2>());
167  EXPECT_POISONED(v_s4 = *GetPoisoned<S2>());
168  EXPECT_POISONED(v_s8 = *GetPoisoned<S2>());
169
170  EXPECT_POISONED(v_s1 = *GetPoisoned<S4>());
171  EXPECT_POISONED(v_s2 = *GetPoisoned<S4>());
172  EXPECT_POISONED(v_s8 = *GetPoisoned<S4>());
173
174  EXPECT_POISONED(v_s1 = *GetPoisoned<S8>());
175  EXPECT_POISONED(v_s2 = *GetPoisoned<S8>());
176  EXPECT_POISONED(v_s4 = *GetPoisoned<S8>());
177
178  // ZExt
179  EXPECT_POISONED(v_s2 = *GetPoisoned<U1>());
180  EXPECT_POISONED(v_s4 = *GetPoisoned<U1>());
181  EXPECT_POISONED(v_s8 = *GetPoisoned<U1>());
182  EXPECT_POISONED(v_s4 = *GetPoisoned<U2>());
183  EXPECT_POISONED(v_s8 = *GetPoisoned<U2>());
184  EXPECT_POISONED(v_s8 = *GetPoisoned<U4>());
185
186  // Unary ops.
187  EXPECT_POISONED(v_s4 = - *GetPoisoned<S4>());
188
189  EXPECT_POISONED(a_s4[g_zero] = 100 / *GetPoisoned<S4>(0, 1));
190
191
192  a_s4[g_zero] = 1 - *GetPoisoned<S4>();
193  a_s4[g_zero] = 1 + *GetPoisoned<S4>();
194}
195
196TEST(MemorySanitizer, Phi1) {
197  S4 c;
198  if (g_one) {
199    c = *GetPoisoned<S4>();
200  } else {
201    __msan_break_optimization(0);
202    c = 0;
203  }
204  EXPECT_POISONED(v_s4 = c);
205}
206
207TEST(MemorySanitizer, Phi2) {
208  S4 i = *GetPoisoned<S4>();
209  S4 n = g_one;
210  EXPECT_POISONED(for (; i < g_one; i++););
211  EXPECT_POISONED(v_s4 = i);
212}
213
214NOINLINE void Arg1ExpectUMR(S4 a1) { EXPECT_POISONED(v_s4 = a1); }
215NOINLINE void Arg2ExpectUMR(S4 a1, S4 a2) { EXPECT_POISONED(v_s4 = a2); }
216NOINLINE void Arg3ExpectUMR(S1 a1, S4 a2, S8 a3) { EXPECT_POISONED(v_s8 = a3); }
217
218TEST(MemorySanitizer, ArgTest) {
219  Arg1ExpectUMR(*GetPoisoned<S4>());
220  Arg2ExpectUMR(0, *GetPoisoned<S4>());
221  Arg3ExpectUMR(0, 1, *GetPoisoned<S8>());
222}
223
224
225TEST(MemorySanitizer, CallAndRet) {
226  if (!__msan_has_dynamic_component()) return;
227  ReturnPoisoned<S1>();
228  ReturnPoisoned<S2>();
229  ReturnPoisoned<S4>();
230  ReturnPoisoned<S8>();
231
232  EXPECT_POISONED(v_s1 = ReturnPoisoned<S1>());
233  EXPECT_POISONED(v_s2 = ReturnPoisoned<S2>());
234  EXPECT_POISONED(v_s4 = ReturnPoisoned<S4>());
235  EXPECT_POISONED(v_s8 = ReturnPoisoned<S8>());
236}
237
238// malloc() in the following test may be optimized to produce a compile-time
239// undef value. Check that we trap on the volatile assignment anyway.
240TEST(MemorySanitizer, DISABLED_MallocNoIdent) {
241  S4 *x = (int*)malloc(sizeof(S4));
242  EXPECT_POISONED(v_s4 = *x);
243  free(x);
244}
245
246TEST(MemorySanitizer, Malloc) {
247  S4 *x = (int*)Ident(malloc(sizeof(S4)));
248  EXPECT_POISONED(v_s4 = *x);
249  free(x);
250}
251
252TEST(MemorySanitizer, Realloc) {
253  S4 *x = (int*)Ident(realloc(0, sizeof(S4)));
254  EXPECT_POISONED(v_s4 = x[0]);
255  x[0] = 1;
256  x = (int*)Ident(realloc(x, 2 * sizeof(S4)));
257  v_s4 = x[0];  // Ok, was inited before.
258  EXPECT_POISONED(v_s4 = x[1]);
259  x = (int*)Ident(realloc(x, 3 * sizeof(S4)));
260  v_s4 = x[0];  // Ok, was inited before.
261  EXPECT_POISONED(v_s4 = x[2]);
262  EXPECT_POISONED(v_s4 = x[1]);
263  x[2] = 1;  // Init this here. Check that after realloc it is poisoned again.
264  x = (int*)Ident(realloc(x, 2 * sizeof(S4)));
265  v_s4 = x[0];  // Ok, was inited before.
266  EXPECT_POISONED(v_s4 = x[1]);
267  x = (int*)Ident(realloc(x, 3 * sizeof(S4)));
268  EXPECT_POISONED(v_s4 = x[1]);
269  EXPECT_POISONED(v_s4 = x[2]);
270  free(x);
271}
272
273TEST(MemorySanitizer, Calloc) {
274  S4 *x = (int*)Ident(calloc(1, sizeof(S4)));
275  v_s4 = *x;  // Should not be poisoned.
276  // EXPECT_EQ(0, *x);
277  free(x);
278}
279
280TEST(MemorySanitizer, AndOr) {
281  U4 *p = GetPoisoned<U4>();
282  // We poison two bytes in the midle of a 4-byte word to make the test
283  // correct regardless of endianness.
284  ((U1*)p)[1] = 0;
285  ((U1*)p)[2] = 0xff;
286  v_u4 = *p & 0x00ffff00;
287  v_u4 = *p & 0x00ff0000;
288  v_u4 = *p & 0x0000ff00;
289  EXPECT_POISONED(v_u4 = *p & 0xff000000);
290  EXPECT_POISONED(v_u4 = *p & 0x000000ff);
291  EXPECT_POISONED(v_u4 = *p & 0x0000ffff);
292  EXPECT_POISONED(v_u4 = *p & 0xffff0000);
293
294  v_u4 = *p | 0xff0000ff;
295  v_u4 = *p | 0xff00ffff;
296  v_u4 = *p | 0xffff00ff;
297  EXPECT_POISONED(v_u4 = *p | 0xff000000);
298  EXPECT_POISONED(v_u4 = *p | 0x000000ff);
299  EXPECT_POISONED(v_u4 = *p | 0x0000ffff);
300  EXPECT_POISONED(v_u4 = *p | 0xffff0000);
301
302  EXPECT_POISONED(v_u4 = *GetPoisoned<bool>() & *GetPoisoned<bool>());
303}
304
305template<class T>
306static void testNot(T value, T shadow) {
307  __msan_partial_poison(&value, &shadow, sizeof(T));
308  volatile bool v_T = !value;
309}
310
311TEST(MemorySanitizer, Not) {
312  testNot<U4>(0x0, 0x0);
313  testNot<U4>(0xFFFFFFFF, 0x0);
314  EXPECT_POISONED(testNot<U4>(0xFFFFFFFF, 0xFFFFFFFF));
315  testNot<U4>(0xFF000000, 0x0FFFFFFF);
316  testNot<U4>(0xFF000000, 0x00FFFFFF);
317  testNot<U4>(0xFF000000, 0x0000FFFF);
318  testNot<U4>(0xFF000000, 0x00000000);
319  EXPECT_POISONED(testNot<U4>(0xFF000000, 0xFF000000));
320  testNot<U4>(0xFF800000, 0xFF000000);
321  EXPECT_POISONED(testNot<U4>(0x00008000, 0x00008000));
322
323  testNot<U1>(0x0, 0x0);
324  testNot<U1>(0xFF, 0xFE);
325  testNot<U1>(0xFF, 0x0);
326  EXPECT_POISONED(testNot<U1>(0xFF, 0xFF));
327
328  EXPECT_POISONED(testNot<void*>((void*)0xFFFFFF, (void*)(-1)));
329  testNot<void*>((void*)0xFFFFFF, (void*)(-2));
330}
331
332TEST(MemorySanitizer, Shift) {
333  U4 *up = GetPoisoned<U4>();
334  ((U1*)up)[0] = 0;
335  ((U1*)up)[3] = 0xff;
336  v_u4 = *up >> 30;
337  v_u4 = *up >> 24;
338  EXPECT_POISONED(v_u4 = *up >> 23);
339  EXPECT_POISONED(v_u4 = *up >> 10);
340
341  v_u4 = *up << 30;
342  v_u4 = *up << 24;
343  EXPECT_POISONED(v_u4 = *up << 23);
344  EXPECT_POISONED(v_u4 = *up << 10);
345
346  S4 *sp = (S4*)up;
347  v_s4 = *sp >> 30;
348  v_s4 = *sp >> 24;
349  EXPECT_POISONED(v_s4 = *sp >> 23);
350  EXPECT_POISONED(v_s4 = *sp >> 10);
351
352  sp = GetPoisoned<S4>();
353  ((S1*)sp)[1] = 0;
354  ((S1*)sp)[2] = 0;
355  EXPECT_POISONED(v_s4 = *sp >> 31);
356
357  v_s4 = 100;
358  EXPECT_POISONED(v_s4 = v_s4 >> *GetPoisoned<S4>());
359  v_u4 = 100;
360  EXPECT_POISONED(v_u4 = v_u4 >> *GetPoisoned<S4>());
361  v_u4 = 100;
362  EXPECT_POISONED(v_u4 = v_u4 << *GetPoisoned<S4>());
363}
364
365NOINLINE static int GetPoisonedZero() {
366  int *zero = new int;
367  *zero = 0;
368  __msan_poison(zero, sizeof(*zero));
369  int res = *zero;
370  delete zero;
371  return res;
372}
373
374TEST(MemorySanitizer, LoadFromDirtyAddress) {
375  int *a = new int;
376  *a = 0;
377  EXPECT_POISONED(__msan_break_optimization((void*)(U8)a[GetPoisonedZero()]));
378  delete a;
379}
380
381TEST(MemorySanitizer, StoreToDirtyAddress) {
382  int *a = new int;
383  EXPECT_POISONED(a[GetPoisonedZero()] = 0);
384  __msan_break_optimization(a);
385  delete a;
386}
387
388
389NOINLINE void StackTestFunc() {
390  S4 p4;
391  S4 ok4 = 1;
392  S2 p2;
393  S2 ok2 = 1;
394  S1 p1;
395  S1 ok1 = 1;
396  __msan_break_optimization(&p4);
397  __msan_break_optimization(&ok4);
398  __msan_break_optimization(&p2);
399  __msan_break_optimization(&ok2);
400  __msan_break_optimization(&p1);
401  __msan_break_optimization(&ok1);
402
403  EXPECT_POISONED(v_s4 = p4);
404  EXPECT_POISONED(v_s2 = p2);
405  EXPECT_POISONED(v_s1 = p1);
406  v_s1 = ok1;
407  v_s2 = ok2;
408  v_s4 = ok4;
409}
410
411TEST(MemorySanitizer, StackTest) {
412  StackTestFunc();
413}
414
415NOINLINE void StackStressFunc() {
416  int foo[10000];
417  __msan_break_optimization(foo);
418}
419
420TEST(MemorySanitizer, DISABLED_StackStressTest) {
421  for (int i = 0; i < 1000000; i++)
422    StackStressFunc();
423}
424
425template<class T>
426void TestFloatingPoint() {
427  static volatile T v;
428  static T g[100];
429  __msan_break_optimization(&g);
430  T *x = GetPoisoned<T>();
431  T *y = GetPoisoned<T>(1);
432  EXPECT_POISONED(v = *x);
433  EXPECT_POISONED(v_s8 = *x);
434  EXPECT_POISONED(v_s4 = *x);
435  g[0] = *x;
436  g[1] = *x + *y;
437  g[2] = *x - *y;
438  g[3] = *x * *y;
439}
440
441TEST(MemorySanitizer, FloatingPointTest) {
442  TestFloatingPoint<float>();
443  TestFloatingPoint<double>();
444}
445
446TEST(MemorySanitizer, DynMem) {
447  S4 x = 0;
448  S4 *y = GetPoisoned<S4>();
449  memcpy(y, &x, g_one * sizeof(S4));
450  v_s4 = *y;
451}
452
453static char *DynRetTestStr;
454
455TEST(MemorySanitizer, DynRet) {
456  if (!__msan_has_dynamic_component()) return;
457  ReturnPoisoned<S8>();
458  v_s4 = clearenv();
459}
460
461
462TEST(MemorySanitizer, DynRet1) {
463  if (!__msan_has_dynamic_component()) return;
464  ReturnPoisoned<S8>();
465}
466
467struct LargeStruct {
468  S4 x[10];
469};
470
471NOINLINE
472LargeStruct LargeRetTest() {
473  LargeStruct res;
474  res.x[0] = *GetPoisoned<S4>();
475  res.x[1] = *GetPoisoned<S4>();
476  res.x[2] = *GetPoisoned<S4>();
477  res.x[3] = *GetPoisoned<S4>();
478  res.x[4] = *GetPoisoned<S4>();
479  res.x[5] = *GetPoisoned<S4>();
480  res.x[6] = *GetPoisoned<S4>();
481  res.x[7] = *GetPoisoned<S4>();
482  res.x[8] = *GetPoisoned<S4>();
483  res.x[9] = *GetPoisoned<S4>();
484  return res;
485}
486
487TEST(MemorySanitizer, LargeRet) {
488  LargeStruct a = LargeRetTest();
489  EXPECT_POISONED(v_s4 = a.x[0]);
490  EXPECT_POISONED(v_s4 = a.x[9]);
491}
492
493TEST(MemorySanitizer, fread) {
494  char *x = new char[32];
495  FILE *f = fopen("/proc/self/stat", "r");
496  assert(f);
497  fread(x, 1, 32, f);
498  v_s1 = x[0];
499  v_s1 = x[16];
500  v_s1 = x[31];
501  fclose(f);
502  delete x;
503}
504
505TEST(MemorySanitizer, read) {
506  char *x = new char[32];
507  int fd = open("/proc/self/stat", O_RDONLY);
508  assert(fd > 0);
509  int sz = read(fd, x, 32);
510  assert(sz == 32);
511  v_s1 = x[0];
512  v_s1 = x[16];
513  v_s1 = x[31];
514  close(fd);
515  delete x;
516}
517
518TEST(MemorySanitizer, pread) {
519  char *x = new char[32];
520  int fd = open("/proc/self/stat", O_RDONLY);
521  assert(fd > 0);
522  int sz = pread(fd, x, 32, 0);
523  assert(sz == 32);
524  v_s1 = x[0];
525  v_s1 = x[16];
526  v_s1 = x[31];
527  close(fd);
528  delete x;
529}
530
531// FIXME: fails now.
532TEST(MemorySanitizer, DISABLED_ioctl) {
533  struct winsize ws;
534  EXPECT_EQ(ioctl(2, TIOCGWINSZ, &ws), 0);
535  v_s4 = ws.ws_col;
536}
537
538TEST(MemorySanitizer, readlink) {
539  char *x = new char[1000];
540  readlink("/proc/self/exe", x, 1000);
541  v_s1 = x[0];
542  delete [] x;
543}
544
545
546TEST(MemorySanitizer, stat) {
547  struct stat* st = new struct stat;
548  int res = stat("/proc/self/stat", st);
549  assert(!res);
550  v_u8 = st->st_dev;
551  v_u8 = st->st_mode;
552  v_u8 = st->st_size;
553}
554
555TEST(MemorySanitizer, statfs) {
556  struct statfs* st = new struct statfs;
557  int res = statfs("/", st);
558  assert(!res);
559  v_u8 = st->f_type;
560  v_u8 = st->f_bfree;
561  v_u8 = st->f_namelen;
562}
563
564TEST(MemorySanitizer, pipe) {
565  int* pipefd = new int[2];
566  int res = pipe(pipefd);
567  assert(!res);
568  v_u8 = pipefd[0];
569  v_u8 = pipefd[1];
570  close(pipefd[0]);
571  close(pipefd[1]);
572}
573
574TEST(MemorySanitizer, getcwd) {
575  char path[PATH_MAX + 1];
576  char* res = getcwd(path, sizeof(path));
577  assert(res);
578  v_s1 = path[0];
579}
580
581TEST(MemorySanitizer, realpath) {
582  const char* relpath = ".";
583  char path[PATH_MAX + 1];
584  char* res = realpath(relpath, path);
585  assert(res);
586  v_s1 = path[0];
587}
588
589TEST(MemorySanitizer, memcpy) {
590  char* x = new char[2];
591  char* y = new char[2];
592  x[0] = 1;
593  x[1] = *GetPoisoned<char>();
594  memcpy(y, x, 2);
595  v_s4 = y[0];
596  EXPECT_POISONED(v_s4 = y[1]);
597}
598
599TEST(MemorySanitizer, memmove) {
600  char* x = new char[2];
601  char* y = new char[2];
602  x[0] = 1;
603  x[1] = *GetPoisoned<char>();
604  memmove(y, x, 2);
605  v_s4 = y[0];
606  EXPECT_POISONED(v_s4 = y[1]);
607}
608
609TEST(MemorySanitizer, strdup) {
610  char *x = strdup("zzz");
611  v_s1 = *x;
612  free(x);
613}
614
615template<class T, int size>
616void TestOverlapMemmove() {
617  T *x = new T[size];
618  assert(size >= 3);
619  x[2] = 0;
620  memmove(x, x + 1, (size - 1) * sizeof(T));
621  v_s8 = x[1];
622  if (!__msan_has_dynamic_component()) {
623    // FIXME: under DR we will lose this information
624    // because accesses in memmove will unpoisin the shadow.
625    // We need to use our own memove implementation instead of libc's.
626    EXPECT_POISONED(v_s8 = x[0]);
627    EXPECT_POISONED(v_s8 = x[2]);
628  }
629  delete [] x;
630}
631
632TEST(MemorySanitizer, overlap_memmove) {
633  TestOverlapMemmove<U1, 10>();
634  TestOverlapMemmove<U1, 1000>();
635  TestOverlapMemmove<U8, 4>();
636  TestOverlapMemmove<U8, 1000>();
637}
638
639TEST(MemorySanitizer, strcpy) {  // NOLINT
640  char* x = new char[3];
641  char* y = new char[3];
642  x[0] = 'a';
643  x[1] = *GetPoisoned<char>(1, 1);
644  x[2] = 0;
645  strcpy(y, x);  // NOLINT
646  v_s4 = y[0];
647  EXPECT_POISONED(v_s4 = y[1]);
648  v_s4 = y[2];
649}
650
651TEST(MemorySanitizer, strncpy) {  // NOLINT
652  char* x = new char[3];
653  char* y = new char[3];
654  x[0] = 'a';
655  x[1] = *GetPoisoned<char>(1, 1);
656  x[2] = 0;
657  strncpy(y, x, 2);  // NOLINT
658  v_s4 = y[0];
659  EXPECT_POISONED(v_s4 = y[1]);
660  EXPECT_POISONED(v_s4 = y[2]);
661}
662
663TEST(MemorySanitizer, strtol) {
664  char *e;
665  assert(1 == strtol("1", &e, 10));
666  v_s8 = (S8) e;
667}
668
669TEST(MemorySanitizer, strtoll) {
670  char *e;
671  assert(1 == strtoll("1", &e, 10));
672  v_s8 = (S8) e;
673}
674
675TEST(MemorySanitizer, strtoul) {
676  char *e;
677  assert(1 == strtoul("1", &e, 10));
678  v_s8 = (S8) e;
679}
680
681TEST(MemorySanitizer, strtoull) {
682  char *e;
683  assert(1 == strtoull("1", &e, 10));
684  v_s8 = (S8) e;
685}
686
687TEST(MemorySanitizer, strtod) {
688  char *e;
689  assert(0 != strtod("1.5", &e));
690  v_s8 = (S8) e;
691}
692
693TEST(MemorySanitizer, strtof) {
694  char *e;
695  assert(0 != strtof("1.5", &e));
696  v_s8 = (S8) e;
697}
698
699TEST(MemorySanitizer, strtold) {
700  char *e;
701  assert(0 != strtold("1.5", &e));
702  v_s8 = (S8) e;
703}
704
705TEST(MemorySanitizer, sprintf) {  // NOLINT
706  char buff[10];
707  __msan_break_optimization(buff);
708  EXPECT_POISONED(v_s1 = buff[0]);
709  int res = sprintf(buff, "%d", 1234567);  // NOLINT
710  assert(res == 7);
711  assert(buff[0] == '1');
712  assert(buff[1] == '2');
713  assert(buff[2] == '3');
714  assert(buff[6] == '7');
715  assert(buff[7] == 0);
716  EXPECT_POISONED(v_s1 = buff[8]);
717}
718
719TEST(MemorySanitizer, snprintf) {
720  char buff[10];
721  __msan_break_optimization(buff);
722  EXPECT_POISONED(v_s1 = buff[0]);
723  int res = snprintf(buff, sizeof(buff), "%d", 1234567);
724  assert(res == 7);
725  assert(buff[0] == '1');
726  assert(buff[1] == '2');
727  assert(buff[2] == '3');
728  assert(buff[6] == '7');
729  assert(buff[7] == 0);
730  EXPECT_POISONED(v_s1 = buff[8]);
731}
732
733TEST(MemorySanitizer, swprintf) {
734  wchar_t buff[10];
735  assert(sizeof(wchar_t) == 4);
736  __msan_break_optimization(buff);
737  EXPECT_POISONED(v_s1 = buff[0]);
738  int res = swprintf(buff, 9, L"%d", 1234567);
739  assert(res == 7);
740  assert(buff[0] == '1');
741  assert(buff[1] == '2');
742  assert(buff[2] == '3');
743  assert(buff[6] == '7');
744  assert(buff[7] == 0);
745  EXPECT_POISONED(v_s4 = buff[8]);
746}
747
748TEST(MemorySanitizer, wcstombs) {
749  const wchar_t *x = L"abc";
750  char buff[10];
751  int res = wcstombs(buff, x, 4);
752  EXPECT_EQ(res, 3);
753  EXPECT_EQ(buff[0], 'a');
754  EXPECT_EQ(buff[1], 'b');
755  EXPECT_EQ(buff[2], 'c');
756}
757
758TEST(MemorySanitizer, gettimeofday) {
759  struct timeval tv;
760  struct timezone tz;
761  __msan_break_optimization(&tv);
762  __msan_break_optimization(&tz);
763  assert(sizeof(tv) == 16);
764  assert(sizeof(tz) == 8);
765  EXPECT_POISONED(v_s8 = tv.tv_sec);
766  EXPECT_POISONED(v_s8 = tv.tv_usec);
767  EXPECT_POISONED(v_s4 = tz.tz_minuteswest);
768  EXPECT_POISONED(v_s4 = tz.tz_dsttime);
769  assert(0 == gettimeofday(&tv, &tz));
770  v_s8 = tv.tv_sec;
771  v_s8 = tv.tv_usec;
772  v_s4 = tz.tz_minuteswest;
773  v_s4 = tz.tz_dsttime;
774}
775
776TEST(MemorySanitizer, mmap) {
777  const int size = 4096;
778  void *p1, *p2;
779  p1 = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
780  __msan_poison(p1, size);
781  munmap(p1, size);
782  for (int i = 0; i < 1000; i++) {
783    p2 = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
784    if (p2 == p1)
785      break;
786    else
787      munmap(p2, size);
788  }
789  if (p1 == p2) {
790    v_s1 = *(char*)p2;
791    munmap(p2, size);
792  }
793}
794
795// FIXME: enable and add ecvt.
796// FIXME: check why msandr does nt handle fcvt.
797TEST(MemorySanitizer, fcvt) {
798  int a, b;
799  __msan_break_optimization(&a);
800  __msan_break_optimization(&b);
801  EXPECT_POISONED(v_s4 = a);
802  EXPECT_POISONED(v_s4 = b);
803  char *str = fcvt(12345.6789, 10, &a, &b);
804  v_s4 = a;
805  v_s4 = b;
806}
807
808TEST(MemorySanitizer, LoadUnpoisoned) {
809  S8 s = *GetPoisoned<S8>();
810  EXPECT_POISONED(v_s8 = s);
811  S8 safe = *GetPoisoned<S8>();
812  __msan_load_unpoisoned(&s, sizeof(s), &safe);
813  v_s8 = safe;
814}
815
816struct StructWithDtor {
817  ~StructWithDtor();
818};
819
820NOINLINE StructWithDtor::~StructWithDtor() {
821  __msan_break_optimization(0);
822}
823
824NOINLINE void ExpectGood(int a) { v_s4 = a; }
825NOINLINE void ExpectPoisoned(int a) {
826  EXPECT_POISONED(v_s4 = a);
827}
828
829TEST(MemorySanitizer, Invoke) {
830  StructWithDtor s;  // Will cause the calls to become invokes.
831  ExpectGood(0);
832  ExpectPoisoned(*GetPoisoned<int>());
833  ExpectGood(0);
834  ExpectPoisoned(*GetPoisoned<int>());
835  EXPECT_POISONED(v_s4 = ReturnPoisoned<S4>());
836}
837
838TEST(MemorySanitizer, ptrtoint) {
839  // Test that shadow is propagated through pointer-to-integer conversion.
840  void* p = (void*)0xABCD;
841  __msan_poison(((char*)&p) + 1, sizeof(p));
842  v_u1 = (((uptr)p) & 0xFF) == 0;
843
844  void* q = (void*)0xABCD;
845  __msan_poison(&q, sizeof(q) - 1);
846  EXPECT_POISONED(v_u1 = (((uptr)q) & 0xFF) == 0);
847}
848
849static void vaargsfn2(int guard, ...) {
850  va_list vl;
851  va_start(vl, guard);
852  v_s4 = va_arg(vl, int);
853  v_s4 = va_arg(vl, int);
854  v_s4 = va_arg(vl, int);
855  EXPECT_POISONED(v_d = va_arg(vl, double));
856  va_end(vl);
857}
858
859static void vaargsfn(int guard, ...) {
860  va_list vl;
861  va_start(vl, guard);
862  v_s4 = va_arg(vl, int);
863  EXPECT_POISONED(v_s4 = va_arg(vl, int));
864  // The following call will overwrite __msan_param_tls.
865  // Checks after it test that arg shadow was somehow saved across the call.
866  vaargsfn2(1, 2, 3, 4, *GetPoisoned<double>());
867  v_s4 = va_arg(vl, int);
868  EXPECT_POISONED(v_s4 = va_arg(vl, int));
869  va_end(vl);
870}
871
872TEST(MemorySanitizer, VAArgTest) {
873  int* x = GetPoisoned<int>();
874  int* y = GetPoisoned<int>(4);
875  vaargsfn(1, 13, *x, 42, *y);
876}
877
878static void vaargsfn_many(int guard, ...) {
879  va_list vl;
880  va_start(vl, guard);
881  v_s4 = va_arg(vl, int);
882  EXPECT_POISONED(v_s4 = va_arg(vl, int));
883  v_s4 = va_arg(vl, int);
884  v_s4 = va_arg(vl, int);
885  v_s4 = va_arg(vl, int);
886  v_s4 = va_arg(vl, int);
887  v_s4 = va_arg(vl, int);
888  v_s4 = va_arg(vl, int);
889  v_s4 = va_arg(vl, int);
890  EXPECT_POISONED(v_s4 = va_arg(vl, int));
891  va_end(vl);
892}
893
894TEST(MemorySanitizer, VAArgManyTest) {
895  int* x = GetPoisoned<int>();
896  int* y = GetPoisoned<int>(4);
897  vaargsfn_many(1, 2, *x, 3, 4, 5, 6, 7, 8, 9, *y);
898}
899
900static void vaargsfn_pass2(va_list vl) {
901  v_s4 = va_arg(vl, int);
902  v_s4 = va_arg(vl, int);
903  EXPECT_POISONED(v_s4 = va_arg(vl, int));
904}
905
906static void vaargsfn_pass(int guard, ...) {
907  va_list vl;
908  va_start(vl, guard);
909  EXPECT_POISONED(v_s4 = va_arg(vl, int));
910  vaargsfn_pass2(vl);
911  va_end(vl);
912}
913
914TEST(MemorySanitizer, VAArgPass) {
915  int* x = GetPoisoned<int>();
916  int* y = GetPoisoned<int>(4);
917  vaargsfn_pass(1, *x, 2, 3, *y);
918}
919
920static void vaargsfn_copy2(va_list vl) {
921  v_s4 = va_arg(vl, int);
922  EXPECT_POISONED(v_s4 = va_arg(vl, int));
923}
924
925static void vaargsfn_copy(int guard, ...) {
926  va_list vl;
927  va_start(vl, guard);
928  v_s4 = va_arg(vl, int);
929  EXPECT_POISONED(v_s4 = va_arg(vl, int));
930  va_list vl2;
931  va_copy(vl2, vl);
932  vaargsfn_copy2(vl2);
933  v_s4 = va_arg(vl, int);
934  EXPECT_POISONED(v_s4 = va_arg(vl, int));
935  va_end(vl);
936}
937
938TEST(MemorySanitizer, VAArgCopy) {
939  int* x = GetPoisoned<int>();
940  int* y = GetPoisoned<int>(4);
941  vaargsfn_copy(1, 2, *x, 3, *y);
942}
943
944static void vaargsfn_ptr(int guard, ...) {
945  va_list vl;
946  va_start(vl, guard);
947  v_p = va_arg(vl, int*);
948  EXPECT_POISONED(v_p = va_arg(vl, int*));
949  v_p = va_arg(vl, int*);
950  EXPECT_POISONED(v_p = va_arg(vl, double*));
951  va_end(vl);
952}
953
954TEST(MemorySanitizer, VAArgPtr) {
955  int** x = GetPoisoned<int*>();
956  double** y = GetPoisoned<double*>(8);
957  int z;
958  vaargsfn_ptr(1, &z, *x, &z, *y);
959}
960
961static void vaargsfn_overflow(int guard, ...) {
962  va_list vl;
963  va_start(vl, guard);
964  v_s4 = va_arg(vl, int);
965  v_s4 = va_arg(vl, int);
966  EXPECT_POISONED(v_s4 = va_arg(vl, int));
967  v_s4 = va_arg(vl, int);
968  v_s4 = va_arg(vl, int);
969  v_s4 = va_arg(vl, int);
970
971  v_d = va_arg(vl, double);
972  v_d = va_arg(vl, double);
973  v_d = va_arg(vl, double);
974  EXPECT_POISONED(v_d = va_arg(vl, double));
975  v_d = va_arg(vl, double);
976  EXPECT_POISONED(v_p = va_arg(vl, int*));
977  v_d = va_arg(vl, double);
978  v_d = va_arg(vl, double);
979
980  EXPECT_POISONED(v_s4 = va_arg(vl, int));
981  EXPECT_POISONED(v_d = va_arg(vl, double));
982  EXPECT_POISONED(v_p = va_arg(vl, int*));
983
984  v_s4 = va_arg(vl, int);
985  v_d = va_arg(vl, double);
986  v_p = va_arg(vl, int*);
987
988  EXPECT_POISONED(v_s4 = va_arg(vl, int));
989  EXPECT_POISONED(v_d = va_arg(vl, double));
990  EXPECT_POISONED(v_p = va_arg(vl, int*));
991
992  va_end(vl);
993}
994
995TEST(MemorySanitizer, VAArgOverflow) {
996  int* x = GetPoisoned<int>();
997  double* y = GetPoisoned<double>(8);
998  int** p = GetPoisoned<int*>(16);
999  int z;
1000  vaargsfn_overflow(1,
1001      1, 2, *x, 4, 5, 6,
1002      1.1, 2.2, 3.3, *y, 5.5, *p, 7.7, 8.8,
1003      // the following args will overflow for sure
1004      *x, *y, *p,
1005      7, 9.9, &z,
1006      *x, *y, *p);
1007}
1008
1009static void vaargsfn_tlsoverwrite2(int guard, ...) {
1010  va_list vl;
1011  va_start(vl, guard);
1012  v_s4 = va_arg(vl, int);
1013  va_end(vl);
1014}
1015
1016static void vaargsfn_tlsoverwrite(int guard, ...) {
1017  // This call will overwrite TLS contents unless it's backed up somewhere.
1018  vaargsfn_tlsoverwrite2(2, 42);
1019  va_list vl;
1020  va_start(vl, guard);
1021  EXPECT_POISONED(v_s4 = va_arg(vl, int));
1022  va_end(vl);
1023}
1024
1025TEST(MemorySanitizer, VAArgTLSOverwrite) {
1026  int* x = GetPoisoned<int>();
1027  vaargsfn_tlsoverwrite(1, *x);
1028}
1029
1030struct StructByVal {
1031  int a, b, c, d, e, f;
1032};
1033
1034NOINLINE void StructByValTestFunc(struct StructByVal s) {
1035  v_s4 = s.a;
1036  EXPECT_POISONED(v_s4 = s.b);
1037  v_s4 = s.c;
1038  EXPECT_POISONED(v_s4 = s.d);
1039  v_s4 = s.e;
1040  EXPECT_POISONED(v_s4 = s.f);
1041}
1042
1043NOINLINE void StructByValTestFunc1(struct StructByVal s) {
1044  StructByValTestFunc(s);
1045}
1046
1047NOINLINE void StructByValTestFunc2(int z, struct StructByVal s) {
1048  StructByValTestFunc(s);
1049}
1050
1051TEST(MemorySanitizer, StructByVal) {
1052  // Large aggregates are passed as "byval" pointer argument in LLVM.
1053  struct StructByVal s;
1054  s.a = 1;
1055  s.b = *GetPoisoned<int>();
1056  s.c = 2;
1057  s.d = *GetPoisoned<int>();
1058  s.e = 3;
1059  s.f = *GetPoisoned<int>();
1060  StructByValTestFunc(s);
1061  StructByValTestFunc1(s);
1062  StructByValTestFunc2(0, s);
1063}
1064
1065
1066#if MSAN_HAS_M128
1067NOINLINE __m128i m128Eq(__m128i *a, __m128i *b) { return *a == *b; }
1068NOINLINE __m128i m128Lt(__m128i *a, __m128i *b) { return *a < *b; }
1069TEST(MemorySanitizer, m128) {
1070  __m128i a = _mm_set1_epi16(0x1234);
1071  __m128i b = _mm_set1_epi16(0x7890);
1072  v_m128 = m128Eq(&a, &b);
1073  v_m128 = m128Lt(&a, &b);
1074}
1075// FIXME: add more tests for __m128i.
1076#endif  // MSAN_HAS_M128
1077
1078// We should not complain when copying this poisoned hole.
1079struct StructWithHole {
1080  U4  a;
1081  // 4-byte hole.
1082  U8  b;
1083};
1084
1085NOINLINE StructWithHole ReturnStructWithHole() {
1086  StructWithHole res;
1087  __msan_poison(&res, sizeof(res));
1088  res.a = 1;
1089  res.b = 2;
1090  return res;
1091}
1092
1093TEST(MemorySanitizer, StructWithHole) {
1094  StructWithHole a = ReturnStructWithHole();
1095  __msan_break_optimization(&a);
1096}
1097
1098template <class T>
1099NOINLINE T ReturnStruct() {
1100  T res;
1101  __msan_poison(&res, sizeof(res));
1102  res.a = 1;
1103  return res;
1104}
1105
1106template <class T>
1107NOINLINE void TestReturnStruct() {
1108  T s1 = ReturnStruct<T>();
1109  v_s4 = s1.a;
1110  EXPECT_POISONED(v_s4 = s1.b);
1111}
1112
1113struct SSS1 {
1114  int a, b, c;
1115};
1116struct SSS2 {
1117  int b, a, c;
1118};
1119struct SSS3 {
1120  int b, c, a;
1121};
1122struct SSS4 {
1123  int c, b, a;
1124};
1125
1126struct SSS5 {
1127  int a;
1128  float b;
1129};
1130struct SSS6 {
1131  int a;
1132  double b;
1133};
1134struct SSS7 {
1135  S8 b;
1136  int a;
1137};
1138struct SSS8 {
1139  S2 b;
1140  S8 a;
1141};
1142
1143TEST(MemorySanitizer, IntStruct3) {
1144  TestReturnStruct<SSS1>();
1145  TestReturnStruct<SSS2>();
1146  TestReturnStruct<SSS3>();
1147  TestReturnStruct<SSS4>();
1148  TestReturnStruct<SSS5>();
1149  TestReturnStruct<SSS6>();
1150  TestReturnStruct<SSS7>();
1151  TestReturnStruct<SSS8>();
1152}
1153
1154struct LongStruct {
1155  U1 a1, b1;
1156  U2 a2, b2;
1157  U4 a4, b4;
1158  U8 a8, b8;
1159};
1160
1161NOINLINE LongStruct ReturnLongStruct1() {
1162  LongStruct res;
1163  __msan_poison(&res, sizeof(res));
1164  res.a1 = res.a2 = res.a4 = res.a8 = 111;
1165  // leaves b1, .., b8 poisoned.
1166  return res;
1167}
1168
1169NOINLINE LongStruct ReturnLongStruct2() {
1170  LongStruct res;
1171  __msan_poison(&res, sizeof(res));
1172  res.b1 = res.b2 = res.b4 = res.b8 = 111;
1173  // leaves a1, .., a8 poisoned.
1174  return res;
1175}
1176
1177TEST(MemorySanitizer, LongStruct) {
1178  LongStruct s1 = ReturnLongStruct1();
1179  __msan_print_shadow(&s1, sizeof(s1));
1180  v_u1 = s1.a1;
1181  v_u2 = s1.a2;
1182  v_u4 = s1.a4;
1183  v_u8 = s1.a8;
1184
1185  EXPECT_POISONED(v_u1 = s1.b1);
1186  EXPECT_POISONED(v_u2 = s1.b2);
1187  EXPECT_POISONED(v_u4 = s1.b4);
1188  EXPECT_POISONED(v_u8 = s1.b8);
1189
1190  LongStruct s2 = ReturnLongStruct2();
1191  __msan_print_shadow(&s2, sizeof(s2));
1192  v_u1 = s2.b1;
1193  v_u2 = s2.b2;
1194  v_u4 = s2.b4;
1195  v_u8 = s2.b8;
1196
1197  EXPECT_POISONED(v_u1 = s2.a1);
1198  EXPECT_POISONED(v_u2 = s2.a2);
1199  EXPECT_POISONED(v_u4 = s2.a4);
1200  EXPECT_POISONED(v_u8 = s2.a8);
1201}
1202
1203TEST(MemorySanitizer, getrlimit) {
1204  struct rlimit limit;
1205  __msan_poison(&limit, sizeof(limit));
1206  int result = getrlimit(RLIMIT_DATA, &limit);
1207  assert(result == 0);
1208  volatile rlim_t t;
1209  t = limit.rlim_cur;
1210  t = limit.rlim_max;
1211}
1212
1213TEST(MemorySanitizer, getrusage) {
1214  struct rusage usage;
1215  __msan_poison(&usage, sizeof(usage));
1216  int result = getrusage(RUSAGE_SELF, &usage);
1217  assert(result == 0);
1218  volatile struct timeval t;
1219  v_u8 = usage.ru_utime.tv_sec;
1220  v_u8 = usage.ru_utime.tv_usec;
1221  v_u8 = usage.ru_stime.tv_sec;
1222  v_u8 = usage.ru_stime.tv_usec;
1223  v_s8 = usage.ru_maxrss;
1224  v_s8 = usage.ru_minflt;
1225  v_s8 = usage.ru_majflt;
1226  v_s8 = usage.ru_inblock;
1227  v_s8 = usage.ru_oublock;
1228  v_s8 = usage.ru_nvcsw;
1229  v_s8 = usage.ru_nivcsw;
1230}
1231
1232static void dladdr_testfn() {}
1233
1234TEST(MemorySanitizer, dladdr) {
1235  Dl_info info;
1236  __msan_poison(&info, sizeof(info));
1237  int result = dladdr((const void*)dladdr_testfn, &info);
1238  assert(result != 0);
1239  v_u8 = (unsigned long)info.dli_fname;
1240  if (info.dli_fname)
1241    v_u8 = strlen(info.dli_fname);
1242  v_u8 = (unsigned long)info.dli_fbase;
1243  v_u8 = (unsigned long)info.dli_sname;
1244  if (info.dli_sname)
1245    v_u8 = strlen(info.dli_sname);
1246  v_u8 = (unsigned long)info.dli_saddr;
1247}
1248
1249static void* SimpleThread_threadfn(void* data) {
1250  return new int;
1251}
1252
1253TEST(MemorySanitizer, SimpleThread) {
1254  pthread_t t;
1255  void* p;
1256  int res = pthread_create(&t, NULL, SimpleThread_threadfn, NULL);
1257  assert(!res);
1258  res = pthread_join(t, &p);
1259  assert(!res);
1260  if (!__msan_has_dynamic_component())  // FIXME: intercept pthread_join (?).
1261    __msan_unpoison(&p, sizeof(p));
1262  delete (int*)p;
1263}
1264
1265TEST(MemorySanitizer, uname) {
1266  struct utsname u;
1267  int res = uname(&u);
1268  assert(!res);
1269  v_u8 = strlen(u.sysname);
1270  v_u8 = strlen(u.nodename);
1271  v_u8 = strlen(u.release);
1272  v_u8 = strlen(u.version);
1273  v_u8 = strlen(u.machine);
1274}
1275
1276template<class T>
1277static void testSlt(T value, T shadow) {
1278  __msan_partial_poison(&value, &shadow, sizeof(T));
1279  volatile bool zzz = true;
1280  // This "|| zzz" trick somehow makes LLVM emit "icmp slt" instead of
1281  // a shift-and-trunc to get at the highest bit.
1282  volatile bool v_T = value < 0 || zzz;
1283}
1284
1285TEST(MemorySanitizer, SignedCompareWithZero) {
1286  testSlt<S4>(0xF, 0xF);
1287  testSlt<S4>(0xF, 0xFF);
1288  testSlt<S4>(0xF, 0xFFFFFF);
1289  testSlt<S4>(0xF, 0x7FFFFFF);
1290  EXPECT_POISONED(testSlt<S4>(0xF, 0x80FFFFFF));
1291  EXPECT_POISONED(testSlt<S4>(0xF, 0xFFFFFFFF));
1292}
1293
1294extern "C" {
1295NOINLINE void ZZZZZZZZZZZZZZ() {
1296  __msan_break_optimization(0);
1297
1298  // v_s1 = ReturnPoisoned<S1>();
1299  // a_s8[g_zero] = *GetPoisoned<S8>() - 1;
1300  // v_s4 = a_s4[g_zero];
1301  __msan_break_optimization(0);
1302}
1303}
1304
1305TEST(MemorySanitizer, ZZZTest) {
1306  ZZZZZZZZZZZZZZ();
1307}
1308
1309TEST(MemorySanitizerDr, StoreInDSOTest) {
1310  if (!__msan_has_dynamic_component()) return;
1311  char* s = new char[10];
1312  dso_memfill(s, 9);
1313  v_s1 = s[5];
1314  EXPECT_POISONED(v_s1 = s[9]);
1315}
1316
1317int return_poisoned_int() {
1318  return ReturnPoisoned<U8>();
1319}
1320
1321TEST(MemorySanitizerDr, ReturnFromDSOTest) {
1322  if (!__msan_has_dynamic_component()) return;
1323  v_u8 = dso_callfn(return_poisoned_int);
1324}
1325
1326NOINLINE int TrashParamTLS(long long x, long long y, long long z) {  //NOLINT
1327  EXPECT_POISONED(v_s8 = x);
1328  EXPECT_POISONED(v_s8 = y);
1329  EXPECT_POISONED(v_s8 = z);
1330  return 0;
1331}
1332
1333static int CheckParamTLS(long long x, long long y, long long z) {  //NOLINT
1334  v_s8 = x;
1335  v_s8 = y;
1336  v_s8 = z;
1337  return 0;
1338}
1339
1340TEST(MemorySanitizerDr, CallFromDSOTest) {
1341  if (!__msan_has_dynamic_component()) return;
1342  S8* x = GetPoisoned<S8>();
1343  S8* y = GetPoisoned<S8>();
1344  S8* z = GetPoisoned<S8>();
1345  v_s4 = TrashParamTLS(*x, *y, *z);
1346  v_u8 = dso_callfn1(CheckParamTLS);
1347}
1348
1349static void StackStoreInDSOFn(int* x, int* y) {
1350  v_s4 = *x;
1351  v_s4 = *y;
1352}
1353
1354TEST(MemorySanitizerDr, StackStoreInDSOTest) {
1355  if (!__msan_has_dynamic_component()) return;
1356  dso_stack_store(StackStoreInDSOFn, 1);
1357}
1358
1359TEST(MemorySanitizerOrigins, SetGet) {
1360  EXPECT_EQ(TrackingOrigins(), __msan_get_track_origins());
1361  if (!TrackingOrigins()) return;
1362  int x;
1363  __msan_set_origin(&x, sizeof(x), 1234);
1364  EXPECT_EQ(1234, __msan_get_origin(&x));
1365  __msan_set_origin(&x, sizeof(x), 5678);
1366  EXPECT_EQ(5678, __msan_get_origin(&x));
1367  __msan_set_origin(&x, sizeof(x), 0);
1368  EXPECT_EQ(0, __msan_get_origin(&x));
1369}
1370
1371namespace {
1372struct S {
1373  U4 dummy;
1374  U2 a;
1375  U2 b;
1376};
1377
1378// http://code.google.com/p/memory-sanitizer/issues/detail?id=6
1379TEST(MemorySanitizerOrigins, DISABLED_InitializedStoreDoesNotChangeOrigin) {
1380  if (!TrackingOrigins()) return;
1381
1382  S s;
1383  u32 origin = rand();  // NOLINT
1384  s.a = *GetPoisonedO<U2>(0, origin);
1385  EXPECT_EQ(origin, __msan_get_origin(&s.a));
1386  EXPECT_EQ(origin, __msan_get_origin(&s.b));
1387
1388  s.b = 42;
1389  EXPECT_EQ(origin, __msan_get_origin(&s.a));
1390  EXPECT_EQ(origin, __msan_get_origin(&s.b));
1391}
1392}  // namespace
1393
1394template<class T, class BinaryOp>
1395INLINE
1396void BinaryOpOriginTest(BinaryOp op) {
1397  u32 ox = rand();  //NOLINT
1398  u32 oy = rand();  //NOLINT
1399  T *x = GetPoisonedO<T>(0, ox, 0);
1400  T *y = GetPoisonedO<T>(1, oy, 0);
1401  T *z = GetPoisonedO<T>(2, 0, 0);
1402
1403  *z = op(*x, *y);
1404  u32 origin = __msan_get_origin(z);
1405  EXPECT_POISONED_O(v_s8 = *z, origin);
1406  EXPECT_EQ(true, origin == ox || origin == oy);
1407
1408  // y is poisoned, x is not.
1409  *x = 10101;
1410  *y = *GetPoisonedO<T>(1, oy);
1411  __msan_break_optimization(x);
1412  __msan_set_origin(z, sizeof(*z), 0);
1413  *z = op(*x, *y);
1414  EXPECT_POISONED_O(v_s8 = *z, oy);
1415  EXPECT_EQ(__msan_get_origin(z), oy);
1416
1417  // x is poisoned, y is not.
1418  *x = *GetPoisonedO<T>(0, ox);
1419  *y = 10101010;
1420  __msan_break_optimization(y);
1421  __msan_set_origin(z, sizeof(*z), 0);
1422  *z = op(*x, *y);
1423  EXPECT_POISONED_O(v_s8 = *z, ox);
1424  EXPECT_EQ(__msan_get_origin(z), ox);
1425}
1426
1427template<class T> INLINE T XOR(const T &a, const T&b) { return a ^ b; }
1428template<class T> INLINE T ADD(const T &a, const T&b) { return a + b; }
1429template<class T> INLINE T SUB(const T &a, const T&b) { return a - b; }
1430template<class T> INLINE T MUL(const T &a, const T&b) { return a * b; }
1431template<class T> INLINE T AND(const T &a, const T&b) { return a & b; }
1432template<class T> INLINE T OR (const T &a, const T&b) { return a | b; }
1433
1434TEST(MemorySanitizerOrigins, BinaryOp) {
1435  if (!TrackingOrigins()) return;
1436  BinaryOpOriginTest<S8>(XOR<S8>);
1437  BinaryOpOriginTest<U8>(ADD<U8>);
1438  BinaryOpOriginTest<S4>(SUB<S4>);
1439  BinaryOpOriginTest<S4>(MUL<S4>);
1440  BinaryOpOriginTest<U4>(OR<U4>);
1441  BinaryOpOriginTest<U4>(AND<U4>);
1442  BinaryOpOriginTest<double>(ADD<U4>);
1443  BinaryOpOriginTest<float>(ADD<S4>);
1444  BinaryOpOriginTest<double>(ADD<double>);
1445  BinaryOpOriginTest<float>(ADD<double>);
1446}
1447
1448TEST(MemorySanitizerOrigins, Unary) {
1449  if (!TrackingOrigins()) return;
1450  EXPECT_POISONED_O(v_s8 = *GetPoisonedO<S8>(0, __LINE__), __LINE__);
1451  EXPECT_POISONED_O(v_s4 = *GetPoisonedO<S8>(0, __LINE__), __LINE__);
1452  EXPECT_POISONED_O(v_s2 = *GetPoisonedO<S8>(0, __LINE__), __LINE__);
1453  EXPECT_POISONED_O(v_s1 = *GetPoisonedO<S8>(0, __LINE__), __LINE__);
1454
1455  EXPECT_POISONED_O(v_s8 = *GetPoisonedO<S4>(0, __LINE__), __LINE__);
1456  EXPECT_POISONED_O(v_s4 = *GetPoisonedO<S4>(0, __LINE__), __LINE__);
1457  EXPECT_POISONED_O(v_s2 = *GetPoisonedO<S4>(0, __LINE__), __LINE__);
1458  EXPECT_POISONED_O(v_s1 = *GetPoisonedO<S4>(0, __LINE__), __LINE__);
1459
1460  EXPECT_POISONED_O(v_s8 = *GetPoisonedO<U4>(0, __LINE__), __LINE__);
1461  EXPECT_POISONED_O(v_s4 = *GetPoisonedO<U4>(0, __LINE__), __LINE__);
1462  EXPECT_POISONED_O(v_s2 = *GetPoisonedO<U4>(0, __LINE__), __LINE__);
1463  EXPECT_POISONED_O(v_s1 = *GetPoisonedO<U4>(0, __LINE__), __LINE__);
1464
1465  EXPECT_POISONED_O(v_u8 = *GetPoisonedO<S4>(0, __LINE__), __LINE__);
1466  EXPECT_POISONED_O(v_u4 = *GetPoisonedO<S4>(0, __LINE__), __LINE__);
1467  EXPECT_POISONED_O(v_u2 = *GetPoisonedO<S4>(0, __LINE__), __LINE__);
1468  EXPECT_POISONED_O(v_u1 = *GetPoisonedO<S4>(0, __LINE__), __LINE__);
1469
1470  EXPECT_POISONED_O(v_p = (void*)*GetPoisonedO<S8>(0, __LINE__), __LINE__);
1471  EXPECT_POISONED_O(v_u8 = (U8)*GetPoisonedO<void*>(0, __LINE__), __LINE__);
1472}
1473
1474TEST(MemorySanitizerOrigins, EQ) {
1475  if (!TrackingOrigins()) return;
1476  EXPECT_POISONED_O(v_u1 = *GetPoisonedO<S4>(0, __LINE__) <= 11, __LINE__);
1477  EXPECT_POISONED_O(v_u1 = *GetPoisonedO<S4>(0, __LINE__) == 11, __LINE__);
1478  EXPECT_POISONED_O(v_u1 = *GetPoisonedO<float>(0, __LINE__) == 1.1, __LINE__);
1479}
1480
1481TEST(MemorySanitizerOrigins, DIV) {
1482  if (!TrackingOrigins()) return;
1483  EXPECT_POISONED_O(v_u8 = *GetPoisonedO<U8>(0, __LINE__) / 100, __LINE__);
1484  EXPECT_POISONED_O(v_s4 = 100 / *GetPoisonedO<S4>(0, __LINE__, 1), __LINE__);
1485}
1486
1487TEST(MemorySanitizerOrigins, SHIFT) {
1488  if (!TrackingOrigins()) return;
1489  EXPECT_POISONED_O(v_u8 = *GetPoisonedO<U8>(0, __LINE__) >> 10, __LINE__);
1490  EXPECT_POISONED_O(v_s8 = *GetPoisonedO<S8>(0, __LINE__) >> 10, __LINE__);
1491  EXPECT_POISONED_O(v_s8 = *GetPoisonedO<S8>(0, __LINE__) << 10, __LINE__);
1492  EXPECT_POISONED_O(v_u8 = 10U << *GetPoisonedO<U8>(0, __LINE__), __LINE__);
1493  EXPECT_POISONED_O(v_s8 = -10 >> *GetPoisonedO<S8>(0, __LINE__), __LINE__);
1494  EXPECT_POISONED_O(v_s8 = -10 << *GetPoisonedO<S8>(0, __LINE__), __LINE__);
1495}
1496
1497template<class T, int N>
1498void MemCpyTest() {
1499  int ox = __LINE__;
1500  T *x = new T[N];
1501  T *y = new T[N];
1502  T *z = new T[N];
1503  __msan_poison(x, N * sizeof(T));
1504  __msan_set_origin(x, N * sizeof(T), ox);
1505  __msan_set_origin(y, N * sizeof(T), 777777);
1506  __msan_set_origin(z, N * sizeof(T), 888888);
1507  v_p = x;
1508  memcpy(y, v_p, N * sizeof(T));
1509  EXPECT_POISONED_O(v_s1 = y[0], ox);
1510  EXPECT_POISONED_O(v_s1 = y[N/2], ox);
1511  EXPECT_POISONED_O(v_s1 = y[N-1], ox);
1512  v_p = x;
1513  memmove(z, v_p, N * sizeof(T));
1514  EXPECT_POISONED_O(v_s1 = z[0], ox);
1515  EXPECT_POISONED_O(v_s1 = z[N/2], ox);
1516  EXPECT_POISONED_O(v_s1 = z[N-1], ox);
1517}
1518
1519TEST(MemorySanitizerOrigins, LargeMemCpy) {
1520  if (!TrackingOrigins()) return;
1521  MemCpyTest<U1, 10000>();
1522  MemCpyTest<U8, 10000>();
1523}
1524
1525TEST(MemorySanitizerOrigins, SmallMemCpy) {
1526  if (!TrackingOrigins()) return;
1527  MemCpyTest<U8, 1>();
1528  MemCpyTest<U8, 2>();
1529  MemCpyTest<U8, 3>();
1530}
1531
1532TEST(MemorySanitizerOrigins, Select) {
1533  if (!TrackingOrigins()) return;
1534  v_s8 = g_one ? 1 : *GetPoisonedO<S4>(0, __LINE__);
1535  EXPECT_POISONED_O(v_s8 = *GetPoisonedO<S4>(0, __LINE__), __LINE__);
1536  S4 x;
1537  __msan_break_optimization(&x);
1538  x = g_1 ? *GetPoisonedO<S4>(0, __LINE__) : 0;
1539
1540  EXPECT_POISONED_O(v_s8 = g_1 ? *GetPoisonedO<S4>(0, __LINE__) : 1, __LINE__);
1541  EXPECT_POISONED_O(v_s8 = g_0 ? 1 : *GetPoisonedO<S4>(0, __LINE__), __LINE__);
1542}
1543
1544extern "C"
1545NOINLINE void AllocaTOTest() {
1546  int ar[100];
1547  __msan_break_optimization(ar);
1548  v_s8 = ar[10];
1549  // fprintf(stderr, "Descr: %s\n",
1550  //        __msan_get_origin_descr_if_stack(__msan_get_origin_tls()));
1551}
1552
1553TEST(MemorySanitizerOrigins, Alloca) {
1554  if (!TrackingOrigins()) return;
1555  EXPECT_POISONED_S(AllocaTOTest(), "ar@AllocaTOTest");
1556  EXPECT_POISONED_S(AllocaTOTest(), "ar@AllocaTOTest");
1557  EXPECT_POISONED_S(AllocaTOTest(), "ar@AllocaTOTest");
1558  EXPECT_POISONED_S(AllocaTOTest(), "ar@AllocaTOTest");
1559}
1560
1561// FIXME: replace with a lit-like test.
1562TEST(MemorySanitizerOrigins, DISABLED_AllocaDeath) {
1563  if (!TrackingOrigins()) return;
1564  EXPECT_DEATH(AllocaTOTest(), "ORIGIN: stack allocation: ar@AllocaTOTest");
1565}
1566
1567NOINLINE int RetvalOriginTest(u32 origin) {
1568  int *a = new int;
1569  __msan_break_optimization(a);
1570  __msan_set_origin(a, sizeof(*a), origin);
1571  int res = *a;
1572  delete a;
1573  return res;
1574}
1575
1576TEST(MemorySanitizerOrigins, Retval) {
1577  if (!TrackingOrigins()) return;
1578  EXPECT_POISONED_O(v_s4 = RetvalOriginTest(__LINE__), __LINE__);
1579}
1580
1581NOINLINE void ParamOriginTest(int param, u32 origin) {
1582  EXPECT_POISONED_O(v_s4 = param, origin);
1583}
1584
1585TEST(MemorySanitizerOrigins, Param) {
1586  if (!TrackingOrigins()) return;
1587  int *a = new int;
1588  u32 origin = __LINE__;
1589  __msan_break_optimization(a);
1590  __msan_set_origin(a, sizeof(*a), origin);
1591  ParamOriginTest(*a, origin);
1592  delete a;
1593}
1594
1595TEST(MemorySanitizerOrigins, Invoke) {
1596  if (!TrackingOrigins()) return;
1597  StructWithDtor s;  // Will cause the calls to become invokes.
1598  EXPECT_POISONED_O(v_s4 = RetvalOriginTest(__LINE__), __LINE__);
1599}
1600
1601TEST(MemorySanitizerOrigins, strlen) {
1602  S8 alignment;
1603  __msan_break_optimization(&alignment);
1604  char x[4] = {'a', 'b', 0, 0};
1605  __msan_poison(&x[2], 1);
1606  u32 origin = __LINE__;
1607  __msan_set_origin(x, sizeof(x), origin);
1608  EXPECT_POISONED_O(v_s4 = strlen(x), origin);
1609}
1610
1611TEST(MemorySanitizerOrigins, wcslen) {
1612  wchar_t w[3] = {'a', 'b', 0};
1613  u32 origin = __LINE__;
1614  __msan_set_origin(w, sizeof(w), origin);
1615  __msan_poison(&w[2], sizeof(wchar_t));
1616  EXPECT_POISONED_O(v_s4 = wcslen(w), origin);
1617}
1618
1619#if MSAN_HAS_M128
1620TEST(MemorySanitizerOrigins, StoreIntrinsic) {
1621  __m128 x, y;
1622  u32 origin = __LINE__;
1623  __msan_set_origin(&x, sizeof(x), origin);
1624  __msan_poison(&x, sizeof(x));
1625  __builtin_ia32_storeups((float*)&y, x);
1626  EXPECT_POISONED_O(v_m128 = y, origin);
1627}
1628#endif
1629
1630NOINLINE void RecursiveMalloc(int depth) {
1631  static int count;
1632  count++;
1633  if ((count % (1024 * 1024)) == 0)
1634    printf("RecursiveMalloc: %d\n", count);
1635  int *x1 = new int;
1636  int *x2 = new int;
1637  __msan_break_optimization(x1);
1638  __msan_break_optimization(x2);
1639  if (depth > 0) {
1640    RecursiveMalloc(depth-1);
1641    RecursiveMalloc(depth-1);
1642  }
1643  delete x1;
1644  delete x2;
1645}
1646
1647TEST(MemorySanitizerStress, DISABLED_MallocStackTrace) {
1648  RecursiveMalloc(22);
1649}
1650
1651int main(int argc, char **argv) {
1652  __msan_set_poison_in_malloc(1);
1653  testing::InitGoogleTest(&argc, argv);
1654  int res = RUN_ALL_TESTS();
1655  return res;
1656}
1657