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

Develop/issue 863 #864

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
741 changes: 413 additions & 328 deletions Mono.Cecil/AssemblyReader.cs

Large diffs are not rendered by default.

137 changes: 80 additions & 57 deletions Mono.Cecil/BaseAssemblyResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ namespace Mono.Cecil {
public delegate AssemblyDefinition AssemblyResolveEventHandler (object sender, AssemblyNameReference reference);

public sealed class AssemblyResolveEventArgs : EventArgs {

readonly AssemblyNameReference reference;
private readonly AssemblyNameReference reference;

public AssemblyNameReference AssemblyReference {
get { return reference; }
Expand All @@ -37,9 +36,9 @@ public AssemblyResolveEventArgs (AssemblyNameReference reference)
#if !NET_CORE
[Serializable]
#endif
public sealed class AssemblyResolutionException : FileNotFoundException {

readonly AssemblyNameReference reference;
public sealed class AssemblyResolutionException : FileNotFoundException {
private readonly AssemblyNameReference reference;

public AssemblyNameReference AssemblyReference {
get { return reference; }
Expand Down Expand Up @@ -67,18 +66,15 @@ public AssemblyResolutionException (AssemblyNameReference reference, Exception i
}

public abstract class BaseAssemblyResolver : IAssemblyResolver {
private static readonly bool on_mono = Type.GetType ("Mono.Runtime") != null;

static readonly bool on_mono = Type.GetType ("Mono.Runtime") != null;

readonly Collection<string> directories;
private readonly Collection<string> directories;

#if NET_CORE
// Maps file names of available trusted platform assemblies to their full paths.
// Internal for testing.
internal static readonly Lazy<Dictionary<string, string>> TrustedPlatformAssemblies = new Lazy<Dictionary<string, string>> (CreateTrustedPlatformAssemblyMap);
#else
Collection<string> gac_paths;
#endif

private Collection<string> gac_paths;

public void AddSearchDirectory (string directory)
{
Expand All @@ -90,6 +86,12 @@ public void RemoveSearchDirectory (string directory)
directories.Remove (directory);
}

protected bool NetCore { get; set; }

protected bool AsMono { get; set; }

protected Module CoreModule { get; set; }

public string [] GetSearchDirectories ()
{
var directories = new string [this.directories.size];
Expand All @@ -102,9 +104,17 @@ public string [] GetSearchDirectories ()
protected BaseAssemblyResolver ()
{
directories = new Collection<string> (2) { ".", "bin" };
#if NET_CORE
NetCore = true;
#else
NetCore = false;
#endif

AsMono = on_mono;
CoreModule = typeof (object).Module;
}

AssemblyDefinition GetAssembly (string file, ReaderParameters parameters)
private AssemblyDefinition GetAssembly (string file, ReaderParameters parameters)
{
if (parameters.AssemblyResolver == null)
parameters.AssemblyResolver = this;
Expand Down Expand Up @@ -133,13 +143,33 @@ public virtual AssemblyDefinition Resolve (AssemblyNameReference name, ReaderPar
};
}

#if NET_CORE
assembly = SearchTrustedPlatformAssemblies (name, parameters);
assembly = NetCore ? SearchTrustedPlatformAssemblies (name, parameters) :
SearchFrameworkAssemblies (name, parameters);
if (assembly != null)
return assembly;
#else
var framework_dir = Path.GetDirectoryName (typeof (object).Module.FullyQualifiedName);
var framework_dirs = on_mono

assembly = LastChanceResolution (assembly, name, parameters);
if (assembly != null)
return assembly;

throw new AssemblyResolutionException (name);
}

protected virtual AssemblyDefinition LastChanceResolution (AssemblyDefinition assembly, AssemblyNameReference name, ReaderParameters parameters)
{
if (ResolveFailure != null) {
assembly = ResolveFailure (this, name);
}

return assembly;
}

protected AssemblyDefinition SearchFrameworkAssemblies (AssemblyNameReference name, ReaderParameters parameters)
{
AssemblyDefinition assembly = null;

var framework_dir = Path.GetDirectoryName (CoreModule.FullyQualifiedName);
var framework_dirs = AsMono
? new [] { framework_dir, Path.Combine (framework_dir, "Facades") }
: new [] { framework_dir };

Expand All @@ -160,20 +190,10 @@ public virtual AssemblyDefinition Resolve (AssemblyNameReference name, ReaderPar
return assembly;

assembly = SearchDirectory (name, framework_dirs, parameters);
if (assembly != null)
return assembly;
#endif
if (ResolveFailure != null) {
assembly = ResolveFailure (this, name);
if (assembly != null)
return assembly;
}

throw new AssemblyResolutionException (name);
return assembly;
}

#if NET_CORE
AssemblyDefinition SearchTrustedPlatformAssemblies (AssemblyNameReference name, ReaderParameters parameters)
protected AssemblyDefinition SearchTrustedPlatformAssemblies (AssemblyNameReference name, ReaderParameters parameters)
{
if (name.IsWindowsRuntime)
return null;
Expand All @@ -184,15 +204,16 @@ AssemblyDefinition SearchTrustedPlatformAssemblies (AssemblyNameReference name,
return null;
}

static Dictionary<string, string> CreateTrustedPlatformAssemblyMap ()
private static Dictionary<string, string> CreateTrustedPlatformAssemblyMap ()
{
var result = new Dictionary<string, string> (StringComparer.OrdinalIgnoreCase);

string paths;

try {
paths = (string) AppDomain.CurrentDomain.GetData ("TRUSTED_PLATFORM_ASSEMBLIES");
} catch {
paths = (string)AppDomain.CurrentDomain.GetData ("TRUSTED_PLATFORM_ASSEMBLIES");
}
catch {
paths = null;
}

Expand All @@ -205,7 +226,6 @@ static Dictionary<string, string> CreateTrustedPlatformAssemblyMap ()

return result;
}
#endif

protected virtual AssemblyDefinition SearchDirectory (AssemblyNameReference name, IEnumerable<string> directories, ReaderParameters parameters)
{
Expand All @@ -217,7 +237,8 @@ protected virtual AssemblyDefinition SearchDirectory (AssemblyNameReference name
continue;
try {
return GetAssembly (file, parameters);
} catch (System.BadImageFormatException) {
}
catch (System.BadImageFormatException) {
continue;
}
}
Expand All @@ -226,25 +247,24 @@ protected virtual AssemblyDefinition SearchDirectory (AssemblyNameReference name
return null;
}

static bool IsZero (Version version)
private static bool IsZero (Version version)
{
return version.Major == 0 && version.Minor == 0 && version.Build == 0 && version.Revision == 0;
}

#if !NET_CORE
AssemblyDefinition GetCorlib (AssemblyNameReference reference, ReaderParameters parameters)
private AssemblyDefinition GetCorlib (AssemblyNameReference reference, ReaderParameters parameters)
{
var version = reference.Version;
var corlib = typeof (object).Assembly.GetName ();
var corlib = CoreModule.Assembly.GetName (); // GetFramework
if (corlib.Version == version || IsZero (version))
return GetAssembly (typeof (object).Module.FullyQualifiedName, parameters);
return GetAssembly (CoreModule.FullyQualifiedName, parameters);

var path = Directory.GetParent (
Directory.GetParent (
typeof (object).Module.FullyQualifiedName).FullName
CoreModule.FullyQualifiedName).FullName
).FullName;

if (on_mono) {
if (AsMono) {
if (version.Major == 1)
path = Path.Combine (path, "1.0");
else if (version.Major == 2) {
Expand All @@ -264,12 +284,15 @@ AssemblyDefinition GetCorlib (AssemblyNameReference reference, ReaderParameters
else
path = Path.Combine (path, "v1.1.4322");
break;

case 2:
path = Path.Combine (path, "v2.0.50727");
break;

case 4:
path = Path.Combine (path, "v4.0.30319");
break;

default:
throw new NotSupportedException ("Version not supported: " + version);
}
Expand All @@ -279,7 +302,7 @@ AssemblyDefinition GetCorlib (AssemblyNameReference reference, ReaderParameters
if (File.Exists (file))
return GetAssembly (file, parameters);

if (on_mono && Directory.Exists (path + "-api")) {
if (AsMono && Directory.Exists (path + "-api")) {
file = Path.Combine (path + "-api", "mscorlib.dll");
if (File.Exists (file))
return GetAssembly (file, parameters);
Expand All @@ -288,10 +311,10 @@ AssemblyDefinition GetCorlib (AssemblyNameReference reference, ReaderParameters
return null;
}

static Collection<string> GetGacPaths ()
private static Collection<string> GetGacPaths (bool mono, Module core)
{
if (on_mono)
return GetDefaultMonoGacPaths ();
if (mono)
return GetDefaultMonoGacPaths (core);

var paths = new Collection<string> (2);
var windir = Environment.GetEnvironmentVariable ("WINDIR");
Expand All @@ -303,10 +326,10 @@ static Collection<string> GetGacPaths ()
return paths;
}

static Collection<string> GetDefaultMonoGacPaths ()
private static Collection<string> GetDefaultMonoGacPaths (Module core)
{
var paths = new Collection<string> (1);
var gac = GetCurrentMonoGac ();
var gac = GetCurrentMonoGac (core);
if (gac != null)
paths.Add (gac);

Expand All @@ -327,29 +350,29 @@ static Collection<string> GetDefaultMonoGacPaths ()
return paths;
}

static string GetCurrentMonoGac ()
private static string GetCurrentMonoGac (Module core)
{
return Path.Combine (
Directory.GetParent (
Path.GetDirectoryName (typeof (object).Module.FullyQualifiedName)).FullName,
Path.GetDirectoryName (core.FullyQualifiedName)).FullName, // GetFrameworkDirectory
"gac");
}

AssemblyDefinition GetAssemblyInGac (AssemblyNameReference reference, ReaderParameters parameters)
private AssemblyDefinition GetAssemblyInGac (AssemblyNameReference reference, ReaderParameters parameters)
{
if (reference.PublicKeyToken == null || reference.PublicKeyToken.Length == 0)
return null;

if (gac_paths == null)
gac_paths = GetGacPaths ();
gac_paths = GetGacPaths (AsMono, CoreModule);

if (on_mono)
if (AsMono)
return GetAssemblyInMonoGac (reference, parameters);

return GetAssemblyInNetGac (reference, parameters);
}

AssemblyDefinition GetAssemblyInMonoGac (AssemblyNameReference reference, ReaderParameters parameters)
private AssemblyDefinition GetAssemblyInMonoGac (AssemblyNameReference reference, ReaderParameters parameters)
{
for (int i = 0; i < gac_paths.Count; i++) {
var gac_path = gac_paths [i];
Expand All @@ -361,7 +384,7 @@ AssemblyDefinition GetAssemblyInMonoGac (AssemblyNameReference reference, Reader
return null;
}

AssemblyDefinition GetAssemblyInNetGac (AssemblyNameReference reference, ReaderParameters parameters)
private AssemblyDefinition GetAssemblyInNetGac (AssemblyNameReference reference, ReaderParameters parameters)
{
var gacs = new [] { "GAC_MSIL", "GAC_32", "GAC_64", "GAC" };
var prefixes = new [] { string.Empty, "v4.0_" };
Expand All @@ -378,7 +401,7 @@ AssemblyDefinition GetAssemblyInNetGac (AssemblyNameReference reference, ReaderP
return null;
}

static string GetAssemblyFile (AssemblyNameReference reference, string prefix, string gac)
private static string GetAssemblyFile (AssemblyNameReference reference, string prefix, string gac)
{
var gac_folder = new StringBuilder ()
.Append (prefix)
Expand All @@ -393,7 +416,7 @@ static string GetAssemblyFile (AssemblyNameReference reference, string prefix, s
Path.Combine (gac, reference.Name), gac_folder.ToString ()),
reference.Name + ".dll");
}
#endif

public void Dispose ()
{
Dispose (true);
Expand All @@ -404,4 +427,4 @@ protected virtual void Dispose (bool disposing)
{
}
}
}
}
Loading