Skip to content

Commit b384ed7

Browse files
[release/7.0] Set AssemblyName.ProcessorArchitecture for compatibility. (#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 <[email protected]> Co-authored-by: Vladimir Sadov <[email protected]>
1 parent 0a9c99f commit b384ed7

File tree

3 files changed

+51
-2
lines changed

3 files changed

+51
-2
lines changed

src/libraries/System.Reflection.Metadata/src/System.Reflection.Metadata.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
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>
1111
<PackageReadmeFile>README.md</PackageReadmeFile>
12+
<ServicingVersion>1</ServicingVersion>
13+
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
1214
</PropertyGroup>
1315

1416
<!-- DesignTimeBuild requires all the TargetFramework Derived Properties to not be present in the first property group. -->

src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/MetadataReader.netstandard.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,12 @@ public static unsafe AssemblyName GetAssemblyName(string assemblyFile)
8585
peReader = new PEReader((byte*)safeBuffer.DangerousGetHandle(), (int)safeBuffer.ByteLength);
8686
MetadataReader mdReader = peReader.GetMetadataReader(MetadataReaderOptions.None);
8787
AssemblyName assemblyName = mdReader.GetAssemblyDefinition().GetAssemblyName();
88+
89+
AssemblyFlags aFlags = mdReader.AssemblyTable.GetFlags();
90+
#pragma warning disable SYSLIB0037 // AssemblyName.ProcessorArchitecture is obsolete
91+
assemblyName.ProcessorArchitecture = CalculateProcArch(peReader, aFlags);
92+
#pragma warning restore SYSLIB0037
93+
8894
return assemblyName;
8995
}
9096
finally
@@ -101,6 +107,42 @@ public static unsafe AssemblyName GetAssemblyName(string assemblyFile)
101107
}
102108
}
103109

110+
private static ProcessorArchitecture CalculateProcArch(PEReader peReader, AssemblyFlags aFlags)
111+
{
112+
// 0x70 specifies "reference assembly".
113+
// For these, CLR wants to return None as arch so they can be always loaded, regardless of process type.
114+
if (((uint)aFlags & 0xF0) == 0x70)
115+
return ProcessorArchitecture.None;
116+
117+
PEHeaders peHeaders = peReader.PEHeaders;
118+
switch (peHeaders.CoffHeader.Machine)
119+
{
120+
case Machine.IA64:
121+
return ProcessorArchitecture.IA64;
122+
case Machine.Arm:
123+
return ProcessorArchitecture.Arm;
124+
case Machine.Amd64:
125+
return ProcessorArchitecture.Amd64;
126+
case Machine.I386:
127+
{
128+
CorFlags flags = peHeaders.CorHeader!.Flags;
129+
if ((flags & CorFlags.ILOnly) != 0 &&
130+
(flags & CorFlags.Requires32Bit) == 0)
131+
{
132+
// platform neutral.
133+
return ProcessorArchitecture.MSIL;
134+
}
135+
136+
// requires x86
137+
return ProcessorArchitecture.X86;
138+
}
139+
}
140+
141+
// ProcessorArchitecture is a legacy API and does not cover other Machine kinds.
142+
// For example ARM64 is not expressible
143+
return ProcessorArchitecture.None;
144+
}
145+
104146
private static AssemblyNameFlags GetAssemblyNameFlags(AssemblyFlags flags)
105147
{
106148
AssemblyNameFlags assemblyNameFlags = AssemblyNameFlags.None;

src/libraries/System.Reflection.Metadata/tests/Metadata/MetadataReaderTests.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3090,8 +3090,13 @@ public void GetAssemblyName()
30903090

30913091
if (PlatformDetection.HasAssemblyFiles)
30923092
{
3093-
Assembly a = typeof(MetadataReaderTests).Assembly;
3094-
Assert.Equal(new AssemblyName(a.FullName).ToString(), MetadataReader.GetAssemblyName(AssemblyPathHelper.GetAssemblyLocation(a)).ToString());
3093+
Assembly a = typeof(MetadataReader).Assembly;
3094+
AssemblyName name = MetadataReader.GetAssemblyName(AssemblyPathHelper.GetAssemblyLocation(a));
3095+
Assert.Equal(new AssemblyName(a.FullName).ToString(), name.ToString());
3096+
3097+
#pragma warning disable SYSLIB0037 // AssemblyName.ProcessorArchitecture is obsolete
3098+
Assert.Equal(ProcessorArchitecture.MSIL, name.ProcessorArchitecture);
3099+
#pragma warning restore SYSLIB0037
30953100
}
30963101
}
30973102
}

0 commit comments

Comments
 (0)