1 | /* Checks that BOLT correctly handles instrumentation shared libraries |
2 | * with further optimization. |
3 | */ |
4 | #include <dlfcn.h> |
5 | #include <stdio.h> |
6 | |
7 | #ifdef LIB |
8 | int foo(int x) { return x + 1; } |
9 | |
10 | int fib(int x) { |
11 | if (x < 2) |
12 | return x; |
13 | return fib(x - 1) + fib(x - 2); |
14 | } |
15 | |
16 | int bar(int x) { return x - 1; } |
17 | #endif |
18 | |
19 | #ifndef LIB |
20 | int main(int argc, char **argv) { |
21 | int (*fib_func)(int); |
22 | char *libname; |
23 | void *hndl; |
24 | int val; |
25 | if (argc < 2) |
26 | return -1; |
27 | /* |
28 | * Expected library name as input to switch |
29 | * between original and instrumented file |
30 | */ |
31 | libname = argv[1]; |
32 | hndl = dlopen(file: libname, RTLD_LAZY); |
33 | if (!hndl) { |
34 | printf(format: "library load failed\n" ); |
35 | return -1; |
36 | } |
37 | fib_func = dlsym(handle: hndl, name: "fib" ); |
38 | if (!fib_func) { |
39 | printf(format: "fib_func load failed\n" ); |
40 | return -1; |
41 | } |
42 | val = fib_func(argc); |
43 | dlclose(handle: hndl); |
44 | printf(format: "fib(%d) = %d\n" , argc, val); |
45 | return 0; |
46 | } |
47 | #endif |
48 | |
49 | /* |
50 | REQUIRES: system-linux,bolt-runtime |
51 | |
52 | RUN: %clang %cflags %s -o %t.so -Wl,-q -fpie -fPIC -shared -DLIB |
53 | RUN: %clang %cflags %s -o %t.exe -Wl,-q -ldl |
54 | |
55 | RUN: llvm-bolt %t.so --instrument --instrumentation-file=%t.so.fdata \ |
56 | RUN: -o %t.so.instrumented |
57 | |
58 | # Program with instrumented shared library needs to finish returning zero |
59 | RUN: %t.exe %t.so.instrumented 1 2 | FileCheck %s -check-prefix=CHECK-OUTPUT |
60 | RUN: test -f %t.so.fdata |
61 | |
62 | # Test that the instrumented data makes sense |
63 | RUN: llvm-bolt %t.so -o %t.so.bolted --data %t.so.fdata \ |
64 | RUN: --reorder-blocks=ext-tsp --reorder-functions=hfsort+ |
65 | |
66 | RUN: %t.exe %t.so.bolted 1 2 | FileCheck %s -check-prefix=CHECK-OUTPUT |
67 | |
68 | CHECK-OUTPUT: fib(4) = 3 |
69 | */ |
70 | |