1f61602b0SVignesh Balasubramanian /*
2f61602b0SVignesh Balasubramanian * ompd-specific.cpp -- OpenMP debug support
3f61602b0SVignesh Balasubramanian */
4f61602b0SVignesh Balasubramanian
5f61602b0SVignesh Balasubramanian //===----------------------------------------------------------------------===//
6f61602b0SVignesh Balasubramanian //
7f61602b0SVignesh Balasubramanian // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
8f61602b0SVignesh Balasubramanian // See https://llvm.org/LICENSE.txt for license information.
9f61602b0SVignesh Balasubramanian // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
10f61602b0SVignesh Balasubramanian //
11f61602b0SVignesh Balasubramanian //===----------------------------------------------------------------------===//
12f61602b0SVignesh Balasubramanian
13f61602b0SVignesh Balasubramanian #include "ompd-specific.h"
14f61602b0SVignesh Balasubramanian
15f61602b0SVignesh Balasubramanian #if OMPD_SUPPORT
16f61602b0SVignesh Balasubramanian
17f61602b0SVignesh Balasubramanian /**
18f61602b0SVignesh Balasubramanian * Declaration of symbols to hold struct size and member offset information
19f61602b0SVignesh Balasubramanian */
20f61602b0SVignesh Balasubramanian
21f61602b0SVignesh Balasubramanian #define ompd_declare_access(t, m) uint64_t ompd_access__##t##__##m;
22f61602b0SVignesh Balasubramanian OMPD_FOREACH_ACCESS(ompd_declare_access)
23f61602b0SVignesh Balasubramanian #undef ompd_declare_access
24f61602b0SVignesh Balasubramanian
25f61602b0SVignesh Balasubramanian #define ompd_declare_sizeof_member(t, m) uint64_t ompd_sizeof__##t##__##m;
26f61602b0SVignesh Balasubramanian OMPD_FOREACH_ACCESS(ompd_declare_sizeof_member)
27f61602b0SVignesh Balasubramanian #undef ompd_declare_sizeof_member
28f61602b0SVignesh Balasubramanian
29f61602b0SVignesh Balasubramanian #define ompd_declare_bitfield(t, m) uint64_t ompd_bitfield__##t##__##m;
30f61602b0SVignesh Balasubramanian OMPD_FOREACH_BITFIELD(ompd_declare_bitfield)
31f61602b0SVignesh Balasubramanian #undef ompd_declare_bitfield
32f61602b0SVignesh Balasubramanian
33f61602b0SVignesh Balasubramanian #define ompd_declare_sizeof(t) uint64_t ompd_sizeof__##t;
34f61602b0SVignesh Balasubramanian OMPD_FOREACH_SIZEOF(ompd_declare_sizeof)
35f61602b0SVignesh Balasubramanian #undef ompd_declare_sizeof
36f61602b0SVignesh Balasubramanian
37f61602b0SVignesh Balasubramanian volatile const char **ompd_dll_locations = NULL;
38f61602b0SVignesh Balasubramanian uint64_t ompd_state = 0;
39f61602b0SVignesh Balasubramanian
40f61602b0SVignesh Balasubramanian char *ompd_env_block = NULL;
41f61602b0SVignesh Balasubramanian ompd_size_t ompd_env_block_size = 0;
42f61602b0SVignesh Balasubramanian
ompd_init()43f61602b0SVignesh Balasubramanian void ompd_init() {
44f61602b0SVignesh Balasubramanian
45f61602b0SVignesh Balasubramanian static int ompd_initialized = 0;
46f61602b0SVignesh Balasubramanian
47f61602b0SVignesh Balasubramanian if (ompd_initialized)
48f61602b0SVignesh Balasubramanian return;
49f61602b0SVignesh Balasubramanian
50f61602b0SVignesh Balasubramanian /**
51f61602b0SVignesh Balasubramanian * Calculate member offsets for structs and unions
52f61602b0SVignesh Balasubramanian */
53f61602b0SVignesh Balasubramanian
54f61602b0SVignesh Balasubramanian #define ompd_init_access(t, m) \
55f61602b0SVignesh Balasubramanian ompd_access__##t##__##m = (uint64_t) & (((t *)0)->m);
56f61602b0SVignesh Balasubramanian OMPD_FOREACH_ACCESS(ompd_init_access)
57f61602b0SVignesh Balasubramanian #undef ompd_init_access
58f61602b0SVignesh Balasubramanian
59f61602b0SVignesh Balasubramanian /**
60f61602b0SVignesh Balasubramanian * Create bit mask for bitfield access
61f61602b0SVignesh Balasubramanian */
62f61602b0SVignesh Balasubramanian
63f61602b0SVignesh Balasubramanian #define ompd_init_bitfield(t, m) \
64f61602b0SVignesh Balasubramanian ompd_bitfield__##t##__##m = 0; \
65f61602b0SVignesh Balasubramanian ((t *)(&ompd_bitfield__##t##__##m))->m = 1;
66f61602b0SVignesh Balasubramanian OMPD_FOREACH_BITFIELD(ompd_init_bitfield)
67f61602b0SVignesh Balasubramanian #undef ompd_init_bitfield
68f61602b0SVignesh Balasubramanian
69f61602b0SVignesh Balasubramanian /**
70f61602b0SVignesh Balasubramanian * Calculate type size information
71f61602b0SVignesh Balasubramanian */
72f61602b0SVignesh Balasubramanian
73f61602b0SVignesh Balasubramanian #define ompd_init_sizeof_member(t, m) \
74f61602b0SVignesh Balasubramanian ompd_sizeof__##t##__##m = sizeof(((t *)0)->m);
75f61602b0SVignesh Balasubramanian OMPD_FOREACH_ACCESS(ompd_init_sizeof_member)
76f61602b0SVignesh Balasubramanian #undef ompd_init_sizeof_member
77f61602b0SVignesh Balasubramanian
78f61602b0SVignesh Balasubramanian #define ompd_init_sizeof(t) ompd_sizeof__##t = sizeof(t);
79f61602b0SVignesh Balasubramanian OMPD_FOREACH_SIZEOF(ompd_init_sizeof)
80f61602b0SVignesh Balasubramanian #undef ompd_init_sizeof
81f61602b0SVignesh Balasubramanian
82f61602b0SVignesh Balasubramanian char *libname = NULL;
83f61602b0SVignesh Balasubramanian
84f61602b0SVignesh Balasubramanian #if KMP_OS_UNIX
85f61602b0SVignesh Balasubramanian // Find the location of libomp.so thru dladdr and replace the libomp with
86f61602b0SVignesh Balasubramanian // libompd to get the full path of libompd
87f61602b0SVignesh Balasubramanian Dl_info dl_info;
88f61602b0SVignesh Balasubramanian int ret = dladdr((void *)ompd_init, &dl_info);
89f61602b0SVignesh Balasubramanian if (!ret) {
90f61602b0SVignesh Balasubramanian fprintf(stderr, "%s\n", dlerror());
91f61602b0SVignesh Balasubramanian }
92f61602b0SVignesh Balasubramanian int lib_path_length;
93f61602b0SVignesh Balasubramanian if (strrchr(dl_info.dli_fname, '/')) {
94f61602b0SVignesh Balasubramanian lib_path_length = strrchr(dl_info.dli_fname, '/') - dl_info.dli_fname;
95f61602b0SVignesh Balasubramanian libname =
96f61602b0SVignesh Balasubramanian (char *)malloc(lib_path_length + 12 /*for '/libompd.so' and '\0'*/);
97*4709d9d5SRoman Lebedev strncpy(libname, dl_info.dli_fname, lib_path_length);
98*4709d9d5SRoman Lebedev memcpy(libname + lib_path_length, "/libompd.so\0", 12);
99f61602b0SVignesh Balasubramanian }
100f61602b0SVignesh Balasubramanian #endif
101f61602b0SVignesh Balasubramanian
102f61602b0SVignesh Balasubramanian const char *ompd_env_var = getenv("OMP_DEBUG");
103f61602b0SVignesh Balasubramanian if (ompd_env_var && !strcmp(ompd_env_var, "enabled")) {
104f61602b0SVignesh Balasubramanian fprintf(stderr, "OMP_OMPD active\n");
105f61602b0SVignesh Balasubramanian ompt_enabled.enabled = 1;
106f61602b0SVignesh Balasubramanian ompd_state |= OMPD_ENABLE_BP;
107f61602b0SVignesh Balasubramanian }
108f61602b0SVignesh Balasubramanian
109f61602b0SVignesh Balasubramanian ompd_initialized = 1;
110f61602b0SVignesh Balasubramanian ompd_dll_locations = (volatile const char **)malloc(3 * sizeof(const char *));
111f61602b0SVignesh Balasubramanian ompd_dll_locations[0] = "libompd.so";
112f61602b0SVignesh Balasubramanian ompd_dll_locations[1] = libname;
113f61602b0SVignesh Balasubramanian ompd_dll_locations[2] = NULL;
114f61602b0SVignesh Balasubramanian ompd_dll_locations_valid();
115f61602b0SVignesh Balasubramanian }
116f61602b0SVignesh Balasubramanian
ompd_dll_locations_valid(void)117f61602b0SVignesh Balasubramanian void __attribute__((noinline)) ompd_dll_locations_valid(void) {
118f61602b0SVignesh Balasubramanian /* naive way of implementing hard to opt-out empty function
119f61602b0SVignesh Balasubramanian we might want to use a separate object file? */
120f61602b0SVignesh Balasubramanian asm("");
121f61602b0SVignesh Balasubramanian }
122f61602b0SVignesh Balasubramanian
ompd_bp_parallel_begin(void)123f61602b0SVignesh Balasubramanian void ompd_bp_parallel_begin(void) {
124f61602b0SVignesh Balasubramanian /* naive way of implementing hard to opt-out empty function
125f61602b0SVignesh Balasubramanian we might want to use a separate object file? */
126f61602b0SVignesh Balasubramanian asm("");
127f61602b0SVignesh Balasubramanian }
ompd_bp_parallel_end(void)128f61602b0SVignesh Balasubramanian void ompd_bp_parallel_end(void) {
129f61602b0SVignesh Balasubramanian /* naive way of implementing hard to opt-out empty function
130f61602b0SVignesh Balasubramanian we might want to use a separate object file? */
131f61602b0SVignesh Balasubramanian asm("");
132f61602b0SVignesh Balasubramanian }
ompd_bp_task_begin(void)133f61602b0SVignesh Balasubramanian void ompd_bp_task_begin(void) {
134f61602b0SVignesh Balasubramanian /* naive way of implementing hard to opt-out empty function
135f61602b0SVignesh Balasubramanian we might want to use a separate object file? */
136f61602b0SVignesh Balasubramanian asm("");
137f61602b0SVignesh Balasubramanian }
ompd_bp_task_end(void)138f61602b0SVignesh Balasubramanian void ompd_bp_task_end(void) {
139f61602b0SVignesh Balasubramanian /* naive way of implementing hard to opt-out empty function
140f61602b0SVignesh Balasubramanian we might want to use a separate object file? */
141f61602b0SVignesh Balasubramanian asm("");
142f61602b0SVignesh Balasubramanian }
ompd_bp_thread_begin(void)143f61602b0SVignesh Balasubramanian void ompd_bp_thread_begin(void) {
144f61602b0SVignesh Balasubramanian /* naive way of implementing hard to opt-out empty function
145f61602b0SVignesh Balasubramanian we might want to use a separate object file? */
146f61602b0SVignesh Balasubramanian asm("");
147f61602b0SVignesh Balasubramanian }
ompd_bp_thread_end(void)148f61602b0SVignesh Balasubramanian void ompd_bp_thread_end(void) {
149f61602b0SVignesh Balasubramanian /* naive way of implementing hard to opt-out empty function
150f61602b0SVignesh Balasubramanian we might want to use a separate object file? */
151f61602b0SVignesh Balasubramanian asm("");
152f61602b0SVignesh Balasubramanian }
153f61602b0SVignesh Balasubramanian
154f61602b0SVignesh Balasubramanian #endif /* OMPD_SUPPORT */
155