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