1*d21b3d34SFangrui Song // RUN: %clangxx_msan -std=c++11 -O0 %s -o %t && %run %t
2*d21b3d34SFangrui Song // RUN: %clangxx_msan -std=c++11 -O0 %s -o %t -DPOSITIVE && not %run %t 2>&1 | FileCheck %s
3*d21b3d34SFangrui Song
4*d21b3d34SFangrui Song #include <assert.h>
5*d21b3d34SFangrui Song #include <dlfcn.h>
6*d21b3d34SFangrui Song #include <sanitizer/msan_interface.h>
7*d21b3d34SFangrui Song #include <stdio.h>
8*d21b3d34SFangrui Song #include <string.h>
9*d21b3d34SFangrui Song #include <sys/types.h>
10*d21b3d34SFangrui Song #include <sys/uio.h>
11*d21b3d34SFangrui Song #include <unistd.h>
12*d21b3d34SFangrui Song #include <errno.h>
13*d21b3d34SFangrui Song
14*d21b3d34SFangrui Song typedef ssize_t (*process_vm_readwritev_fn)(pid_t, const iovec *, unsigned long,
15*d21b3d34SFangrui Song const iovec *, unsigned long,
16*d21b3d34SFangrui Song unsigned long);
17*d21b3d34SFangrui Song
18*d21b3d34SFangrui Song // Exit with success, emulating the expected output.
exit_dummy()19*d21b3d34SFangrui Song int exit_dummy()
20*d21b3d34SFangrui Song {
21*d21b3d34SFangrui Song #ifdef POSITIVE
22*d21b3d34SFangrui Song printf("process_vm_readv not found or not implemented!\n");
23*d21b3d34SFangrui Song printf(
24*d21b3d34SFangrui Song "WARNING: MemorySanitizer: use-of-uninitialized-value (not really)\n");
25*d21b3d34SFangrui Song return 1;
26*d21b3d34SFangrui Song #else
27*d21b3d34SFangrui Song return 0;
28*d21b3d34SFangrui Song #endif
29*d21b3d34SFangrui Song }
30*d21b3d34SFangrui Song
main(void)31*d21b3d34SFangrui Song int main(void) {
32*d21b3d34SFangrui Song // This requires glibc 2.15.
33*d21b3d34SFangrui Song process_vm_readwritev_fn libc_process_vm_readv =
34*d21b3d34SFangrui Song (process_vm_readwritev_fn)dlsym(RTLD_NEXT, "process_vm_readv");
35*d21b3d34SFangrui Song if (!libc_process_vm_readv)
36*d21b3d34SFangrui Song return exit_dummy();
37*d21b3d34SFangrui Song
38*d21b3d34SFangrui Song process_vm_readwritev_fn process_vm_readv =
39*d21b3d34SFangrui Song (process_vm_readwritev_fn)dlsym(RTLD_DEFAULT, "process_vm_readv");
40*d21b3d34SFangrui Song process_vm_readwritev_fn process_vm_writev =
41*d21b3d34SFangrui Song (process_vm_readwritev_fn)dlsym(RTLD_DEFAULT, "process_vm_writev");
42*d21b3d34SFangrui Song
43*d21b3d34SFangrui Song char a[100];
44*d21b3d34SFangrui Song memset(a, 0xab, 100);
45*d21b3d34SFangrui Song
46*d21b3d34SFangrui Song char b[100];
47*d21b3d34SFangrui Song iovec iov_a[] = {{(void *)a, 20}, (void *)(a + 50), 10};
48*d21b3d34SFangrui Song iovec iov_b[] = {{(void *)(b + 10), 10}, (void *)(b + 30), 20};
49*d21b3d34SFangrui Song
50*d21b3d34SFangrui Song __msan_poison(&b, sizeof(b));
51*d21b3d34SFangrui Song ssize_t res = process_vm_readv(getpid(), iov_b, 2, iov_a, 2, 0);
52*d21b3d34SFangrui Song if (errno == ENOSYS) // Function not implemented
53*d21b3d34SFangrui Song return exit_dummy();
54*d21b3d34SFangrui Song
55*d21b3d34SFangrui Song assert(res == 30);
56*d21b3d34SFangrui Song __msan_check_mem_is_initialized(b + 10, 10);
57*d21b3d34SFangrui Song __msan_check_mem_is_initialized(b + 30, 20);
58*d21b3d34SFangrui Song assert(__msan_test_shadow(b + 9, 1) == 0);
59*d21b3d34SFangrui Song assert(__msan_test_shadow(b + 20, 1) == 0);
60*d21b3d34SFangrui Song assert(__msan_test_shadow(b + 29, 1) == 0);
61*d21b3d34SFangrui Song assert(__msan_test_shadow(b + 50, 1) == 0);
62*d21b3d34SFangrui Song
63*d21b3d34SFangrui Song #ifdef POSITIVE
64*d21b3d34SFangrui Song __msan_unpoison(&b, sizeof(b));
65*d21b3d34SFangrui Song __msan_poison(b + 32, 1);
66*d21b3d34SFangrui Song res = process_vm_writev(getpid(), iov_b, 2, iov_a, 2, 0);
67*d21b3d34SFangrui Song // CHECK: WARNING: MemorySanitizer: use-of-uninitialized-value
68*d21b3d34SFangrui Song #else
69*d21b3d34SFangrui Song __msan_unpoison(&b, sizeof(b));
70*d21b3d34SFangrui Song res = process_vm_writev(getpid(), iov_b, 2, iov_a, 2, 0);
71*d21b3d34SFangrui Song assert(res == 30);
72*d21b3d34SFangrui Song #endif
73*d21b3d34SFangrui Song
74*d21b3d34SFangrui Song return 0;
75*d21b3d34SFangrui Song }
76