1 /*
2 Copyright (C) 2005-2019 Intel Corporation
3
4 SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause
5 */
6
7 #include "ittnotify_config.h"
8
9 #if ITT_PLATFORM==ITT_PLATFORM_WIN
10 #include <windows.h>
11 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
12 #if ITT_PLATFORM != ITT_PLATFORM_MAC && ITT_PLATFORM != ITT_PLATFORM_FREEBSD
13 #include <malloc.h>
14 #endif
15 #include <stdlib.h>
16
17 #include "jitprofiling.h"
18
19 static const char rcsid[] = "\n@(#) $Revision$\n";
20
21 #define DLL_ENVIRONMENT_VAR "VS_PROFILER"
22
23 #ifndef NEW_DLL_ENVIRONMENT_VAR
24 #if ITT_ARCH==ITT_ARCH_IA32
25 #define NEW_DLL_ENVIRONMENT_VAR "INTEL_JIT_PROFILER32"
26 #else
27 #define NEW_DLL_ENVIRONMENT_VAR "INTEL_JIT_PROFILER64"
28 #endif
29 #endif /* NEW_DLL_ENVIRONMENT_VAR */
30
31 #if ITT_PLATFORM==ITT_PLATFORM_WIN
32 #define DEFAULT_DLLNAME "JitPI.dll"
33 HINSTANCE m_libHandle = NULL;
34 #elif ITT_PLATFORM==ITT_PLATFORM_MAC
35 #define DEFAULT_DLLNAME "libJitPI.dylib"
36 void* m_libHandle = NULL;
37 #else
38 #define DEFAULT_DLLNAME "libJitPI.so"
39 void* m_libHandle = NULL;
40 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
41
42 /* default location of JIT profiling agent on Android */
43 #define ANDROID_JIT_AGENT_PATH "/data/intel/libittnotify.so"
44
45 /* the function pointers */
46 typedef unsigned int(JITAPI *TPInitialize)(void);
47 static TPInitialize FUNC_Initialize=NULL;
48
49 typedef unsigned int(JITAPI *TPNotify)(unsigned int, void*);
50 static TPNotify FUNC_NotifyEvent=NULL;
51
52 static iJIT_IsProfilingActiveFlags executionMode = iJIT_NOTHING_RUNNING;
53
54 /* end collector dll part. */
55
56 /* loadiJIT_Funcs() : this function is called just in the beginning
57 * and is responsible to load the functions from BistroJavaCollector.dll
58 * result:
59 * on success: the functions loads, iJIT_DLL_is_missing=0, return value = 1
60 * on failure: the functions are NULL, iJIT_DLL_is_missing=1, return value = 0
61 */
62 static int loadiJIT_Funcs(void);
63
64 /* global representing whether the collector can't be loaded */
65 static int iJIT_DLL_is_missing = 0;
66
67 ITT_EXTERN_C int JITAPI
iJIT_NotifyEvent(iJIT_JVM_EVENT event_type,void * EventSpecificData)68 iJIT_NotifyEvent(iJIT_JVM_EVENT event_type, void *EventSpecificData)
69 {
70 int ReturnValue = 0;
71
72 /* initialization part - the collector has not been loaded yet. */
73 if (!FUNC_NotifyEvent)
74 {
75 if (iJIT_DLL_is_missing)
76 return 0;
77
78 if (!loadiJIT_Funcs())
79 return 0;
80 }
81
82 if (event_type == iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED ||
83 event_type == iJVM_EVENT_TYPE_METHOD_UPDATE)
84 {
85 if (((piJIT_Method_Load)EventSpecificData)->method_id == 0)
86 return 0;
87 }
88 else if (event_type == iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED_V2)
89 {
90 if (((piJIT_Method_Load_V2)EventSpecificData)->method_id == 0)
91 return 0;
92 }
93 else if (event_type == iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED_V3)
94 {
95 if (((piJIT_Method_Load_V3)EventSpecificData)->method_id == 0)
96 return 0;
97 }
98 else if (event_type == iJVM_EVENT_TYPE_METHOD_INLINE_LOAD_FINISHED)
99 {
100 if (((piJIT_Method_Inline_Load)EventSpecificData)->method_id == 0 ||
101 ((piJIT_Method_Inline_Load)EventSpecificData)->parent_method_id == 0)
102 return 0;
103 }
104
105 ReturnValue = (int)FUNC_NotifyEvent(event_type, EventSpecificData);
106
107 return ReturnValue;
108 }
109
iJIT_IsProfilingActive()110 ITT_EXTERN_C iJIT_IsProfilingActiveFlags JITAPI iJIT_IsProfilingActive()
111 {
112 if (!iJIT_DLL_is_missing)
113 {
114 loadiJIT_Funcs();
115 }
116
117 return executionMode;
118 }
119
120 /* This function loads the collector dll and the relevant functions.
121 * on success: all functions load, iJIT_DLL_is_missing = 0, return value = 1
122 * on failure: all functions are NULL, iJIT_DLL_is_missing = 1, return value = 0
123 */
loadiJIT_Funcs()124 static int loadiJIT_Funcs()
125 {
126 static int bDllWasLoaded = 0;
127 char *dllName = (char*)rcsid; /* !! Just to avoid unused code elimination */
128 #if ITT_PLATFORM==ITT_PLATFORM_WIN
129 DWORD dNameLength = 0;
130 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
131
132 if(bDllWasLoaded)
133 {
134 /* dll was already loaded, no need to do it for the second time */
135 return 1;
136 }
137
138 /* Assumes that the DLL will not be found */
139 iJIT_DLL_is_missing = 1;
140 FUNC_NotifyEvent = NULL;
141
142 if (m_libHandle)
143 {
144 #if ITT_PLATFORM==ITT_PLATFORM_WIN
145 FreeLibrary(m_libHandle);
146 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
147 dlclose(m_libHandle);
148 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
149 m_libHandle = NULL;
150 }
151
152 /* Try to get the dll name from the environment */
153 #if ITT_PLATFORM==ITT_PLATFORM_WIN
154 dNameLength = GetEnvironmentVariableA(NEW_DLL_ENVIRONMENT_VAR, NULL, 0);
155 if (dNameLength)
156 {
157 DWORD envret = 0;
158 dllName = (char*)malloc(sizeof(char) * (dNameLength + 1));
159 if(dllName != NULL)
160 {
161 envret = GetEnvironmentVariableA(NEW_DLL_ENVIRONMENT_VAR,
162 dllName, dNameLength);
163 if (envret)
164 {
165 /* Try to load the dll from the PATH... */
166 m_libHandle = LoadLibraryExA(dllName,
167 NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
168 }
169 free(dllName);
170 }
171 } else {
172 /* Try to use old VS_PROFILER variable */
173 dNameLength = GetEnvironmentVariableA(DLL_ENVIRONMENT_VAR, NULL, 0);
174 if (dNameLength)
175 {
176 DWORD envret = 0;
177 dllName = (char*)malloc(sizeof(char) * (dNameLength + 1));
178 if(dllName != NULL)
179 {
180 envret = GetEnvironmentVariableA(DLL_ENVIRONMENT_VAR,
181 dllName, dNameLength);
182 if (envret)
183 {
184 /* Try to load the dll from the PATH... */
185 m_libHandle = LoadLibraryA(dllName);
186 }
187 free(dllName);
188 }
189 }
190 }
191 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
192 dllName = getenv(NEW_DLL_ENVIRONMENT_VAR);
193 if (!dllName)
194 dllName = getenv(DLL_ENVIRONMENT_VAR);
195 #if defined(__ANDROID__) || defined(ANDROID)
196 if (!dllName)
197 dllName = ANDROID_JIT_AGENT_PATH;
198 #endif
199 if (dllName)
200 {
201 /* Try to load the dll from the PATH... */
202 if (DL_SYMBOLS)
203 {
204 m_libHandle = dlopen(dllName, RTLD_LAZY);
205 }
206 }
207 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
208
209 if (!m_libHandle)
210 {
211 #if ITT_PLATFORM==ITT_PLATFORM_WIN
212 m_libHandle = LoadLibraryA(DEFAULT_DLLNAME);
213 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
214 if (DL_SYMBOLS)
215 {
216 m_libHandle = dlopen(DEFAULT_DLLNAME, RTLD_LAZY);
217 }
218 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
219 }
220
221 /* if the dll wasn't loaded - exit. */
222 if (!m_libHandle)
223 {
224 iJIT_DLL_is_missing = 1; /* don't try to initialize
225 * JIT agent the second time
226 */
227 return 0;
228 }
229
230 #if ITT_PLATFORM==ITT_PLATFORM_WIN
231 FUNC_NotifyEvent = (TPNotify)GetProcAddress(m_libHandle, "NotifyEvent");
232 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
233 FUNC_NotifyEvent = (TPNotify)dlsym(m_libHandle, "NotifyEvent");
234 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
235 if (!FUNC_NotifyEvent)
236 {
237 FUNC_Initialize = NULL;
238 return 0;
239 }
240
241 #if ITT_PLATFORM==ITT_PLATFORM_WIN
242 FUNC_Initialize = (TPInitialize)GetProcAddress(m_libHandle, "Initialize");
243 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
244 FUNC_Initialize = (TPInitialize)dlsym(m_libHandle, "Initialize");
245 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
246 if (!FUNC_Initialize)
247 {
248 FUNC_NotifyEvent = NULL;
249 return 0;
250 }
251
252 executionMode = (iJIT_IsProfilingActiveFlags)FUNC_Initialize();
253
254 bDllWasLoaded = 1;
255 iJIT_DLL_is_missing = 0; /* DLL is ok. */
256
257 return 1;
258 }
259
iJIT_GetNewMethodID()260 ITT_EXTERN_C unsigned int JITAPI iJIT_GetNewMethodID()
261 {
262 static unsigned int methodID = 1;
263
264 if (methodID == 0)
265 return 0; /* ERROR : this is not a valid value */
266
267 return methodID++;
268 }
269