diff --git a/src/Common/src/CoreLib/Internal/Runtime/CompilerServices/Unsafe.cs b/src/Common/src/CoreLib/Internal/Runtime/CompilerServices/Unsafe.cs
new file mode 100644
index 000000000000..8e6c5da47bf5
--- /dev/null
+++ b/src/Common/src/CoreLib/Internal/Runtime/CompilerServices/Unsafe.cs
@@ -0,0 +1,315 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.Versioning;
+
+#if BIT64
+using nuint = System.UInt64;
+using nint = System.Int64;
+#else
+using nuint = System.UInt32;
+using nint = System.Int32;
+#endif
+
+//
+// The implementations of most the methods in this file are provided as intrinsics.
+// In CoreCLR, the body of the functions are replaced by the EE with unsafe code. See see getILIntrinsicImplementationForUnsafe for details.
+// In CoreRT, see Internal.IL.Stubs.UnsafeIntrinsics for details.
+//
+
+namespace Internal.Runtime.CompilerServices
+{
+ //
+ // Subsetted clone of System.Runtime.CompilerServices.Unsafe for internal runtime use.
+ // Keep in sync with https://github.com/dotnet/corefx/tree/master/src/System.Runtime.CompilerServices.Unsafe.
+ //
+
+ ///
+ /// For internal use only. Contains generic, low-level functionality for manipulating pointers.
+ ///
+ [CLSCompliant(false)]
+ public static unsafe class Unsafe
+ {
+ ///
+ /// Returns a pointer to the given by-ref parameter.
+ ///
+ [Intrinsic]
+ [NonVersionable]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void* AsPointer(ref T value)
+ {
+ throw new PlatformNotSupportedException();
+
+ // ldarg.0
+ // conv.u
+ // ret
+ }
+
+ ///
+ /// Returns the size of an object of the given type parameter.
+ ///
+ [Intrinsic]
+ [NonVersionable]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int SizeOf()
+ {
+#if CORECLR
+ typeof(T).ToString(); // Type token used by the actual method body
+#endif
+ throw new PlatformNotSupportedException();
+
+ // sizeof !!0
+ // ret
+ }
+
+ ///
+ /// Casts the given object to the specified type, performs no dynamic type checking.
+ ///
+ [Intrinsic]
+ [NonVersionable]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static T As(object value) where T : class
+ {
+ throw new PlatformNotSupportedException();
+
+ // ldarg.0
+ // ret
+ }
+
+ ///
+ /// Reinterprets the given reference as a reference to a value of type .
+ ///
+ [Intrinsic]
+ [NonVersionable]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static ref TTo As(ref TFrom source)
+ {
+ throw new PlatformNotSupportedException();
+
+ // ldarg.0
+ // ret
+ }
+
+ ///
+ /// Adds an element offset to the given reference.
+ ///
+ [Intrinsic]
+ [NonVersionable]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static ref T Add(ref T source, int elementOffset)
+ {
+#if CORECLR
+ typeof(T).ToString(); // Type token used by the actual method body
+ throw new PlatformNotSupportedException();
+#else
+ return ref AddByteOffset(ref source, (IntPtr)(elementOffset * (nint)SizeOf()));
+#endif
+ }
+
+ ///
+ /// Adds an element offset to the given pointer.
+ ///
+ [Intrinsic]
+ [NonVersionable]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void* Add(void* source, int elementOffset)
+ {
+#if CORECLR
+ typeof(T).ToString(); // Type token used by the actual method body
+ throw new PlatformNotSupportedException();
+#else
+ return (byte*)source + (elementOffset * (nint)SizeOf());
+#endif
+ }
+
+ ///
+ /// Adds an element offset to the given reference.
+ ///
+ [Intrinsic]
+ [NonVersionable]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal static ref T AddByteOffset(ref T source, nuint byteOffset)
+ {
+ return ref AddByteOffset(ref source, (IntPtr)(void*)byteOffset);
+ }
+
+ ///
+ /// Determines whether the specified references point to the same location.
+ ///
+ [Intrinsic]
+ [NonVersionable]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool AreSame(ref T left, ref T right)
+ {
+ throw new PlatformNotSupportedException();
+
+ // ldarg.0
+ // ldarg.1
+ // ceq
+ // ret
+ }
+
+ ///
+ /// Initializes a block of memory at the given location with a given initial value
+ /// without assuming architecture dependent alignment of the address.
+ ///
+ [Intrinsic]
+ [NonVersionable]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void InitBlockUnaligned(ref byte startAddress, byte value, uint byteCount)
+ {
+ for (uint i = 0; i < byteCount; i++)
+ AddByteOffset(ref startAddress, i) = value;
+ }
+
+ ///
+ /// Reads a value of type from the given location.
+ ///
+ [Intrinsic]
+ [NonVersionable]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static T ReadUnaligned(void* source)
+ {
+#if CORECLR
+ typeof(T).ToString(); // Type token used by the actual method body
+ throw new PlatformNotSupportedException();
+#else
+ return Unsafe.As(ref *(byte*)source);
+#endif
+ }
+
+ ///
+ /// Reads a value of type from the given location.
+ ///
+ [Intrinsic]
+ [NonVersionable]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static T ReadUnaligned(ref byte source)
+ {
+#if CORECLR
+ typeof(T).ToString(); // Type token used by the actual method body
+ throw new PlatformNotSupportedException();
+#else
+ return Unsafe.As(ref source);
+#endif
+ }
+
+ ///
+ /// Writes a value of type to the given location.
+ ///
+ [Intrinsic]
+ [NonVersionable]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void WriteUnaligned(void* destination, T value)
+ {
+#if CORECLR
+ typeof(T).ToString(); // Type token used by the actual method body
+ throw new PlatformNotSupportedException();
+#else
+ Unsafe.As(ref *(byte*)destination) = value;
+#endif
+ }
+
+ ///
+ /// Writes a value of type to the given location.
+ ///
+ [Intrinsic]
+ [NonVersionable]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void WriteUnaligned(ref byte destination, T value)
+ {
+#if CORECLR
+ typeof(T).ToString(); // Type token used by the actual method body
+ throw new PlatformNotSupportedException();
+#else
+ Unsafe.As(ref destination) = value;
+#endif
+ }
+
+ ///
+ /// Adds an element offset to the given reference.
+ ///
+ [Intrinsic]
+ [NonVersionable]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static ref T AddByteOffset(ref T source, IntPtr byteOffset)
+ {
+ // This method is implemented by the toolchain
+ throw new PlatformNotSupportedException();
+
+ // ldarg.0
+ // ldarg.1
+ // add
+ // ret
+ }
+
+ ///
+ /// Reads a value of type from the given location.
+ ///
+ [Intrinsic]
+ [NonVersionable]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static T Read(void* source)
+ {
+ return Unsafe.As(ref *(byte*)source);
+ }
+
+ ///
+ /// Reads a value of type from the given location.
+ ///
+ [Intrinsic]
+ [NonVersionable]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static T Read(ref byte source)
+ {
+ return Unsafe.As(ref source);
+ }
+
+ ///
+ /// Writes a value of type to the given location.
+ ///
+ [Intrinsic]
+ [NonVersionable]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void Write(void* destination, T value)
+ {
+ Unsafe.As(ref *(byte*)destination) = value;
+ }
+
+ ///
+ /// Writes a value of type to the given location.
+ ///
+ [Intrinsic]
+ [NonVersionable]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void Write(ref byte destination, T value)
+ {
+ Unsafe.As(ref destination) = value;
+ }
+
+ ///
+ /// Reinterprets the given location as a reference to a value of type .
+ ///
+ [Intrinsic]
+ [NonVersionable]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static ref T AsRef(void* source)
+ {
+ return ref Unsafe.As(ref *(byte*)source);
+ }
+
+ ///
+ /// Determines the byte offset from origin to target from the given references.
+ ///
+ [Intrinsic]
+ [NonVersionable]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static IntPtr ByteOffset(ref T origin, ref T target)
+ {
+ throw new PlatformNotSupportedException();
+ }
+ }
+}
diff --git a/src/Common/src/CoreLib/System.Private.CoreLib.Shared.projitems b/src/Common/src/CoreLib/System.Private.CoreLib.Shared.projitems
index 20bf4353a25f..90587d2bd0ab 100644
--- a/src/Common/src/CoreLib/System.Private.CoreLib.Shared.projitems
+++ b/src/Common/src/CoreLib/System.Private.CoreLib.Shared.projitems
@@ -19,6 +19,7 @@
+