1c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// RUN: %clang_esan_wset -O0 %s -o %t 2>&1 2c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// RUN: %run %t 2>&1 | FileCheck %s 3c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 4c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#include <assert.h> 5c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#include <setjmp.h> 6c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#include <signal.h> 7c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#include <stdio.h> 8c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#include <stdlib.h> 9c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#include <sys/mman.h> 10c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 11c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarsigjmp_buf mark; 12c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 13c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarstatic void SignalHandler(int Sig) { 14c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar if (Sig == SIGSEGV) { 15c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar fprintf(stderr, "Handling SIGSEGV for signal\n"); 16c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar siglongjmp(mark, 1); 17c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar } 18c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar exit(1); 19c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar} 20c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 21c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarstatic void SigactionHandler(int Sig, siginfo_t *Info, void *Ctx) { 22c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar if (Sig == SIGSEGV) { 23c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar fprintf(stderr, "Handling SIGSEGV for sigaction\n"); 24c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar siglongjmp(mark, 1); 25c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar } 26c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar exit(1); 27c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar} 28c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 29c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarint main(int argc, char **argv) { 30c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar __sighandler_t Prior = signal(SIGSEGV, SignalHandler); 31c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar assert(Prior == SIG_DFL); 32c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar if (sigsetjmp(mark, 1) == 0) 33c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar *((volatile int *)(ssize_t)argc) = 42; // Raise SIGSEGV 34c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar fprintf(stderr, "Past longjmp for signal\n"); 35c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 36c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar Prior = signal(SIGSEGV, SIG_DFL); 37c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar assert(Prior == SignalHandler); 38c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 39c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar struct sigaction SigAct; 40c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar SigAct.sa_sigaction = SigactionHandler; 41c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar int Res = sigfillset(&SigAct.sa_mask); 42c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar assert(Res == 0); 43c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar SigAct.sa_flags = SA_SIGINFO; 44c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar Res = sigaction(SIGSEGV, &SigAct, NULL); 45c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar assert(Res == 0); 46c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 47c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar if (sigsetjmp(mark, 1) == 0) 48c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar *((volatile int *)(ssize_t)argc) = 42; // Raise SIGSEGV 49c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar fprintf(stderr, "Past longjmp for sigaction\n"); 50c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 51c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar Res = sigaction(SIGSEGV, NULL, &SigAct); 52c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar assert(Res == 0); 53c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar assert(SigAct.sa_sigaction == SigactionHandler); 54c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 55c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // Test blocking SIGSEGV and raising a shadow fault. 56c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar sigset_t Set; 57c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar sigemptyset(&Set); 58c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar sigaddset(&Set, SIGSEGV); 59c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar Res = sigprocmask(SIG_BLOCK, &Set, NULL); 60c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // Make a large enough mapping that its start point will be before any 61c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar // prior library-region shadow access. 62c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar char *buf = (char *)mmap(0, 640*1024, PROT_READ | PROT_WRITE, 63c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 64c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar buf[0] = 4; 65c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar munmap(buf, 640*1024); 66c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar fprintf(stderr, "Past blocked-SIGSEGV shadow fault\n"); 67c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 68c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar return 0; 69c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar} 70c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// CHECK: Handling SIGSEGV for signal 71c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// CHECK-NEXT: Past longjmp for signal 72c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// CHECK-NEXT: Handling SIGSEGV for sigaction 73c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// CHECK-NEXT: Past longjmp for sigaction 74c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// CHECK-NEXT: Past blocked-SIGSEGV shadow fault 75c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// CHECK: {{.*}} EfficiencySanitizer: the total working set size: {{[0-9]+}} Bytes ({{[0-9][0-9]}} cache lines) 76