[utils] Add check for ANDROID_UNIFIED_HEADERS to mono-compiler.h (#5742)
[mono.git] / mono / utils / mono-compiler.h
index 680c5a4cdded0ff203f10adf121c6dff8d416fa5..f8481d004d10e34da4cf629fef17b4bf38190137 100644 (file)
@@ -1,3 +1,7 @@
+/**
+ * \file
+ */
+
 #ifndef __UTILS_MONO_COMPILER_H__
 #define __UTILS_MONO_COMPILER_H__
 
  * compiler behaviours.
  */
 #include <config.h>
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
 
 #ifdef __GNUC__
-#define MONO_ATTR_USED __attribute__ ((used))
+#define MONO_ATTR_USED __attribute__ ((__used__))
 #else
 #define MONO_ATTR_USED
 #endif
 
 #ifdef __GNUC__
-#define MONO_ATTR_FORMAT_PRINTF(fmt_pos,arg_pos) __attribute__((format(printf,fmt_pos,arg_pos)))
+#define MONO_ATTR_FORMAT_PRINTF(fmt_pos,arg_pos) __attribute__ ((__format__(__printf__,fmt_pos,arg_pos)))
 #else
 #define MONO_ATTR_FORMAT_PRINTF(fmt_pos,arg_pos)
 #endif
 
-#ifdef HAVE_KW_THREAD
-
-#define MONO_HAVE_FAST_TLS
-#define MONO_FAST_TLS_SET(x,y) x = y
-#define MONO_FAST_TLS_GET(x) x
-#define MONO_FAST_TLS_INIT(x)
-#define MONO_FAST_TLS_DECLARE(x) static __thread gpointer x MONO_TLS_FAST MONO_ATTR_USED;
-
-#if HAVE_TLS_MODEL_ATTR
-
-#if defined(__PIC__) && !defined(PIC)
-/*
- * Must be compiling -fPIE, for executables.  Build PIC
- * but with initial-exec.
- * http://bugs.gentoo.org/show_bug.cgi?id=165547
- */
-#define PIC
-#define PIC_INITIAL_EXEC
-#endif
-
-/* 
- * Define this if you want a faster libmono, which cannot be loaded dynamically as a 
- * module.
- */
-//#define PIC_INITIAL_EXEC
-
-#if defined(PIC)
-
-#ifdef PIC_INITIAL_EXEC
-#define MONO_TLS_FAST __attribute__((tls_model("initial-exec")))
-#else
-#if defined (__powerpc__)
-/* local dynamic requires a call to __tls_get_addr to look up the
-   TLS block address via the Dynamic Thread Vector. In this case Thread
-   Pointer relative offsets can't be used as this modules TLS was
-   allocated separately (none contiguoiusly) from the initial TLS
-   block.
-
-   For now we will disable this. */
-#define MONO_TLS_FAST
-#else
-#define MONO_TLS_FAST __attribute__((tls_model("local-dynamic")))
-#endif
-#endif
-
-#else
-
-#define MONO_TLS_FAST __attribute__((tls_model("local-exec")))
-
-#endif
-
-#else
-#define MONO_TLS_FAST 
-#endif
-
-#if defined(__GNUC__) && defined(__i386__)
-#if defined(PIC)
-#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)
-#else
-#define MONO_THREAD_VAR_OFFSET(var,offset) __asm ("movl $" #var "@ntpoff, %0" : "=r" (offset))
-#endif
-#elif defined(__x86_64__)
-#if defined(PIC)
-// This only works if libmono is linked into the application
-#define MONO_THREAD_VAR_OFFSET(var,offset) do { guint64 foo;  __asm ("movq " #var "@GOTTPOFF(%%rip), %0" : "=r" (foo)); offset = foo; } while (0)
-#else
-#define MONO_THREAD_VAR_OFFSET(var,offset) do { guint64 foo;  __asm ("movq $" #var "@TPOFF, %0" : "=r" (foo)); offset = foo; } while (0)
-#endif
-#elif defined(__ia64__) && !defined(__INTEL_COMPILER)
-#if defined(PIC)
-#define MONO_THREAD_VAR_OFFSET(var,offset) __asm ("addl %0 = @ltoff(@tprel(" #var "#)), gp ;; ld8 %0 = [%0]\n" : "=r" (offset))
-#else
-#define MONO_THREAD_VAR_OFFSET(var,offset) __asm ("addl %0 = @tprel(" #var "#), r0 ;;\n" : "=r" (offset))
-#endif
-#elif defined(__arm__) && defined(__ARM_EABI__) && !defined(PIC)
-#define MONO_THREAD_VAR_OFFSET(var,offset) __asm ("    ldr     %0, 1f; b 2f; 1: .word " #var "(tpoff); 2:" : "=r" (offset))
-#elif defined(__aarch64__) && !defined(PIC)
-#define MONO_THREAD_VAR_OFFSET(var,offset) \
-       __asm ( "mov %0, #0\n add %0, %0, #:tprel_hi12:" #var "\n add %0, %0, #:tprel_lo12_nc:" #var "\n" \
-                       : "=r" (offset))
-#elif defined(__mono_ppc__) && defined(__GNUC__)
-#if defined(PIC)
-#ifdef PIC_INITIAL_EXEC
-
-#if defined(__mono_ppc64__)
-#define MONO_THREAD_VAR_OFFSET(var,offset) \
-       do { long off; \
-       __asm ( "ld     %0," #var "@got@tprel(2)\n" \
-       : "=r" (off)); \
-       (offset) = off; } while (0)
-#else
-/* must be powerpc32 */
-#define MONO_THREAD_VAR_OFFSET(var,offset) \
-       __asm ( "lwz    %0," #var "@got@tprel(30)\n" \
-       : "=r" (offset))
-#endif
-
-#else
-
-/* local dynamic requires a call to __tls_get_addr to look up the
-   TLS block address via the Dynamic Thread Vector. In this case Thread
-   Pointer relative offsets can't be used as this modules TLS was
-   allocated separately (none contiguoiusly) from the initial TLS
-   block.
-
-   For now we will disable this. */
-#define MONO_THREAD_VAR_OFFSET(var,offset) (offset) = -1
-
-#endif
-#else
-/* Must be local-exec TLS */
-#define MONO_THREAD_VAR_OFFSET(var,offset) \
-       __asm ( "lis    %0," #var "@tprel@ha\n" \
-               "addi   %0,%0, " #var "@tprel@l\n" \
-       : "=r" (offset))
-#endif
-#elif defined(__s390x__)
-# if defined(__PIC__)
-#  if !defined(__PIE__)
-// This only works if libmono is linked into the application
-#   define MONO_THREAD_VAR_OFFSET(var,offset) do { guint64 foo;                                \
-                                               __asm__ ("basr  %%r1,0\n\t"                     \
-                                                        "j     0f\n\t"                         \
-                                                        ".quad " #var "@TLSGD\n"               \
-                                                        "0:\n\t"                               \
-                                                        "lg    %%r2,4(%%r1)\n\t"               \
-                                                        "brasl %%r14,__tls_get_offset@PLT:tls_gdcall:"#var"\n\t" \
-                                                        "lgr   %0,%%r2\n\t"                    \
-                                                       : "=r" (foo) :                          \
-                                                       : "1", "2", "14", "cc");                \
-                                               offset = foo; } while (0)
-#  elif __PIE__ == 1
-#   define MONO_THREAD_VAR_OFFSET(var,offset) do { guint64 foo;                                        \
-                                               __asm__ ("lg    %0," #var "@GOTNTPOFF(%%r12)\n\t"       \
-                                                        : "=r" (foo));                                 \
-                                               offset = foo; } while (0)
-#  elif __PIE__ == 2
-#   define MONO_THREAD_VAR_OFFSET(var,offset) do { guint64 foo;                                \
-                                               __asm__ ("larl  %%r1," #var "@INDNTPOFF\n\t"    \
-                                                        "lg    %0,0(%%r1)\n\t"                 \
-                                                        : "=r" (foo) :                         \
-                                                        : "1", "cc");                          \
-                                               offset = foo; } while (0)
-#  endif
-# else
-#  define MONO_THREAD_VAR_OFFSET(var,offset) do { guint64 foo;                         \
-                                               __asm__ ("basr  %%r1,0\n\t"             \
-                                                        "j     0f\n\t"                 \
-                                                        ".quad " #var "@NTPOFF\n"      \
-                                                        "0:\n\t"                       \
-                                                        "lg    %0,4(%%r1)\n\t"         \
-                                                       : "=r" (foo) : : "1");          \
-                                               offset = foo; } while (0)
-# endif
-#else
-#define MONO_THREAD_VAR_OFFSET(var,offset) (offset) = -1
-#endif
-
-#if defined(PIC) && !defined(PIC_INITIAL_EXEC)
-/* 
- * The above definitions do not seem to work if libmono is loaded dynamically as a module.
- * See bug #78767.
- */
-#undef MONO_THREAD_VAR_OFFSET
-#define MONO_THREAD_VAR_OFFSET(var,offset) (offset) = -1
-#endif
-
-#elif !defined(MONO_CROSS_COMPILE) && defined(PLATFORM_MACOSX) && (defined(__i386__) || defined(__x86_64__))
-
-#define MONO_HAVE_FAST_TLS 1
-#define MONO_FAST_TLS_SET(x,y) pthread_setspecific(x, y)
-#define MONO_FAST_TLS_GET(x) pthread_getspecific(x)
-#define MONO_FAST_TLS_ADDR(x) (mono_mach_get_tls_address_from_thread (pthread_self (), x))
-#define MONO_FAST_TLS_INIT(x) pthread_key_create(&x, NULL)
-#define MONO_FAST_TLS_DECLARE(x) static pthread_key_t x;
-
-#define MONO_THREAD_VAR_OFFSET(x,y) ({ \
-       __typeof__(x) _x = (x);                 \
-       pthread_key_t _y;       \
-       (void) (&_x == &_y);            \
-       y = (gint32) x; })
-
-#elif !defined(MONO_CROSS_COMPILE) && (defined(PLATFORM_ANDROID) || defined(TARGET_IOS)) && defined(TARGET_ARM)
-
-#define MONO_HAVE_FAST_TLS
-#define MONO_FAST_TLS_SET(x,y) pthread_setspecific(x, y)
-#define MONO_FAST_TLS_GET(x) pthread_getspecific(x)
-#define MONO_FAST_TLS_INIT(x) pthread_key_create(&x, NULL)
-#define MONO_FAST_TLS_DECLARE(x) static pthread_key_t x;
-
-#define MONO_THREAD_VAR_OFFSET(var, offset) do { offset = (int)var; } while (0)
-
-#else /* no HAVE_KW_THREAD */
-
-#define MONO_THREAD_VAR_OFFSET(var,offset) (offset) = -1
-
-/*Macros to facilitate user code*/
-#define MONO_FAST_TLS_INIT(x)
-#endif
-
-#if defined(MONO_HAVE_FAST_TLS) && !defined(MONO_FAST_TLS_ADDR)
-#define MONO_FAST_TLS_ADDR(x) (&(x))
-#endif
-
-
 /* Deal with Microsoft C compiler differences */
 #ifdef _MSC_VER
 
