1 | // Check that we can turn a function id to a function address, and also get the |
2 | // maximum function id for the current binary. |
3 | // |
4 | // RUN: %clangxx_xray -std=c++11 %s -o %t |
5 | // RUN: XRAY_OPTIONS="patch_premain=false" %run %t |
6 | // RUN: %clangxx_xray -fno-xray-function-index -std=c++11 %s -o %t |
7 | // RUN: XRAY_OPTIONS="patch_premain=false" %run %t |
8 | |
9 | // UNSUPPORTED: target-is-mips64,target-is-mips64el |
10 | |
11 | #include "xray/xray_interface.h" |
12 | #include <algorithm> |
13 | #include <cassert> |
14 | #include <cstdio> |
15 | #include <iterator> |
16 | #include <set> |
17 | |
18 | [[clang::xray_always_instrument]] void bar(){} |
19 | |
20 | [[clang::xray_always_instrument]] void foo() { |
21 | bar(); |
22 | } |
23 | |
24 | [[clang::xray_always_instrument]] int main(int argc, char *argv[]) { |
25 | assert(__xray_max_function_id() != 0 && "we need xray instrumentation!" ); |
26 | std::set<void *> must_be_instrumented = {reinterpret_cast<void *>(&foo), |
27 | reinterpret_cast<void *>(&bar), |
28 | reinterpret_cast<void *>(&main)}; |
29 | std::set<void *> all_instrumented; |
30 | for (auto i = __xray_max_function_id(); i != 0; --i) { |
31 | auto addr = __xray_function_address(FuncId: i); |
32 | all_instrumented.insert(x: reinterpret_cast<void *>(addr)); |
33 | } |
34 | assert(all_instrumented.size() == __xray_max_function_id() && |
35 | "each function id must be assigned to a unique function" ); |
36 | |
37 | std::set<void *> not_instrumented; |
38 | std::set_difference( |
39 | first1: must_be_instrumented.begin(), last1: must_be_instrumented.end(), |
40 | first2: all_instrumented.begin(), last2: all_instrumented.end(), |
41 | result: std::inserter(x&: not_instrumented, i: not_instrumented.begin())); |
42 | assert( |
43 | not_instrumented.empty() && |
44 | "we should see all explicitly instrumented functions with function ids" ); |
45 | return not_instrumented.empty() ? 0 : 1; |
46 | } |
47 | |