Coreclr gnuport (#22129)
authorSinan Kaya <41809318+franksinankaya@users.noreply.github.com>
Fri, 1 Feb 2019 15:27:39 +0000 (10:27 -0500)
committerJan Vorlicek <janvorli@microsoft.com>
Fri, 1 Feb 2019 15:27:39 +0000 (16:27 +0100)
* Abstract away NOINLINE statement

MSVC and GNU compilers use different attributes for noinline.
Abstract away compiler differences.

* Replace __sync_swap with __atomic_exchange_n

__sync_swap doesn't exist on GNU. Replacing with __atomic_exchange_n
which is universally available.

* Define CDECL for GNUC

__cdecl is not defined by default on GNU compilers.

* Define gcc version of __declspec(thread)

* Correct pointer casting

A pointer value is usually unsigned long on most platforms.
Casting it to integer causes signedness issues. Use size_t
to be efficient on all 32 and 64 bit architectures.

* Put quotes around the error string

Correct error statement. GNU G++ is picky about the string
following the error statement with ' character in it. It needs
to be enclosed with double quotes.

* Fix casting problem

Seeing these warnings with GNU G++ compiler

src/pal/src/sync/cs.cpp: In function ‘void CorUnix::InternalInitializeCriticalSectionAndSpinCount(PCRITICAL_SECTION, DWORD, bool)’:
src/pal/src/sync/cs.cpp:630:48: warning: converting to non-pointer type ‘SIZE_T {aka long unsigned int}’ from NULL [-Wconversion-null]
         pPalCriticalSection->OwningThread      = NULL;
                                                ^
src/pal/src/sync/cs.cpp: In function ‘void CorUnix::InternalLeaveCriticalSection(CorUnix::CPalThread*, _CRITICAL_SECTION*)’:
src/pal/src/sync/cs.cpp:880:43: warning: converting to non-pointer type ‘SIZE_T {aka long unsigned int}’ from NULL [-Wconversion-null]
         pPalCriticalSection->OwningThread = NULL;
                                           ^

* Abstract optnone compiler attribute

GNU compiler doesn't support optnone attribute.

pal/src/exception/seh-unwind.cpp:449:77: warning: ‘optnone’ attribute directive ignored [-Wattributes]

* Set the aligned attribute for GNU compiler

* Make __rotl and __rotr functions portable

GNU compiler doesn't have an intrinsic for these. Open code them
using the provided implementation.

* Define deprecated attribute for gcc

* Add throw specifier for GCC

/usr/include/string.h:43:28: error: declaration of ‘void* memcpy(void*, const void*, size_t) throw ()’ has a different exception specifier
        size_t __n) __THROW __nonnull ((1, 2));

15 files changed:
src/inc/palclr.h
src/inc/staticcontract.h
src/pal/inc/mbusafecrt.h
src/pal/inc/pal.h
src/pal/inc/rt/safecrt.h
src/pal/src/exception/seh-unwind.cpp
src/pal/src/exception/seh.cpp
src/pal/src/include/pal/context.h
src/pal/src/init/pal.cpp
src/pal/src/locale/utf8.cpp
src/pal/src/safecrt/memcpy_s.cpp
src/pal/src/sync/cs.cpp
src/pal/src/thread/context.cpp
src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest1.cpp
src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest2.cpp

index 10ef462..a9dbe0d 100644 (file)
 #define _DEBUG_IMPL 1
 #endif
 
+#if __GNUC__
+#ifndef __cdecl
+#define __cdecl        __attribute__((__cdecl__))
+#endif
+#endif
+
 //
 // CPP_ASSERT() can be used within a class definition, to perform a
 // compile-time assertion involving private names within the class.
index f7390c9..4cf7f4a 100644 (file)
 #define SCAN_WIDEN2(x) L ## x
 #define SCAN_WIDEN(x) SCAN_WIDEN2(x)
 
+#ifndef NOINLINE
+#if __GNUC__
+#define NOINLINE __attribute__((noinline))
+#else
+#define NOINLINE __declspec(noinline)
+#endif
+#endif
+
 //
 // PDB annotations for the static contract analysis tool. These are seperated
 // from Contract.h to allow their inclusion in any part of the system.
