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