/* Checks that BOLT correctly handles instrumentation of indirect calls * including case with indirect calls in signals handlers. */ #include #include #include #include #include int foo(int x) { return x + 1; } int bar(int (*fn)(int), int val) { return fn(val); } void sigHandler(int signum) { bar(foo, 3); } int main(int argc, char **argv) { long long i; pid_t pid, wpid; int wstatus; signal(SIGUSR1, sigHandler); pid = fork(); if (pid) { do { kill(pid, SIGUSR1); usleep(0); wpid = waitpid(pid, &wstatus, WNOHANG); } while (wpid == 0); printf("[parent]\n"); } else { for (i = 0; i < 100000; i++) { bar(foo, i % 10); } printf("[child]\n"); } return 0; } /* REQUIRES: system-linux,bolt-runtime,lit-max-individual-test-time RUN: %clang %cflags -D_GNU_SOURCE %s -o %t.exe -Wl,-q -pie -fpie RUN: llvm-bolt %t.exe --instrument --instrumentation-file=%t.fdata \ RUN: --instrumentation-wait-forks=1 --conservative-instrumentation \ RUN: -o %t.instrumented_conservative # Instrumented program needs to finish returning zero RUN: %t.instrumented_conservative | FileCheck %s -check-prefix=CHECK-OUTPUT RUN: llvm-bolt %t.exe --instrument --instrumentation-file=%t.fdata \ RUN: --instrumentation-wait-forks=1 \ RUN: -o %t.instrumented # Instrumented program needs to finish returning zero RUN: %t.instrumented | FileCheck %s -check-prefix=CHECK-OUTPUT # Test that the instrumented data makes sense RUN: llvm-bolt %t.exe -o %t.bolted --data %t.fdata \ RUN: --reorder-blocks=ext-tsp --reorder-functions=hfsort+ \ RUN: --print-only=interp --print-finalized RUN: %t.bolted | FileCheck %s -check-prefix=CHECK-OUTPUT CHECK-OUTPUT: [child] CHECK-OUTPUT: [parent] */