@@ -275,7 +77,7 @@ typedef SSIZE_T ssize_t;
 #define MONO_EMPTY_SOURCE_FILE(x)
 #endif
 
-#if !defined(_MSC_VER) && !defined(PLATFORM_SOLARIS) && !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MONOTOUCH) && HAVE_VISIBILITY_HIDDEN
+#if !defined(_MSC_VER) && !defined(HOST_SOLARIS) && !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MONOTOUCH) && HAVE_VISIBILITY_HIDDEN
 #if MONO_LLVM_LOADED
 #define MONO_LLVM_INTERNAL MONO_API
 #else
@@ -285,8 +87,11 @@ typedef SSIZE_T ssize_t;
 #define MONO_LLVM_INTERNAL 
 #endif
 
+/* Used to mark internal functions used by the profiler modules */
+#define MONO_PROFILER_API MONO_API
+
 #ifdef __GNUC__
-#define MONO_ALWAYS_INLINE __attribute__((always_inline))
+#define MONO_ALWAYS_INLINE __attribute__ ((__always_inline__))
 #elif defined(_MSC_VER)
 #define MONO_ALWAYS_INLINE __forceinline
 #else
@@ -294,7 +99,7 @@ typedef SSIZE_T ssize_t;
 #endif
 
 #ifdef __GNUC__
