[runtime] Fixed get_process_module module name.
[mono.git] / mono / utils / mono-compiler.h
1 #ifndef __UTILS_MONO_COMPILER_H__
2 #define __UTILS_MONO_COMPILER_H__
3
4 /*
5  * This file includes macros used in the runtime to encapsulate different
6  * compiler behaviours.
7  */
8 #include <config.h>
9
10 #ifdef __GNUC__
11 #define MONO_ATTR_USED __attribute__ ((used))
12 #else
13 #define MONO_ATTR_USED
14 #endif
15
16 #ifdef HAVE_KW_THREAD
17
18 #define MONO_HAVE_FAST_TLS
19 #define MONO_FAST_TLS_SET(x,y) x = y
20 #define MONO_FAST_TLS_GET(x) x
21 #define MONO_FAST_TLS_INIT(x)
22 #define MONO_FAST_TLS_DECLARE(x) static __thread gpointer x MONO_TLS_FAST MONO_ATTR_USED;
23
24 #if HAVE_TLS_MODEL_ATTR
25
26 #if defined(__PIC__) && !defined(PIC)
27 /*
28  * Must be compiling -fPIE, for executables.  Build PIC
29  * but with initial-exec.
30  * http://bugs.gentoo.org/show_bug.cgi?id=165547
31  */
32 #define PIC
33 #define PIC_INITIAL_EXEC
34 #endif
35
36 /* 
37  * Define this if you want a faster libmono, which cannot be loaded dynamically as a 
38  * module.
39  */
40 //#define PIC_INITIAL_EXEC
41
42 #if defined(PIC)
43
44 #ifdef PIC_INITIAL_EXEC
45 #define MONO_TLS_FAST __attribute__((tls_model("initial-exec")))
46 #else
47 #if defined (__powerpc__)
48 /* local dynamic requires a call to __tls_get_addr to look up the
49    TLS block address via the Dynamic Thread Vector. In this case Thread
50    Pointer relative offsets can't be used as this modules TLS was
51    allocated separately (none contiguoiusly) from the initial TLS
52    block.
53
54    For now we will disable this. */
55 #define MONO_TLS_FAST
56 #else
57 #define MONO_TLS_FAST __attribute__((tls_model("local-dynamic")))
58 #endif
59 #endif
60
61 #else
62
63 #define MONO_TLS_FAST __attribute__((tls_model("local-exec")))
64
65 #endif
66
67 #else
68 #define MONO_TLS_FAST 
69 #endif
70
71 #if defined(__GNUC__) && defined(__i386__)
72 #if defined(PIC)
73 #define MONO_THREAD_VAR_OFFSET(var,offset) do { int tmp; __asm ("call 1f; 1: popl %0; addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %0; movl " #var "@gotntpoff(%0), %1" : "=r" (tmp), "=r" (offset)); } while (0)
74 #else
75 #define MONO_THREAD_VAR_OFFSET(var,offset) __asm ("movl $" #var "@ntpoff, %0" : "=r" (offset))
76 #endif
77 #elif defined(__x86_64__)
78 #if defined(PIC)
79 // This only works if libmono is linked into the application
80 #define MONO_THREAD_VAR_OFFSET(var,offset) do { guint64 foo;  __asm ("movq " #var "@GOTTPOFF(%%rip), %0" : "=r" (foo)); offset = foo; } while (0)
81 #else
82 #define MONO_THREAD_VAR_OFFSET(var,offset) do { guint64 foo;  __asm ("movq $" #var "@TPOFF, %0" : "=r" (foo)); offset = foo; } while (0)
83 #endif
84 #elif defined(__ia64__) && !defined(__INTEL_COMPILER)
85 #if defined(PIC)
86 #define MONO_THREAD_VAR_OFFSET(var,offset) __asm ("addl %0 = @ltoff(@tprel(" #var "#)), gp ;; ld8 %0 = [%0]\n" : "=r" (offset))
87 #else
88 #define MONO_THREAD_VAR_OFFSET(var,offset) __asm ("addl %0 = @tprel(" #var "#), r0 ;;\n" : "=r" (offset))
89 #endif
90 #elif defined(__arm__) && defined(__ARM_EABI__) && !defined(PIC)
91 #define MONO_THREAD_VAR_OFFSET(var,offset) __asm ("     ldr     %0, 1f; b 2f; 1: .word " #var "(tpoff); 2:" : "=r" (offset))
92 #elif defined(__aarch64__) && !defined(PIC)
93 #define MONO_THREAD_VAR_OFFSET(var,offset) \
94         __asm ( "mov %0, #0\n add %0, %0, #:tprel_hi12:" #var "\n add %0, %0, #:tprel_lo12_nc:" #var "\n" \
95                         : "=r" (offset))
96 #elif defined(__mono_ppc__) && defined(__GNUC__)
97 #if defined(PIC)
98 #ifdef PIC_INITIAL_EXEC
99
100 #if defined(__mono_ppc64__)
101 #define MONO_THREAD_VAR_OFFSET(var,offset) \
102         do { long off; \
103         __asm ( "ld     %0," #var "@got@tprel(2)\n" \
104         : "=r" (off)); \
105         (offset) = off; } while (0)
106 #else
107 /* must be powerpc32 */
108 #define MONO_THREAD_VAR_OFFSET(var,offset) \
109         __asm ( "lwz    %0," #var "@got@tprel(30)\n" \
110         : "=r" (offset))
111 #endif
112
113 #else
114
115 /* local dynamic requires a call to __tls_get_addr to look up the
116    TLS block address via the Dynamic Thread Vector. In this case Thread
117    Pointer relative offsets can't be used as this modules TLS was
118    allocated separately (none contiguoiusly) from the initial TLS
119    block.
120
121    For now we will disable this. */
122 #define MONO_THREAD_VAR_OFFSET(var,offset) (offset) = -1
123
124 #endif
125 #else
126 /* Must be local-exec TLS */
127 #define MONO_THREAD_VAR_OFFSET(var,offset) \
128         __asm ( "lis    %0," #var "@tprel@ha\n" \
129                 "addi   %0,%0, " #var "@tprel@l\n" \
130         : "=r" (offset))
131 #endif
132 #elif defined(__s390x__)
133 # if defined(PIC)
134 // This only works if libmono is linked into the application
135 #  define MONO_THREAD_VAR_OFFSET(var,offset) do { guint64 foo;                                  \
136                                                 __asm__ ("basr  %%r1,0\n\t"                     \
137                                                          "j     0f\n\t"                         \
138                                                          ".quad " #var "@TLSGD\n\t"             \
139                                                          "0:\n\t"                               \
140                                                          "lg    %%r2,4(%%r1)\n\t"               \
141                                                          "brasl %%r14,__tls_get_offset@PLT:tls_gdcall:"#var"\n\t" \
142                                                          "lgr   %0,%%r2\n\t"                    \
143                                                         : "=r" (foo) :                          \
144                                                         : "1", "2", "14", "cc");                \
145                                                 offset = foo; } while (0)
146 # else
147 #  define MONO_THREAD_VAR_OFFSET(var,offset) do { guint64 foo;                                  \
148                                                 __asm__ ("basr  %%r1,0\n\t"                     \
149                                                          "j     0f\n\t"                         \
150                                                          ".quad " #var "@NTPOFF\n"              \
151                                                          "0:\n\t"                               \
152                                                          "lg    %0,4(%%r1)\n\t"                 \
153                                                         : "=r" (foo) : : "1");                  \
154                                                 offset = foo; } while (0)
155 # endif
156
157 #else
158 #define MONO_THREAD_VAR_OFFSET(var,offset) (offset) = -1
159 #endif
160
161 #if defined(PIC) && !defined(PIC_INITIAL_EXEC)
162 /* 
163  * The above definitions do not seem to work if libmono is loaded dynamically as a module.
164  * See bug #78767.
165  */
166 #undef MONO_THREAD_VAR_OFFSET
167 #define MONO_THREAD_VAR_OFFSET(var,offset) (offset) = -1
168 #endif
169
170 #elif defined(TARGET_MACH) && (defined(__i386__) || defined(__x86_64__))
171
172 #define MONO_HAVE_FAST_TLS
173 #define MONO_FAST_TLS_SET(x,y) pthread_setspecific(x, y)
174 #define MONO_FAST_TLS_GET(x) pthread_getspecific(x)
175 #define MONO_FAST_TLS_ADDR(x) (mono_mach_get_tls_address_from_thread (pthread_self (), x))
176 #define MONO_FAST_TLS_INIT(x) pthread_key_create(&x, NULL)
177 #define MONO_FAST_TLS_DECLARE(x) static pthread_key_t x;
178
179 #define MONO_THREAD_VAR_OFFSET(x,y) ({  \
180         __typeof__(x) _x = (x);                 \
181         pthread_key_t _y;       \
182         (void) (&_x == &_y);            \
183         y = (gint32) x; })
184 #else /* no HAVE_KW_THREAD */
185
186 #define MONO_THREAD_VAR_OFFSET(var,offset) (offset) = -1
187
188 /*Macros to facilitate user code*/
189 #define MONO_FAST_TLS_INIT(x)
190 #endif
191
192 #if defined(MONO_HAVE_FAST_TLS) && !defined(MONO_FAST_TLS_ADDR)
193 #define MONO_FAST_TLS_ADDR(x) (&(x))
194 #endif
195
196
197 /* Deal with Microsoft C compiler differences */
198 #ifdef _MSC_VER
199
200 #include <math.h>
201
202 #if _MSC_VER < 1800 /* VS 2013 */
203 #define strtoull _strtoui64
204 #endif
205
206 #include <float.h>
207 #define trunc(x)        (((x) < 0) ? ceil((x)) : floor((x)))
208 #if _MSC_VER < 1800 /* VS 2013 */
209 #define isnan(x)        _isnan(x)
210 #define isinf(x)        (_isnan(x) ? 0 : (_fpclass(x) == _FPCLASS_NINF) ? -1 : (_fpclass(x) == _FPCLASS_PINF) ? 1 : 0)
211 #define isnormal(x)     _finite(x)
212 #endif
213
214 #define popen           _popen
215 #define pclose          _pclose
216
217 #include <direct.h>
218 #define mkdir(x)        _mkdir(x)
219
220 /* GCC specific functions aren't available */
221 #define __builtin_return_address(x)     NULL
222
223 #define __func__ __FUNCTION__
224
225 #include <BaseTsd.h>
226 typedef SSIZE_T ssize_t;
227
228 /*
229  * SSIZE_MAX is not defined in MSVC, so define it here.
230  *
231  * These values come from MinGW64, and are public domain.
232  *
233  */
234 #ifndef SSIZE_MAX
235 #ifdef _WIN64
236 #define SSIZE_MAX _I64_MAX
237 #else
238 #define SSIZE_MAX INT_MAX
239 #endif
240 #endif
241
242 #endif /* _MSC_VER */
243
244 #if !defined(_MSC_VER) && !defined(PLATFORM_SOLARIS) && !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MONOTOUCH) && HAVE_VISIBILITY_HIDDEN
245 #if MONO_LLVM_LOADED
246 #define MONO_LLVM_INTERNAL MONO_API
247 #else
248 #define MONO_LLVM_INTERNAL
249 #endif
250 #else
251 #define MONO_LLVM_INTERNAL 
252 #endif
253
254 #if HAVE_DEPRECATED
255 #define MONO_DEPRECATED __attribute__ ((deprecated))
256 #else
257 #define MONO_DEPRECATED 
258 #endif
259
260 #ifdef __GNUC__
261 #define MONO_ALWAYS_INLINE __attribute__((always_inline))
262 #elif defined(_MSC_VER)
263 #define MONO_ALWAYS_INLINE __forceinline
264 #else
265 #define MONO_ALWAYS_INLINE
266 #endif
267
268 #ifdef __GNUC__
269 #define MONO_NEVER_INLINE __attribute__((noinline))
270 #elif defined(_MSC_VER)
271 #define MONO_NEVER_INLINE __declspec(noinline)
272 #else
273 #define MONO_NEVER_INLINE
274 #endif
275
276 #ifdef __GNUC__
277 #define MONO_COLD __attribute__((cold))
278 #else
279 #define MONO_COLD
280 #endif
281
282 #endif /* __UTILS_MONO_COMPILER_H__*/
283