1 /* <copyright>
2 
3   Contact Information:
4   https://software.intel.com/content/www/us/en/develop/tools/vtune-profiler.html
5 
6   BSD LICENSE
7 
8   Copyright (c) 2005-2014 Intel Corporation. All rights reserved.
9   All rights reserved.
10 
11   Redistribution and use in source and binary forms, with or without
12   modification, are permitted provided that the following conditions
13   are met:
14 
15     * Redistributions of source code must retain the above copyright
16       notice, this list of conditions and the following disclaimer.
17     * Redistributions in binary form must reproduce the above copyright
18       notice, this list of conditions and the following disclaimer in
19       the documentation and/or other materials provided with the
20       distribution.
21     * Neither the name of Intel Corporation nor the names of its
22       contributors may be used to endorse or promote products derived
23       from this software without specific prior written permission.
24 
25   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 </copyright> */
37 
38 #include "ittnotify_config.h"
39 
40 #if ITT_PLATFORM==ITT_PLATFORM_WIN
41 #include <windows.h>
42 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
43 #if ITT_PLATFORM != ITT_PLATFORM_MAC && ITT_PLATFORM != ITT_PLATFORM_FREEBSD && ITT_PLATFORM != ITT_PLATFORM_OPENBSD && ITT_PLATFORM != ITT_PLATFORM_DRAGONFLY
44 #include <malloc.h>
45 #endif
46 #include <stdlib.h>
47 
48 #include "jitprofiling.h"
49 
50 static const char rcsid[] = "\n@(#) $Revision: 471937 $\n";
51 
52 #define DLL_ENVIRONMENT_VAR             "VS_PROFILER"
53 
54 #ifndef NEW_DLL_ENVIRONMENT_VAR
55 #if ITT_ARCH==ITT_ARCH_IA32
56 #define NEW_DLL_ENVIRONMENT_VAR	        "INTEL_JIT_PROFILER32"
57 #else
58 #define NEW_DLL_ENVIRONMENT_VAR	        "INTEL_JIT_PROFILER64"
59 #endif
60 #endif /* NEW_DLL_ENVIRONMENT_VAR */
61 
62 #if ITT_PLATFORM==ITT_PLATFORM_WIN
63 #define DEFAULT_DLLNAME                 "JitPI.dll"
64 HINSTANCE m_libHandle = NULL;
65 #elif ITT_PLATFORM==ITT_PLATFORM_MAC
66 #define DEFAULT_DLLNAME                 "libJitPI.dylib"
67 void* m_libHandle = NULL;
68 #else
69 #define DEFAULT_DLLNAME                 "libJitPI.so"
70 void* m_libHandle = NULL;
71 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
72 
73 /* default location of JIT profiling agent on Android */
74 #define ANDROID_JIT_AGENT_PATH  "/data/intel/libittnotify.so"
75 
76 /* the function pointers */
77 typedef unsigned int(JITAPI *TPInitialize)(void);
78 static TPInitialize FUNC_Initialize=NULL;
79 
80 typedef unsigned int(JITAPI *TPNotify)(unsigned int, void*);
81 static TPNotify FUNC_NotifyEvent=NULL;
82 
83 static iJIT_IsProfilingActiveFlags executionMode = iJIT_NOTHING_RUNNING;
84 
85 /* end collector dll part. */
86 
87 /* loadiJIT_Funcs() : this function is called just in the beginning
88  * and is responsible to load the functions from BistroJavaCollector.dll
89  * result:
90  *  on success: the functions loads, iJIT_DLL_is_missing=0, return value = 1
91  *  on failure: the functions are NULL, iJIT_DLL_is_missing=1, return value = 0
92  */
93 static int loadiJIT_Funcs(void);
94 
95 /* global representing whether the collector can't be loaded */
96 static int iJIT_DLL_is_missing = 0;
97 
98 ITT_EXTERN_C int JITAPI
iJIT_NotifyEvent(iJIT_JVM_EVENT event_type,void * EventSpecificData)99 iJIT_NotifyEvent(iJIT_JVM_EVENT event_type, void *EventSpecificData)
100 {
101     int ReturnValue = 0;
102 
103     /* initialization part - the collector has not been loaded yet. */
104     if (!FUNC_NotifyEvent)
105     {
106         if (iJIT_DLL_is_missing)
107             return 0;
108 
109         if (!loadiJIT_Funcs())
110             return 0;
111     }
112 
113     if (event_type == iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED ||
114         event_type == iJVM_EVENT_TYPE_METHOD_UPDATE)
115     {
116         if (((piJIT_Method_Load)EventSpecificData)->method_id == 0)
117             return 0;
118     }
119     else if (event_type == iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED_V2)
120     {
121         if (((piJIT_Method_Load_V2)EventSpecificData)->method_id == 0)
122             return 0;
123     }
124     else if (event_type == iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED_V3)
125     {
126         if (((piJIT_Method_Load_V3)EventSpecificData)->method_id == 0)
127             return 0;
128     }
129     else if (event_type == iJVM_EVENT_TYPE_METHOD_INLINE_LOAD_FINISHED)
130     {
131         if (((piJIT_Method_Inline_Load)EventSpecificData)->method_id == 0 ||
132             ((piJIT_Method_Inline_Load)EventSpecificData)->parent_method_id == 0)
133             return 0;
134     }
135 
136     ReturnValue = (int)FUNC_NotifyEvent(event_type, EventSpecificData);
137 
138     return ReturnValue;
139 }
140 
iJIT_IsProfilingActive()141 ITT_EXTERN_C iJIT_IsProfilingActiveFlags JITAPI iJIT_IsProfilingActive()
142 {
143     if (!iJIT_DLL_is_missing)
144     {
145         loadiJIT_Funcs();
146     }
147 
148     return executionMode;
149 }
150 
151 /* This function loads the collector dll and the relevant functions.
152  * on success: all functions load,     iJIT_DLL_is_missing = 0, return value = 1
153  * on failure: all functions are NULL, iJIT_DLL_is_missing = 1, return value = 0
154  */
loadiJIT_Funcs()155 static int loadiJIT_Funcs()
156 {
157     static int bDllWasLoaded = 0;
158     char *dllName = (char*)rcsid; /* !! Just to avoid unused code elimination */
159 #if ITT_PLATFORM==ITT_PLATFORM_WIN
160     DWORD dNameLength = 0;
161 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
162 
163     if(bDllWasLoaded)
164     {
165         /* dll was already loaded, no need to do it for the second time */
166         return 1;
167     }
168 
169     /* Assumes that the DLL will not be found */
170     iJIT_DLL_is_missing = 1;
171     FUNC_NotifyEvent = NULL;
172 
173     if (m_libHandle)
174     {
175 #if ITT_PLATFORM==ITT_PLATFORM_WIN
176         FreeLibrary(m_libHandle);
177 #else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
178         dlclose(m_libHandle);
179 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
180         m_libHandle = NULL;
181     }
182 
183     /* Try to get the dll name from the environment */
184 #if ITT_PLATFORM==ITT_PLATFORM_WIN
185     dNameLength = GetEnvironmentVariableA(NEW_DLL_ENVIRONMENT_VAR, NULL, 0);
186     if (dNameLength)
187     {
188         DWORD envret = 0;
189         dllName = (char*)malloc(sizeof(char) * (dNameLength + 1));
190         if(dllName != NULL)
191         {
192             envret = GetEnvironmentVariableA(NEW_DLL_ENVIRONMENT_VAR,
193                                              dllName, dNameLength);
194             if (envret)
195             {
196                 /* Try to load the dll from the PATH... */
197                 m_libHandle = LoadLibraryExA(dllName,
198                                              NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
199             }
200             free(dllName);
201         }
202     } else {
203         /* Try to use old VS_PROFILER variable */
204         dNameLength = GetEnvironmentVariableA(DLL_ENVIRONMENT_VAR, NULL, 0);
205         if (dNameLength)
206         {
207             DWORD envret = 0;
208             dllName = (char*)malloc(sizeof(char) * (dNameLength + 1));
209             if(dllName != NULL)
210             {
211                 envret = GetEnvironmentVariableA(DLL_ENVIRONMENT_VAR,
212                                                  dllName, dNameLength);
213                 if (envret)
214                 {
215                     /* Try to load the dll from the PATH... */
216                     m_libHandle = LoadLibraryA(dllName);
217                 }
218                 free(dllName);
219             }
220         }
221     }
222 #else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
223     dllName = getenv(NEW_DLL_ENVIRONMENT_VAR);
224     if (!dllName)
225         dllName = getenv(DLL_ENVIRONMENT_VAR);
226 #if defined(__ANDROID__) || defined(ANDROID)
227     if (!dllName)
228         dllName = ANDROID_JIT_AGENT_PATH;
229 #endif
230     if (dllName)
231     {
232         /* Try to load the dll from the PATH... */
233         m_libHandle = dlopen(dllName, RTLD_LAZY);
234     }
235 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
236 
237     if (!m_libHandle)
238     {
239 #if ITT_PLATFORM==ITT_PLATFORM_WIN
240         m_libHandle = LoadLibraryA(DEFAULT_DLLNAME);
241 #else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
242         m_libHandle = dlopen(DEFAULT_DLLNAME, RTLD_LAZY);
243 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
244     }
245 
246     /* if the dll wasn't loaded - exit. */
247     if (!m_libHandle)
248     {
249         iJIT_DLL_is_missing = 1; /* don't try to initialize
250                                   * JIT agent the second time
251                                   */
252         return 0;
253     }
254 
255 #if ITT_PLATFORM==ITT_PLATFORM_WIN
256     FUNC_NotifyEvent = (TPNotify)GetProcAddress(m_libHandle, "NotifyEvent");
257 #else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
258     FUNC_NotifyEvent = (TPNotify)dlsym(m_libHandle, "NotifyEvent");
259 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
260     if (!FUNC_NotifyEvent)
261     {
262         FUNC_Initialize = NULL;
263         return 0;
264     }
265 
266 #if ITT_PLATFORM==ITT_PLATFORM_WIN
267     FUNC_Initialize = (TPInitialize)GetProcAddress(m_libHandle, "Initialize");
268 #else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
269     FUNC_Initialize = (TPInitialize)dlsym(m_libHandle, "Initialize");
270 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
271     if (!FUNC_Initialize)
272     {
273         FUNC_NotifyEvent = NULL;
274         return 0;
275     }
276 
277     executionMode = (iJIT_IsProfilingActiveFlags)FUNC_Initialize();
278 
279     bDllWasLoaded = 1;
280     iJIT_DLL_is_missing = 0; /* DLL is ok. */
281 
282     return 1;
283 }
284 
iJIT_GetNewMethodID()285 ITT_EXTERN_C unsigned int JITAPI iJIT_GetNewMethodID()
286 {
287     static unsigned int methodID = 1;
288 
289     if (methodID == 0)
290         return 0;  /* ERROR : this is not a valid value */
291 
292     return methodID++;
293 }
294