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(i); 32 all_instrumented.insert(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 must_be_instrumented.begin(), must_be_instrumented.end(), 40 all_instrumented.begin(), all_instrumented.end(), 41 std::inserter(not_instrumented, 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