Add AssemblyExtensions.TryGetRawMetadata to the System.Reflection.Metadata namespace.
authorKoundinya Veluri <kouvel@microsoft.com>
Fri, 4 Sep 2015 05:06:56 +0000 (22:06 -0700)
committerKoundinya Veluri <kouvel@microsoft.com>
Wed, 9 Sep 2015 20:12:36 +0000 (13:12 -0700)
This patch contains has the necessary changes in coreclr and mscorlib. Tests will be added separately, once the new API is
published and can be consumed.

Part of dotnet/corefxdotnet/coreclr#2768

Commit migrated from https://github.com/dotnet/coreclr/commit/2f042a1212137e558fca716dbb92197f7a770e55

src/coreclr/src/mscorlib/model.xml
src/coreclr/src/mscorlib/mscorlib.shared.sources.props
src/coreclr/src/mscorlib/src/System/Reflection/Metadata/AssemblyExtensions.cs [new file with mode: 0644]
src/coreclr/src/vm/assemblynative.cpp
src/coreclr/src/vm/assemblynative.hpp
src/coreclr/src/vm/ecalllist.h

index 4d169f8..8136c81 100644 (file)
     <Member Name="SetProfileOptimizationRoot(System.String)" />
     <Member Name="StartProfileOptimization(System.String)" />
     </Type>
+    <Type Name="System.Reflection.Metadata.AssemblyExtensions">
+      <Member Name="TryGetRawMetadata(System.Reflection.Assembly,System.Byte*@,System.Int32@)"/>
+    </Type>
     <Type Status="ApiFxInternal" Name="System.Runtime.Versioning.BinaryCompatibility">
       <Member Status="ApiFxInternal" MemberType="Property" Name="TargetsAtLeast_Phone_V7_1" />
       <Member Status="ApiFxInternal" MemberType="Property" Name="TargetsAtLeast_Phone_V8_0" />
index a4b0511..5dc14a4 100644 (file)
     <ReflectionEmitSources Include="$(BclSourcesRoot)\System\Reflection\Emit\XXXOnTypeBuilderInstantiation.cs" />
     <ReflectionEmitSources Include="$(BclSourcesRoot)\System\Reflection\Emit\UnmanagedMarshal.cs" />
   </ItemGroup>
+  <ItemGroup Condition="'$(FeatureCoreclr)' == 'true'">
+    <ReflectionMetadataSources Include="$(BclSourcesRoot)\System\Reflection\Metadata\AssemblyExtensions.cs" />
+  </ItemGroup>
   <ItemGroup>
     <GlobalizationSources Include="$(BclSourcesRoot)\System\Globalization\DateTimeFormat.cs" />
     <GlobalizationSources Include="$(BclSourcesRoot)\System\Globalization\DateTimeParse.cs" />
     <MscorlibSources Include="@(SerializationFormattersSources)" ><Visible>true</Visible></MscorlibSources>
     <MscorlibSources Include="@(SerializationFormattersBinarySources)" ><Visible>true</Visible></MscorlibSources>
     <MscorlibSources Include="@(ReflectionEmitSources)" ><Visible>true</Visible></MscorlibSources>
+    <MscorlibSources Include="@(ReflectionMetadataSources)" ><Visible>true</Visible></MscorlibSources>
     <MscorlibSources Include="@(ConfigurationAssembliesSources)" ><Visible>true</Visible></MscorlibSources>
     <MscorlibSources Include="@(SecCryptographySources)" ><Visible>true</Visible></MscorlibSources>
     <MscorlibSources Include="@(SecPublickeySources)" ><Visible>true</Visible></MscorlibSources>
