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