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