diff --git a/eng/native/configurecompiler.cmake b/eng/native/configurecompiler.cmake index cee494e67091d1..40e9e75242e267 100644 --- a/eng/native/configurecompiler.cmake +++ b/eng/native/configurecompiler.cmake @@ -94,9 +94,9 @@ if (MSVC) add_compile_options($<$:$>) add_link_options($<$>:/guard:cf>) - if (NOT CLR_CMAKE_PGO_INSTRUMENT) + if (NOT CLR_CMAKE_PGO_INSTRUMENT AND NOT CLR_CMAKE_ENABLE_SANITIZERS) # Load all imported DLLs from the System32 directory. - # Don't do this when instrumenting for PGO as a local DLL dependency is introduced by the instrumentation + # Don't do this when instrumenting for PGO or when a sanitizer is enabled as a local DLL dependency is introduced by the instrumentation add_linker_flag(/DEPENDENTLOADFLAG:0x800) endif() diff --git a/src/coreclr/inc/formattype.h b/src/coreclr/inc/formattype.h index b112c9792dc443..757b15bd86c045 100644 --- a/src/coreclr/inc/formattype.h +++ b/src/coreclr/inc/formattype.h @@ -6,14 +6,6 @@ #include "corpriv.h" // for IMDInternalImport -// ILDASM code doesn't memcpy on gc pointers, so it prefers the real -// memcpy rather than GCSafeMemCpy. -#if defined(_DEBUG) && !defined(DACCESS_COMPILE) -#ifdef memcpy -#undef memcpy -#endif -#endif - #define MAX_PREFIX_SIZE 32 struct ParamDescriptor diff --git a/src/coreclr/nativeaot/CMakeLists.txt b/src/coreclr/nativeaot/CMakeLists.txt index 8fd36f1a78ee27..11eb0aa8202a8a 100644 --- a/src/coreclr/nativeaot/CMakeLists.txt +++ b/src/coreclr/nativeaot/CMakeLists.txt @@ -42,3 +42,7 @@ add_compile_definitions($<${FEATURE_JAVAMARSHAL}:FEATURE_JAVAMARSHAL>) add_subdirectory(Bootstrap) add_subdirectory(Runtime) + +if (NOT "${ASAN_RUNTIME}" STREQUAL "") + install(FILES ${ASAN_RUNTIME} DESTINATION . COMPONENT nativeaot) +endif() diff --git a/src/coreclr/utilcode/ex.cpp b/src/coreclr/utilcode/ex.cpp index e4036d236b6a5e..d93e6c6ce57a09 100644 --- a/src/coreclr/utilcode/ex.cpp +++ b/src/coreclr/utilcode/ex.cpp @@ -96,12 +96,7 @@ void Exception::Delete(Exception* pvMemory) return; } -#ifdef DACCESS_COMPILE delete pvMemory; -#else - ::delete pvMemory; -#endif - } void Exception::GetMessage(SString &result) diff --git a/src/coreclr/vm/common.h b/src/coreclr/vm/common.h index 54c17e3594bb3a..0ecd3dac69b117 100644 --- a/src/coreclr/vm/common.h +++ b/src/coreclr/vm/common.h @@ -180,13 +180,6 @@ FORCEINLINE void* memcpyNoGCRefs(void * dest, const void * src, size_t len) return memcpy(dest, src, len); } -#if defined(_DEBUG) && !defined(DACCESS_COMPILE) - // You should be using CopyValueClass if you are doing an memcpy - // in the GC heap. - extern "C" void * __cdecl GCSafeMemCpy(void *, const void *, size_t); -#define memcpy(dest, src, len) GCSafeMemCpy(dest, src, len) -#endif // _DEBUG && !DACCESS_COMPILE - namespace Loader { typedef enum diff --git a/src/coreclr/vm/interpexec.cpp b/src/coreclr/vm/interpexec.cpp index 0e5dbcd61106cc..678b2a089fbbf6 100644 --- a/src/coreclr/vm/interpexec.cpp +++ b/src/coreclr/vm/interpexec.cpp @@ -3,6 +3,9 @@ #ifdef FEATURE_INTERPRETER +#include +#include + #include "threads.h" #include "gcenv.h" #include "interpexec.h" diff --git a/src/coreclr/vm/object.cpp b/src/coreclr/vm/object.cpp index c0a50aa2bd73b4..2bb5865114d014 100644 --- a/src/coreclr/vm/object.cpp +++ b/src/coreclr/vm/object.cpp @@ -1169,35 +1169,6 @@ OBJECTREF& OBJECTREF::operator=(TADDR nul) } #endif // DEBUG -#ifdef _DEBUG - -void* __cdecl GCSafeMemCpy(void * dest, const void * src, size_t len) -{ - STATIC_CONTRACT_NOTHROW; - STATIC_CONTRACT_GC_NOTRIGGER; - STATIC_CONTRACT_FORBID_FAULT; - - if (!(((*(BYTE**)&dest) < g_lowest_address ) || - ((*(BYTE**)&dest) >= g_highest_address))) - { - Thread* pThread = GetThreadNULLOk(); - - // GCHeapUtilities::IsHeapPointer has race when called in preemptive mode. It walks the list of segments - // that can be modified by GC. Do the check below only if it is safe to do so. - if (pThread != NULL && pThread->PreemptiveGCDisabled()) - { - // Note there is memcpyNoGCRefs which will allow you to do a memcpy into the GC - // heap if you really know you don't need to call the write barrier - - _ASSERTE(!GCHeapUtilities::GetGCHeap()->IsHeapPointer((BYTE *) dest) || - !"using memcpy to copy into the GC heap, use CopyValueClass"); - } - } - return memcpyNoGCRefs(dest, src, len); -} - -#endif // _DEBUG - // This function clears a piece of memory in a GC safe way. It makes the guarantee // that it will clear memory in at least pointer sized chunks whenever possible. // Unaligned memory at the beginning and remaining bytes at the end are written bytewise. diff --git a/src/native/minipal/CMakeLists.txt b/src/native/minipal/CMakeLists.txt index 2aab34901c228c..32c9497f273c13 100644 --- a/src/native/minipal/CMakeLists.txt +++ b/src/native/minipal/CMakeLists.txt @@ -60,9 +60,17 @@ if(CLR_CMAKE_HOST_ANDROID) target_link_libraries(minipal PRIVATE log) endif(CLR_CMAKE_HOST_ANDROID) +set(SANITIZER_EXPORTS_FILE ${CMAKE_CURRENT_SOURCE_DIR}/sanitizer_exports.def) + add_library(minipal_sanitizer_support OBJECT sansupport.c) -# Exclude this target from the default build as we may not have sanitzer headers available + +set_source_files_properties(sansupport.c PROPERTIES OBJECT_DEPENDS ${SANITIZER_EXPORTS_FILE}) + +if (MSVC) + target_link_options(minipal_sanitizer_support INTERFACE /DEF:${SANITIZER_EXPORTS_FILE}) +endif() +# Exclude this target from the default build as we may not have sanitizer headers available # in a non-sanitized build. set_target_properties(minipal_sanitizer_support PROPERTIES EXCLUDE_FROM_ALL ON) diff --git a/src/native/minipal/sanitizer_exports.def b/src/native/minipal/sanitizer_exports.def new file mode 100644 index 00000000000000..c68857ce3f396e --- /dev/null +++ b/src/native/minipal/sanitizer_exports.def @@ -0,0 +1,6 @@ +; Licensed to the .NET Foundation under one or more agreements. +; The .NET Foundation licenses this file to you under the MIT license. + +EXPORTS + __asan_default_options + __asan_on_error \ No newline at end of file diff --git a/src/native/minipal/sansupport.c b/src/native/minipal/sansupport.c index d6474e21791a3b..c687c6f53ee8b5 100644 --- a/src/native/minipal/sansupport.c +++ b/src/native/minipal/sansupport.c @@ -6,6 +6,10 @@ // Use a typedef here as __declspec + pointer return type causes a parse error in MSVC typedef const char* charptr_t; +#ifdef __cplusplus +extern "C" +{ +#endif charptr_t SANITIZER_CALLBACK_CALLCONV __asan_default_options(void) { // symbolize=1 to get symbolized stack traces @@ -20,3 +24,7 @@ charptr_t SANITIZER_CALLBACK_CALLCONV __asan_default_options(void) { void SANITIZER_CALLBACK_CALLCONV __asan_on_error(void) { } + +#ifdef __cplusplus +} +#endif diff --git a/src/native/minipal/utils.h b/src/native/minipal/utils.h index cb1fa309b3b134..e1f1f439e4ca16 100644 --- a/src/native/minipal/utils.h +++ b/src/native/minipal/utils.h @@ -109,13 +109,8 @@ #endif #if defined(_MSC_VER) -# ifdef SANITIZER_SHARED_RUNTIME -# define SANITIZER_CALLBACK_CALLCONV __declspec(dllexport no_sanitize_address) __cdecl -# define SANITIZER_INTERFACE_CALLCONV __declspec(dllimport) __cdecl -# else -# define SANITIZER_CALLBACK_CALLCONV __declspec(no_sanitize_address) __cdecl -# define SANITIZER_INTERFACE_CALLCONV __cdecl -# endif +# define SANITIZER_CALLBACK_CALLCONV __declspec(no_sanitize_address) __cdecl +# define SANITIZER_INTERFACE_CALLCONV __cdecl #else # ifdef SANITIZER_SHARED_RUNTIME # define SANITIZER_CALLBACK_CALLCONV __attribute__((no_address_safety_analysis)) __attribute__((visibility("default"))) diff --git a/src/tests/nativeaot/CustomMain/CustomMainNative.cpp b/src/tests/nativeaot/CustomMain/CustomMainNative.cpp index e9bb1c25b9d460..2ab3b6bed8f95e 100644 --- a/src/tests/nativeaot/CustomMain/CustomMainNative.cpp +++ b/src/tests/nativeaot/CustomMain/CustomMainNative.cpp @@ -6,6 +6,7 @@ #ifndef TARGET_WINDOWS #define __stdcall +#define __cdecl #endif #if defined(_WIN32) @@ -27,7 +28,7 @@ int main(int argc, char* argv[]) return __managed__Main(argc, argv); } -extern "C" const char* __stdcall __asan_default_options() +extern "C" const char* __cdecl __asan_default_options() { // NativeAOT is not designed to be unloadable, so we'll leak a few allocations from the shared library. // Disable leak detection as we don't care about these leaks as of now. diff --git a/src/tests/nativeaot/CustomMainWithStubExe/CustomMainWithStubExeNative.cpp b/src/tests/nativeaot/CustomMainWithStubExe/CustomMainWithStubExeNative.cpp index c883eacbcb9fa3..293dd5a623aa24 100644 --- a/src/tests/nativeaot/CustomMainWithStubExe/CustomMainWithStubExeNative.cpp +++ b/src/tests/nativeaot/CustomMainWithStubExe/CustomMainWithStubExeNative.cpp @@ -12,6 +12,7 @@ #ifndef TARGET_WINDOWS #define __stdcall +#define __cdecl #endif // typedef for shared lib exported methods @@ -52,7 +53,7 @@ int main(int argc, char* argv[]) return __managed__MainFunc(argc, argv); } -extern "C" const char* __stdcall __asan_default_options() +extern "C" const char* __cdecl __asan_default_options() { // NativeAOT is not designed to be unloadable, so we'll leak a few allocations from the shared library. // Disable leak detection as we don't care about these leaks as of now. diff --git a/src/tests/nativeaot/SmokeTests/SharedLibrary/SharedLibrary.cpp b/src/tests/nativeaot/SmokeTests/SharedLibrary/SharedLibrary.cpp index c76b3535b03023..cc03865016a4f9 100644 --- a/src/tests/nativeaot/SmokeTests/SharedLibrary/SharedLibrary.cpp +++ b/src/tests/nativeaot/SmokeTests/SharedLibrary/SharedLibrary.cpp @@ -11,6 +11,7 @@ #ifndef TARGET_WINDOWS #define __stdcall +#define __cdecl #endif // typedef for shared lib exported methods @@ -83,7 +84,7 @@ int main(int argc, char* argv[]) return 100; } -extern "C" const char* __stdcall __asan_default_options() +extern "C" const char* __cdecl __asan_default_options() { // NativeAOT is not designed to be unloadable, so we'll leak a few allocations from the shared library. // Disable leak detection as we don't care about these leaks as of now.