161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky//===-- OProfileWrapper.h - OProfile JIT API Wrapper ------------*- C++ -*-===//
261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky//
361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky//                     The LLVM Compiler Infrastructure
461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky//
561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky// This file is distributed under the University of Illinois Open Source
661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky// License. See LICENSE.TXT for details.
761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky//
861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky//===----------------------------------------------------------------------===//
961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky// This file defines a OProfileWrapper object that detects if the oprofile
1061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky// daemon is running, and provides wrappers for opagent functions used to
1161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky// communicate with the oprofile JIT interface. The dynamic library libopagent
1261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky// does not need to be linked directly as this object lazily loads the library
1361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky// when the first op_ function is called.
1461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky//
1561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky// See http://oprofile.sourceforge.net/doc/devel/jit-interface.html for the
1661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky// definition of the interface.
1761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky//
1861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky//===----------------------------------------------------------------------===//
1961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky
20674be02d525d4e24bc6943ed9274958c580bcfbcJakub Staszak#ifndef LLVM_EXECUTIONENGINE_OPROFILEWRAPPER_H
21674be02d525d4e24bc6943ed9274958c580bcfbcJakub Staszak#define LLVM_EXECUTIONENGINE_OPROFILEWRAPPER_H
2261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky
2361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky#include "llvm/Support/DataTypes.h"
2461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky#include <opagent.h>
2561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky
2661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Benderskynamespace llvm {
2761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky
2861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky
2961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Benderskyclass OProfileWrapper {
3061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  typedef  op_agent_t    (*op_open_agent_ptr_t)();
3161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  typedef  int           (*op_close_agent_ptr_t)(op_agent_t);
3261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  typedef  int           (*op_write_native_code_ptr_t)(op_agent_t,
3361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky                                                const char*,
3461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky                                                uint64_t,
3561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky                                                void const*,
3661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky                                                const unsigned int);
3761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  typedef  int           (*op_write_debug_line_info_ptr_t)(op_agent_t,
3861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky                                                void const*,
3961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky                                                size_t,
4061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky                                                struct debug_line_info const*);
4161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  typedef  int           (*op_unload_native_code_ptr_t)(op_agent_t, uint64_t);
4261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky
4361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  // Also used for op_minor_version function which has the same signature
4479c07d2a36282b09b9c5d0aa65ebf4bff017621bDmitri Gribenko  typedef  int           (*op_major_version_ptr_t)();
4561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky
4661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  // This is not a part of the opagent API, but is useful nonetheless
4779c07d2a36282b09b9c5d0aa65ebf4bff017621bDmitri Gribenko  typedef  bool          (*IsOProfileRunningPtrT)();
4861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky
4961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky
5061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  op_agent_t                      Agent;
5161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  op_open_agent_ptr_t             OpenAgentFunc;
5261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  op_close_agent_ptr_t            CloseAgentFunc;
5361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  op_write_native_code_ptr_t      WriteNativeCodeFunc;
5461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  op_write_debug_line_info_ptr_t  WriteDebugLineInfoFunc;
5561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  op_unload_native_code_ptr_t     UnloadNativeCodeFunc;
5661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  op_major_version_ptr_t          MajorVersionFunc;
5761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  op_major_version_ptr_t          MinorVersionFunc;
5861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  IsOProfileRunningPtrT           IsOProfileRunningFunc;
5961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky
6061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  bool Initialized;
6161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky
6261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Benderskypublic:
6361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  OProfileWrapper();
6461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky
6561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  // For testing with a mock opagent implementation, skips the dynamic load and
6661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  // the function resolution.
6761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  OProfileWrapper(op_open_agent_ptr_t OpenAgentImpl,
6861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky                  op_close_agent_ptr_t CloseAgentImpl,
6961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky                  op_write_native_code_ptr_t WriteNativeCodeImpl,
7061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky                  op_write_debug_line_info_ptr_t WriteDebugLineInfoImpl,
7161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky                  op_unload_native_code_ptr_t UnloadNativeCodeImpl,
7261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky                  op_major_version_ptr_t MajorVersionImpl,
7361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky                  op_major_version_ptr_t MinorVersionImpl,
7461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky                  IsOProfileRunningPtrT MockIsOProfileRunningImpl = 0)
7561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  : OpenAgentFunc(OpenAgentImpl),
7661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky    CloseAgentFunc(CloseAgentImpl),
7761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky    WriteNativeCodeFunc(WriteNativeCodeImpl),
7861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky    WriteDebugLineInfoFunc(WriteDebugLineInfoImpl),
7961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky    UnloadNativeCodeFunc(UnloadNativeCodeImpl),
8061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky    MajorVersionFunc(MajorVersionImpl),
8161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky    MinorVersionFunc(MinorVersionImpl),
8261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky    IsOProfileRunningFunc(MockIsOProfileRunningImpl),
8361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky    Initialized(true)
8461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  {
8561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  }
8661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky
8761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  // Calls op_open_agent in the oprofile JIT library and saves the returned
8861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  // op_agent_t handle internally so it can be used when calling all the other
8961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  // op_* functions. Callers of this class do not need to keep track of
9061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  // op_agent_t objects.
9161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  bool op_open_agent();
9261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky
9361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  int op_close_agent();
9461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  int op_write_native_code(const char* name,
9561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky                           uint64_t addr,
9661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky                           void const* code,
9761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky                           const unsigned int size);
9861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  int op_write_debug_line_info(void const* code,
9961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky                               size_t num_entries,
10061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky                               struct debug_line_info const* info);
10161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  int op_unload_native_code(uint64_t addr);
10279c07d2a36282b09b9c5d0aa65ebf4bff017621bDmitri Gribenko  int op_major_version();
10379c07d2a36282b09b9c5d0aa65ebf4bff017621bDmitri Gribenko  int op_minor_version();
10461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky
10561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  // Returns true if the oprofiled process is running, the opagent library is
10661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  // loaded and a connection to the agent has been established, and false
10761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  // otherwise.
10861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  bool isAgentAvailable();
10961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky
11061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Benderskyprivate:
11161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  // Loads the libopagent library and initializes this wrapper if the oprofile
11261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  // daemon is running
11361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  bool initialize();
11461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky
11561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  // Searches /proc for the oprofile daemon and returns true if the process if
11661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  // found, or false otherwise.
11761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  bool checkForOProfileProcEntry();
11861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky
11961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  bool isOProfileRunning();
12061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky};
12161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky
12261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky} // namespace llvm
12361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky
124674be02d525d4e24bc6943ed9274958c580bcfbcJakub Staszak#endif // LLVM_EXECUTIONENGINE_OPROFILEWRAPPER_H
125