You've already forked linux-packaging-mono
Imported Upstream version 4.3.2.467
Former-commit-id: 9c2cb47f45fa221e661ab616387c9cda183f283d
This commit is contained in:
@@ -45,7 +45,8 @@ net_4_5_dirs := \
|
||||
security \
|
||||
mdbrebase \
|
||||
ikdasm \
|
||||
mono-symbolicate
|
||||
mono-symbolicate \
|
||||
linker-analyzer
|
||||
|
||||
build_SUBDIRS = gacutil security culevel
|
||||
net_4_5_SUBDIRS = gacutil
|
||||
|
@@ -11,7 +11,10 @@ COMMON_SOURCES = \
|
||||
|
||||
PROGRAM_INSTALL_DIR = $(mono_libdir)/mono/$(FRAMEWORK_VERSION)
|
||||
|
||||
APIINFO_SOURCES = mono-api-info.cs $(COMMON_SOURCES)
|
||||
APIINFO_SOURCES = \
|
||||
mono-api-info.cs \
|
||||
../../class/Mono.Options/Mono.Options/Options.cs \
|
||||
$(COMMON_SOURCES)
|
||||
|
||||
DISTFILES= $(COMMON_SOURCES) $(APIINFO_SOURCES)
|
||||
|
||||
@@ -39,5 +42,5 @@ clean-local:
|
||||
|
||||
dist-local: dist-default
|
||||
|
||||
mono-api-info.exe: $(APIINFO_SOURCES)
|
||||
mono-api-info.exe: $(APIINFO_SOURCES) ../../class/Mono.Options/Mono.Options/Options.cs
|
||||
$(CSCOMPILE) -r:Mono.Cecil.dll -out:$@ $^
|
||||
|
@@ -83,5 +83,112 @@ namespace CorCompare {
|
||||
{
|
||||
return att.AttributeType.Resolve ();
|
||||
}
|
||||
|
||||
static bool IsOverride (MethodDefinition method)
|
||||
{
|
||||
return method.IsVirtual && !method.IsNewSlot;
|
||||
}
|
||||
|
||||
public static MethodDefinition GetBaseMethodInTypeHierarchy (MethodDefinition method)
|
||||
{
|
||||
if (!IsOverride (method))
|
||||
return method;
|
||||
|
||||
var @base = GetBaseType (method.DeclaringType);
|
||||
while (@base != null) {
|
||||
MethodDefinition base_method = TryMatchMethod (@base.Resolve (), method);
|
||||
if (base_method != null)
|
||||
return GetBaseMethodInTypeHierarchy (base_method) ?? base_method;
|
||||
|
||||
@base = GetBaseType (@base);
|
||||
}
|
||||
|
||||
return method;
|
||||
}
|
||||
|
||||
static MethodDefinition TryMatchMethod (TypeDefinition type, MethodDefinition method)
|
||||
{
|
||||
if (!type.HasMethods)
|
||||
return null;
|
||||
|
||||
foreach (MethodDefinition candidate in type.Methods)
|
||||
if (MethodMatch (candidate, method))
|
||||
return candidate;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static bool MethodMatch (MethodDefinition candidate, MethodDefinition method)
|
||||
{
|
||||
if (!candidate.IsVirtual)
|
||||
return false;
|
||||
|
||||
if (candidate.Name != method.Name)
|
||||
return false;
|
||||
|
||||
if (!TypeMatch (candidate.ReturnType, method.ReturnType))
|
||||
return false;
|
||||
|
||||
if (candidate.Parameters.Count != method.Parameters.Count)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < candidate.Parameters.Count; i++)
|
||||
if (!TypeMatch (candidate.Parameters [i].ParameterType, method.Parameters [i].ParameterType))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool TypeMatch (IModifierType a, IModifierType b)
|
||||
{
|
||||
if (!TypeMatch (a.ModifierType, b.ModifierType))
|
||||
return false;
|
||||
|
||||
return TypeMatch (a.ElementType, b.ElementType);
|
||||
}
|
||||
|
||||
public static bool TypeMatch (TypeSpecification a, TypeSpecification b)
|
||||
{
|
||||
if (a is GenericInstanceType)
|
||||
return TypeMatch ((GenericInstanceType) a, (GenericInstanceType) b);
|
||||
|
||||
if (a is IModifierType)
|
||||
return TypeMatch ((IModifierType) a, (IModifierType) b);
|
||||
|
||||
return TypeMatch (a.ElementType, b.ElementType);
|
||||
}
|
||||
|
||||
public static bool TypeMatch (GenericInstanceType a, GenericInstanceType b)
|
||||
{
|
||||
if (!TypeMatch (a.ElementType, b.ElementType))
|
||||
return false;
|
||||
|
||||
if (a.GenericArguments.Count != b.GenericArguments.Count)
|
||||
return false;
|
||||
|
||||
if (a.GenericArguments.Count == 0)
|
||||
return true;
|
||||
|
||||
for (int i = 0; i < a.GenericArguments.Count; i++)
|
||||
if (!TypeMatch (a.GenericArguments [i], b.GenericArguments [i]))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool TypeMatch (TypeReference a, TypeReference b)
|
||||
{
|
||||
if (a is GenericParameter)
|
||||
return true;
|
||||
|
||||
if (a is TypeSpecification || b is TypeSpecification) {
|
||||
if (a.GetType () != b.GetType ())
|
||||
return false;
|
||||
|
||||
return TypeMatch ((TypeSpecification) a, (TypeSpecification) b);
|
||||
}
|
||||
|
||||
return a.FullName == b.FullName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -15,11 +15,6 @@ namespace CorCompare {
|
||||
|
||||
public class WellFormedXmlWriter : DefaultXmlWriter
|
||||
{
|
||||
public static bool IsValid (int ch)
|
||||
{
|
||||
return !IsInvalid (ch);
|
||||
}
|
||||
|
||||
public static bool IsInvalid (int ch)
|
||||
{
|
||||
switch (ch) {
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -197,7 +197,9 @@ namespace Mono {
|
||||
} else
|
||||
dumb = false;
|
||||
|
||||
editor = new Mono.Terminal.LineEditor ("csharp", 300);
|
||||
editor = new Mono.Terminal.LineEditor ("csharp", 300) {
|
||||
HeuristicsMode = "csharp"
|
||||
};
|
||||
InteractiveBaseShell.Editor = editor;
|
||||
|
||||
editor.AutoCompleteEvent += delegate (string s, int pos){
|
||||
@@ -399,9 +401,45 @@ namespace Mono {
|
||||
output.Write (s);
|
||||
}
|
||||
|
||||
static string EscapeString (string s)
|
||||
static void EscapeString (TextWriter output, string s)
|
||||
{
|
||||
return s.Replace ("\"", "\\\"");
|
||||
foreach (var c in s){
|
||||
if (c > 32){
|
||||
output.Write (c);
|
||||
continue;
|
||||
}
|
||||
switch (c){
|
||||
case '\"':
|
||||
output.Write ("\\\""); break;
|
||||
case '\a':
|
||||
output.Write ("\\a"); break;
|
||||
case '\b':
|
||||
output.Write ("\\b"); break;
|
||||
case '\n':
|
||||
output.Write ("\\n");
|
||||
break;
|
||||
|
||||
case '\v':
|
||||
output.Write ("\\v");
|
||||
break;
|
||||
|
||||
case '\r':
|
||||
output.Write ("\\r");
|
||||
break;
|
||||
|
||||
case '\f':
|
||||
output.Write ("\\f");
|
||||
break;
|
||||
|
||||
case '\t':
|
||||
output.Write ("\\t");
|
||||
break;
|
||||
|
||||
default:
|
||||
output.Write ("\\x{0:x}", (int) c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void EscapeChar (TextWriter output, char c)
|
||||
@@ -491,7 +529,9 @@ namespace Mono {
|
||||
else
|
||||
p (output, "false");
|
||||
} else if (result is string){
|
||||
p (output, String.Format ("\"{0}\"", EscapeString ((string)result)));
|
||||
p (output, "\"");
|
||||
EscapeString (output, (string)result);
|
||||
p (output, "\"");
|
||||
} else if (result is IDictionary){
|
||||
IDictionary dict = (IDictionary) result;
|
||||
int top = dict.Count, count = 0;
|
||||
|
@@ -7,6 +7,7 @@
|
||||
../../../external/ikdasm/Program.cs
|
||||
../../../external/ikdasm/Util.cs
|
||||
../../../external/ikdasm/VTableFixups.cs
|
||||
../../../external/ikdasm/TableDumper.cs
|
||||
|
||||
../../../external/ikvm/reflect/*.cs
|
||||
../../../external/ikvm/reflect/Emit/*.cs
|
||||
|
146
mcs/tools/linker-analyzer/ConsoleDependencyGraph.cs
Normal file
146
mcs/tools/linker-analyzer/ConsoleDependencyGraph.cs
Normal file
@@ -0,0 +1,146 @@
|
||||
//
|
||||
// ConsoleDependencyGraph.cs: text output related code for dependency graph
|
||||
//
|
||||
// Author:
|
||||
// Radek Doulik (rodo@xamarin.com)
|
||||
//
|
||||
// Copyright 2015 Xamarin Inc (http://www.xamarin.com).
|
||||
//
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using LinkerAnalyzer.Core;
|
||||
|
||||
namespace LinkerAnalyzer
|
||||
{
|
||||
public class ConsoleDependencyGraph : DependencyGraph
|
||||
{
|
||||
public bool Tree = false;
|
||||
|
||||
public void ShowDependencies (string raw, List<VertexData> verticesList, string searchString)
|
||||
{
|
||||
VertexData vertex = Vertex (raw);
|
||||
if (vertex == null) {
|
||||
Regex regex = new Regex (searchString);
|
||||
int count = 0;
|
||||
|
||||
foreach (var v in verticesList) {
|
||||
if (regex.Match (v.value) != Match.Empty) {
|
||||
ShowDependencies (v);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (count == 0)
|
||||
Console.WriteLine ("\nUnable to find vertex: {0}", raw);
|
||||
else
|
||||
Console.WriteLine ("\nFound {0} matches", count);
|
||||
} else
|
||||
ShowDependencies (vertex);
|
||||
}
|
||||
|
||||
public void ShowDependencies (VertexData vertex)
|
||||
{
|
||||
Header ("{0} dependencies", vertex.value);
|
||||
if (vertex.parentIndexes == null) {
|
||||
Console.WriteLine ("Root dependency");
|
||||
} else {
|
||||
int i = 0;
|
||||
foreach (int index in vertex.parentIndexes) {
|
||||
Console.WriteLine ("Dependency #{0}", ++i);
|
||||
Console.WriteLine ("\t{0}", vertex.value);
|
||||
var childVertex = Vertex (index);
|
||||
Console.WriteLine ("\t| {0}{1}", childVertex.value, childVertex.DepsCount);
|
||||
while (childVertex.parentIndexes != null) {
|
||||
childVertex = Vertex (childVertex.parentIndexes [0]);
|
||||
Console.WriteLine ("\t| {0}{1}", childVertex.value, childVertex.DepsCount);
|
||||
}
|
||||
if (Tree)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ShowAllDependencies ()
|
||||
{
|
||||
Header ("All dependencies");
|
||||
Console.WriteLine ("Types count: {0}", vertices.Count);
|
||||
foreach (var vertex in vertices)
|
||||
ShowDependencies (vertex);
|
||||
}
|
||||
|
||||
public void ShowTypesDependencies ()
|
||||
{
|
||||
Header ("All types dependencies");
|
||||
Console.WriteLine ("Deps count: {0}", Types.Count);
|
||||
foreach (var type in Types)
|
||||
ShowDependencies (type);
|
||||
}
|
||||
|
||||
string Tabs (string key)
|
||||
{
|
||||
int count = Math.Max (1, 2 - key.Length / 8);
|
||||
|
||||
if (count == 1)
|
||||
return "\t";
|
||||
else
|
||||
return "\t\t";
|
||||
}
|
||||
|
||||
public void ShowStat (bool verbose = false)
|
||||
{
|
||||
Header ("Statistics");
|
||||
if (verbose) {
|
||||
foreach (var key in counts.Keys)
|
||||
Console.WriteLine ("Vertex type:\t{0}{1}count:{2}", key, Tabs (key), counts [key]);
|
||||
} else {
|
||||
Console.WriteLine ("Assemblies:\t{0}", counts ["Assembly"]);
|
||||
Console.WriteLine ("Modules:\t{0}", counts ["Module"]);
|
||||
Console.WriteLine ("Types:\t\t{0}", counts ["TypeDef"]);
|
||||
Console.WriteLine ("Fields:\t\t{0}", counts ["Field"]);
|
||||
Console.WriteLine ("Methods:\t{0}", counts ["Method"]);
|
||||
}
|
||||
|
||||
Console.WriteLine ();
|
||||
Console.WriteLine ("Total vertices: {0}", vertices.Count);
|
||||
}
|
||||
|
||||
public void ShowRoots ()
|
||||
{
|
||||
Header ("Root vertices");
|
||||
|
||||
int count = 0;
|
||||
foreach (var vertex in vertices) {
|
||||
if (vertex.parentIndexes == null) {
|
||||
Console.WriteLine ("{0}", vertex.value);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine ();
|
||||
Console.WriteLine ("Total root vertices: {0}", count);
|
||||
}
|
||||
|
||||
public void ShowRawDependencies (string raw)
|
||||
{
|
||||
Header ("Raw dependencies: '{0}'", raw);
|
||||
ShowDependencies (raw, vertices, raw);
|
||||
}
|
||||
|
||||
public void ShowTypeDependencies (string raw)
|
||||
{
|
||||
Header ("Type dependencies: '{0}'", raw);
|
||||
ShowDependencies ("TypeDef:" + raw, Types, raw);
|
||||
}
|
||||
|
||||
void Header (string header, params object[] values)
|
||||
{
|
||||
string formatted = string.Format (header, values);
|
||||
Console.WriteLine ();
|
||||
Console.Write ("--- {0} ", formatted);
|
||||
for (int i=0; i< Math.Max (3, 64 - formatted.Length); i++)
|
||||
Console.Write ('-');
|
||||
Console.WriteLine ();
|
||||
}
|
||||
}
|
||||
}
|
118
mcs/tools/linker-analyzer/LinkerAnalyzerCore/DependencyGraph.cs
Normal file
118
mcs/tools/linker-analyzer/LinkerAnalyzerCore/DependencyGraph.cs
Normal file
@@ -0,0 +1,118 @@
|
||||
//
|
||||
// DependencyGraph.cs: linker dependencies graph
|
||||
//
|
||||
// Author:
|
||||
// Radek Doulik (rodo@xamarin.com)
|
||||
//
|
||||
// Copyright 2015 Xamarin Inc (http://www.xamarin.com).
|
||||
//
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Xml;
|
||||
|
||||
namespace LinkerAnalyzer.Core
|
||||
{
|
||||
public class VertexData {
|
||||
public string value;
|
||||
public List<int> parentIndexes;
|
||||
public int index;
|
||||
|
||||
public string DepsCount {
|
||||
get {
|
||||
if (parentIndexes == null || parentIndexes.Count < 1)
|
||||
return "";
|
||||
return string.Format (" [{0} deps]", parentIndexes.Count);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public class DependencyGraph
|
||||
{
|
||||
protected List<VertexData> vertices = new List<VertexData> ();
|
||||
public List<VertexData> Types = new List<VertexData> ();
|
||||
Dictionary<string, int> indexes = new Dictionary<string, int> ();
|
||||
protected Dictionary<string, int> counts = new Dictionary<string, int> ();
|
||||
|
||||
public void Load (string filename)
|
||||
{
|
||||
Console.WriteLine ("Loading dependency tree from: {0}", filename);
|
||||
|
||||
using (var fileStream = File.OpenRead (filename))
|
||||
using (var zipStream = new GZipStream (fileStream, CompressionMode.Decompress)) {
|
||||
try {
|
||||
Load (zipStream);
|
||||
} catch (Exception) {
|
||||
Console.WriteLine ("Unable to open and read the dependecies.");
|
||||
Environment.Exit (1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Load (GZipStream zipStream) {
|
||||
using (XmlReader reader = XmlReader.Create (zipStream)) {
|
||||
while (reader.Read ()) {
|
||||
switch (reader.NodeType) {
|
||||
case XmlNodeType.Element:
|
||||
//Console.WriteLine (reader.Name);
|
||||
if (reader.Name == "edge" && reader.IsStartElement ()) {
|
||||
string b = reader.GetAttribute ("b");
|
||||
string e = reader.GetAttribute ("e");
|
||||
//Console.WriteLine ("edge value " + b + " --> " + e);
|
||||
|
||||
if (e != b) {
|
||||
VertexData begin = Vertex (b, true);
|
||||
VertexData end = Vertex (e, true);
|
||||
|
||||
if (end.parentIndexes == null)
|
||||
end.parentIndexes = new List<int> ();
|
||||
if (!end.parentIndexes.Contains (begin.index)) {
|
||||
end.parentIndexes.Add (begin.index);
|
||||
//Console.WriteLine (" end parent index: {0}", end.parentIndexes);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
//Console.WriteLine ("node: " + reader.NodeType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public VertexData Vertex (string vertexName, bool create = false)
|
||||
{
|
||||
VertexData vertex;
|
||||
|
||||
try {
|
||||
vertex = vertices [indexes [vertexName]];
|
||||
} catch (KeyNotFoundException) {
|
||||
if (create) {
|
||||
int index = vertices.Count;
|
||||
vertex = new VertexData () { value = vertexName, index = index };
|
||||
vertices.Add (vertex);
|
||||
indexes.Add (vertexName, index);
|
||||
string prefix = vertexName.Substring (0, vertexName.IndexOf (':'));
|
||||
if (counts.ContainsKey (prefix))
|
||||
counts [prefix]++;
|
||||
else
|
||||
counts [prefix] = 1;
|
||||
//Console.WriteLine ("prefix " + prefix + " count " + counts[prefix]);
|
||||
if (prefix == "TypeDef") {
|
||||
Types.Add (vertex);
|
||||
}
|
||||
} else
|
||||
return null;
|
||||
}
|
||||
|
||||
return vertex;
|
||||
}
|
||||
|
||||
public VertexData Vertex (int index)
|
||||
{
|
||||
return vertices [index];
|
||||
}
|
||||
}
|
||||
}
|
86
mcs/tools/linker-analyzer/Main.cs
Normal file
86
mcs/tools/linker-analyzer/Main.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
//
|
||||
// Main.cs: Main program file of command line utility.
|
||||
//
|
||||
// Author:
|
||||
// Radek Doulik (rodo@xamarin.com)
|
||||
//
|
||||
// Copyright 2015 Xamarin Inc (http://www.xamarin.com).
|
||||
//
|
||||
using System;
|
||||
using Mono.Options;
|
||||
using LinkerAnalyzer.Core;
|
||||
|
||||
namespace LinkerAnalyzer
|
||||
{
|
||||
static class MainClass
|
||||
{
|
||||
static void Main (string[] args)
|
||||
{
|
||||
bool showUsage = true;
|
||||
bool showAllDeps = false;
|
||||
bool showTypeDeps = false;
|
||||
string typeName = null;
|
||||
bool showRawDeps = false;
|
||||
string rawName = null;
|
||||
bool showRoots = false;
|
||||
bool showSpaceUsage = false;
|
||||
bool showStat = false;
|
||||
bool showTypes = false;
|
||||
bool reduceToTree = false;
|
||||
bool verbose = false;
|
||||
|
||||
var optionsParser = new OptionSet () {
|
||||
{ "a|alldeps", "show all dependencies", v => { showAllDeps = v != null; } },
|
||||
{ "h|help", "show this message and exit.", v => showUsage = v != null },
|
||||
{ "r|rawdeps=", "show raw vertex dependencies. Raw vertex VALUE is in the raw format written by linker to the dependency XML file. VALUE can be regular expression", v => { showRawDeps = v != null; rawName = v; } },
|
||||
{ "roots", "show root dependencies.", v => showRoots = v != null },
|
||||
{ "stat", "show statistic of loaded dependencies.", v => showStat = v != null },
|
||||
{ "tree", "reduce the dependency graph to the tree.", v => reduceToTree = v != null },
|
||||
{ "types", "show all types dependencies.", v => showTypes = v != null },
|
||||
{ "t|typedeps=", "show type dependencies. The VALUE can be regular expression", v => { showTypeDeps = v != null; typeName = v; } },
|
||||
//{ "u|spaceusage", "show space analysis.", v => showSpaceUsage = v != null },
|
||||
{ "v|verbose", "be more verbose. Enables stat and roots options.", v => verbose = v != null },
|
||||
};
|
||||
|
||||
if (args.Length > 0) {
|
||||
showUsage = false;
|
||||
optionsParser.Parse (args);
|
||||
}
|
||||
|
||||
if (showUsage) {
|
||||
Console.WriteLine ("Usage:\n\n\tlinkeranalyzer [Options] <linker-dependency-file.xml.gz>\n\nOptions:\n");
|
||||
optionsParser.WriteOptionDescriptions (Console.Out);
|
||||
Console.WriteLine ();
|
||||
return;
|
||||
}
|
||||
|
||||
string dependencyFile = args [args.Length - 1];
|
||||
|
||||
ConsoleDependencyGraph deps = new ConsoleDependencyGraph () { Tree = reduceToTree };
|
||||
deps.Load (dependencyFile);
|
||||
|
||||
if (showSpaceUsage) {
|
||||
// SpaceAnalyzer sa = new SpaceAnalyzer (System.IO.Path.GetDirectoryName (dependencyFile));
|
||||
// sa.LoadAssemblies (verbose);
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
showStat = true;
|
||||
showRoots = true;
|
||||
}
|
||||
|
||||
if (showStat)
|
||||
deps.ShowStat (verbose);
|
||||
if (showRoots)
|
||||
deps.ShowRoots ();
|
||||
if (showRawDeps)
|
||||
deps.ShowRawDependencies (rawName);
|
||||
if (showTypeDeps)
|
||||
deps.ShowTypeDependencies (typeName);
|
||||
if (showAllDeps)
|
||||
deps.ShowAllDependencies ();
|
||||
else if (showTypes)
|
||||
deps.ShowTypesDependencies ();
|
||||
}
|
||||
}
|
||||
}
|
7
mcs/tools/linker-analyzer/Makefile
Normal file
7
mcs/tools/linker-analyzer/Makefile
Normal file
@@ -0,0 +1,7 @@
|
||||
thisdir = tools/linker-analyzer
|
||||
SUBDIRS =
|
||||
include ../../build/rules.make
|
||||
|
||||
PROGRAM = linkeranalyzer.exe
|
||||
|
||||
include ../../build/executable.make
|
5
mcs/tools/linker-analyzer/linkeranalyzer.exe.sources
Normal file
5
mcs/tools/linker-analyzer/linkeranalyzer.exe.sources
Normal file
@@ -0,0 +1,5 @@
|
||||
ConsoleDependencyGraph.cs
|
||||
Main.cs
|
||||
|
||||
LinkerAnalyzerCore/DependencyGraph.cs
|
||||
../../class/Mono.Options/Mono.Options/Options.cs
|
@@ -312,6 +312,7 @@
|
||||
<type fullname="System.Threading.ExecutionContext" />
|
||||
<type fullname="System.Threading.Interlocked">
|
||||
<method name="CompareExchange" />
|
||||
<method name="Exchange" />
|
||||
</type>
|
||||
<type fullname="System.Threading.Monitor">
|
||||
<method name="Enter" />
|
||||
|
@@ -47,7 +47,7 @@ namespace Mono.Linker.Steps {
|
||||
protected override void Process ()
|
||||
{
|
||||
foreach (string name in Assembly.GetExecutingAssembly ().GetManifestResourceNames ()) {
|
||||
if (Path.GetExtension (name) != ".xml" || !IsReferenced (GetAssemblyName (name)))
|
||||
if (!name.EndsWith (".xml", StringComparison.OrdinalIgnoreCase) || !IsReferenced (GetAssemblyName (name)))
|
||||
continue;
|
||||
|
||||
try {
|
||||
@@ -61,22 +61,23 @@ namespace Mono.Linker.Steps {
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var rsc in Context.GetAssemblies ()
|
||||
.SelectMany (asm => asm.Modules)
|
||||
.SelectMany (mod => mod.Resources)
|
||||
.Where (res => res.ResourceType == ResourceType.Embedded)
|
||||
.Where (res => Path.GetExtension (res.Name) == ".xml")
|
||||
.Where (res => IsReferenced (GetAssemblyName (res.Name)))
|
||||
.Cast<EmbeddedResource> ()) {
|
||||
try {
|
||||
if (Context.LogInternalExceptions)
|
||||
Console.WriteLine ("Processing embedded resource linker descriptor: {0}", rsc.Name);
|
||||
foreach (var asm in Context.GetAssemblies ()) {
|
||||
foreach (var rsc in asm.Modules
|
||||
.SelectMany (mod => mod.Resources)
|
||||
.Where (res => res.ResourceType == ResourceType.Embedded)
|
||||
.Where (res => res.Name.EndsWith (".xml", StringComparison.OrdinalIgnoreCase))
|
||||
.Where (res => IsReferenced (GetAssemblyName (res.Name)))
|
||||
.Cast<EmbeddedResource> ()) {
|
||||
try {
|
||||
if (Context.LogInternalExceptions)
|
||||
Console.WriteLine ("Processing embedded resource linker descriptor: {0}", rsc.Name);
|
||||
|
||||
Context.Pipeline.AddStepAfter (typeof (TypeMapStep), GetExternalResolveStep (rsc));
|
||||
} catch (XmlException ex) {
|
||||
/* This could happen if some broken XML file is embedded. */
|
||||
if (Context.LogInternalExceptions)
|
||||
Console.WriteLine ("Error processing {0}: {1}", rsc.Name, ex);
|
||||
Context.Pipeline.AddStepAfter (typeof (TypeMapStep), GetExternalResolveStep (rsc, asm));
|
||||
} catch (XmlException ex) {
|
||||
/* This could happen if some broken XML file is embedded. */
|
||||
if (Context.LogInternalExceptions)
|
||||
Console.WriteLine ("Error processing {0}: {1}", rsc.Name, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -99,14 +100,14 @@ namespace Mono.Linker.Steps {
|
||||
return false;
|
||||
}
|
||||
|
||||
static ResolveFromXmlStep GetExternalResolveStep (EmbeddedResource resource)
|
||||
static ResolveFromXmlStep GetExternalResolveStep (EmbeddedResource resource, AssemblyDefinition assembly)
|
||||
{
|
||||
return new ResolveFromXmlStep (GetExternalDescriptor (resource));
|
||||
return new ResolveFromXmlStep (GetExternalDescriptor (resource), "resource " + resource.Name + " in " + assembly.FullName);
|
||||
}
|
||||
|
||||
static ResolveFromXmlStep GetResolveStep (string descriptor)
|
||||
{
|
||||
return new ResolveFromXmlStep (GetDescriptor (descriptor));
|
||||
return new ResolveFromXmlStep (GetDescriptor (descriptor), "descriptor " + descriptor + " from " + Assembly.GetExecutingAssembly ().FullName);
|
||||
}
|
||||
|
||||
static XPathDocument GetExternalDescriptor (EmbeddedResource resource)
|
||||
|
@@ -123,7 +123,9 @@ namespace Mono.Linker.Steps {
|
||||
{
|
||||
while (!QueueIsEmpty ()) {
|
||||
MethodDefinition method = (MethodDefinition) _methods.Dequeue ();
|
||||
Annotations.Push (method);
|
||||
ProcessMethod (method);
|
||||
Annotations.Pop ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -485,6 +487,8 @@ namespace Mono.Linker.Steps {
|
||||
if (CheckProcessed (type))
|
||||
return null;
|
||||
|
||||
Annotations.Push (type);
|
||||
|
||||
MarkScope (type.Scope);
|
||||
MarkType (type.BaseType);
|
||||
MarkType (type.DeclaringType);
|
||||
@@ -518,6 +522,8 @@ namespace Mono.Linker.Steps {
|
||||
|
||||
DoAdditionalTypeProcessing (type);
|
||||
|
||||
Annotations.Pop ();
|
||||
|
||||
Annotations.Mark (type);
|
||||
|
||||
ApplyPreserveInfo (type);
|
||||
@@ -880,6 +886,7 @@ namespace Mono.Linker.Steps {
|
||||
if (reference.DeclaringType is ArrayType)
|
||||
return null;
|
||||
|
||||
Annotations.Push (reference);
|
||||
if (reference.DeclaringType is GenericInstanceType)
|
||||
MarkType (reference.DeclaringType);
|
||||
|
||||
@@ -888,13 +895,18 @@ namespace Mono.Linker.Steps {
|
||||
|
||||
MethodDefinition method = ResolveMethodDefinition (reference);
|
||||
|
||||
if (method == null)
|
||||
if (method == null) {
|
||||
Annotations.Pop ();
|
||||
throw new ResolutionException (reference);
|
||||
}
|
||||
|
||||
if (Annotations.GetAction (method) == MethodAction.Nothing)
|
||||
Annotations.SetAction (method, MethodAction.Parse);
|
||||
|
||||
EnqueueMethod (method);
|
||||
|
||||
Annotations.Pop ();
|
||||
|
||||
return method;
|
||||
}
|
||||
|
||||
|
@@ -39,6 +39,7 @@ namespace Mono.Linker.Steps {
|
||||
protected override void Process ()
|
||||
{
|
||||
CheckOutputDirectory ();
|
||||
Annotations.SaveDependencies ();
|
||||
}
|
||||
|
||||
void CheckOutputDirectory ()
|
||||
@@ -63,9 +64,11 @@ namespace Mono.Linker.Steps {
|
||||
switch (Annotations.GetAction (assembly)) {
|
||||
case AssemblyAction.Save:
|
||||
case AssemblyAction.Link:
|
||||
Context.Annotations.AddDependency (assembly);
|
||||
assembly.Write (GetAssemblyFileName (assembly, directory), SaveSymbols (assembly));
|
||||
break;
|
||||
case AssemblyAction.Copy:
|
||||
Context.Annotations.AddDependency (assembly);
|
||||
CloseSymbols (assembly);
|
||||
CopyAssembly (GetOriginalAssemblyFileInfo (assembly), directory, Context.LinkSymbols);
|
||||
break;
|
||||
|
@@ -56,10 +56,10 @@ namespace Mono.Linker.Steps {
|
||||
switch (assembly.MainModule.Kind) {
|
||||
case ModuleKind.Dll:
|
||||
ProcessLibrary (Context, assembly);
|
||||
return;
|
||||
break;
|
||||
default:
|
||||
ProcessExecutable (assembly);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,14 +79,20 @@ namespace Mono.Linker.Steps {
|
||||
{
|
||||
SetAction (context, assembly, AssemblyAction.Copy);
|
||||
|
||||
context.Annotations.Push (assembly);
|
||||
|
||||
foreach (TypeDefinition type in assembly.MainModule.Types)
|
||||
MarkType (context, type);
|
||||
|
||||
context.Annotations.Pop ();
|
||||
}
|
||||
|
||||
static void MarkType (LinkContext context, TypeDefinition type)
|
||||
{
|
||||
context.Annotations.Mark (type);
|
||||
|
||||
context.Annotations.Push (type);
|
||||
|
||||
if (type.HasFields)
|
||||
MarkFields (context, type.Fields);
|
||||
if (type.HasMethods)
|
||||
@@ -94,14 +100,20 @@ namespace Mono.Linker.Steps {
|
||||
if (type.HasNestedTypes)
|
||||
foreach (var nested in type.NestedTypes)
|
||||
MarkType (context, nested);
|
||||
|
||||
context.Annotations.Pop ();
|
||||
}
|
||||
|
||||
void ProcessExecutable (AssemblyDefinition assembly)
|
||||
{
|
||||
SetAction (Context, assembly, AssemblyAction.Link);
|
||||
|
||||
Annotations.Push (assembly);
|
||||
|
||||
Annotations.Mark (assembly.EntryPoint.DeclaringType);
|
||||
MarkMethod (Context, assembly.EntryPoint, MethodAction.Parse);
|
||||
|
||||
Annotations.Pop ();
|
||||
}
|
||||
|
||||
static void MarkFields (LinkContext context, ICollection fields)
|
||||
|
@@ -38,6 +38,13 @@ using Mono.Cecil;
|
||||
|
||||
namespace Mono.Linker.Steps {
|
||||
|
||||
public class XmlResolutionException : Exception {
|
||||
public XmlResolutionException (string message, Exception innerException)
|
||||
: base (message, innerException)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class ResolveFromXmlStep : ResolveStep {
|
||||
|
||||
static readonly string _signature = "signature";
|
||||
@@ -47,10 +54,12 @@ namespace Mono.Linker.Steps {
|
||||
static readonly string _ns = string.Empty;
|
||||
|
||||
XPathDocument _document;
|
||||
string _xmlDocumentLocation;
|
||||
|
||||
public ResolveFromXmlStep (XPathDocument document)
|
||||
public ResolveFromXmlStep (XPathDocument document, string xmlDocumentLocation = "<unspecified>")
|
||||
{
|
||||
_document = document;
|
||||
_xmlDocumentLocation = xmlDocumentLocation;
|
||||
}
|
||||
|
||||
protected override void Process ()
|
||||
@@ -63,7 +72,11 @@ namespace Mono.Linker.Steps {
|
||||
if (nav.LocalName != "linker")
|
||||
return;
|
||||
|
||||
ProcessAssemblies (Context, nav.SelectChildren ("assembly", _ns));
|
||||
try {
|
||||
ProcessAssemblies (Context, nav.SelectChildren ("assembly", _ns));
|
||||
} catch (Exception ex) {
|
||||
throw new XmlResolutionException (string.Format ("Failed to process XML description: {0}", _xmlDocumentLocation), ex);
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessAssemblies (LinkContext context, XPathNodeIterator iterator)
|
||||
|
@@ -155,8 +155,8 @@ namespace Mono.Linker.Steps {
|
||||
scope = assembly.MainModule.Import (td).Scope;
|
||||
if (tr.Scope != scope)
|
||||
changes = true;
|
||||
hash.Add (tr, scope);
|
||||
}
|
||||
hash.Add (tr, scope);
|
||||
}
|
||||
if (assembly.MainModule.HasExportedTypes) {
|
||||
foreach (var et in assembly.MainModule.ExportedTypes) {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user