From a4b81e48d8dd5b86c646e5cc1e4e617b1467fa4d Mon Sep 17 00:00:00 2001 From: Sinan Kaya <41809318+franksinankaya@users.noreply.github.com> Date: Fri, 1 Feb 2019 10:27:39 -0500 Subject: [PATCH] Coreclr gnuport (dotnet/coreclr#22129) MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit * 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)); Commit migrated from https://github.com/dotnet/coreclr/commit/fc7a8fbbc1754c8dd49f66f9b59c1ff12a5f842e --- src/coreclr/src/inc/palclr.h | 6 +++ src/coreclr/src/inc/staticcontract.h | 20 ++++++--- src/coreclr/src/pal/inc/mbusafecrt.h | 8 +++- src/coreclr/src/pal/inc/pal.h | 51 +++++++++++++++------- src/coreclr/src/pal/inc/rt/safecrt.h | 4 ++ src/coreclr/src/pal/src/exception/seh-unwind.cpp | 2 +- src/coreclr/src/pal/src/exception/seh.cpp | 12 ++--- src/coreclr/src/pal/src/include/pal/context.h | 6 +-- src/coreclr/src/pal/src/init/pal.cpp | 2 +- src/coreclr/src/pal/src/locale/utf8.cpp | 10 ++--- src/coreclr/src/pal/src/safecrt/memcpy_s.cpp | 2 +- src/coreclr/src/pal/src/sync/cs.cpp | 4 +- src/coreclr/src/pal/src/thread/context.cpp | 2 +- .../exception_handling/pal_sxs/test1/dlltest1.cpp | 2 +- .../exception_handling/pal_sxs/test1/dlltest2.cpp | 2 +- 15 files changed, 89 insertions(+), 44 deletions(-) diff --git a/src/coreclr/src/inc/palclr.h b/src/coreclr/src/inc/palclr.h index 10ef462..a9dbe0d 100644 --- a/src/coreclr/src/inc/palclr.h +++ b/src/coreclr/src/inc/palclr.h @@ -31,6 +31,12 @@ #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. diff --git a/src/coreclr/src/inc/staticcontract.h b/src/coreclr/src/inc/staticcontract.h index f7390c9..4cf7f4a 100644 --- a/src/coreclr/src/inc/staticcontract.h +++ b/src/coreclr/src/inc/staticcontract.h @@ -15,6 +15,14 @@ #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 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; diff --git a/src/coreclr/src/pal/inc/mbusafecrt.h b/src/coreclr/src/pal/inc/mbusafecrt.h index f030b7d..9c516e0 100644 --- a/src/coreclr/src/pal/inc/mbusafecrt.h +++ b/src/coreclr/src/pal/inc/mbusafecrt.h @@ -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 diff --git a/src/coreclr/src/pal/inc/pal.h b/src/coreclr/src/pal/inc/pal.h index 76e04cd..7bf3496 100644 --- a/src/coreclr/src/pal/inc/pal.h +++ b/src/coreclr/src/pal/inc/pal.h @@ -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); diff --git a/src/coreclr/src/pal/inc/rt/safecrt.h b/src/coreclr/src/pal/inc/rt/safecrt.h index 92366df..9f9e15c 100644 --- a/src/coreclr/src/pal/inc/rt/safecrt.h +++ b/src/coreclr/src/pal/inc/rt/safecrt.h @@ -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) diff --git a/src/coreclr/src/pal/src/exception/seh-unwind.cpp b/src/coreclr/src/pal/src/exception/seh-unwind.cpp index c62f975..0940361 100644 --- a/src/coreclr/src/pal/src/exception/seh-unwind.cpp +++ b/src/coreclr/src/pal/src/exception/seh-unwind.cpp @@ -444,7 +444,7 @@ Note: --*/ PAL_NORETURN __attribute__((noinline)) -__attribute__((optnone)) +__attribute__((NOOPT_ATTRIBUTE)) static void RtlpRaiseException(EXCEPTION_RECORD *ExceptionRecord, CONTEXT *ContextRecord) { diff --git a/src/coreclr/src/pal/src/exception/seh.cpp b/src/coreclr/src/pal/src/exception/seh.cpp index 07cdb31..5cfea0c 100644 --- a/src/coreclr/src/pal/src/exception/seh.cpp +++ b/src/coreclr/src/pal/src/exception/seh.cpp @@ -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 ** diff --git a/src/coreclr/src/pal/src/include/pal/context.h b/src/coreclr/src/pal/src/include/pal/context.h index a488e0a..146b9a0 100644 --- a/src/coreclr/src/pal/src/include/pal/context.h +++ b/src/coreclr/src/pal/src/include/pal/context.h @@ -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 } diff --git a/src/coreclr/src/pal/src/init/pal.cpp b/src/coreclr/src/pal/src/init/pal.cpp index 119e611..d683ca7 100644 --- a/src/coreclr/src/pal/src/init/pal.cpp +++ b/src/coreclr/src/pal/src/init/pal.cpp @@ -239,7 +239,7 @@ Abstract: real life scenarios work. --*/ -__attribute__((noinline,optnone)) +__attribute__((noinline,NOOPT_ATTRIBUTE)) void EnsureStackSize(SIZE_T stackSize) { diff --git a/src/coreclr/src/pal/src/locale/utf8.cpp b/src/coreclr/src/pal/src/locale/utf8.cpp index c83b5a8..db83dd0 100644 --- a/src/coreclr/src/pal/src/locale/utf8.cpp +++ b/src/coreclr/src/pal/src/locale/utf8.cpp @@ -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 diff --git a/src/coreclr/src/pal/src/safecrt/memcpy_s.cpp b/src/coreclr/src/pal/src/safecrt/memcpy_s.cpp index 27aeb79..a75ec41 100644 --- a/src/coreclr/src/pal/src/safecrt/memcpy_s.cpp +++ b/src/coreclr/src/pal/src/safecrt/memcpy_s.cpp @@ -54,7 +54,7 @@ errno_t __cdecl memcpy_s( size_t sizeInBytes, const void * src, size_t count -) +) THROW_DECL { if (count == 0) { diff --git a/src/coreclr/src/pal/src/sync/cs.cpp b/src/coreclr/src/pal/src/sync/cs.cpp index af5dddc..f2913e4 100644 --- a/src/coreclr/src/pal/src/sync/cs.cpp +++ b/src/coreclr/src/pal/src/sync/cs.cpp @@ -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; diff --git a/src/coreclr/src/pal/src/thread/context.cpp b/src/coreclr/src/pal/src/thread/context.cpp index 12672e8..b98b99d 100644 --- a/src/coreclr/src/pal/src/thread/context.cpp +++ b/src/coreclr/src/pal/src/thread/context.cpp @@ -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 \ diff --git a/src/coreclr/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest1.cpp b/src/coreclr/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest1.cpp index 0b9d78f..22602bf 100644 --- a/src/coreclr/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest1.cpp +++ b/src/coreclr/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest1.cpp @@ -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) diff --git a/src/coreclr/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest2.cpp b/src/coreclr/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest2.cpp index 1f17b81..222898f 100644 --- a/src/coreclr/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest2.cpp +++ b/src/coreclr/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest2.cpp @@ -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) -- 2.7.4