Skip to content

Commit

Permalink
[release/7.0] Set AssemblyName.ProcessorArchitecture for compatibilit…
Browse files Browse the repository at this point in the history
…y. (#81101)

* Set AssemblyName.ProcessorArchitecture for compatibility.

* Simplified ProcArch computation.

* Make GetAssemblyName test more robust (#80878)

* undo AssemblyName.CoreCLR change

* Library servicing steps.

---------

Co-authored-by: vsadov <8218165+VSadov@users.noreply.github.com>
Co-authored-by: Vladimir Sadov <vsadov@microsoft.com>
  • Loading branch information
3 people committed Feb 8, 2023
1 parent 0a9c99f commit b384ed7
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

The System.Reflection.Metadata library is built-in as part of the shared framework in .NET Runtime. The package can be installed when you need to use it in other target frameworks.</PackageDescription>
<PackageReadmeFile>README.md</PackageReadmeFile>
<ServicingVersion>1</ServicingVersion>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>

<!-- DesignTimeBuild requires all the TargetFramework Derived Properties to not be present in the first property group. -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ public static unsafe AssemblyName GetAssemblyName(string assemblyFile)
peReader = new PEReader((byte*)safeBuffer.DangerousGetHandle(), (int)safeBuffer.ByteLength);
MetadataReader mdReader = peReader.GetMetadataReader(MetadataReaderOptions.None);
AssemblyName assemblyName = mdReader.GetAssemblyDefinition().GetAssemblyName();

AssemblyFlags aFlags = mdReader.AssemblyTable.GetFlags();
#pragma warning disable SYSLIB0037 // AssemblyName.ProcessorArchitecture is obsolete
assemblyName.ProcessorArchitecture = CalculateProcArch(peReader, aFlags);
#pragma warning restore SYSLIB0037

return assemblyName;
}
finally
Expand All @@ -101,6 +107,42 @@ public static unsafe AssemblyName GetAssemblyName(string assemblyFile)
}
}

private static ProcessorArchitecture CalculateProcArch(PEReader peReader, AssemblyFlags aFlags)
{
// 0x70 specifies "reference assembly".
// For these, CLR wants to return None as arch so they can be always loaded, regardless of process type.
if (((uint)aFlags & 0xF0) == 0x70)
return ProcessorArchitecture.None;

PEHeaders peHeaders = peReader.PEHeaders;
switch (peHeaders.CoffHeader.Machine)
{
case Machine.IA64:
return ProcessorArchitecture.IA64;
case Machine.Arm:
return ProcessorArchitecture.Arm;
case Machine.Amd64:
return ProcessorArchitecture.Amd64;
case Machine.I386:
{
CorFlags flags = peHeaders.CorHeader!.Flags;
if ((flags & CorFlags.ILOnly) != 0 &&
(flags & CorFlags.Requires32Bit) == 0)
{
// platform neutral.
return ProcessorArchitecture.MSIL;
}

// requires x86
return ProcessorArchitecture.X86;
}
}

// ProcessorArchitecture is a legacy API and does not cover other Machine kinds.
// For example ARM64 is not expressible
return ProcessorArchitecture.None;
}

private static AssemblyNameFlags GetAssemblyNameFlags(AssemblyFlags flags)
{
AssemblyNameFlags assemblyNameFlags = AssemblyNameFlags.None;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3090,8 +3090,13 @@ public void GetAssemblyName()

if (PlatformDetection.HasAssemblyFiles)
{
Assembly a = typeof(MetadataReaderTests).Assembly;
Assert.Equal(new AssemblyName(a.FullName).ToString(), MetadataReader.GetAssemblyName(AssemblyPathHelper.GetAssemblyLocation(a)).ToString());
Assembly a = typeof(MetadataReader).Assembly;
AssemblyName name = MetadataReader.GetAssemblyName(AssemblyPathHelper.GetAssemblyLocation(a));
Assert.Equal(new AssemblyName(a.FullName).ToString(), name.ToString());

#pragma warning disable SYSLIB0037 // AssemblyName.ProcessorArchitecture is obsolete
Assert.Equal(ProcessorArchitecture.MSIL, name.ProcessorArchitecture);
#pragma warning restore SYSLIB0037
}
}
}
Expand Down

0 comments on commit b384ed7

Please sign in to comment.