1 //===-- OProfileWrapper.h - OProfile JIT API Wrapper ------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // This file defines a OProfileWrapper object that detects if the oprofile 9 // daemon is running, and provides wrappers for opagent functions used to 10 // communicate with the oprofile JIT interface. The dynamic library libopagent 11 // does not need to be linked directly as this object lazily loads the library 12 // when the first op_ function is called. 13 // 14 // See http://oprofile.sourceforge.net/doc/devel/jit-interface.html for the 15 // definition of the interface. 16 // 17 //===----------------------------------------------------------------------===// 18 19 #ifndef LLVM_EXECUTIONENGINE_OPROFILEWRAPPER_H 20 #define LLVM_EXECUTIONENGINE_OPROFILEWRAPPER_H 21 22 #include "llvm/Support/DataTypes.h" 23 #include <opagent.h> 24 25 namespace llvm { 26 27 28 class OProfileWrapper { 29 typedef op_agent_t (*op_open_agent_ptr_t)(); 30 typedef int (*op_close_agent_ptr_t)(op_agent_t); 31 typedef int (*op_write_native_code_ptr_t)(op_agent_t, 32 const char*, 33 uint64_t, 34 void const*, 35 const unsigned int); 36 typedef int (*op_write_debug_line_info_ptr_t)(op_agent_t, 37 void const*, 38 size_t, 39 struct debug_line_info const*); 40 typedef int (*op_unload_native_code_ptr_t)(op_agent_t, uint64_t); 41 42 // Also used for op_minor_version function which has the same signature 43 typedef int (*op_major_version_ptr_t)(); 44 45 // This is not a part of the opagent API, but is useful nonetheless 46 typedef bool (*IsOProfileRunningPtrT)(); 47 48 49 op_agent_t Agent; 50 op_open_agent_ptr_t OpenAgentFunc; 51 op_close_agent_ptr_t CloseAgentFunc; 52 op_write_native_code_ptr_t WriteNativeCodeFunc; 53 op_write_debug_line_info_ptr_t WriteDebugLineInfoFunc; 54 op_unload_native_code_ptr_t UnloadNativeCodeFunc; 55 op_major_version_ptr_t MajorVersionFunc; 56 op_major_version_ptr_t MinorVersionFunc; 57 IsOProfileRunningPtrT IsOProfileRunningFunc; 58 59 bool Initialized; 60 61 public: 62 OProfileWrapper(); 63 64 // For testing with a mock opagent implementation, skips the dynamic load and 65 // the function resolution. 66 OProfileWrapper(op_open_agent_ptr_t OpenAgentImpl, 67 op_close_agent_ptr_t CloseAgentImpl, 68 op_write_native_code_ptr_t WriteNativeCodeImpl, 69 op_write_debug_line_info_ptr_t WriteDebugLineInfoImpl, 70 op_unload_native_code_ptr_t UnloadNativeCodeImpl, 71 op_major_version_ptr_t MajorVersionImpl, 72 op_major_version_ptr_t MinorVersionImpl, 73 IsOProfileRunningPtrT MockIsOProfileRunningImpl = 0) 74 : OpenAgentFunc(OpenAgentImpl), 75 CloseAgentFunc(CloseAgentImpl), 76 WriteNativeCodeFunc(WriteNativeCodeImpl), 77 WriteDebugLineInfoFunc(WriteDebugLineInfoImpl), 78 UnloadNativeCodeFunc(UnloadNativeCodeImpl), 79 MajorVersionFunc(MajorVersionImpl), 80 MinorVersionFunc(MinorVersionImpl), 81 IsOProfileRunningFunc(MockIsOProfileRunningImpl), 82 Initialized(true) 83 { 84 } 85 86 // Calls op_open_agent in the oprofile JIT library and saves the returned 87 // op_agent_t handle internally so it can be used when calling all the other 88 // op_* functions. Callers of this class do not need to keep track of 89 // op_agent_t objects. 90 bool op_open_agent(); 91 92 int op_close_agent(); 93 int op_write_native_code(const char* name, 94 uint64_t addr, 95 void const* code, 96 const unsigned int size); 97 int op_write_debug_line_info(void const* code, 98 size_t num_entries, 99 struct debug_line_info const* info); 100 int op_unload_native_code(uint64_t addr); 101 int op_major_version(); 102 int op_minor_version(); 103 104 // Returns true if the oprofiled process is running, the opagent library is 105 // loaded and a connection to the agent has been established, and false 106 // otherwise. 107 bool isAgentAvailable(); 108 109 private: 110 // Loads the libopagent library and initializes this wrapper if the oprofile 111 // daemon is running 112 bool initialize(); 113 114 // Searches /proc for the oprofile daemon and returns true if the process is 115 // found, or false otherwise. 116 bool checkForOProfileProcEntry(); 117 118 bool isOProfileRunning(); 119 }; 120 121 } // namespace llvm 122 123 #endif // LLVM_EXECUTIONENGINE_OPROFILEWRAPPER_H 124