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