diff --git a/src/coreclr/src/mscorlib/src/System/Reflection/Metadata/AssemblyExtensions.cs b/src/coreclr/src/mscorlib/src/System/Reflection/Metadata/AssemblyExtensions.cs
new file mode 100644 (file)
index 0000000..64c0e5c
--- /dev/null
@@ -0,0 +1,37 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Security;
+
+namespace System.Reflection.Metadata
+{
+    public static class AssemblyExtensions
+    {
+        [DllImport(JitHelpers.QCall)]
+        [SuppressUnmanagedCodeSecurity]
+        [return: MarshalAs(UnmanagedType.Bool)]
+        private unsafe static extern bool InternalTryGetRawMetadata(RuntimeAssembly assembly, ref byte* blob, ref int length);
+
+        // Retrieves the metadata section of the assembly, for use with System.Reflection.Metadata.MetadataReader.
+        //   - Returns false upon failure. Metadata might not be available for some assemblies, such as AssemblyBuilder, .NET
+        //     native images, etc.
+        //   - Callers should not write to the metadata blob
+        //   - The metadata blob pointer will remain valid as long as the AssemblyLoadContext with which the assembly is
+        //     associated, is alive. The caller is responsible for keeping the assembly object alive while accessing the
+        //     metadata blob.
+        [CLSCompliant(false)] // out byte* blob
+        public unsafe static bool TryGetRawMetadata(this Assembly assembly, out byte* blob, out int length)
+        {
+            if (assembly == null)
+            {
+                throw new ArgumentNullException("assembly");
+            }
+
+            blob = null;
+            length = 0;
+            return InternalTryGetRawMetadata((RuntimeAssembly)assembly, ref blob, ref length);
+        }
+    }
+}
index 40df006..5b4e0c5 100644 (file)
@@ -2614,3 +2614,29 @@ INT_PTR QCALLTYPE AssemblyNative::GetLoadContextForAssembly(QCall::AssemblyHandl
     return ptrManagedAssemblyLoadContext;
 }
 #endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
+
+// static
+BOOL QCALLTYPE AssemblyNative::InternalTryGetRawMetadata(
+    QCall::AssemblyHandle assembly,
+    UINT8 **blobRef,
+    INT32 *lengthRef)
+{
+    QCALL_CONTRACT;
+
+    PTR_CVOID metadata = nullptr;
+
+    BEGIN_QCALL;
+
+    _ASSERTE(assembly != nullptr);
+    _ASSERTE(blobRef != nullptr);
+    _ASSERTE(lengthRef != nullptr);
+
+    static_assert_no_msg(sizeof(*lengthRef) == sizeof(COUNT_T));
+    metadata = assembly->GetFile()->GetLoadedMetadata(reinterpret_cast<COUNT_T *>(lengthRef));
+    *blobRef = reinterpret_cast<UINT8 *>(const_cast<PTR_VOID>(metadata));
+    _ASSERTE(*lengthRef >= 0);
+
+    END_QCALL;
+
+    return metadata != nullptr;
+}
index 9163710..f4ca12e 100644 (file)
@@ -282,6 +282,8 @@ public:
     static void QCALLTYPE LoadFromStream(INT_PTR ptrNativeAssemblyLoadContext, INT_PTR ptrAssemblyArray, INT32 cbAssemblyArrayLength, INT_PTR ptrSymbolArray, INT32 cbSymbolArrayLength, QCall::ObjectHandleOnStack retLoadedAssembly);
     static Assembly* LoadFromPEImage(CLRPrivBinderAssemblyLoadContext* pBinderContext, PEImage *pILImage, PEImage *pNIImage);
     static INT_PTR QCALLTYPE GetLoadContextForAssembly(QCall::AssemblyHandle pAssembly);
+
+    static BOOL QCALLTYPE InternalTryGetRawMetadata(QCall::AssemblyHandle assembly, UINT8 **blobRef, INT32 *lengthRef);
 };
 
 #endif
index c35168f..b6bd8ee 100644 (file)
@@ -1156,6 +1156,12 @@ FCFuncStart(gAssemblyFuncs)
 
 FCFuncEnd()
 
+#ifdef FEATURE_CORECLR
+FCFuncStart(gAssemblyExtensionsFuncs)
+    QCFuncElement("InternalTryGetRawMetadata", AssemblyNative::InternalTryGetRawMetadata)
+FCFuncEnd()
+#endif
+
 #if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
 FCFuncStart(gAssemblyLoadContextFuncs)
     QCFuncElement("InitializeAssemblyLoadContext", AssemblyNative::InitializeAssemblyLoadContext)
@@ -2148,6 +2154,10 @@ FCClassElement("AssemblyBuilder", "System.Reflection.Emit", gAssemblyBuilderFunc
 FCClassElement("AssemblyEvidenceFactory", "System.Security.Policy", gAssemblyEvidenceFactoryFuncs)
 #endif // FEATURE_CAS_POLICY
 
+#ifdef FEATURE_CORECLR
+FCClassElement("AssemblyExtensions", "System.Reflection.Metadata", gAssemblyExtensionsFuncs)
+#endif
+
 #if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
 FCClassElement("AssemblyLoadContext", "System.Runtime.Loader", gAssemblyLoadContextFuncs)
 #endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER)