1 /*
2     Copyright (c) 2005-2021 Intel Corporation
3 
4     Licensed under the Apache License, Version 2.0 (the "License");
5     you may not use this file except in compliance with the License.
6     You may obtain a copy of the License at
7 
8         http://www.apache.org/licenses/LICENSE-2.0
9 
10     Unless required by applicable law or agreed to in writing, software
11     distributed under the License is distributed on an "AS IS" BASIS,
12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13     See the License for the specific language governing permissions and
14     limitations under the License.
15 */
16 
17 #include "ittnotify_config.h"
18 
19 #if ITT_PLATFORM==ITT_PLATFORM_WIN
20 #ifdef PATH_MAX
21 #undef PATH_MAX
22 #endif
23 #define PATH_MAX 512
24 #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */
25 #include <limits.h>
26 #include <dlfcn.h>
27 #include <errno.h>
28 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <stdarg.h>
32 #include <string.h>
33 
34 #define INTEL_NO_MACRO_BODY
35 #define INTEL_ITTNOTIFY_API_PRIVATE
36 #include "ittnotify.h"
37 #include "legacy/ittnotify.h"
38 
39 #include "disable_warnings.h"
40 
41 static const char api_version[] = API_VERSION "\0\n@(#) $Revision$\n";
42 
43 #define _N_(n) ITT_JOIN(INTEL_ITTNOTIFY_PREFIX,n)
44 
45 #ifndef HAS_CPP_ATTR
46 #if defined(__cplusplus) && defined(__has_cpp_attribute)
47 #define HAS_CPP_ATTR(X) __has_cpp_attribute(X)
48 #else
49 #define HAS_CPP_ATTR(X) 0
50 #endif
51 #endif
52 
53 #ifndef HAS_C_ATTR
54 #if defined(__STDC__) && defined(__has_c_attribute)
55 #define HAS_C_ATTR(X) __has_c_attribute(X)
56 #else
57 #define HAS_C_ATTR(X) 0
58 #endif
59 #endif
60 
61 #ifndef HAS_GNU_ATTR
62 #if defined(__has_attribute)
63 #define HAS_GNU_ATTR(X) __has_attribute(X)
64 #else
65 #define HAS_GNU_ATTR(X) 0
66 #endif
67 #endif
68 
69 #ifndef ITT_ATTRIBUTE_FALLTHROUGH
70 #if (HAS_CPP_ATTR(fallthrough) || HAS_C_ATTR(fallthrough)) && (__cplusplus >= 201703L || _MSVC_LANG >= 201703L)
71 #define ITT_ATTRIBUTE_FALLTHROUGH [[fallthrough]]
72 #elif HAS_CPP_ATTR(gnu::fallthrough)
73 #define ITT_ATTRIBUTE_FALLTHROUGH [[gnu::fallthrough]]
74 #elif HAS_CPP_ATTR(clang::fallthrough)
75 #define ITT_ATTRIBUTE_FALLTHROUGH [[clang::fallthrough]]
76 #elif HAS_GNU_ATTR(fallthrough) && !__INTEL_COMPILER
77 #define ITT_ATTRIBUTE_FALLTHROUGH __attribute__((fallthrough))
78 #else
79 #define ITT_ATTRIBUTE_FALLTHROUGH
80 #endif
81 #endif
82 
83 #if ITT_OS==ITT_OS_WIN
84 static const char* ittnotify_lib_name = "libittnotify.dll";
85 #elif ITT_OS==ITT_OS_LINUX || ITT_OS==ITT_OS_FREEBSD
86 static const char* ittnotify_lib_name = "libittnotify.so";
87 #elif ITT_OS==ITT_OS_MAC
88 static const char* ittnotify_lib_name = "libittnotify.dylib";
89 #else
90 #error Unsupported or unknown OS.
91 #endif
92 
93 #ifdef __ANDROID__
94 #include <android/log.h>
95 #include <stdio.h>
96 #include <unistd.h>
97 #include <sys/types.h>
98 #include <sys/stat.h>
99 #include <fcntl.h>
100 #include <linux/limits.h>
101 
102 #ifdef ITT_ANDROID_LOG
103     #define ITT_ANDROID_LOG_TAG   "INTEL_VTUNE_USERAPI"
104     #define ITT_ANDROID_LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, ITT_ANDROID_LOG_TAG, __VA_ARGS__))
105     #define ITT_ANDROID_LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, ITT_ANDROID_LOG_TAG, __VA_ARGS__))
106     #define ITT_ANDROID_LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR,ITT_ANDROID_LOG_TAG, __VA_ARGS__))
107     #define ITT_ANDROID_LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG,ITT_ANDROID_LOG_TAG, __VA_ARGS__))
108 #else
109     #define ITT_ANDROID_LOGI(...)
110     #define ITT_ANDROID_LOGW(...)
111     #define ITT_ANDROID_LOGE(...)
112     #define ITT_ANDROID_LOGD(...)
113 #endif
114 
115 /* default location of userapi collector on Android */
116 #define ANDROID_ITTNOTIFY_DEFAULT_PATH_MASK(x)  "/data/data/com.intel.vtune/perfrun/lib" \
117                                                 #x "/runtime/libittnotify.so"
118 
119 #if ITT_ARCH==ITT_ARCH_IA32 || ITT_ARCH==ITT_ARCH_ARM
120 #define ANDROID_ITTNOTIFY_DEFAULT_PATH  ANDROID_ITTNOTIFY_DEFAULT_PATH_MASK(32)
121 #else
122 #define ANDROID_ITTNOTIFY_DEFAULT_PATH  ANDROID_ITTNOTIFY_DEFAULT_PATH_MASK(64)
123 #endif
124 
125 #endif
126 
127 
128 #ifndef LIB_VAR_NAME
129 #if ITT_ARCH==ITT_ARCH_IA32 || ITT_ARCH==ITT_ARCH_ARM
130 #define LIB_VAR_NAME INTEL_LIBITTNOTIFY32
131 #else
132 #define LIB_VAR_NAME INTEL_LIBITTNOTIFY64
133 #endif
134 #endif /* LIB_VAR_NAME */
135 
136 #define ITT_MUTEX_INIT_AND_LOCK(p) {                                 \
137     if (PTHREAD_SYMBOLS)                                             \
138     {                                                                \
139         if (!p.mutex_initialized)                                    \
140         {                                                            \
141             if (__itt_interlocked_increment(&p.atomic_counter) == 1) \
142             {                                                        \
143                 __itt_mutex_init(&p.mutex);                          \
144                 p.mutex_initialized = 1;                             \
145             }                                                        \
146             else                                                     \
147                 while (!p.mutex_initialized)                         \
148                     __itt_thread_yield();                            \
149         }                                                            \
150         __itt_mutex_lock(&p.mutex);                                  \
151     }                                                                \
152 }
153 
154 #define ITT_MODULE_OBJECT_VERSION 1
155 
156 typedef int (__itt_init_ittlib_t)(const char*, __itt_group_id);
157 
158 /* this define used to control initialization function name. */
159 #ifndef __itt_init_ittlib_name
160 ITT_EXTERN_C int _N_(init_ittlib)(const char*, __itt_group_id);
161 static __itt_init_ittlib_t* __itt_init_ittlib_ptr = _N_(init_ittlib);
162 #define __itt_init_ittlib_name __itt_init_ittlib_ptr
163 #endif /* __itt_init_ittlib_name */
164 
165 typedef void (__itt_fini_ittlib_t)(void);
166 
167 /* this define used to control finalization function name. */
168 #ifndef __itt_fini_ittlib_name
169 ITT_EXTERN_C void _N_(fini_ittlib)(void);
170 static __itt_fini_ittlib_t* __itt_fini_ittlib_ptr = _N_(fini_ittlib);
171 #define __itt_fini_ittlib_name __itt_fini_ittlib_ptr
172 #endif /* __itt_fini_ittlib_name */
173 
174 extern __itt_global _N_(_ittapi_global);
175 
176 /* building pointers to imported funcs */
177 #undef ITT_STUBV
178 #undef ITT_STUB
179 #define ITT_STUB(api,type,name,args,params,ptr,group,format)   \
180 static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args;\
181 typedef type api ITT_JOIN(_N_(name),_t) args;                  \
182 ITT_EXTERN_C_BEGIN ITT_JOIN(_N_(name),_t)* ITTNOTIFY_NAME(name) = ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)); ITT_EXTERN_C_END \
183 static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args \
184 {                                                              \
185     if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL) \
186         __itt_init_ittlib_name(NULL, __itt_group_all);         \
187     if (ITTNOTIFY_NAME(name) && ITTNOTIFY_NAME(name) != ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init))) \
188         return ITTNOTIFY_NAME(name) params;                    \
189     else                                                       \
190         return (type)0;                                        \
191 }
192 
193 #define ITT_STUBV(api,type,name,args,params,ptr,group,format)  \
194 static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args;\
195 typedef type api ITT_JOIN(_N_(name),_t) args;                  \
196 ITT_EXTERN_C_BEGIN ITT_JOIN(_N_(name),_t)* ITTNOTIFY_NAME(name) = ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)); ITT_EXTERN_C_END \
197 static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args \
198 {                                                              \
199     if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL) \
200         __itt_init_ittlib_name(NULL, __itt_group_all);         \
201     if (ITTNOTIFY_NAME(name) && ITTNOTIFY_NAME(name) != ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init))) \
202         ITTNOTIFY_NAME(name) params;                           \
203     else                                                       \
204         return;                                                \
205 }
206 
207 #undef __ITT_INTERNAL_INIT
208 #include "ittnotify_static.h"
209 
210 #undef ITT_STUB
211 #undef ITT_STUBV
212 #define ITT_STUB(api,type,name,args,params,ptr,group,format)   \
213 static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args;\
214 typedef type api ITT_JOIN(_N_(name),_t) args;                  \
215 ITT_EXTERN_C_BEGIN ITT_JOIN(_N_(name),_t)* ITTNOTIFY_NAME(name) = ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)); ITT_EXTERN_C_END
216 
217 #define ITT_STUBV(api,type,name,args,params,ptr,group,format)  \
218 static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args;\
219 typedef type api ITT_JOIN(_N_(name),_t) args;                  \
220 ITT_EXTERN_C_BEGIN ITT_JOIN(_N_(name),_t)* ITTNOTIFY_NAME(name) = ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)); ITT_EXTERN_C_END
221 
222 #define __ITT_INTERNAL_INIT
223 #include "ittnotify_static.h"
224 #undef __ITT_INTERNAL_INIT
225 
226 ITT_GROUP_LIST(group_list);
227 
228 #pragma pack(push, 8)
229 
230 typedef struct ___itt_group_alias
231 {
232     const char*    env_var;
233     __itt_group_id groups;
234 } __itt_group_alias;
235 
236 static __itt_group_alias group_alias[] = {
237     { "KMP_FOR_TPROFILE", (__itt_group_id)(__itt_group_control | __itt_group_thread | __itt_group_sync  | __itt_group_mark) },
238     { "KMP_FOR_TCHECK",   (__itt_group_id)(__itt_group_control | __itt_group_thread | __itt_group_sync  | __itt_group_fsync | __itt_group_mark | __itt_group_suppress) },
239     { NULL,               (__itt_group_none) },
240     { api_version,        (__itt_group_none) } /* !!! Just to avoid unused code elimination !!! */
241 };
242 
243 #pragma pack(pop)
244 
245 #if ITT_PLATFORM==ITT_PLATFORM_WIN && _MSC_VER
246 #pragma warning(push)
247 #pragma warning(disable: 4054) /* warning C4054: 'type cast' : from function pointer 'XXX' to data pointer 'void *' */
248 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
249 
250 static __itt_api_info api_list[] = {
251 /* Define functions with static implementation */
252 #undef ITT_STUB
253 #undef ITT_STUBV
254 #define ITT_STUB(api,type,name,args,params,nameindll,group,format) { ITT_TO_STR(ITT_JOIN(__itt_,nameindll)), (void**)(void*)&ITTNOTIFY_NAME(name), (void*)(size_t)&ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)), (void*)(size_t)&ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)), (__itt_group_id)(group)},
255 #define ITT_STUBV ITT_STUB
256 #define __ITT_INTERNAL_INIT
257 #include "ittnotify_static.h"
258 #undef __ITT_INTERNAL_INIT
259 /* Define functions without static implementation */
260 #undef ITT_STUB
261 #undef ITT_STUBV
262 #define ITT_STUB(api,type,name,args,params,nameindll,group,format) {ITT_TO_STR(ITT_JOIN(__itt_,nameindll)), (void**)(void*)&ITTNOTIFY_NAME(name), (void*)(size_t)&ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)), NULL, (__itt_group_id)(group)},
263 #define ITT_STUBV ITT_STUB
264 #include "ittnotify_static.h"
265     {NULL, NULL, NULL, NULL, __itt_group_none}
266 };
267 
268 #if ITT_PLATFORM==ITT_PLATFORM_WIN && _MSC_VER
269 #pragma warning(pop)
270 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
271 
272 /* static part descriptor which handles. all notification api attributes. */
273 __itt_global _N_(_ittapi_global) = {
274     ITT_MAGIC,                                     /* identification info */
275     ITT_MAJOR, ITT_MINOR, API_VERSION_BUILD,       /* version info */
276     0,                                             /* api_initialized */
277     0,                                             /* mutex_initialized */
278     0,                                             /* atomic_counter */
279     MUTEX_INITIALIZER,                             /* mutex */
280     NULL,                                          /* dynamic library handle */
281     NULL,                                          /* error_handler */
282     NULL,                                          /* dll_path_ptr */
283     (__itt_api_info*)&api_list,                    /* api_list_ptr */
284     NULL,                                          /* next __itt_global */
285     NULL,                                          /* thread_list */
286     NULL,                                          /* domain_list */
287     NULL,                                          /* string_list */
288     __itt_collection_normal,                       /* collection state */
289     NULL,                                          /* counter_list */
290     0                                              /* ipt_collect_events */
291 };
292 
293 typedef void (__itt_api_init_t)(__itt_global*, __itt_group_id);
294 typedef void (__itt_api_fini_t)(__itt_global*);
295 
296 static __itt_domain dummy_domain;
297 /* ========================================================================= */
298 
299 #ifdef ITT_NOTIFY_EXT_REPORT
300 ITT_EXTERN_C void _N_(error_handler)(__itt_error_code, va_list args);
301 #endif /* ITT_NOTIFY_EXT_REPORT */
302 
303 #if ITT_PLATFORM==ITT_PLATFORM_WIN && _MSC_VER
304 #pragma warning(push)
305 #pragma warning(disable: 4055) /* warning C4055: 'type cast' : from data pointer 'void *' to function pointer 'XXX' */
306 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
307 
__itt_report_error(int code,...)308 static void __itt_report_error(int code, ...)
309 {
310     va_list args;
311     va_start(args, code);
312     if (_N_(_ittapi_global).error_handler != NULL)
313     {
314         __itt_error_handler_t* handler = (__itt_error_handler_t*)(size_t)_N_(_ittapi_global).error_handler;
315         handler((__itt_error_code)code, args);
316     }
317 #ifdef ITT_NOTIFY_EXT_REPORT
318     _N_(error_handler)((__itt_error_code)code, args);
319 #endif /* ITT_NOTIFY_EXT_REPORT */
320     va_end(args);
321 }
322 
323 #if ITT_PLATFORM==ITT_PLATFORM_WIN && _MSC_VER
324 #pragma warning(pop)
325 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
326 
327 #if ITT_PLATFORM==ITT_PLATFORM_WIN
ITT_VERSIONIZE(ITT_JOIN (_N_ (domain_createW),_init))328 static __itt_domain* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(domain_createW),_init))(const wchar_t* name)
329 {
330     __itt_domain *h_tail = NULL, *h = NULL;
331 
332     if (name == NULL)
333     {
334         return NULL;
335     }
336 
337     ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
338     if (_N_(_ittapi_global).api_initialized)
339     {
340         if (ITTNOTIFY_NAME(domain_createW) && ITTNOTIFY_NAME(domain_createW) != ITT_VERSIONIZE(ITT_JOIN(_N_(domain_createW),_init)))
341         {
342             __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
343             return ITTNOTIFY_NAME(domain_createW)(name);
344         }
345         else
346         {
347             __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
348             return &dummy_domain;
349         }
350     }
351     for (h_tail = NULL, h = _N_(_ittapi_global).domain_list; h != NULL; h_tail = h, h = h->next)
352     {
353         if (h->nameW != NULL && !wcscmp(h->nameW, name)) break;
354     }
355     if (h == NULL)
356     {
357         NEW_DOMAIN_W(&_N_(_ittapi_global),h,h_tail,name);
358     }
359     if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
360     return h;
361 }
362 
ITT_VERSIONIZE(ITT_JOIN (_N_ (domain_createA),_init))363 static __itt_domain* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(domain_createA),_init))(const char* name)
364 #else  /* ITT_PLATFORM!=ITT_PLATFORM_WIN */
365 static __itt_domain* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(domain_create),_init))(const char* name)
366 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
367 {
368     __itt_domain *h_tail = NULL, *h = NULL;
369 
370     if (name == NULL)
371     {
372         return NULL;
373     }
374 
375     ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
376     if (_N_(_ittapi_global).api_initialized)
377     {
378 #if ITT_PLATFORM==ITT_PLATFORM_WIN
379         if (ITTNOTIFY_NAME(domain_createA) && ITTNOTIFY_NAME(domain_createA) != ITT_VERSIONIZE(ITT_JOIN(_N_(domain_createA),_init)))
380         {
381             __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
382             return ITTNOTIFY_NAME(domain_createA)(name);
383         }
384 #else
385         if (ITTNOTIFY_NAME(domain_create) && ITTNOTIFY_NAME(domain_create) != ITT_VERSIONIZE(ITT_JOIN(_N_(domain_create),_init)))
386         {
387             if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
388             return ITTNOTIFY_NAME(domain_create)(name);
389         }
390 #endif
391         else
392         {
393 #if ITT_PLATFORM==ITT_PLATFORM_WIN
394             __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
395 #else
396             if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
397 #endif
398             return &dummy_domain;
399         }
400     }
401     for (h_tail = NULL, h = _N_(_ittapi_global).domain_list; h != NULL; h_tail = h, h = h->next)
402     {
403         if (h->nameA != NULL && !__itt_fstrcmp(h->nameA, name)) break;
404     }
405     if (h == NULL)
406     {
407         NEW_DOMAIN_A(&_N_(_ittapi_global),h,h_tail,name);
408     }
409     if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
410     return h;
411 }
412 
ITT_VERSIONIZE(ITT_JOIN (_N_ (module_load_with_sections),_init))413 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(module_load_with_sections),_init))(__itt_module_object* module_obj)
414 {
415     if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL)
416     {
417         __itt_init_ittlib_name(NULL, __itt_group_all);
418     }
419     if (ITTNOTIFY_NAME(module_load_with_sections) && ITTNOTIFY_NAME(module_load_with_sections) != ITT_VERSIONIZE(ITT_JOIN(_N_(module_load_with_sections),_init)))
420     {
421         if(module_obj != NULL)
422         {
423             module_obj->version = ITT_MODULE_OBJECT_VERSION;
424             ITTNOTIFY_NAME(module_load_with_sections)(module_obj);
425         }
426     }
427 }
428 
ITT_VERSIONIZE(ITT_JOIN (_N_ (module_unload_with_sections),_init))429 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(module_unload_with_sections),_init))(__itt_module_object* module_obj)
430 {
431     if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL)
432     {
433         __itt_init_ittlib_name(NULL, __itt_group_all);
434     }
435     if (ITTNOTIFY_NAME(module_unload_with_sections) && ITTNOTIFY_NAME(module_unload_with_sections) != ITT_VERSIONIZE(ITT_JOIN(_N_(module_unload_with_sections),_init)))
436     {
437         if(module_obj != NULL)
438         {
439             module_obj->version = ITT_MODULE_OBJECT_VERSION;
440             ITTNOTIFY_NAME(module_unload_with_sections)(module_obj);
441         }
442     }
443 }
444 
445 #if ITT_PLATFORM==ITT_PLATFORM_WIN
ITT_VERSIONIZE(ITT_JOIN (_N_ (string_handle_createW),_init))446 static __itt_string_handle* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_createW),_init))(const wchar_t* name)
447 {
448     __itt_string_handle *h_tail = NULL, *h = NULL;
449 
450     if (name == NULL)
451     {
452         return NULL;
453     }
454 
455     ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
456     if (_N_(_ittapi_global).api_initialized)
457     {
458         if (ITTNOTIFY_NAME(string_handle_createW) && ITTNOTIFY_NAME(string_handle_createW) != ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_createW),_init)))
459         {
460             __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
461             return ITTNOTIFY_NAME(string_handle_createW)(name);
462         }
463         else
464         {
465             __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
466             return NULL;
467         }
468     }
469     for (h_tail = NULL, h = _N_(_ittapi_global).string_list; h != NULL; h_tail = h, h = h->next)
470     {
471         if (h->strW != NULL && !wcscmp(h->strW, name)) break;
472     }
473     if (h == NULL)
474     {
475         NEW_STRING_HANDLE_W(&_N_(_ittapi_global),h,h_tail,name);
476     }
477     __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
478     return h;
479 }
480 
ITT_VERSIONIZE(ITT_JOIN (_N_ (string_handle_createA),_init))481 static __itt_string_handle* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_createA),_init))(const char* name)
482 #else  /* ITT_PLATFORM!=ITT_PLATFORM_WIN */
483 static __itt_string_handle* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_create),_init))(const char* name)
484 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
485 {
486     __itt_string_handle *h_tail = NULL, *h = NULL;
487 
488     if (name == NULL)
489     {
490         return NULL;
491     }
492 
493     ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
494     if (_N_(_ittapi_global).api_initialized)
495     {
496 #if ITT_PLATFORM==ITT_PLATFORM_WIN
497         if (ITTNOTIFY_NAME(string_handle_createA) && ITTNOTIFY_NAME(string_handle_createA) != ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_createA),_init)))
498         {
499             __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
500             return ITTNOTIFY_NAME(string_handle_createA)(name);
501         }
502 #else
503         if (ITTNOTIFY_NAME(string_handle_create) && ITTNOTIFY_NAME(string_handle_create) != ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_create),_init)))
504         {
505             if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
506             return ITTNOTIFY_NAME(string_handle_create)(name);
507         }
508 #endif
509         else
510         {
511 #if ITT_PLATFORM==ITT_PLATFORM_WIN
512             __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
513 #else
514             if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
515 #endif
516             return NULL;
517         }
518     }
519     for (h_tail = NULL, h = _N_(_ittapi_global).string_list; h != NULL; h_tail = h, h = h->next)
520     {
521         if (h->strA != NULL && !__itt_fstrcmp(h->strA, name)) break;
522     }
523     if (h == NULL)
524     {
525         NEW_STRING_HANDLE_A(&_N_(_ittapi_global),h,h_tail,name);
526     }
527     if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
528     return h;
529 }
530 
531 #if ITT_PLATFORM==ITT_PLATFORM_WIN
ITT_VERSIONIZE(ITT_JOIN (_N_ (counter_createW),_init))532 static __itt_counter ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(counter_createW),_init))(const wchar_t *name, const wchar_t *domain)
533 {
534     __itt_counter_info_t *h_tail = NULL, *h = NULL;
535     __itt_metadata_type type = __itt_metadata_u64;
536 
537     if (name == NULL)
538     {
539         return NULL;
540     }
541 
542     ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
543     if (_N_(_ittapi_global).api_initialized)
544     {
545         if (ITTNOTIFY_NAME(counter_createW) && ITTNOTIFY_NAME(counter_createW) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_createW),_init)))
546         {
547             __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
548             return ITTNOTIFY_NAME(counter_createW)(name, domain);
549         }
550         else
551         {
552             __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
553             return NULL;
554         }
555     }
556     for (h_tail = NULL, h = _N_(_ittapi_global).counter_list; h != NULL; h_tail = h, h = h->next)
557     {
558         if (h->nameW != NULL  && h->type == (int)type && !wcscmp(h->nameW, name) && ((h->domainW == NULL && domain == NULL) ||
559             (h->domainW != NULL && domain != NULL && !wcscmp(h->domainW, domain)))) break;
560 
561     }
562     if (h == NULL)
563     {
564         NEW_COUNTER_W(&_N_(_ittapi_global),h,h_tail,name,domain,type);
565     }
566     __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
567     return (__itt_counter)h;
568 }
569 
ITT_VERSIONIZE(ITT_JOIN (_N_ (counter_createA),_init))570 static __itt_counter ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(counter_createA),_init))(const char *name, const char *domain)
571 #else  /* ITT_PLATFORM!=ITT_PLATFORM_WIN */
572 static __itt_counter ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create),_init))(const char *name, const char *domain)
573 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
574 {
575     __itt_counter_info_t *h_tail = NULL, *h = NULL;
576     __itt_metadata_type type = __itt_metadata_u64;
577 
578     if (name == NULL)
579     {
580         return NULL;
581     }
582 
583     ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
584     if (_N_(_ittapi_global).api_initialized)
585     {
586 #if ITT_PLATFORM==ITT_PLATFORM_WIN
587         if (ITTNOTIFY_NAME(counter_createA) && ITTNOTIFY_NAME(counter_createA) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_createA),_init)))
588         {
589             __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
590             return ITTNOTIFY_NAME(counter_createA)(name, domain);
591         }
592 #else
593         if (ITTNOTIFY_NAME(counter_create) && ITTNOTIFY_NAME(counter_create) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create),_init)))
594         {
595             if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
596             return ITTNOTIFY_NAME(counter_create)(name, domain);
597         }
598 #endif
599         else
600         {
601 #if ITT_PLATFORM==ITT_PLATFORM_WIN
602             __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
603 #else
604             if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
605 #endif
606             return NULL;
607         }
608     }
609     for (h_tail = NULL, h = _N_(_ittapi_global).counter_list; h != NULL; h_tail = h, h = h->next)
610     {
611         if (h->nameA != NULL  && h->type == (int)type && !__itt_fstrcmp(h->nameA, name) && ((h->domainA == NULL && domain == NULL) ||
612             (h->domainA != NULL && domain != NULL && !__itt_fstrcmp(h->domainA, domain)))) break;
613     }
614     if (h == NULL)
615     {
616        NEW_COUNTER_A(&_N_(_ittapi_global),h,h_tail,name,domain,type);
617     }
618     if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
619     return (__itt_counter)h;
620 }
621 
622 #if ITT_PLATFORM==ITT_PLATFORM_WIN
ITT_VERSIONIZE(ITT_JOIN (_N_ (counter_create_typedW),_init))623 static __itt_counter ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typedW),_init))(const wchar_t *name, const wchar_t *domain, __itt_metadata_type type)
624 {
625     __itt_counter_info_t *h_tail = NULL, *h = NULL;
626 
627     if (name == NULL)
628     {
629         return NULL;
630     }
631 
632     ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
633     if (_N_(_ittapi_global).api_initialized)
634     {
635         if (ITTNOTIFY_NAME(counter_create_typedW) && ITTNOTIFY_NAME(counter_create_typedW) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typedW),_init)))
636         {
637             __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
638             return ITTNOTIFY_NAME(counter_create_typedW)(name, domain, type);
639         }
640         else
641         {
642             __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
643             return NULL;
644         }
645     }
646     for (h_tail = NULL, h = _N_(_ittapi_global).counter_list; h != NULL; h_tail = h, h = h->next)
647     {
648         if (h->nameW != NULL  && h->type == (int)type && !wcscmp(h->nameW, name) && ((h->domainW == NULL && domain == NULL) ||
649             (h->domainW != NULL && domain != NULL && !wcscmp(h->domainW, domain)))) break;
650 
651     }
652     if (h == NULL)
653     {
654         NEW_COUNTER_W(&_N_(_ittapi_global),h,h_tail,name,domain,type);
655     }
656     __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
657     return (__itt_counter)h;
658 }
659 
ITT_VERSIONIZE(ITT_JOIN (_N_ (counter_create_typedA),_init))660 static __itt_counter ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typedA),_init))(const char *name, const char *domain, __itt_metadata_type type)
661 #else  /* ITT_PLATFORM!=ITT_PLATFORM_WIN */
662 static __itt_counter ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typed),_init))(const char *name, const char *domain, __itt_metadata_type type)
663 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
664 {
665     __itt_counter_info_t *h_tail = NULL, *h = NULL;
666 
667     if (name == NULL)
668     {
669         return NULL;
670     }
671 
672     ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
673     if (_N_(_ittapi_global).api_initialized)
674     {
675 #if ITT_PLATFORM==ITT_PLATFORM_WIN
676         if (ITTNOTIFY_NAME(counter_create_typedA) && ITTNOTIFY_NAME(counter_create_typedA) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typedA),_init)))
677         {
678             __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
679             return ITTNOTIFY_NAME(counter_create_typedA)(name, domain, type);
680         }
681 #else
682         if (ITTNOTIFY_NAME(counter_create_typed) && ITTNOTIFY_NAME(counter_create_typed) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typed),_init)))
683         {
684             if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
685             return ITTNOTIFY_NAME(counter_create_typed)(name, domain, type);
686         }
687 #endif
688         else
689         {
690 #if ITT_PLATFORM==ITT_PLATFORM_WIN
691             __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
692 #else
693             if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
694 #endif
695             return NULL;
696         }
697     }
698     for (h_tail = NULL, h = _N_(_ittapi_global).counter_list; h != NULL; h_tail = h, h = h->next)
699     {
700         if (h->nameA != NULL  && h->type == (int)type && !__itt_fstrcmp(h->nameA, name) && ((h->domainA == NULL && domain == NULL) ||
701             (h->domainA != NULL && domain != NULL && !__itt_fstrcmp(h->domainA, domain)))) break;
702     }
703     if (h == NULL)
704     {
705        NEW_COUNTER_A(&_N_(_ittapi_global),h,h_tail,name,domain,type);
706     }
707     if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
708     return (__itt_counter)h;
709 }
710 
711 /* -------------------------------------------------------------------------- */
712 
ITT_VERSIONIZE(ITT_JOIN (_N_ (pause),_init))713 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(pause),_init))(void)
714 {
715     if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL)
716     {
717         __itt_init_ittlib_name(NULL, __itt_group_all);
718     }
719     if (ITTNOTIFY_NAME(pause) && ITTNOTIFY_NAME(pause) != ITT_VERSIONIZE(ITT_JOIN(_N_(pause),_init)))
720     {
721         ITTNOTIFY_NAME(pause)();
722     }
723     else
724     {
725         _N_(_ittapi_global).state = __itt_collection_paused;
726     }
727 }
728 
ITT_VERSIONIZE(ITT_JOIN (_N_ (resume),_init))729 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(resume),_init))(void)
730 {
731     if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL)
732     {
733         __itt_init_ittlib_name(NULL, __itt_group_all);
734     }
735     if (ITTNOTIFY_NAME(resume) && ITTNOTIFY_NAME(resume) != ITT_VERSIONIZE(ITT_JOIN(_N_(resume),_init)))
736     {
737         ITTNOTIFY_NAME(resume)();
738     }
739     else
740     {
741         _N_(_ittapi_global).state = __itt_collection_normal;
742     }
743 }
744 
745 #if ITT_PLATFORM==ITT_PLATFORM_WIN
ITT_VERSIONIZE(ITT_JOIN (_N_ (thread_set_nameW),_init))746 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameW),_init))(const wchar_t* name)
747 {
748     if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL)
749     {
750         __itt_init_ittlib_name(NULL, __itt_group_all);
751     }
752     if (ITTNOTIFY_NAME(thread_set_nameW) && ITTNOTIFY_NAME(thread_set_nameW) != ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameW),_init)))
753     {
754         ITTNOTIFY_NAME(thread_set_nameW)(name);
755     }
756 }
757 
ITT_VERSIONIZE(ITT_JOIN (_N_ (thr_name_setW),_init))758 static int ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thr_name_setW),_init))(const wchar_t* name, int namelen)
759 {
760     (void)namelen;
761     ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameW),_init))(name);
762     return 0;
763 }
764 
ITT_VERSIONIZE(ITT_JOIN (_N_ (thread_set_nameA),_init))765 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameA),_init))(const char* name)
766 #else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
767 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_name),_init))(const char* name)
768 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
769 {
770     if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL)
771     {
772         __itt_init_ittlib_name(NULL, __itt_group_all);
773     }
774 #if ITT_PLATFORM==ITT_PLATFORM_WIN
775     if (ITTNOTIFY_NAME(thread_set_nameA) && ITTNOTIFY_NAME(thread_set_nameA) != ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameA),_init)))
776     {
777         ITTNOTIFY_NAME(thread_set_nameA)(name);
778     }
779 #else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
780     if (ITTNOTIFY_NAME(thread_set_name) && ITTNOTIFY_NAME(thread_set_name) != ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_name),_init)))
781     {
782         ITTNOTIFY_NAME(thread_set_name)(name);
783     }
784 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
785 }
786 
787 #if ITT_PLATFORM==ITT_PLATFORM_WIN
ITT_VERSIONIZE(ITT_JOIN (_N_ (thr_name_setA),_init))788 static int ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thr_name_setA),_init))(const char* name, int namelen)
789 {
790     (void)namelen;
791     ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameA),_init))(name);
792     return 0;
793 }
794 #else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
ITT_VERSIONIZE(ITT_JOIN (_N_ (thr_name_set),_init))795 static int ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thr_name_set),_init))(const char* name, int namelen)
796 {
797     (void)namelen;
798     ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_name),_init))(name);
799     return 0;
800 }
801 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
802 
ITT_VERSIONIZE(ITT_JOIN (_N_ (thread_ignore),_init))803 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thread_ignore),_init))(void)
804 {
805     if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL)
806     {
807         __itt_init_ittlib_name(NULL, __itt_group_all);
808     }
809     if (ITTNOTIFY_NAME(thread_ignore) && ITTNOTIFY_NAME(thread_ignore) != ITT_VERSIONIZE(ITT_JOIN(_N_(thread_ignore),_init)))
810     {
811         ITTNOTIFY_NAME(thread_ignore)();
812     }
813 }
814 
ITT_VERSIONIZE(ITT_JOIN (_N_ (thr_ignore),_init))815 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thr_ignore),_init))(void)
816 {
817     ITT_VERSIONIZE(ITT_JOIN(_N_(thread_ignore),_init))();
818 }
819 
ITT_VERSIONIZE(ITT_JOIN (_N_ (enable_attach),_init))820 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(enable_attach),_init))(void)
821 {
822 #ifdef __ANDROID__
823     /*
824      * if LIB_VAR_NAME env variable were set before then stay previous value
825      * else set default path
826     */
827     setenv(ITT_TO_STR(LIB_VAR_NAME), ANDROID_ITTNOTIFY_DEFAULT_PATH, 0);
828 #endif
829 }
830 
831 /* -------------------------------------------------------------------------- */
832 
__itt_fsplit(const char * s,const char * sep,const char ** out,int * len)833 static const char* __itt_fsplit(const char* s, const char* sep, const char** out, int* len)
834 {
835     int i;
836     int j;
837 
838     if (!s || !sep || !out || !len)
839         return NULL;
840 
841     for (i = 0; s[i]; i++)
842     {
843         int b = 0;
844         for (j = 0; sep[j]; j++)
845             if (s[i] == sep[j])
846             {
847                 b = 1;
848                 break;
849             }
850         if (!b)
851             break;
852     }
853 
854     if (!s[i])
855         return NULL;
856 
857     *len = 0;
858     *out = &s[i];
859 
860     for (; s[i]; i++, (*len)++)
861     {
862         int b = 0;
863         for (j = 0; sep[j]; j++)
864             if (s[i] == sep[j])
865             {
866                 b = 1;
867                 break;
868             }
869         if (b)
870             break;
871     }
872 
873     for (; s[i]; i++)
874     {
875         int b = 0;
876         for (j = 0; sep[j]; j++)
877             if (s[i] == sep[j])
878             {
879                 b = 1;
880                 break;
881             }
882         if (!b)
883             break;
884     }
885 
886     return &s[i];
887 }
888 
889 /* This function return value of env variable that placed into static buffer.
890  * !!! The same static buffer is used for subsequent calls. !!!
891  * This was done to avoid dynamic allocation for few calls.
892  * Actually we need this function only four times.
893  */
__itt_get_env_var(const char * name)894 static const char* __itt_get_env_var(const char* name)
895 {
896 #define MAX_ENV_VALUE_SIZE 4086
897     static char  env_buff[MAX_ENV_VALUE_SIZE];
898     static char* env_value = (char*)env_buff;
899 
900     if (name != NULL)
901     {
902 #if ITT_PLATFORM==ITT_PLATFORM_WIN
903         size_t max_len = MAX_ENV_VALUE_SIZE - (size_t)(env_value - env_buff);
904         DWORD rc = GetEnvironmentVariableA(name, env_value, (DWORD)max_len);
905         if (rc >= max_len)
906             __itt_report_error(__itt_error_env_too_long, name, (size_t)rc - 1, (size_t)(max_len - 1));
907         else if (rc > 0)
908         {
909             const char* ret = (const char*)env_value;
910             env_value += rc + 1;
911             return ret;
912         }
913         else
914         {
915             /* If environment variable is empty, GetEnvironmentVariables()
916              * returns zero (number of characters (not including terminating null),
917              * and GetLastError() returns ERROR_SUCCESS. */
918             DWORD err = GetLastError();
919             if (err == ERROR_SUCCESS)
920                 return env_value;
921 
922             if (err != ERROR_ENVVAR_NOT_FOUND)
923                 __itt_report_error(__itt_error_cant_read_env, name, (int)err);
924         }
925 #else  /* ITT_PLATFORM!=ITT_PLATFORM_WIN */
926         char* env = getenv(name);
927         if (env != NULL)
928         {
929             size_t len = __itt_fstrnlen(env, MAX_ENV_VALUE_SIZE);
930             size_t max_len = MAX_ENV_VALUE_SIZE - (size_t)(env_value - env_buff);
931             if (len < max_len)
932             {
933                 const char* ret = (const char*)env_value;
934                 __itt_fstrcpyn(env_value, max_len, env, len + 1);
935                 env_value += len + 1;
936                 return ret;
937             } else
938                 __itt_report_error(__itt_error_env_too_long, name, (size_t)len, (size_t)(max_len - 1));
939         }
940 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
941     }
942     return NULL;
943 }
944 
__itt_get_lib_name(void)945 static const char* __itt_get_lib_name(void)
946 {
947     const char* lib_name = __itt_get_env_var(ITT_TO_STR(LIB_VAR_NAME));
948 
949 #ifdef __ANDROID__
950     if (lib_name == NULL)
951     {
952 
953 #if ITT_ARCH==ITT_ARCH_IA32 || ITT_ARCH==ITT_ARCH_ARM
954         const char* const marker_filename = "com.intel.itt.collector_lib_32";
955 #else
956         const char* const marker_filename = "com.intel.itt.collector_lib_64";
957 #endif
958 
959         char system_wide_marker_filename[PATH_MAX] = {0};
960         int itt_marker_file_fd = -1;
961         ssize_t res = 0;
962 
963         res = snprintf(system_wide_marker_filename, PATH_MAX - 1, "%s%s", "/data/local/tmp/", marker_filename);
964         if (res < 0)
965         {
966             ITT_ANDROID_LOGE("Unable to concatenate marker file string.");
967             return lib_name;
968         }
969         itt_marker_file_fd = open(system_wide_marker_filename, O_RDONLY);
970 
971         if (itt_marker_file_fd == -1)
972         {
973             const pid_t my_pid = getpid();
974             char cmdline_path[PATH_MAX] = {0};
975             char package_name[PATH_MAX] = {0};
976             char app_sandbox_file[PATH_MAX] = {0};
977             int cmdline_fd = 0;
978 
979             ITT_ANDROID_LOGI("Unable to open system-wide marker file.");
980             res = snprintf(cmdline_path, PATH_MAX - 1, "/proc/%d/cmdline", my_pid);
981             if (res < 0)
982             {
983                 ITT_ANDROID_LOGE("Unable to get cmdline path string.");
984                 return lib_name;
985             }
986 
987             ITT_ANDROID_LOGI("CMD file: %s\n", cmdline_path);
988             cmdline_fd = open(cmdline_path, O_RDONLY);
989             if (cmdline_fd == -1)
990             {
991                 ITT_ANDROID_LOGE("Unable to open %s file!", cmdline_path);
992                 return lib_name;
993             }
994             res = read(cmdline_fd, package_name, PATH_MAX - 1);
995             if (res == -1)
996             {
997                 ITT_ANDROID_LOGE("Unable to read %s file!", cmdline_path);
998                 res = close(cmdline_fd);
999                 if (res == -1)
1000                 {
1001                     ITT_ANDROID_LOGE("Unable to close %s file!", cmdline_path);
1002                 }
1003                 return lib_name;
1004             }
1005             res = close(cmdline_fd);
1006             if (res == -1)
1007             {
1008                 ITT_ANDROID_LOGE("Unable to close %s file!", cmdline_path);
1009                 return lib_name;
1010             }
1011             ITT_ANDROID_LOGI("Package name: %s\n", package_name);
1012             res = snprintf(app_sandbox_file, PATH_MAX - 1, "/data/data/%s/%s", package_name, marker_filename);
1013             if (res < 0)
1014             {
1015                 ITT_ANDROID_LOGE("Unable to concatenate marker file string.");
1016                 return lib_name;
1017             }
1018 
1019             ITT_ANDROID_LOGI("Lib marker file name: %s\n", app_sandbox_file);
1020             itt_marker_file_fd = open(app_sandbox_file, O_RDONLY);
1021             if (itt_marker_file_fd == -1)
1022             {
1023                 ITT_ANDROID_LOGE("Unable to open app marker file!");
1024                 return lib_name;
1025             }
1026         }
1027 
1028         {
1029             char itt_lib_name[PATH_MAX] = {0};
1030 
1031             res = read(itt_marker_file_fd, itt_lib_name, PATH_MAX - 1);
1032             if (res == -1)
1033             {
1034                 ITT_ANDROID_LOGE("Unable to read %s file!", itt_marker_file_fd);
1035                 res = close(itt_marker_file_fd);
1036                 if (res == -1)
1037                 {
1038                     ITT_ANDROID_LOGE("Unable to close %s file!", itt_marker_file_fd);
1039                 }
1040                 return lib_name;
1041             }
1042             ITT_ANDROID_LOGI("ITT Lib path: %s", itt_lib_name);
1043             res = close(itt_marker_file_fd);
1044             if (res == -1)
1045             {
1046                 ITT_ANDROID_LOGE("Unable to close %s file!", itt_marker_file_fd);
1047                 return lib_name;
1048             }
1049             ITT_ANDROID_LOGI("Set env %s to %s", ITT_TO_STR(LIB_VAR_NAME), itt_lib_name);
1050             res = setenv(ITT_TO_STR(LIB_VAR_NAME), itt_lib_name, 0);
1051             if (res == -1)
1052             {
1053                 ITT_ANDROID_LOGE("Unable to set env var!");
1054                 return lib_name;
1055             }
1056             lib_name = __itt_get_env_var(ITT_TO_STR(LIB_VAR_NAME));
1057             ITT_ANDROID_LOGI("ITT Lib path from env: %s", lib_name);
1058         }
1059     }
1060 #endif
1061 
1062     return lib_name;
1063 }
1064 
1065 /* Avoid clashes with std::min */
1066 #define __itt_min(a,b) ((a) < (b) ? (a) : (b))
1067 
__itt_get_groups(void)1068 static __itt_group_id __itt_get_groups(void)
1069 {
1070     int i;
1071     __itt_group_id res = __itt_group_none;
1072     const char* var_name  = "INTEL_ITTNOTIFY_GROUPS";
1073     const char* group_str = __itt_get_env_var(var_name);
1074 
1075     if (group_str != NULL)
1076     {
1077         int len;
1078         char gr[255];
1079         const char* chunk;
1080         while ((group_str = __itt_fsplit(group_str, ",; ", &chunk, &len)) != NULL)
1081         {
1082             int min_len = __itt_min(len, (int)(sizeof(gr) - 1));
1083             __itt_fstrcpyn(gr, sizeof(gr) - 1, chunk,  min_len);
1084             gr[min_len] = 0;
1085 
1086             for (i = 0; group_list[i].name != NULL; i++)
1087             {
1088                 if (!__itt_fstrcmp(gr, group_list[i].name))
1089                 {
1090                     res = (__itt_group_id)(res | group_list[i].id);
1091                     break;
1092                 }
1093             }
1094         }
1095         /* TODO: !!! Workaround for bug with warning for unknown group !!!
1096          * Should be fixed in new initialization scheme.
1097          * Now the following groups should be set always. */
1098         for (i = 0; group_list[i].id != __itt_group_none; i++)
1099             if (group_list[i].id != __itt_group_all &&
1100                 group_list[i].id > __itt_group_splitter_min &&
1101                 group_list[i].id < __itt_group_splitter_max)
1102                 res = (__itt_group_id)(res | group_list[i].id);
1103         return res;
1104     }
1105     else
1106     {
1107         for (i = 0; group_alias[i].env_var != NULL; i++)
1108             if (__itt_get_env_var(group_alias[i].env_var) != NULL)
1109                 return group_alias[i].groups;
1110     }
1111 
1112     return res;
1113 }
1114 
1115 #undef __itt_min
1116 
__itt_lib_version(lib_t lib)1117 static int __itt_lib_version(lib_t lib)
1118 {
1119     if (lib == NULL)
1120         return 0;
1121     if (__itt_get_proc(lib, "__itt_api_init"))
1122         return 2;
1123     if (__itt_get_proc(lib, "__itt_api_version"))
1124         return 1;
1125     return 0;
1126 }
1127 
1128 /* It's not used right now! Comment it out to avoid warnings.
1129 static void __itt_reinit_all_pointers(void)
1130 {
1131     register int i;
1132     // Fill all pointers with initial stubs
1133     for (i = 0; _N_(_ittapi_global).api_list_ptr[i].name != NULL; i++)
1134         *_N_(_ittapi_global).api_list_ptr[i].func_ptr = _N_(_ittapi_global).api_list_ptr[i].init_func;
1135 }
1136 */
1137 
__itt_nullify_all_pointers(void)1138 static void __itt_nullify_all_pointers(void)
1139 {
1140     int i;
1141     /* Nulify all pointers except domain_create, string_handle_create  and counter_create */
1142     for (i = 0; _N_(_ittapi_global).api_list_ptr[i].name != NULL; i++)
1143         *_N_(_ittapi_global).api_list_ptr[i].func_ptr = _N_(_ittapi_global).api_list_ptr[i].null_func;
1144 }
1145 
1146 #if ITT_PLATFORM==ITT_PLATFORM_WIN && _MSC_VER
1147 #pragma warning(push)
1148 #pragma warning(disable: 4054) /* warning C4054: 'type cast' : from function pointer 'XXX' to data pointer 'void *' */
1149 #pragma warning(disable: 4055) /* warning C4055: 'type cast' : from data pointer 'void *' to function pointer 'XXX' */
1150 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
1151 
_N_(fini_ittlib)1152 ITT_EXTERN_C void _N_(fini_ittlib)(void)
1153 {
1154     __itt_api_fini_t* __itt_api_fini_ptr = NULL;
1155     static volatile TIDT current_thread = 0;
1156 
1157     if (_N_(_ittapi_global).api_initialized)
1158     {
1159         ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
1160         if (_N_(_ittapi_global).api_initialized)
1161         {
1162             if (current_thread == 0)
1163             {
1164                 if (PTHREAD_SYMBOLS) current_thread = __itt_thread_id();
1165                 if (_N_(_ittapi_global).lib != NULL)
1166                 {
1167                     __itt_api_fini_ptr = (__itt_api_fini_t*)(size_t)__itt_get_proc(_N_(_ittapi_global).lib, "__itt_api_fini");
1168                 }
1169                 if (__itt_api_fini_ptr)
1170                 {
1171                     __itt_api_fini_ptr(&_N_(_ittapi_global));
1172                 }
1173 
1174                 __itt_nullify_all_pointers();
1175 
1176  /* TODO: !!! not safe !!! don't support unload so far.
1177   *             if (_N_(_ittapi_global).lib != NULL)
1178   *                 __itt_unload_lib(_N_(_ittapi_global).lib);
1179   *             _N_(_ittapi_global).lib = NULL;
1180   */
1181                 _N_(_ittapi_global).api_initialized = 0;
1182                 current_thread = 0;
1183             }
1184         }
1185         if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
1186     }
1187 }
1188 
_N_(init_ittlib)1189 ITT_EXTERN_C int _N_(init_ittlib)(const char* lib_name, __itt_group_id init_groups)
1190 {
1191     int i;
1192     __itt_group_id groups;
1193 #ifdef ITT_COMPLETE_GROUP
1194     __itt_group_id zero_group = __itt_group_none;
1195 #endif /* ITT_COMPLETE_GROUP */
1196     static volatile TIDT current_thread = 0;
1197 
1198     if (!_N_(_ittapi_global).api_initialized)
1199     {
1200 #ifndef ITT_SIMPLE_INIT
1201         ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
1202 #endif /* ITT_SIMPLE_INIT */
1203 
1204         if (!_N_(_ittapi_global).api_initialized)
1205         {
1206             if (current_thread == 0)
1207             {
1208                 if (PTHREAD_SYMBOLS) current_thread = __itt_thread_id();
1209                 if (lib_name == NULL)
1210                 {
1211                     lib_name = __itt_get_lib_name();
1212                 }
1213                 groups = __itt_get_groups();
1214                 if (DL_SYMBOLS && (groups != __itt_group_none || lib_name != NULL))
1215                 {
1216                     _N_(_ittapi_global).lib = __itt_load_lib((lib_name == NULL) ? ittnotify_lib_name : lib_name);
1217 
1218                     if (_N_(_ittapi_global).lib != NULL)
1219                     {
1220                         __itt_api_init_t* __itt_api_init_ptr;
1221                         int lib_version = __itt_lib_version(_N_(_ittapi_global).lib);
1222 
1223                         switch (lib_version)
1224                         {
1225                         case 0:
1226                             groups = __itt_group_legacy;
1227                             ITT_ATTRIBUTE_FALLTHROUGH;
1228                         case 1:
1229                             /* Fill all pointers from dynamic library */
1230                             for (i = 0; _N_(_ittapi_global).api_list_ptr[i].name != NULL; i++)
1231                             {
1232                                 if (_N_(_ittapi_global).api_list_ptr[i].group & groups & init_groups)
1233                                 {
1234                                     *_N_(_ittapi_global).api_list_ptr[i].func_ptr = (void*)__itt_get_proc(_N_(_ittapi_global).lib, _N_(_ittapi_global).api_list_ptr[i].name);
1235                                     if (*_N_(_ittapi_global).api_list_ptr[i].func_ptr == NULL)
1236                                     {
1237                                         /* Restore pointers for function with static implementation */
1238                                         *_N_(_ittapi_global).api_list_ptr[i].func_ptr = _N_(_ittapi_global).api_list_ptr[i].null_func;
1239                                         __itt_report_error(__itt_error_no_symbol, lib_name, _N_(_ittapi_global).api_list_ptr[i].name);
1240 #ifdef ITT_COMPLETE_GROUP
1241                                         zero_group = (__itt_group_id)(zero_group | _N_(_ittapi_global).api_list_ptr[i].group);
1242 #endif /* ITT_COMPLETE_GROUP */
1243                                     }
1244                                 }
1245                                 else
1246                                     *_N_(_ittapi_global).api_list_ptr[i].func_ptr = _N_(_ittapi_global).api_list_ptr[i].null_func;
1247                             }
1248 
1249                             if (groups == __itt_group_legacy)
1250                             {
1251                                 /* Compatibility with legacy tools */
1252                                 ITTNOTIFY_NAME(thread_ignore)  = ITTNOTIFY_NAME(thr_ignore);
1253 #if ITT_PLATFORM==ITT_PLATFORM_WIN
1254                                 ITTNOTIFY_NAME(sync_createA)   = ITTNOTIFY_NAME(sync_set_nameA);
1255                                 ITTNOTIFY_NAME(sync_createW)   = ITTNOTIFY_NAME(sync_set_nameW);
1256 #else  /* ITT_PLATFORM!=ITT_PLATFORM_WIN */
1257                                 ITTNOTIFY_NAME(sync_create)    = ITTNOTIFY_NAME(sync_set_name);
1258 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
1259                                 ITTNOTIFY_NAME(sync_prepare)   = ITTNOTIFY_NAME(notify_sync_prepare);
1260                                 ITTNOTIFY_NAME(sync_cancel)    = ITTNOTIFY_NAME(notify_sync_cancel);
1261                                 ITTNOTIFY_NAME(sync_acquired)  = ITTNOTIFY_NAME(notify_sync_acquired);
1262                                 ITTNOTIFY_NAME(sync_releasing) = ITTNOTIFY_NAME(notify_sync_releasing);
1263                             }
1264 
1265 #ifdef ITT_COMPLETE_GROUP
1266                             for (i = 0; _N_(_ittapi_global).api_list_ptr[i].name != NULL; i++)
1267                                 if (_N_(_ittapi_global).api_list_ptr[i].group & zero_group)
1268                                     *_N_(_ittapi_global).api_list_ptr[i].func_ptr = _N_(_ittapi_global).api_list_ptr[i].null_func;
1269 #endif /* ITT_COMPLETE_GROUP */
1270                             break;
1271                         case 2:
1272                             __itt_api_init_ptr = (__itt_api_init_t*)(size_t)__itt_get_proc(_N_(_ittapi_global).lib, "__itt_api_init");
1273                             if (__itt_api_init_ptr)
1274                                 __itt_api_init_ptr(&_N_(_ittapi_global), init_groups);
1275                             break;
1276                         }
1277                     }
1278                     else
1279                     {
1280                         __itt_nullify_all_pointers();
1281 
1282                         __itt_report_error(__itt_error_no_module, lib_name,
1283 #if ITT_PLATFORM==ITT_PLATFORM_WIN
1284                             __itt_system_error()
1285 #else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
1286                             dlerror()
1287 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
1288                         );
1289                     }
1290                 }
1291                 else
1292                 {
1293                     __itt_nullify_all_pointers();
1294                 }
1295                 _N_(_ittapi_global).api_initialized = 1;
1296                 current_thread = 0;
1297                 /* !!! Just to avoid unused code elimination !!! */
1298                 if (__itt_fini_ittlib_ptr == _N_(fini_ittlib)) current_thread = 0;
1299             }
1300         }
1301 
1302 #ifndef ITT_SIMPLE_INIT
1303         if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
1304 #endif /* ITT_SIMPLE_INIT */
1305     }
1306 
1307     /* Evaluating if any function ptr is non empty and it's in init_groups */
1308     for (i = 0; _N_(_ittapi_global).api_list_ptr[i].name != NULL; i++)
1309     {
1310         if (*_N_(_ittapi_global).api_list_ptr[i].func_ptr != _N_(_ittapi_global).api_list_ptr[i].null_func &&
1311             _N_(_ittapi_global).api_list_ptr[i].group & init_groups)
1312         {
1313             return 1;
1314         }
1315     }
1316     return 0;
1317 }
1318 
_N_(set_error_handler)1319 ITT_EXTERN_C __itt_error_handler_t* _N_(set_error_handler)(__itt_error_handler_t* handler)
1320 {
1321     __itt_error_handler_t* prev = (__itt_error_handler_t*)(size_t)_N_(_ittapi_global).error_handler;
1322     _N_(_ittapi_global).error_handler = (void*)(size_t)handler;
1323     return prev;
1324 }
1325 
1326 #if ITT_PLATFORM==ITT_PLATFORM_WIN && _MSC_VER
1327 #pragma warning(pop)
1328 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
1329 
1330 /** __itt_mark_pt_region functions marks region of interest
1331  * region parameter defines different regions.
1332  * 0 <= region < 8 */
1333 
1334 #if defined(ITT_API_IPT_SUPPORT) && (ITT_PLATFORM==ITT_PLATFORM_WIN || ITT_PLATFORM==ITT_PLATFORM_POSIX) && !defined(__ANDROID__)
1335 void __itt_pt_mark(__itt_pt_region region);
1336 void __itt_pt_mark_event(__itt_pt_region region);
1337 #endif
1338 
_N_(mark_pt_region_begin)1339 ITT_EXTERN_C void _N_(mark_pt_region_begin)(__itt_pt_region region)
1340 {
1341 #if defined(ITT_API_IPT_SUPPORT) && (ITT_PLATFORM==ITT_PLATFORM_WIN || ITT_PLATFORM==ITT_PLATFORM_POSIX) && !defined(__ANDROID__)
1342     if (_N_(_ittapi_global).ipt_collect_events == 1)
1343     {
1344         __itt_pt_mark_event(2*region);
1345     }
1346     else
1347     {
1348         __itt_pt_mark(2*region);
1349     }
1350 #else
1351     (void)region;
1352 #endif
1353 }
1354 
_N_(mark_pt_region_end)1355 ITT_EXTERN_C void _N_(mark_pt_region_end)(__itt_pt_region region)
1356 {
1357 #if defined(ITT_API_IPT_SUPPORT) && (ITT_PLATFORM==ITT_PLATFORM_WIN || ITT_PLATFORM==ITT_PLATFORM_POSIX) && !defined(__ANDROID__)
1358     if (_N_(_ittapi_global).ipt_collect_events == 1)
1359     {
1360         __itt_pt_mark_event(2*region + 1);
1361     }
1362     else
1363     {
1364         __itt_pt_mark(2*region + 1);
1365     }
1366 #else
1367      (void)region;
1368 #endif
1369 }
1370