-#define MONO_NEVER_INLINE __attribute__((noinline))
+#define MONO_NEVER_INLINE __attribute__ ((__noinline__))
 #elif defined(_MSC_VER)
 #define MONO_NEVER_INLINE __declspec(noinline)
 #else
@@ -302,7 +107,7 @@ typedef SSIZE_T ssize_t;
 #endif
 
 #ifdef __GNUC__
-#define MONO_COLD __attribute__((cold))
+#define MONO_COLD __attribute__ ((__cold__))
 #else
 #define MONO_COLD
 #endif
@@ -311,5 +116,54 @@ typedef SSIZE_T ssize_t;
 #define MONO_GNUC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
 #endif
 
+#if defined(__has_feature)
+#if __has_feature(thread_sanitizer)
+#define MONO_HAS_CLANG_THREAD_SANITIZER 1
+#else
+#define MONO_HAS_CLANG_THREAD_SANITIZER 0
+#endif
+#else
+#define MONO_HAS_CLANG_THREAD_SANITIZER 0
+#endif
+
+/* Used to tell Clang's ThreadSanitizer to not report data races that occur within a certain function */
+#if MONO_HAS_CLANG_THREAD_SANITIZER
+#define MONO_NO_SANITIZE_THREAD __attribute__ ((no_sanitize("thread")))
+#else
+#define MONO_NO_SANITIZE_THREAD
+#endif
+
+/* Used when building with Android NDK's unified headers */
+#if defined(HOST_ANDROID) && defined (ANDROID_UNIFIED_HEADERS)
+#if __ANDROID_API__ < 21
+
+typedef int32_t __mono_off32_t;
+
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+
+#if !defined(mmap)
+/* Unified headers before API 21 do not declare mmap when LARGE_FILES are used (via -D_FILE_OFFSET_BITS=64)
+ * which is always the case when Mono build targets Android. The problem here is that the unified headers
+ * map `mmap` to `mmap64` if large files are enabled but this api exists only in API21 onwards. Therefore
+ * we must carefully declare the 32-bit mmap here without changing the ABI along the way. Carefully because
+ * in this instance off_t is redeclared to be 64-bit and that's not what we want.
+ */
+void* mmap (void*, size_t, int, int, int, __mono_off32_t);
+#endif /* !mmap */
+
+#ifdef HAVE_SYS_SENDFILE_H
+#include <sys/sendfile.h>
+#endif
+
+#if !defined(sendfile)
+/* The same thing as with mmap happens with sendfile */
+ssize_t sendfile (int out_fd, int in_fd, __mono_off32_t* offset, size_t count);
+#endif /* !sendfile */
+
+#endif /* __ANDROID_API__ < 21 */
+#endif /* HOST_ANDROID && ANDROID_UNIFIED_HEADERS */
+
 #endif /* __UTILS_MONO_COMPILER_H__*/