33using AsmResolver . DotNet . Builder ;
44using AsmResolver . DotNet . Serialized ;
55using AsmResolver . IO ;
6+ using AsmResolver . PE ;
7+ using AsmResolver . PE . Builder ;
68using AsmResolver . PE . DotNet . Metadata . Tables ;
79using AsmResolver . PE . DotNet . StrongName ;
10+ using AsmResolver . PE . File ;
811using NuGet . Frameworks ;
912using ShimGen ;
13+ using System . Diagnostics . CodeAnalysis ;
1014
1115if ( args is not [
1216 var outputRefDir ,
@@ -57,7 +61,7 @@ .. var dotnetOobPackagePaths
5761// first, arrange the lookups in a reasonable manner
5862// pkgPath -> framework -> dllPaths
5963var packageLayout = new Dictionary < string , Dictionary < NuGetFramework , List < ( string dllPath , string dllName ) > > > ( ) ;
60- var dllsByDllName = new Dictionary < string , List < string > > ( ) ;
64+ var dllsByDllName = new Dictionary < string , Dictionary < NuGetFramework , string > > ( ) ;
6165foreach ( var ( pkgPath , libPath , framework , dllPath ) in pkgList
6266 . SelectMany ( ta
6367 => ta . Item2 . SelectMany ( tb
@@ -86,7 +90,7 @@ .. var dotnetOobPackagePaths
8690 dllsByDllName . Add ( dllName , dllPathList = new ( ) ) ;
8791 }
8892
89- dllPathList . Add ( dllPath ) ;
93+ dllPathList . Add ( framework , dllPath ) ;
9094}
9195
9296// collect the list of ALL target frameworks that we might care about
@@ -96,7 +100,7 @@ .. var dotnetOobPackagePaths
96100 . ToArray ( ) ;
97101
98102// then build up a mapping of the source files for all of those TFMs
99- var frameworkGroupLayout = new Dictionary < NuGetFramework , List < string > > ( ) ;
103+ var frameworkGroupLayout = new Dictionary < NuGetFramework , List < ( string dllName , string assemblyFullName ) > > ( ) ;
100104foreach ( var tfm in targetTfms )
101105{
102106 if ( ! frameworkGroupLayout . TryGetValue ( tfm , out var list ) )
@@ -106,12 +110,22 @@ .. var dotnetOobPackagePaths
106110
107111 foreach ( var ( pkgPath , pkgFwks ) in packageLayout )
108112 {
109- var bestTfm = fwReducer . GetNearest ( tfm , pkgFwks . Keys ) ;
110- if ( bestTfm is not null )
113+ if ( TryGetFrameworkKey ( pkgFwks , tfm , fwReducer , out var dlls ) )
111114 {
112- foreach ( var ( _ , dllName ) in pkgFwks [ bestTfm ] )
115+ foreach ( var ( dllPath , _ ) in dlls )
113116 {
114- list . Add ( dllName ) ;
117+ var assembly = AssemblyDefinition . FromFile ( dllPath ) ;
118+ if ( assembly . Name == "System.Runtime.CompilerServices.Unsafe" )
119+ {
120+ // For SRCS.Unsafe, we switch to using inbox on net6, BEFORE it's moved into System.Runtime (which happened net7).
121+ // As such, we want to make sure we DO NOT record SRCS.Unsafe for net6.
122+ if ( tfm . Framework == ".NETCoreApp" && tfm . Version is { Major : 6 , Minor : 0 } )
123+ {
124+ continue ;
125+ }
126+ }
127+ // We include FullName here so that if the string name key changes (for some reason) we handle it properly
128+ list . Add ( ( Path . GetFileName ( dllPath ) , assembly . FullName ) ) ;
115129 }
116130 }
117131 }
@@ -126,7 +140,7 @@ .. var dotnetOobPackagePaths
126140// for each (particularly net35), but if we just pick the overall minimum (netstandard2.0), net35 would be preferred
127141// for all .NET Framework targets, even the ones that support NS2.0.
128142var frameworkAssemblies = frameworkGroupLayout
129- . GroupBy ( kvp => kvp . Value , SequenceEqualityComparer < string > . Instance )
143+ . GroupBy ( kvp => kvp . Value , SequenceEqualityComparer < ( string , string ) > . Instance )
130144 . SelectMany ( g =>
131145 g . Select ( kvp => kvp . Key )
132146 . GroupBy ( tfm => tfm . Framework )
@@ -140,42 +154,43 @@ .. var dotnetOobPackagePaths
140154var importedSet = new Dictionary < string , ExportedType > ( ) ;
141155foreach ( var ( targetTfm , assemblies ) in frameworkAssemblies )
142156{
143- foreach ( var dllName in assemblies )
157+ foreach ( var ( dllName , _ ) in assemblies )
144158 {
145159 importedSet . Clear ( ) ;
146160
147161 ModuleDefinition ? backportsShim = null ;
148162 AssemblyDefinition ? backportsShimAssembly = null ;
149163 AssemblyReference ? backportsReference = null ;
150164
151- foreach ( var bclShimPath in dllsByDllName [ dllName ] )
165+ var bclShimPath = GetFrameworkKey ( dllsByDllName [ dllName ] , targetTfm , fwReducer ) ;
166+
167+ var bclShim = ModuleDefinition . FromFile ( bclShimPath , readerParams ) ;
168+
169+ var bcl = KnownCorLibs . FromRuntimeInfo (
170+ DotNetRuntimeInfo . Parse (
171+ targetTfm . GetDotNetFrameworkName ( DefaultFrameworkNameProvider . Instance ) ) ) ;
172+
173+ // set up the new shim module
174+ backportsShim = new ModuleDefinition ( bclShim . Name , bcl )
175+ {
176+ RuntimeVersion = bclShim . RuntimeVersion
177+ } ;
178+ backportsShimAssembly = new AssemblyDefinition ( bclShim . Assembly ! . Name ,
179+ new ( bclShim . Assembly ! . Version . Major , 9999 , 9999 , 9999 ) )
152180 {
153- var bclShim = ModuleDefinition . FromFile ( bclShimPath , readerParams ) ;
181+ Modules = { backportsShim } ,
182+ HashAlgorithm = bclShim . Assembly ! . HashAlgorithm ,
183+ PublicKey = bclShim . Assembly ! . PublicKey ,
184+ HasPublicKey = bclShim . Assembly ! . HasPublicKey ,
185+ } ;
154186
155- if ( peImageBuilder is null || backportsShim is null || backportsShimAssembly is null || backportsReference is null )
156- {
157- var bcl = KnownCorLibs . FromRuntimeInfo (
158- DotNetRuntimeInfo . Parse (
159- targetTfm . GetDotNetFrameworkName ( DefaultFrameworkNameProvider . Instance ) ) ) ;
187+ backportsReference =
188+ new AssemblyReference ( "MonoMod.Backports" , new ( 1 , 0 , 0 , 0 ) )
189+ . ImportWith ( backportsShim . DefaultImporter ) ;
160190
161- // set up the new shim module
162- backportsShim = new ModuleDefinition ( bclShim . Name , bcl )
163- {
164- RuntimeVersion = bclShim . RuntimeVersion
165- } ;
166- backportsShimAssembly = new AssemblyDefinition ( bclShim . Assembly ! . Name ,
167- new ( bclShim . Assembly ! . Version . Major , 9999 , 9999 , 9999 ) )
168- {
169- Modules = { backportsShim } ,
170- HashAlgorithm = bclShim . Assembly ! . HashAlgorithm ,
171- PublicKey = bclShim . Assembly ! . PublicKey ,
172- HasPublicKey = bclShim . Assembly ! . HasPublicKey ,
173- } ;
174-
175- backportsReference =
176- new AssemblyReference ( "MonoMod.Backports" , new ( 1 , 0 , 0 , 0 ) )
177- . ImportWith ( backportsShim . DefaultImporter ) ;
178- }
191+ foreach ( var file in dllsByDllName [ dllName ] . Values )
192+ {
193+ bclShim = ModuleDefinition . FromFile ( file , readerParams ) ;
179194
180195 // go through all public types, make sure they exist in the shim, and generate the forwarder
181196 foreach ( var type in bclShim . TopLevelTypes )
@@ -223,7 +238,11 @@ void ExportType(TypeDefinition type, bool nested, IImplementation impl)
223238 var keyPath = Path . Combine ( snkPath , name + ".snk" ) ;
224239 if ( ! File . Exists ( keyPath ) )
225240 {
226- Console . Error . WriteLine ( $ "ShimGen : warning : Missing SNK file for key { name } (for { backportsShim . Name } )") ;
241+ Console . Error . WriteLine ( $ "ShimGen : warning : Missing SNK file for key { name } (for { backportsShim . Name } ), fakesigning") ;
242+ var pefile = PEFile . FromFile ( newShimPath ) ;
243+ var image = PEImage . FromFile ( pefile ) ;
244+ image . DotNetDirectory ! . Flags |= AsmResolver . PE . DotNet . DotNetDirectoryFlags . StrongNameSigned ;
245+ image . ToPEFile ( new ManagedPEFileBuilder ( listener ) ) . Write ( newShimPath ) ;
227246 }
228247 else
229248 {
@@ -239,3 +258,23 @@ void ExportType(TypeDefinition type, bool nested, IImplementation impl)
239258}
240259
241260return 0 ;
261+
262+ static bool TryGetFrameworkKey < T > ( Dictionary < NuGetFramework , T > dict , NuGetFramework key , FrameworkReducer reducer , [ MaybeNullWhen ( false ) ] out T value )
263+ {
264+ var best = reducer . GetNearest ( key , dict . Keys ) ;
265+ if ( best is null )
266+ {
267+ value = default ;
268+ return false ;
269+ }
270+
271+ return dict . TryGetValue ( best , out value ) ;
272+ }
273+
274+
275+ static T GetFrameworkKey < T > ( Dictionary < NuGetFramework , T > dict , NuGetFramework key , FrameworkReducer reducer )
276+ {
277+ var best = reducer . GetNearest ( key , dict . Keys ) ;
278+ return dict [ best ! ] ;
279+ }
280+
0 commit comments