/* * ompd-specific.cpp -- OpenMP debug support */ //===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "ompd-specific.h" #if OMPD_SUPPORT /** * Declaration of symbols to hold struct size and member offset information */ #define ompd_declare_access(t, m) uint64_t ompd_access__##t##__##m; OMPD_FOREACH_ACCESS(ompd_declare_access) #undef ompd_declare_access #define ompd_declare_sizeof_member(t, m) uint64_t ompd_sizeof__##t##__##m; OMPD_FOREACH_ACCESS(ompd_declare_sizeof_member) #undef ompd_declare_sizeof_member #define ompd_declare_bitfield(t, m) uint64_t ompd_bitfield__##t##__##m; OMPD_FOREACH_BITFIELD(ompd_declare_bitfield) #undef ompd_declare_bitfield #define ompd_declare_sizeof(t) uint64_t ompd_sizeof__##t; OMPD_FOREACH_SIZEOF(ompd_declare_sizeof) #undef ompd_declare_sizeof volatile const char **ompd_dll_locations = NULL; uint64_t ompd_state = 0; char *ompd_env_block = NULL; ompd_size_t ompd_env_block_size = 0; void ompd_init() { static int ompd_initialized = 0; if (ompd_initialized) return; /** * Calculate member offsets for structs and unions */ #define ompd_init_access(t, m) \ ompd_access__##t##__##m = (uint64_t) & (((t *)0)->m); OMPD_FOREACH_ACCESS(ompd_init_access) #undef ompd_init_access /** * Create bit mask for bitfield access */ #define ompd_init_bitfield(t, m) \ ompd_bitfield__##t##__##m = 0; \ ((t *)(&ompd_bitfield__##t##__##m))->m = 1; OMPD_FOREACH_BITFIELD(ompd_init_bitfield) #undef ompd_init_bitfield /** * Calculate type size information */ #define ompd_init_sizeof_member(t, m) \ ompd_sizeof__##t##__##m = sizeof(((t *)0)->m); OMPD_FOREACH_ACCESS(ompd_init_sizeof_member) #undef ompd_init_sizeof_member #define ompd_init_sizeof(t) ompd_sizeof__##t = sizeof(t); OMPD_FOREACH_SIZEOF(ompd_init_sizeof) #undef ompd_init_sizeof char *libname = NULL; #if KMP_OS_UNIX // Find the location of libomp.so thru dladdr and replace the libomp with // libompd to get the full path of libompd Dl_info dl_info; int ret = dladdr((void *)ompd_init, &dl_info); if (!ret) { fprintf(stderr, "%s\n", dlerror()); } int lib_path_length; if (strrchr(dl_info.dli_fname, '/')) { lib_path_length = strrchr(dl_info.dli_fname, '/') - dl_info.dli_fname; libname = (char *)malloc(lib_path_length + 12 /*for '/libompd.so' and '\0'*/); strncpy(libname, dl_info.dli_fname, lib_path_length); memcpy(libname + lib_path_length, "/libompd.so\0", 12); } #endif const char *ompd_env_var = getenv("OMP_DEBUG"); if (ompd_env_var && !strcmp(ompd_env_var, "enabled")) { fprintf(stderr, "OMP_OMPD active\n"); ompt_enabled.enabled = 1; ompd_state |= OMPD_ENABLE_BP; } ompd_initialized = 1; ompd_dll_locations = (volatile const char **)malloc(3 * sizeof(const char *)); ompd_dll_locations[0] = "libompd.so"; ompd_dll_locations[1] = libname; ompd_dll_locations[2] = NULL; ompd_dll_locations_valid(); } void __attribute__((noinline)) ompd_dll_locations_valid(void) { /* naive way of implementing hard to opt-out empty function we might want to use a separate object file? */ asm(""); } void ompd_bp_parallel_begin(void) { /* naive way of implementing hard to opt-out empty function we might want to use a separate object file? */ asm(""); } void ompd_bp_parallel_end(void) { /* naive way of implementing hard to opt-out empty function we might want to use a separate object file? */ asm(""); } void ompd_bp_task_begin(void) { /* naive way of implementing hard to opt-out empty function we might want to use a separate object file? */ asm(""); } void ompd_bp_task_end(void) { /* naive way of implementing hard to opt-out empty function we might want to use a separate object file? */ asm(""); } void ompd_bp_thread_begin(void) { /* naive way of implementing hard to opt-out empty function we might want to use a separate object file? */ asm(""); } void ompd_bp_thread_end(void) { /* naive way of implementing hard to opt-out empty function we might want to use a separate object file? */ asm(""); } #endif /* OMPD_SUPPORT */