@@ -211,7 +219,7 @@ namespace StaticContract
 {
     struct ScanThrowMarkerStandard
     {
-        __declspec(noinline) ScanThrowMarkerStandard()
+        NOINLINE ScanThrowMarkerStandard()
         {
             METHOD_CANNOT_BE_FOLDED_DEBUG;
             STATIC_CONTRACT_THROWS;
@@ -225,7 +233,7 @@ namespace StaticContract
 
     struct ScanThrowMarkerTerminal
     {
-        __declspec(noinline) ScanThrowMarkerTerminal()
+        NOINLINE ScanThrowMarkerTerminal()
         {
             METHOD_CANNOT_BE_FOLDED_DEBUG;
         }
@@ -237,7 +245,7 @@ namespace StaticContract
 
     struct ScanThrowMarkerIgnore
     {
-        __declspec(noinline) ScanThrowMarkerIgnore()
+        NOINLINE ScanThrowMarkerIgnore()
         {
             METHOD_CANNOT_BE_FOLDED_DEBUG;
         }
@@ -283,21 +291,21 @@ template <UINT COUNT>
 class BlockMarker
 {
 public:
-    __declspec(noinline) void MarkBlock()
+    NOINLINE void MarkBlock()
     {
         ANNOTATION_MARK_BLOCK_ANNOTATION;
         METHOD_CANNOT_BE_FOLDED_DEBUG;
         return;
     }
 
-    __declspec(noinline) void UseMarkedBlockAnnotation()
+    NOINLINE void UseMarkedBlockAnnotation()
     {
         ANNOTATION_USE_BLOCK_ANNOTATION;
         METHOD_CANNOT_BE_FOLDED_DEBUG;
         return;
     }
 
-    __declspec(noinline) void EndUseMarkedBlockAnnotation()
+    NOINLINE void EndUseMarkedBlockAnnotation()
     {
         ANNOTATION_END_USE_BLOCK_ANNOTATION;
         METHOD_CANNOT_BE_FOLDED_DEBUG;
index f030b7d..9c516e0 100644 (file)
@@ -31,6 +31,12 @@ typedef int errno_t;
 // define the return value for success 
 #define SAFECRT_SUCCESS 0
 
+#if defined(_MSC_VER) || defined(__llvm__)
+#define THROW_DECL
+#else
+#define THROW_DECL throw()
+#endif
+
 #ifdef __cplusplus
     extern "C" {
 #endif
@@ -98,7 +104,7 @@ extern int swscanf_s( const WCHAR *string, const WCHAR *format, ... );
 extern int _snscanf_s( const char *string, size_t count, const char *format, ... );
 extern int _snwscanf_s( const WCHAR *string, size_t count, const WCHAR *format, ... );
 
-extern errno_t memcpy_s( void * dst, size_t sizeInBytes, const void * src, size_t count );
+extern errno_t memcpy_s( void * dst, size_t sizeInBytes, const void * src, size_t count ) THROW_DECL;
 extern errno_t memmove_s( void * dst, size_t sizeInBytes, const void * src, size_t count );
 
 #ifdef __cplusplus
index 76e04cd..7bf3496 100644 (file)
@@ -143,6 +143,11 @@ typedef void * NATIVE_LIBRARY_HANDLE;
 #define LANG_THAI                        0x1e
 
 /******************* Compiler-specific glue *******************************/
+#if defined(_MSC_VER) || defined(__llvm__)
+#define THROW_DECL
+#else
+#define THROW_DECL throw()
+#endif
 
 #ifndef _MSC_VER
 #if defined(CORECLR)
@@ -156,7 +161,7 @@ typedef void * NATIVE_LIBRARY_HANDLE;
 #if defined(_MSC_VER) || defined(__llvm__)
 #define DECLSPEC_ALIGN(x)   __declspec(align(x))
 #else
-#define DECLSPEC_ALIGN(x) 
+#define DECLSPEC_ALIGN(x)   __attribute__ ((aligned(x)))
 #endif
 
 #define DECLSPEC_NORETURN   PAL_NORETURN
@@ -176,6 +181,14 @@ typedef void * NATIVE_LIBRARY_HANDLE;
 #endif
 #endif
 
+#ifndef NOOPT_ATTRIBUTE
+#if defined(__llvm__)
+#define NOOPT_ATTRIBUTE optnone
+#else
+#define NOOPT_ATTRIBUTE optimize("O0")
+#endif
+#endif
+
 #ifndef PAL_STDCPP_COMPAT
 
 #if __GNUC__
@@ -3503,7 +3516,7 @@ InterlockedExchange(
     IN OUT LONG volatile *Target,
     IN LONG Value)
 {
-    LONG result = __sync_swap(Target, Value);
+    LONG result = __atomic_exchange_n(Target, Value, __ATOMIC_ACQ_REL);
     PAL_ArmInterlockedOperationBarrier();
     return result;
 }
@@ -3517,7 +3530,7 @@ InterlockedExchange64(
     IN OUT LONGLONG volatile *Target,
     IN LONGLONG Value)
 {
-    LONGLONG result = __sync_swap(Target, Value);
+    LONGLONG result = __atomic_exchange_n(Target, Value, __ATOMIC_ACQ_REL);
     PAL_ArmInterlockedOperationBarrier();
     return result;
 }
@@ -4316,7 +4329,7 @@ PALIMPORT int    __cdecl memcmp(const void *, const void *, size_t);
 PALIMPORT void * __cdecl memset(void *, int, size_t);
 PALIMPORT void * __cdecl memmove(void *, const void *, size_t);
 PALIMPORT void * __cdecl memchr(const void *, int, size_t);
-PALIMPORT long long int __cdecl atoll(const char *);
+PALIMPORT long long int __cdecl atoll(const char *) THROW_DECL;
 PALIMPORT size_t __cdecl strlen(const char *);
 PALIMPORT int __cdecl strcmp(const char*, const char *);
 PALIMPORT int __cdecl strncmp(const char*, const char *, size_t);
@@ -4355,7 +4368,7 @@ PALIMPORT int __cdecl toupper(int);
 #define _TRUNCATE ((size_t)-1)
 #endif
 
-PALIMPORT errno_t __cdecl memcpy_s(void *, size_t, const void *, size_t);
+PALIMPORT errno_t __cdecl memcpy_s(void *, size_t, const void *, size_t) THROW_DECL;
 PALIMPORT errno_t __cdecl memmove_s(void *, size_t, const void *, size_t);
 PALIMPORT char * __cdecl _strlwr(char *);
 PALIMPORT int __cdecl _stricmp(const char *, const char *);
@@ -4426,7 +4439,15 @@ inline WCHAR *PAL_wcsstr(WCHAR *_S, const WCHAR *_P)
 }
 #endif
 
-#if !__has_builtin(_rotl)
+#if defined(__llvm__)
+#define HAS_ROTL __has_builtin(_rotl)
+#define HAS_ROTR __has_builtin(_rotr)
+#else
+#define HAS_ROTL 0
+#define HAS_ROTR 0
+#endif
+
+#if !HAS_ROTL
 /*++
 Function:
 _rotl
@@ -4444,14 +4465,14 @@ unsigned int __cdecl _rotl(unsigned int value, int shift)
     retval = (value << shift) | (value >> (sizeof(int) * CHAR_BIT - shift));
     return retval;
 }
-#endif // !__has_builtin(_rotl)
+#endif // !HAS_ROTL
 
 // On 64 bit unix, make the long an int.
 #ifdef BIT64
 #define _lrotl _rotl
 #endif // BIT64
 
-#if !__has_builtin(_rotr)
+#if !HAS_ROTR
 
 /*++
 Function:
@@ -4471,7 +4492,7 @@ unsigned int __cdecl _rotr(unsigned int value, int shift)
     return retval;
 }
 
-#endif // !__has_builtin(_rotr)
+#endif // !HAS_ROTR
 
 PALIMPORT int __cdecl abs(int);
 // clang complains if this is declared with __int64
@@ -4487,10 +4508,10 @@ PALIMPORT double __cdecl acos(double);
 PALIMPORT double __cdecl acosh(double);
 PALIMPORT double __cdecl asin(double);
 PALIMPORT double __cdecl asinh(double);
-PALIMPORT double __cdecl atan(double);
-PALIMPORT double __cdecl atanh(double);
+PALIMPORT double __cdecl atan(double) THROW_DECL;
+PALIMPORT double __cdecl atanh(double) THROW_DECL;
 PALIMPORT double __cdecl atan2(double, double);
-PALIMPORT double __cdecl cbrt(double);
+PALIMPORT double __cdecl cbrt(double) THROW_DECL;
 PALIMPORT double __cdecl ceil(double);
 PALIMPORT double __cdecl cos(double);
 PALIMPORT double __cdecl cosh(double);
@@ -4520,10 +4541,10 @@ PALIMPORT float __cdecl acosf(float);
 PALIMPORT float __cdecl acoshf(float);
 PALIMPORT float __cdecl asinf(float);
 PALIMPORT float __cdecl asinhf(float);
-PALIMPORT float __cdecl atanf(float);
-PALIMPORT float __cdecl atanhf(float);
+PALIMPORT float __cdecl atanf(float) THROW_DECL;
+PALIMPORT float __cdecl atanhf(float) THROW_DECL;
 PALIMPORT float __cdecl atan2f(float, float);
-PALIMPORT float __cdecl cbrtf(float);
+PALIMPORT float __cdecl cbrtf(float) THROW_DECL;
 PALIMPORT float __cdecl ceilf(float);
 PALIMPORT float __cdecl cosf(float);
 PALIMPORT float __cdecl coshf(float);
index 92366df..9f9e15c 100644 (file)
@@ -135,7 +135,11 @@ typedef _W64 unsigned int   uintptr_t;
 #define _UINTPTR_T_DEFINED
 #endif
 
+#ifdef __GNUC__
+#define SAFECRT_DEPRECATED __attribute__((deprecated))
+#else
 #define SAFECRT_DEPRECATED __declspec(deprecated)
+#endif
 
 /* errno_t */
 #if !defined(_ERRCODE_DEFINED)
index c62f975..0940361 100644 (file)
@@ -444,7 +444,7 @@ Note:
 --*/
 PAL_NORETURN
 __attribute__((noinline))
-__attribute__((optnone))
+__attribute__((NOOPT_ATTRIBUTE))
 static void 
 RtlpRaiseException(EXCEPTION_RECORD *ExceptionRecord, CONTEXT *ContextRecord)
 {
index 07cdb31..5cfea0c 100644 (file)
@@ -394,12 +394,12 @@ bool CatchHardwareExceptionHolder::IsEnabled()
 
 --*/
 
-#ifdef __llvm__
-__thread 
-#else // __llvm__
-__declspec(thread)
-#endif // !__llvm__
-static NativeExceptionHolderBase *t_nativeExceptionHolderHead = nullptr;
+#if defined(__GNUC__)
+static __thread
+#else // __GNUC__
+__declspec(thread) static
+#endif // !__GNUC__
+NativeExceptionHolderBase *t_nativeExceptionHolderHead = nullptr;
 
 extern "C"
 NativeExceptionHolderBase **
index a488e0a..146b9a0 100644 (file)
@@ -486,7 +486,7 @@ inline static DWORD64 CONTEXTGetPC(LPCONTEXT pContext)
 #elif defined(_ARM64_) || defined(_ARM_)
     return pContext->Pc;
 #else
-#error don't know how to get the program counter for this architecture
+#error "don't know how to get the program counter for this architecture"
 #endif
 }
 
@@ -499,7 +499,7 @@ inline static void CONTEXTSetPC(LPCONTEXT pContext, DWORD64 pc)
 #elif defined(_ARM64_) || defined(_ARM_)
     pContext->Pc = pc;
 #else
-#error don't know how to set the program counter for this architecture
+#error "don't know how to set the program counter for this architecture"
 #endif
 }
 
@@ -514,7 +514,7 @@ inline static DWORD64 CONTEXTGetFP(LPCONTEXT pContext)
 #elif defined(_ARM64_)
     return pContext->Fp;
 #else
-#error don't know how to get the frame pointer for this architecture
+#error "don't know how to get the frame pointer for this architecture"
 #endif
 }
 
index 119e611..d683ca7 100644 (file)
@@ -239,7 +239,7 @@ Abstract:
   real life scenarios work.
 
 --*/
-__attribute__((noinline,optnone))
+__attribute__((noinline,NOOPT_ATTRIBUTE))
 void
 EnsureStackSize(SIZE_T stackSize)
 {
index c83b5a8..db83dd0 100644 (file)
@@ -1467,7 +1467,7 @@ public:
                 }
 
                 // get pSrc 2-byte aligned
-                if (((int)pSrc & 0x1) != 0) {
+                if (((size_t)pSrc & 0x1) != 0) {
                     ch = *pSrc;
                     pSrc++;
                     if (ch > 0x7F) {
@@ -1476,7 +1476,7 @@ public:
                 }
 
                 // get pSrc 4-byte aligned
-                if (((int)pSrc & 0x2) != 0) {
+                if (((size_t)pSrc & 0x2) != 0) {
                     ch = *(USHORT*)pSrc;
                     if ((ch & 0x8080) != 0) {
                         goto LongCodeWithMask16;
@@ -1906,7 +1906,7 @@ public:
                 pTarget++;
 
                 // get pSrc to be 2-byte aligned
-                if ((((int)pSrc) & 0x1) != 0) {
+                if ((((size_t)pSrc) & 0x1) != 0) {
                     ch = *pSrc;
                     pSrc++;
                     if (ch > 0x7F) {
@@ -1917,7 +1917,7 @@ public:
                 }
 
                 // get pSrc to be 4-byte aligned
-                if ((((int)pSrc) & 0x2) != 0) {
+                if ((((size_t)pSrc) & 0x2) != 0) {
                     ch = *(USHORT*)pSrc;
                     if ((ch & 0x8080) != 0) {
                         goto LongCodeWithMask16;
@@ -2740,7 +2740,7 @@ public:
                 }
 
                 // get pSrc aligned
-                if (((int)pSrc & 0x2) != 0) {
+                if (((size_t)pSrc & 0x2) != 0) {
                     ch = *pSrc;
                     pSrc++;
                     if (ch > 0x7F)                                              // Not ASCII
index 27aeb79..a75ec41 100644 (file)
@@ -54,7 +54,7 @@ errno_t __cdecl memcpy_s(
     size_t sizeInBytes,
     const void * src,
     size_t count
-)
+) THROW_DECL
 {
     if (count == 0)
     {
index af5dddc..f2913e4 100644 (file)
@@ -627,7 +627,7 @@ namespace CorUnix
         pPalCriticalSection->LockCount         = 0;
         pPalCriticalSection->RecursionCount    = 0;
         pPalCriticalSection->SpinCount         = dwSpinCount;
-        pPalCriticalSection->OwningThread      = NULL;
+        pPalCriticalSection->OwningThread      = 0;
         pPalCriticalSection->LockSemaphore     = NULL;
         pPalCriticalSection->fInternal         = fInternal;
 
@@ -877,7 +877,7 @@ namespace CorUnix
         }
 
         // Reset CS ownership
-        pPalCriticalSection->OwningThread = NULL;
+        pPalCriticalSection->OwningThread = 0;
 
         // Load the current LockCount value
         lVal = pPalCriticalSection->LockCount;
index 12672e8..b98b99d 100644 (file)
@@ -167,7 +167,7 @@ typedef int __ptrace_request;
        ASSIGN_REG(X28)
 
 #else
-#error Don't know how to assign registers on this architecture
+#error "Don't know how to assign registers on this architecture"
 #endif
 
 #define ASSIGN_ALL_REGS     \
index 0b9d78f..22602bf 100644 (file)
@@ -21,7 +21,7 @@ int InitializeDllTest1()
     return PAL_InitializeDLL();
 }
 
-__attribute__((noinline,optnone))
+__attribute__((noinline,NOOPT_ATTRIBUTE))
 static void FailingFunction(volatile int *p)
 {
     if (p == NULL)
index 1f17b81..222898f 100644 (file)
@@ -21,7 +21,7 @@ int InitializeDllTest2()
     return PAL_InitializeDLL();
 }
 
-__attribute__((noinline,optnone))
+__attribute__((noinline,NOOPT_ATTRIBUTE))
 static void FailingFunction(volatile int *p)
 {
     if (p == NULL)