xref: /llvm-project/compiler-rt/test/msan/Linux/signal_mcontext.cpp (revision 9d1857f69f4ef00d9fd1b21660c20e00b993d06f)
11298273eSDmitry Vyukov // RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
21298273eSDmitry Vyukov 
31298273eSDmitry Vyukov #include <pthread.h>
41298273eSDmitry Vyukov #include <sanitizer/msan_interface.h>
51298273eSDmitry Vyukov #include <signal.h>
69eeb2c98SPetr Hosek #include <stdint.h>
71298273eSDmitry Vyukov #include <stdio.h>
81298273eSDmitry Vyukov #include <ucontext.h>
91298273eSDmitry Vyukov #include <unistd.h>
101298273eSDmitry Vyukov 
handler(int sig,siginfo_t * info,void * uctx)111298273eSDmitry Vyukov void handler(int sig, siginfo_t *info, void *uctx) {
121298273eSDmitry Vyukov   __msan_check_mem_is_initialized(uctx, sizeof(ucontext_t));
13*9d1857f6SFangrui Song #if defined(__GLIBC__) && defined(__x86_64__)
141298273eSDmitry Vyukov   auto *mctx = &static_cast<ucontext_t *>(uctx)->uc_mcontext;
151298273eSDmitry Vyukov   if (auto *fpregs = mctx->fpregs) {
169eeb2c98SPetr Hosek     // The member names differ across header versions, but the actual layout
179eeb2c98SPetr Hosek     // is always the same.  So avoid using members, just use arithmetic.
189eeb2c98SPetr Hosek     const uint32_t *after_xmm =
199eeb2c98SPetr Hosek         reinterpret_cast<const uint32_t *>(fpregs + 1) - 24;
209eeb2c98SPetr Hosek     if (after_xmm[12] == FP_XSTATE_MAGIC1) {
211298273eSDmitry Vyukov       auto *xstate = reinterpret_cast<_xstate *>(mctx->fpregs);
221298273eSDmitry Vyukov       __msan_check_mem_is_initialized(xstate, sizeof(*xstate));
231298273eSDmitry Vyukov     }
241298273eSDmitry Vyukov   }
251298273eSDmitry Vyukov #endif
261298273eSDmitry Vyukov }
271298273eSDmitry Vyukov 
poison_stack()281298273eSDmitry Vyukov __attribute__((noinline)) void poison_stack() {
291298273eSDmitry Vyukov   char buf[64 << 10];
301298273eSDmitry Vyukov   printf("buf: %p-%p\n", buf, buf + sizeof(buf));
311298273eSDmitry Vyukov }
321298273eSDmitry Vyukov 
main(int argc,char ** argv)331298273eSDmitry Vyukov int main(int argc, char **argv) {
341298273eSDmitry Vyukov   struct sigaction act = {};
351298273eSDmitry Vyukov   act.sa_sigaction = handler;
361298273eSDmitry Vyukov   act.sa_flags = SA_SIGINFO;
371298273eSDmitry Vyukov   sigaction(SIGPROF, &act, 0);
381298273eSDmitry Vyukov   poison_stack();
391298273eSDmitry Vyukov   pthread_kill(pthread_self(), SIGPROF);
401298273eSDmitry Vyukov   return 0;
411298273eSDmitry Vyukov }
421298273eSDmitry Vyukov 
431298273eSDmitry Vyukov // CHECK-NOT: WARNING: MemorySanitizer:
44