1// RUN: %clangxx_msan -fno-sanitize-memory-param-retval -fno-sanitize=memory -c %s -o %t-main.o
2// RUN: %clangxx_msan -fno-sanitize-memory-param-retval %t-main.o %s -o %t
3// RUN: %run %t
4
5#include <assert.h>
6#include <stdio.h>
7#include <stdlib.h>
8#include <ucontext.h>
9#include <unistd.h>
10
11#include <sanitizer/msan_interface.h>
12
13#if __has_feature(memory_sanitizer)
14
15__attribute__((noinline)) int bar(int a, int b) {
16 volatile int zero = 0;
17 return zero;
18}
19
20void foo(int x, int y, int expected) {
21 assert(__msan_test_shadow(&x, sizeof(x)) == expected);
22 assert(__msan_test_shadow(&y, sizeof(y)) == expected);
23
24 // Poisons parameter shadow in TLS so that the next call (to foo) from
25 // uninstrumented main has params 1 and 2 poisoned no matter what.
26 int a, b;
27 (void)bar(a, b);
28}
29
30#else
31
32// This code is not instrumented by MemorySanitizer to prevent it from modifying
33// MSAN TLS data for this test.
34
35int foo(int, int, int);
36
37int main(int argc, char **argv) {
38 int x, y;
39 // The parameters should _not_ be poisoned; this is the first call to foo.
40 foo(x, y, -1);
41 // The parameters should be poisoned; the prior call to foo left them so.
42 foo(x, y, 0);
43
44 ucontext_t ctx;
45 if (getcontext(ucp: &ctx) == -1) {
46 perror(s: "getcontext");
47 _exit(status: 1);
48 }
49
50 // Simulate a fiber switch occurring from MSAN's perspective (though no switch
51 // actually occurs).
52 const void *previous_stack_bottom = nullptr;
53 size_t previous_stack_size = 0;
54 __msan_start_switch_fiber(bottom: ctx.uc_stack.ss_sp, size: ctx.uc_stack.ss_size);
55 __msan_finish_switch_fiber(bottom_old: &previous_stack_bottom, size_old: &previous_stack_size);
56
57 // The simulated fiber switch will reset the TLS parameter shadow. So even
58 // though the most recent call to foo left the parameter shadow poisoned, the
59 // parameters are _not_ expected to be poisoned now.
60 foo(x, y, -1);
61
62 return 0;
63}
64
65#endif
66

source code of compiler-rt/test/msan/Linux/swapcontext_annotation_reset.cpp