mono-compiler.h 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /**
  2. * \file
  3. */
  4. #ifndef __UTILS_MONO_COMPILER_H__
  5. #define __UTILS_MONO_COMPILER_H__
  6. /*
  7. * This file includes macros used in the runtime to encapsulate different
  8. * compiler behaviours.
  9. */
  10. #include <config.h>
  11. #if defined(HAVE_UNISTD_H)
  12. #include <unistd.h>
  13. #endif
  14. #ifdef __GNUC__
  15. #define MONO_ATTR_USED __attribute__ ((__used__))
  16. #else
  17. #define MONO_ATTR_USED
  18. #endif
  19. #ifdef __GNUC__
  20. #define MONO_ATTR_FORMAT_PRINTF(fmt_pos,arg_pos) __attribute__ ((__format__(__printf__,fmt_pos,arg_pos)))
  21. #else
  22. #define MONO_ATTR_FORMAT_PRINTF(fmt_pos,arg_pos)
  23. #endif
  24. /* Deal with Microsoft C compiler differences */
  25. #ifdef _MSC_VER
  26. #include <math.h>
  27. #include <float.h>
  28. #define popen _popen
  29. #define pclose _pclose
  30. #include <direct.h>
  31. #define mkdir(x) _mkdir(x)
  32. #define __func__ __FUNCTION__
  33. #include <stddef.h>
  34. #include <stdint.h>
  35. // ssize_t and SSIZE_MAX are Posix, define for Windows.
  36. typedef ptrdiff_t ssize_t;
  37. #ifndef SSIZE_MAX
  38. #define SSIZE_MAX INTPTR_MAX
  39. #endif
  40. #endif /* _MSC_VER */
  41. // Quiet Visual Studio linker warning, LNK4221: This object file does not define any previously
  42. // undefined public symbols, so it will not be used by any link operation that consumes this library.
  43. // And other linkers, e.g. older Apple.
  44. #define MONO_EMPTY_SOURCE_FILE(x) extern const char mono_quash_linker_empty_file_warning_ ## x; \
  45. const char mono_quash_linker_empty_file_warning_ ## x = 0;
  46. #ifdef _MSC_VER
  47. #define MONO_PRAGMA_WARNING_PUSH() __pragma(warning (push))
  48. #define MONO_PRAGMA_WARNING_DISABLE(x) __pragma(warning (disable:x))
  49. #define MONO_PRAGMA_WARNING_POP() __pragma(warning (pop))
  50. #define MONO_DISABLE_WARNING(x) \
  51. MONO_PRAGMA_WARNING_PUSH() \
  52. MONO_PRAGMA_WARNING_DISABLE(x)
  53. #define MONO_RESTORE_WARNING \
  54. MONO_PRAGMA_WARNING_POP()
  55. #else
  56. #define MONO_PRAGMA_WARNING_PUSH()
  57. #define MONO_PRAGMA_WARNING_DISABLE(x)
  58. #define MONO_PRAGMA_WARNING_POP()
  59. #define MONO_DISABLE_WARNING(x)
  60. #define MONO_RESTORE_WARNING
  61. #endif
  62. /* Used to mark internal functions used by the profiler modules */
  63. #define MONO_PROFILER_API MONO_API
  64. /* Used to mark internal functions used by the CoreFX PAL library */
  65. #define MONO_PAL_API MONO_API
  66. #ifdef __GNUC__
  67. #define MONO_ALWAYS_INLINE __attribute__ ((__always_inline__))
  68. #elif defined(_MSC_VER)
  69. #define MONO_ALWAYS_INLINE __forceinline
  70. #else
  71. #define MONO_ALWAYS_INLINE
  72. #endif
  73. #ifdef __GNUC__
  74. #define MONO_NEVER_INLINE __attribute__ ((__noinline__))
  75. #elif defined(_MSC_VER)
  76. #define MONO_NEVER_INLINE __declspec(noinline)
  77. #else
  78. #define MONO_NEVER_INLINE
  79. #endif
  80. #ifdef __GNUC__
  81. #define MONO_COLD __attribute__ ((__cold__))
  82. #else
  83. #define MONO_COLD
  84. #endif
  85. #if defined (__clang__)
  86. #define MONO_NO_OPTIMIZATION __attribute__ ((optnone))
  87. #elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
  88. #define MONO_NO_OPTIMIZATION __attribute__ ((optimize("O0")))
  89. #else
  90. #define MONO_NO_OPTIMIZATION /* nothing */
  91. #endif
  92. #if defined (__GNUC__) && defined (__GNUC_MINOR__) && defined (__GNUC_PATCHLEVEL__)
  93. #define MONO_GNUC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
  94. #endif
  95. #if defined(__has_feature)
  96. #if __has_feature(thread_sanitizer)
  97. #define MONO_HAS_CLANG_THREAD_SANITIZER 1
  98. #else
  99. #define MONO_HAS_CLANG_THREAD_SANITIZER 0
  100. #endif
  101. #if __has_feature(address_sanitizer)
  102. #define MONO_HAS_CLANG_ADDRESS_SANITIZER 1
  103. #else
  104. #define MONO_HAS_CLANG_ADDRESS_SANITIZER 0
  105. #endif
  106. #else
  107. #define MONO_HAS_CLANG_THREAD_SANITIZER 0
  108. #define MONO_HAS_CLANG_ADDRESS_SANITIZER 0
  109. #endif
  110. /* Used to tell Clang's ThreadSanitizer to not report data races that occur within a certain function */
  111. #if MONO_HAS_CLANG_THREAD_SANITIZER
  112. #define MONO_NO_SANITIZE_THREAD __attribute__ ((no_sanitize("thread")))
  113. #else
  114. #define MONO_NO_SANITIZE_THREAD
  115. #endif
  116. /* Used to tell Clang's AddressSanitizer to turn off instrumentation for a certain function */
  117. #if MONO_HAS_CLANG_ADDRESS_SANITIZER
  118. #define MONO_NO_SANITIZE_ADDRESS __attribute__ ((no_sanitize("address")))
  119. #else
  120. #define MONO_NO_SANITIZE_ADDRESS
  121. #endif
  122. /* Used when building with Android NDK's unified headers */
  123. #if defined(HOST_ANDROID) && defined (ANDROID_UNIFIED_HEADERS)
  124. #ifdef HAVE_ANDROID_NDK_VERSION_H
  125. #include <android/ndk-version.h>
  126. #endif
  127. #if __ANDROID_API__ < 21
  128. typedef int32_t __mono_off32_t;
  129. #ifdef HAVE_SYS_MMAN_H
  130. #include <sys/mman.h>
  131. #endif
  132. #if __NDK_MAJOR__ < 18
  133. #ifdef __cplusplus
  134. extern "C" {
  135. #endif
  136. /* The `mmap` definition problem only occurs with the GCC toolchain. With the
  137. * clang toolchain we should not redefine `mmap`, and instead use the
  138. * definition from the NDK headers.
  139. */
  140. #if !defined(__clang__)
  141. /* Unified headers before API 21 do not declare mmap when LARGE_FILES are used (via -D_FILE_OFFSET_BITS=64)
  142. * which is always the case when Mono build targets Android. The problem here is that the unified headers
  143. * map `mmap` to `mmap64` if large files are enabled but this api exists only in API21 onwards. Therefore
  144. * we must carefully declare the 32-bit mmap here without changing the ABI along the way. Carefully because
  145. * in this instance off_t is redeclared to be 64-bit and that's not what we want.
  146. */
  147. void* mmap (void*, size_t, int, int, int, __mono_off32_t);
  148. #ifdef __cplusplus
  149. } // extern C
  150. #endif
  151. #endif /* __NDK_MAJOR__ < 18 */
  152. #endif /* !__clang__ */
  153. #ifdef HAVE_SYS_SENDFILE_H
  154. #include <sys/sendfile.h>
  155. #endif
  156. #ifdef __cplusplus
  157. extern "C" {
  158. #endif
  159. /* Similar thing as with mmap happens with sendfile, except that the off_t is always used (and
  160. * mono expects 64-bit offset here */
  161. ssize_t sendfile (int out_fd, int in_fd, off_t* offset, size_t count);
  162. #ifdef __cplusplus
  163. } // extern C
  164. #endif
  165. #endif /* __ANDROID_API__ < 21 */
  166. #endif /* HOST_ANDROID && ANDROID_UNIFIED_HEADERS */
  167. #endif /* __UTILS_MONO_COMPILER_H__*/