Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[mono] Implement AssemblyExtensions.TryGetRawMetadata. #111642

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public unsafe class AssemblyExtensionsTest
[Fact]
public void TryGetRawMetadata()
{
bool supportsRawMetadata = PlatformDetection.IsNotMonoRuntime && PlatformDetection.IsNotNativeAot;
bool supportsRawMetadata = PlatformDetection.IsNotNativeAot;

Assembly assembly = typeof(AssemblyExtensionsTest).Assembly;
bool hasMetadata = assembly.TryGetRawMetadata(out byte* blob, out int length);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ public static unsafe bool TryGetRawMetadata(this Assembly assembly, out byte* bl
{
ArgumentNullException.ThrowIfNull(assembly);

if (assembly is RuntimeAssembly runtimeAssembly)
{
return runtimeAssembly.TryGetRawMetadata(out blob, out length);
}

blob = null;
length = 0;
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,12 @@ internal static RuntimeAssembly InternalLoad(AssemblyName assemblyRef, ref Stack
return res;
}

internal unsafe bool TryGetRawMetadata(out byte* blob, out int length)
{
var this_assembly = this;
return InternalTryGetRawMetadata(new QCallAssembly(ref this_assembly), out blob, out length);
}

[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern bool GetManifestResourceInfoInternal(QCallAssembly assembly, string name, ManifestResourceInfo info);

Expand All @@ -489,6 +495,9 @@ internal static RuntimeAssembly InternalLoad(AssemblyName assemblyRef, ref Stack
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern IntPtr InternalGetReferencedAssemblies(Assembly assembly);

[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern unsafe bool InternalTryGetRawMetadata(QCallAssembly assembly, out byte* blob, out int length);

internal string? GetSimpleName()
{
// TODO: Make this cheaper and faster
Expand Down
1 change: 1 addition & 0 deletions src/mono/mono/metadata/icall-def.h
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,7 @@ HANDLES(RASSEM_5, "GetManifestResourceNames", ves_icall_System_Reflection_Runtim
HANDLES(RASSEM_6, "GetModulesInternal", ves_icall_System_Reflection_RuntimeAssembly_GetModulesInternal, void, 2, (MonoQCallAssemblyHandle, MonoObjectHandleOnStack))
HANDLES(RASSEM_6b, "GetTopLevelForwardedTypes", ves_icall_System_Reflection_RuntimeAssembly_GetTopLevelForwardedTypes, void, 2, (MonoQCallAssemblyHandle, MonoObjectHandleOnStack))
HANDLES(RASSEM_7, "InternalGetReferencedAssemblies", ves_icall_System_Reflection_Assembly_InternalGetReferencedAssemblies, GPtrArray_ptr, 1, (MonoReflectionAssembly))
HANDLES(RASSEM_8, "InternalTryGetRawMetadata", ves_icall_System_Reflection_RuntimeAssembly_InternalTryGetRawMetadata, MonoBoolean, 3, (MonoQCallAssemblyHandle, gpointer_ref, gint32_ref))

ICALL_TYPE(MCMETH, "System.Reflection.RuntimeConstructorInfo", MCMETH_1)
HANDLES(MCMETH_1, "GetGenericMethodDefinition_impl", ves_icall_RuntimeMethodInfo_GetGenericMethodDefinition, MonoReflectionMethod, 1, (MonoReflectionMethod))
Expand Down
12 changes: 12 additions & 0 deletions src/mono/mono/metadata/icall.c
Original file line number Diff line number Diff line change
Expand Up @@ -4743,6 +4743,18 @@ ves_icall_System_Reflection_Assembly_InternalGetReferencedAssemblies (MonoReflec
return result;
}

MonoBoolean
ves_icall_System_Reflection_RuntimeAssembly_InternalTryGetRawMetadata (MonoQCallAssemblyHandle assembly_h, gpointer_ref blob, gint32_ref length, MonoError *error)
{
MonoAssembly *assembly = assembly_h.assembly;
MonoImage *image = assembly->image;

*blob = image->raw_metadata;
*((guint32*)length) = image->raw_metadata_len;

return *blob != NULL;
}

/* move this in some file in mono/util/ */
static char *
g_concat_dir_and_file (const char *dir, const char *file)
Expand Down
1 change: 1 addition & 0 deletions src/mono/mono/metadata/image.c
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,7 @@ load_metadata_ptrs (MonoImage *image, MonoCLIImageInfo *iinfo)
if (offset + size > image->raw_data_len)
return FALSE;
image->raw_metadata = image->raw_data + offset;
image->raw_metadata_len = size;

/* 24.2.1: Metadata root starts here */
ptr = image->raw_metadata;
Expand Down
1 change: 1 addition & 0 deletions src/mono/mono/metadata/metadata-internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,7 @@ struct _MonoImage {
MonoMemPool *mempool; /*protected by the image lock*/

char *raw_metadata;
guint32 raw_metadata_len;

MonoStreamHeader heap_strings;
MonoStreamHeader heap_us;
Expand Down
Loading