You've already forked linux-packaging-mono
Imported Upstream version 5.2.0.175
Former-commit-id: bb0468d0f257ff100aa895eb5fe583fb5dfbf900
This commit is contained in:
parent
4bdbaf4a88
commit
966bba02bb
@@ -77,7 +77,7 @@ namespace Mono.Linker.Steps {
|
||||
void LoadAssembly (AssemblyNameReference name)
|
||||
{
|
||||
AssemblyDefinition assembly = Context.Resolve (name);
|
||||
ResolveFromAssemblyStep.ProcessLibrary (Context, assembly);
|
||||
ResolveFromAssemblyStep.ProcessLibrary (Context, assembly, ResolveFromAssemblyStep.RootVisibility.Any);
|
||||
}
|
||||
|
||||
AssemblyNameReference GetAssemblyName (I18nAssemblies assembly)
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
using Mono.Cecil;
|
||||
@@ -48,8 +49,13 @@ namespace Mono.Linker.Steps {
|
||||
|
||||
_references.Add (assembly.Name, assembly);
|
||||
|
||||
foreach (AssemblyNameReference reference in assembly.MainModule.AssemblyReferences)
|
||||
ProcessReferences (Context.Resolve (reference));
|
||||
foreach (AssemblyDefinition referenceDefinition in Context.ResolveReferences (assembly)) {
|
||||
try {
|
||||
ProcessReferences (referenceDefinition);
|
||||
} catch (Exception ex) {
|
||||
throw new LoadException (string.Format ("Error while processing references of '{0}'", assembly.FullName), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
268
external/linker/linker/Mono.Linker.Steps/MarkStep.cs
vendored
268
external/linker/linker/Mono.Linker.Steps/MarkStep.cs
vendored
@@ -30,6 +30,7 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
@@ -122,15 +123,30 @@ namespace Mono.Linker.Steps {
|
||||
continue;
|
||||
|
||||
foreach (var exported in assembly.MainModule.ExportedTypes) {
|
||||
if (!exported.IsForwarder)
|
||||
bool isForwarder = exported.IsForwarder;
|
||||
var declaringType = exported.DeclaringType;
|
||||
while (!isForwarder && (declaringType != null)) {
|
||||
isForwarder = declaringType.IsForwarder;
|
||||
declaringType = declaringType.DeclaringType;
|
||||
}
|
||||
|
||||
if (!isForwarder)
|
||||
continue;
|
||||
var type = exported.Resolve ();
|
||||
TypeDefinition type = null;
|
||||
try {
|
||||
type = exported.Resolve ();
|
||||
}
|
||||
catch (AssemblyResolutionException) {
|
||||
continue;
|
||||
}
|
||||
if (!Annotations.IsMarked (type))
|
||||
continue;
|
||||
Annotations.Mark (exported);
|
||||
Annotations.Mark (assembly.MainModule);
|
||||
if (_context.KeepTypeForwarderOnlyAssemblies) {
|
||||
Annotations.Mark (assembly.MainModule);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessQueue ()
|
||||
@@ -138,8 +154,13 @@ namespace Mono.Linker.Steps {
|
||||
while (!QueueIsEmpty ()) {
|
||||
MethodDefinition method = (MethodDefinition) _methods.Dequeue ();
|
||||
Annotations.Push (method);
|
||||
ProcessMethod (method);
|
||||
Annotations.Pop ();
|
||||
try {
|
||||
ProcessMethod (method);
|
||||
} catch (Exception e) {
|
||||
throw new MarkException (string.Format ("Error processing method: '{0}' in assembly: '{1}'", method.FullName, method.Module.Name), e);
|
||||
} finally {
|
||||
Annotations.Pop ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,20 +232,24 @@ namespace Mono.Linker.Steps {
|
||||
protected virtual void MarkCustomAttribute (CustomAttribute ca)
|
||||
{
|
||||
Annotations.Push (ca);
|
||||
MarkMethod (ca.Constructor);
|
||||
try {
|
||||
MarkMethod (ca.Constructor);
|
||||
|
||||
MarkCustomAttributeArguments (ca);
|
||||
MarkCustomAttributeArguments (ca);
|
||||
|
||||
TypeReference constructor_type = ca.Constructor.DeclaringType;
|
||||
TypeDefinition type = constructor_type.Resolve ();
|
||||
if (type == null) {
|
||||
TypeReference constructor_type = ca.Constructor.DeclaringType;
|
||||
TypeDefinition type = constructor_type.Resolve ();
|
||||
|
||||
if (type == null) {
|
||||
HandleUnresolvedType (constructor_type);
|
||||
return;
|
||||
}
|
||||
|
||||
MarkCustomAttributeProperties (ca, type);
|
||||
MarkCustomAttributeFields (ca, type);
|
||||
} finally {
|
||||
Annotations.Pop ();
|
||||
throw new ResolutionException (constructor_type);
|
||||
}
|
||||
|
||||
MarkCustomAttributeProperties (ca, type);
|
||||
MarkCustomAttributeFields (ca, type);
|
||||
Annotations.Pop ();
|
||||
}
|
||||
|
||||
protected void MarkSecurityDeclarations (ISecurityDeclarationProvider provider)
|
||||
@@ -341,6 +366,19 @@ namespace Mono.Linker.Steps {
|
||||
return null;
|
||||
}
|
||||
|
||||
MethodDefinition GetMethodWithNoParameters (TypeDefinition type, string methodname)
|
||||
{
|
||||
while (type != null) {
|
||||
MethodDefinition method = type.Methods.FirstOrDefault (m => m.Name == methodname && !m.HasParameters);
|
||||
if (method != null)
|
||||
return method;
|
||||
|
||||
type = type.BaseType != null ? ResolveTypeDefinition (type.BaseType) : null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
void MarkCustomAttributeArguments (CustomAttribute ca)
|
||||
{
|
||||
if (!ca.HasConstructorArguments)
|
||||
@@ -388,7 +426,7 @@ namespace Mono.Linker.Steps {
|
||||
// e.g. System.String[] -> System.String
|
||||
var ts = (type as TypeSpecification);
|
||||
if (ts != null) {
|
||||
MarkWithResolvedScope (ts.GetElementType ());
|
||||
MarkWithResolvedScope (ts.ElementType);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -504,8 +542,10 @@ namespace Mono.Linker.Steps {
|
||||
|
||||
TypeDefinition type = ResolveTypeDefinition (reference);
|
||||
|
||||
if (type == null)
|
||||
throw new ResolutionException (reference);
|
||||
if (type == null) {
|
||||
HandleUnresolvedType (reference);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (CheckProcessed (type))
|
||||
return null;
|
||||
@@ -525,6 +565,10 @@ namespace Mono.Linker.Steps {
|
||||
if (IsSerializable (type))
|
||||
MarkSerializable (type);
|
||||
|
||||
if (IsEventSource (type)) {
|
||||
MarkEventSource (type);
|
||||
}
|
||||
|
||||
MarkTypeSpecialCustomAttributes (type);
|
||||
|
||||
MarkGenericParameterProvider (type);
|
||||
@@ -570,6 +614,15 @@ namespace Mono.Linker.Steps {
|
||||
case "System.Xml.Serialization.XmlSchemaProviderAttribute":
|
||||
MarkXmlSchemaProvider (type, attribute);
|
||||
break;
|
||||
case "System.Diagnostics.DebuggerDisplayAttribute":
|
||||
MarkTypeWithDebuggerDisplayAttribute (type, attribute);
|
||||
break;
|
||||
case "System.Diagnostics.DebuggerTypeProxyAttribute":
|
||||
MarkTypeWithDebuggerTypeProxyAttribute (type, attribute);
|
||||
break;
|
||||
case "System.Diagnostics.Tracing.EventDataAttribute":
|
||||
MarkTypeWithEventDataAttribute (type, attribute);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -588,6 +641,11 @@ namespace Mono.Linker.Steps {
|
||||
}
|
||||
}
|
||||
|
||||
void MarkTypeWithEventDataAttribute (TypeDefinition type, CustomAttribute attribute)
|
||||
{
|
||||
MarkMethodsIf (type.Methods, IsPublicInstancePropertyMethod);
|
||||
}
|
||||
|
||||
void MarkXmlSchemaProvider (TypeDefinition type, CustomAttribute attribute)
|
||||
{
|
||||
string method_name;
|
||||
@@ -597,6 +655,73 @@ namespace Mono.Linker.Steps {
|
||||
MarkNamedMethod (type, method_name);
|
||||
}
|
||||
|
||||
void MarkTypeWithDebuggerDisplayAttribute (TypeDefinition type, CustomAttribute attribute)
|
||||
{
|
||||
if (_context.KeepMembersForDebuggerAttributes) {
|
||||
|
||||
string displayString = (string) attribute.ConstructorArguments[0].Value;
|
||||
|
||||
Regex regex = new Regex ("{[^{}]+}", RegexOptions.Compiled);
|
||||
|
||||
foreach (Match match in regex.Matches (displayString)) {
|
||||
// Remove '{' and '}'
|
||||
string realMatch = match.Value.Substring (1, match.Value.Length - 2);
|
||||
|
||||
// Remove ",nq" suffix if present
|
||||
// (it asks the expression evaluator to remove the quotes when displaying the final value)
|
||||
if (Regex.IsMatch(realMatch, @".+,\s*nq")) {
|
||||
realMatch = realMatch.Substring (0, realMatch.LastIndexOf (','));
|
||||
}
|
||||
|
||||
if (realMatch.EndsWith ("()")) {
|
||||
string methodName = realMatch.Substring (0, realMatch.Length - 2);
|
||||
MethodDefinition method = GetMethodWithNoParameters (type, methodName);
|
||||
if (method != null) {
|
||||
MarkMethod (method);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
FieldDefinition field = GetField (type, realMatch);
|
||||
if (field != null) {
|
||||
MarkField (field);
|
||||
continue;
|
||||
}
|
||||
|
||||
PropertyDefinition property = GetProperty (type, realMatch);
|
||||
if (property != null) {
|
||||
if (property.GetMethod != null) {
|
||||
MarkMethod (property.GetMethod);
|
||||
}
|
||||
if (property.SetMethod != null) {
|
||||
MarkMethod (property.SetMethod);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
while (type != null) {
|
||||
MarkMethods (type);
|
||||
MarkFields (type, includeStatic: true);
|
||||
type = type.BaseType != null ? ResolveTypeDefinition (type.BaseType) : null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MarkTypeWithDebuggerTypeProxyAttribute (TypeDefinition type, CustomAttribute attribute)
|
||||
{
|
||||
if (_context.KeepMembersForDebuggerAttributes) {
|
||||
TypeReference proxyTypeReference = (TypeReference) attribute.ConstructorArguments [0].Value;
|
||||
|
||||
MarkType (proxyTypeReference);
|
||||
|
||||
TypeDefinition proxyType = ResolveTypeDefinition (proxyTypeReference);
|
||||
MarkMethods (proxyType);
|
||||
MarkFields (proxyType, includeStatic: true);
|
||||
}
|
||||
}
|
||||
|
||||
static bool TryGetStringArgument (CustomAttribute attribute, out string argument)
|
||||
{
|
||||
argument = null;
|
||||
@@ -784,6 +909,33 @@ namespace Mono.Linker.Steps {
|
||||
return td.BaseType != null && td.BaseType.FullName == "System.MulticastDelegate";
|
||||
}
|
||||
|
||||
bool IsEventSource (TypeDefinition td)
|
||||
{
|
||||
TypeReference type = td;
|
||||
do {
|
||||
if (type.FullName == "System.Diagnostics.Tracing.EventSource") {
|
||||
return true;
|
||||
}
|
||||
|
||||
TypeDefinition typeDef = type.Resolve ();
|
||||
if (typeDef == null) {
|
||||
HandleUnresolvedType (type);
|
||||
return false;
|
||||
}
|
||||
type = typeDef.BaseType;
|
||||
} while (type != null);
|
||||
return false;
|
||||
}
|
||||
|
||||
void MarkEventSource (TypeDefinition td)
|
||||
{
|
||||
foreach (var nestedType in td.NestedTypes) {
|
||||
if (nestedType.Name == "Keywords" || nestedType.Name == "Tasks" || nestedType.Name == "Opcodes") {
|
||||
MarkStaticFields (nestedType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected TypeDefinition ResolveTypeDefinition (TypeReference type)
|
||||
{
|
||||
TypeDefinition td = type as TypeDefinition;
|
||||
@@ -915,6 +1067,17 @@ namespace Mono.Linker.Steps {
|
||||
}
|
||||
}
|
||||
|
||||
protected void MarkStaticFields(TypeDefinition type)
|
||||
{
|
||||
if (!type.HasFields)
|
||||
return;
|
||||
|
||||
foreach (FieldDefinition field in type.Fields) {
|
||||
if (field.IsStatic)
|
||||
MarkField (field);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void MarkMethods (TypeDefinition type)
|
||||
{
|
||||
if (type.HasMethods)
|
||||
@@ -943,17 +1106,19 @@ namespace Mono.Linker.Steps {
|
||||
|
||||
MethodDefinition method = ResolveMethodDefinition (reference);
|
||||
|
||||
if (method == null) {
|
||||
try {
|
||||
if (method == null) {
|
||||
HandleUnresolvedMethod (reference);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Annotations.GetAction (method) == MethodAction.Nothing)
|
||||
Annotations.SetAction (method, MethodAction.Parse);
|
||||
|
||||
EnqueueMethod (method);
|
||||
} finally {
|
||||
Annotations.Pop ();
|
||||
throw new ResolutionException (reference);
|
||||
}
|
||||
|
||||
if (Annotations.GetAction (method) == MethodAction.Nothing)
|
||||
Annotations.SetAction (method, MethodAction.Parse);
|
||||
|
||||
EnqueueMethod (method);
|
||||
|
||||
Annotations.Pop ();
|
||||
Annotations.AddDependency (method);
|
||||
|
||||
return method;
|
||||
@@ -1029,6 +1194,10 @@ namespace Mono.Linker.Steps {
|
||||
MarkCustomAttributes (method.MethodReturnType);
|
||||
MarkMarshalSpec (method.MethodReturnType);
|
||||
|
||||
if (method.IsPInvokeImpl || method.IsInternalCall) {
|
||||
ProcessInteropMethod (method);
|
||||
}
|
||||
|
||||
if (ShouldParseMethodBody (method))
|
||||
MarkMethodBody (method.Body);
|
||||
|
||||
@@ -1060,6 +1229,34 @@ namespace Mono.Linker.Steps {
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessInteropMethod(MethodDefinition method)
|
||||
{
|
||||
TypeDefinition returnTypeDefinition = ResolveTypeDefinition (method.ReturnType);
|
||||
const bool includeStaticFields = false;
|
||||
if (returnTypeDefinition != null) {
|
||||
MarkDefaultConstructor (returnTypeDefinition);
|
||||
MarkFields (returnTypeDefinition, includeStaticFields);
|
||||
}
|
||||
|
||||
if (method.HasThis) {
|
||||
MarkFields (method.DeclaringType, includeStaticFields);
|
||||
}
|
||||
|
||||
foreach (ParameterDefinition pd in method.Parameters) {
|
||||
TypeReference paramTypeReference = pd.ParameterType;
|
||||
if (paramTypeReference is TypeSpecification) {
|
||||
paramTypeReference = (paramTypeReference as TypeSpecification).ElementType;
|
||||
}
|
||||
TypeDefinition paramTypeDefinition = ResolveTypeDefinition (paramTypeReference);
|
||||
if (paramTypeDefinition != null) {
|
||||
MarkFields (paramTypeDefinition, includeStaticFields);
|
||||
if (pd.ParameterType.IsByReference) {
|
||||
MarkDefaultConstructor (paramTypeDefinition);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ShouldParseMethodBody (MethodDefinition method)
|
||||
{
|
||||
if (!method.HasBody)
|
||||
@@ -1076,6 +1273,11 @@ namespace Mono.Linker.Steps {
|
||||
(md.SemanticsAttributes & MethodSemanticsAttributes.Setter) != 0;
|
||||
}
|
||||
|
||||
static internal bool IsPublicInstancePropertyMethod (MethodDefinition md)
|
||||
{
|
||||
return md.IsPublic && !md.IsStatic && IsPropertyMethod (md);
|
||||
}
|
||||
|
||||
static bool IsEventMethod (MethodDefinition md)
|
||||
{
|
||||
return (md.SemanticsAttributes & MethodSemanticsAttributes.AddOn) != 0 ||
|
||||
@@ -1162,5 +1364,15 @@ namespace Mono.Linker.Steps {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void HandleUnresolvedType (TypeReference reference)
|
||||
{
|
||||
throw new ResolutionException (reference);
|
||||
}
|
||||
|
||||
protected virtual void HandleUnresolvedMethod (MethodReference reference)
|
||||
{
|
||||
throw new ResolutionException (reference);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,6 +78,7 @@ namespace Mono.Linker.Steps {
|
||||
if (File.Exists (target)) {
|
||||
File.Delete (target);
|
||||
File.Delete (target + ".mdb");
|
||||
File.Delete (Path.ChangeExtension (target, "pdb"));
|
||||
File.Delete (GetConfigFile (target));
|
||||
}
|
||||
break;
|
||||
@@ -144,15 +145,18 @@ namespace Mono.Linker.Steps {
|
||||
if (!symbols)
|
||||
return;
|
||||
|
||||
source += ".mdb";
|
||||
if (!File.Exists (source))
|
||||
return;
|
||||
File.Copy (source, target + ".mdb", true);
|
||||
var mdb = source + ".mdb";
|
||||
if (File.Exists (mdb))
|
||||
File.Copy (mdb, target + ".mdb", true);
|
||||
|
||||
var pdb = Path.ChangeExtension (source, "pdb");
|
||||
if (File.Exists (pdb))
|
||||
File.Copy (pdb, Path.ChangeExtension (target, "pdb"), true);
|
||||
}
|
||||
|
||||
static string GetAssemblyFileName (AssemblyDefinition assembly, string directory)
|
||||
{
|
||||
string file = assembly.Name.Name + (assembly.MainModule.Kind == ModuleKind.Dll ? ".dll" : ".exe");
|
||||
string file = GetOriginalAssemblyFileInfo (assembly).Name;
|
||||
return Path.Combine (directory, file);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Mono.Cecil;
|
||||
|
||||
@@ -35,10 +36,20 @@ namespace Mono.Linker.Steps {
|
||||
|
||||
AssemblyDefinition _assembly;
|
||||
string _file;
|
||||
RootVisibility _rootVisibility;
|
||||
|
||||
public ResolveFromAssemblyStep (string assembly)
|
||||
public enum RootVisibility
|
||||
{
|
||||
Any = 0,
|
||||
PublicAndFamily = 1,
|
||||
PublicAndFamilyAndAssembly = 2
|
||||
}
|
||||
|
||||
|
||||
public ResolveFromAssemblyStep (string assembly, RootVisibility rootVisibility = RootVisibility.Any)
|
||||
{
|
||||
_file = assembly;
|
||||
_rootVisibility = rootVisibility;
|
||||
}
|
||||
|
||||
public ResolveFromAssemblyStep (AssemblyDefinition assembly)
|
||||
@@ -53,9 +64,13 @@ namespace Mono.Linker.Steps {
|
||||
|
||||
AssemblyDefinition assembly = _assembly ?? Context.Resolve (_file);
|
||||
|
||||
if (_rootVisibility != RootVisibility.Any && HasInternalsVisibleTo (assembly)) {
|
||||
_rootVisibility = RootVisibility.PublicAndFamilyAndAssembly;
|
||||
}
|
||||
|
||||
switch (assembly.MainModule.Kind) {
|
||||
case ModuleKind.Dll:
|
||||
ProcessLibrary (Context, assembly);
|
||||
ProcessLibrary (Context, assembly, _rootVisibility);
|
||||
break;
|
||||
default:
|
||||
ProcessExecutable (assembly);
|
||||
@@ -75,31 +90,78 @@ namespace Mono.Linker.Steps {
|
||||
context.SafeReadSymbols (assembly);
|
||||
}
|
||||
|
||||
public static void ProcessLibrary (LinkContext context, AssemblyDefinition assembly)
|
||||
public static void ProcessLibrary (LinkContext context, AssemblyDefinition assembly, RootVisibility rootVisibility = RootVisibility.Any)
|
||||
{
|
||||
SetAction (context, assembly, AssemblyAction.Copy);
|
||||
var action = rootVisibility == RootVisibility.Any ? AssemblyAction.Copy : AssemblyAction.Link;
|
||||
SetAction (context, assembly, action);
|
||||
|
||||
context.Annotations.Push (assembly);
|
||||
|
||||
foreach (TypeDefinition type in assembly.MainModule.Types)
|
||||
MarkType (context, type);
|
||||
MarkType (context, type, rootVisibility);
|
||||
|
||||
if (assembly.MainModule.HasExportedTypes) {
|
||||
foreach (var exported in assembly.MainModule.ExportedTypes) {
|
||||
bool isForwarder = exported.IsForwarder;
|
||||
var declaringType = exported.DeclaringType;
|
||||
while (!isForwarder && (declaringType != null)) {
|
||||
isForwarder = declaringType.IsForwarder;
|
||||
declaringType = declaringType.DeclaringType;
|
||||
}
|
||||
|
||||
if (!isForwarder)
|
||||
continue;
|
||||
TypeDefinition resolvedExportedType = null;
|
||||
try {
|
||||
resolvedExportedType = exported.Resolve ();
|
||||
}
|
||||
catch (AssemblyResolutionException) {
|
||||
continue;
|
||||
}
|
||||
context.Resolve (resolvedExportedType.Scope);
|
||||
MarkType (context, resolvedExportedType, rootVisibility);
|
||||
context.Annotations.Mark (exported);
|
||||
if (context.KeepTypeForwarderOnlyAssemblies) {
|
||||
context.Annotations.Mark (assembly.MainModule);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context.Annotations.Pop ();
|
||||
}
|
||||
|
||||
static void MarkType (LinkContext context, TypeDefinition type)
|
||||
static void MarkType (LinkContext context, TypeDefinition type, RootVisibility rootVisibility)
|
||||
{
|
||||
bool markType;
|
||||
switch (rootVisibility) {
|
||||
default:
|
||||
markType = true;
|
||||
break;
|
||||
|
||||
case RootVisibility.PublicAndFamilyAndAssembly:
|
||||
markType = !type.IsNestedPrivate;
|
||||
break;
|
||||
|
||||
case RootVisibility.PublicAndFamily:
|
||||
markType = type.IsPublic || type.IsNestedPublic || type.IsNestedFamily || type.IsNestedFamilyOrAssembly;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!markType) {
|
||||
return;
|
||||
}
|
||||
|
||||
context.Annotations.Mark (type);
|
||||
|
||||
context.Annotations.Push (type);
|
||||
|
||||
if (type.HasFields)
|
||||
MarkFields (context, type.Fields);
|
||||
MarkFields (context, type.Fields, rootVisibility);
|
||||
if (type.HasMethods)
|
||||
MarkMethods (context, type.Methods);
|
||||
MarkMethods (context, type.Methods, rootVisibility);
|
||||
if (type.HasNestedTypes)
|
||||
foreach (var nested in type.NestedTypes)
|
||||
MarkType (context, nested);
|
||||
MarkType (context, nested, rootVisibility);
|
||||
|
||||
context.Annotations.Pop ();
|
||||
}
|
||||
@@ -111,27 +173,73 @@ namespace Mono.Linker.Steps {
|
||||
Annotations.Push (assembly);
|
||||
|
||||
Annotations.Mark (assembly.EntryPoint.DeclaringType);
|
||||
MarkMethod (Context, assembly.EntryPoint, MethodAction.Parse);
|
||||
|
||||
MarkMethod (Context, assembly.EntryPoint, MethodAction.Parse, RootVisibility.Any);
|
||||
|
||||
Annotations.Pop ();
|
||||
}
|
||||
|
||||
static void MarkFields (LinkContext context, ICollection fields)
|
||||
static void MarkFields (LinkContext context, ICollection fields, RootVisibility rootVisibility)
|
||||
{
|
||||
foreach (FieldDefinition field in fields)
|
||||
context.Annotations.Mark (field);
|
||||
foreach (FieldDefinition field in fields) {
|
||||
bool markField;
|
||||
switch (rootVisibility) {
|
||||
default:
|
||||
markField = true;
|
||||
break;
|
||||
|
||||
case RootVisibility.PublicAndFamily:
|
||||
markField = field.IsPublic || field.IsFamily || field.IsFamilyOrAssembly;
|
||||
break;
|
||||
|
||||
case RootVisibility.PublicAndFamilyAndAssembly:
|
||||
markField = field.IsPublic || field.IsFamily || field.IsFamilyOrAssembly || field.IsAssembly || field.IsFamilyAndAssembly;
|
||||
break;
|
||||
}
|
||||
if (markField) {
|
||||
context.Annotations.Mark (field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void MarkMethods (LinkContext context, ICollection methods)
|
||||
static void MarkMethods (LinkContext context, ICollection methods, RootVisibility rootVisibility)
|
||||
{
|
||||
foreach (MethodDefinition method in methods)
|
||||
MarkMethod (context, method, MethodAction.ForceParse);
|
||||
MarkMethod (context, method, MethodAction.ForceParse, rootVisibility);
|
||||
}
|
||||
|
||||
static void MarkMethod (LinkContext context, MethodDefinition method, MethodAction action)
|
||||
static void MarkMethod (LinkContext context, MethodDefinition method, MethodAction action, RootVisibility rootVisibility)
|
||||
{
|
||||
context.Annotations.Mark (method);
|
||||
context.Annotations.SetAction (method, action);
|
||||
bool markMethod;
|
||||
switch (rootVisibility) {
|
||||
default:
|
||||
markMethod = true;
|
||||
break;
|
||||
|
||||
case RootVisibility.PublicAndFamily:
|
||||
markMethod = method.IsPublic || method.IsFamily || method.IsFamilyOrAssembly;
|
||||
break;
|
||||
|
||||
case RootVisibility.PublicAndFamilyAndAssembly:
|
||||
markMethod = method.IsPublic || method.IsFamily || method.IsFamilyOrAssembly || method.IsAssembly || method.IsFamilyAndAssembly;
|
||||
break;
|
||||
}
|
||||
|
||||
if (markMethod) {
|
||||
context.Annotations.Mark (method);
|
||||
context.Annotations.SetAction (method, action);
|
||||
}
|
||||
}
|
||||
|
||||
static bool HasInternalsVisibleTo (AssemblyDefinition assembly)
|
||||
{
|
||||
foreach (CustomAttribute attribute in assembly.CustomAttributes) {
|
||||
if (attribute.Constructor.DeclaringType.FullName ==
|
||||
"System.Runtime.CompilerServices.InternalsVisibleToAttribute")
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,14 +129,14 @@ namespace Mono.Linker.Steps {
|
||||
if (type == null) {
|
||||
if (assembly.MainModule.HasExportedTypes) {
|
||||
foreach (var exported in assembly.MainModule.ExportedTypes) {
|
||||
if (fullname == exported.FullName) {
|
||||
if (fullname == exported.FullName) {
|
||||
Annotations.Mark (exported);
|
||||
Annotations.Mark (assembly.MainModule);
|
||||
var resolvedExternal = exported.Resolve ();
|
||||
if (resolvedExternal != null) {
|
||||
type = resolvedExternal;
|
||||
break;
|
||||
}
|
||||
Annotations.Mark (assembly.MainModule);
|
||||
var resolvedExternal = exported.Resolve ();
|
||||
if (resolvedExternal != null) {
|
||||
type = resolvedExternal;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -173,12 +173,17 @@ namespace Mono.Linker.Steps {
|
||||
|
||||
void MatchExportedType (ExportedType exportedType, ModuleDefinition module, Regex regex, XPathNavigator nav)
|
||||
{
|
||||
if (regex.Match (exportedType.FullName).Success) {
|
||||
if (regex.Match (exportedType.FullName).Success) {
|
||||
Annotations.Mark (exportedType);
|
||||
Annotations.Mark (module);
|
||||
var type = exportedType.Resolve ();
|
||||
if (type != null) {
|
||||
ProcessType (type, nav);
|
||||
Annotations.Mark (module);
|
||||
TypeDefinition type = null;
|
||||
try {
|
||||
type = exportedType.Resolve ();
|
||||
}
|
||||
catch (AssemblyResolutionException) {
|
||||
}
|
||||
if (type != null) {
|
||||
ProcessType (type, nav);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -399,8 +404,7 @@ namespace Mono.Linker.Steps {
|
||||
|
||||
static void ProcessReferences (AssemblyDefinition assembly, LinkContext context)
|
||||
{
|
||||
foreach (AssemblyNameReference name in assembly.MainModule.AssemblyReferences)
|
||||
context.Resolve (name);
|
||||
context.ResolveReferences (assembly);
|
||||
}
|
||||
|
||||
static bool IsRequired (XPathNavigator nav)
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace Mono.Linker.Steps {
|
||||
|
||||
ArrayList _unResolved;
|
||||
|
||||
internal ResolveStep ()
|
||||
protected ResolveStep ()
|
||||
{
|
||||
_unResolved = new ArrayList ();
|
||||
}
|
||||
|
||||
@@ -29,8 +29,10 @@
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Mono.Cecil;
|
||||
using Mono.Collections.Generic;
|
||||
using Mono.Cecil.Cil;
|
||||
|
||||
namespace Mono.Linker.Steps {
|
||||
|
||||
@@ -38,30 +40,37 @@ namespace Mono.Linker.Steps {
|
||||
|
||||
AssemblyDefinition [] assemblies;
|
||||
HashSet<AssemblyDefinition> resolvedTypeReferences;
|
||||
readonly bool sweepSymbols;
|
||||
|
||||
public SweepStep (bool sweepSymbols = true)
|
||||
{
|
||||
this.sweepSymbols = sweepSymbols;
|
||||
}
|
||||
|
||||
protected override void Process ()
|
||||
{
|
||||
assemblies = Context.GetAssemblies ();
|
||||
assemblies = Context.Annotations.GetAssemblies ().ToArray ();
|
||||
foreach (var assembly in assemblies) {
|
||||
SweepAssembly (assembly);
|
||||
if (Annotations.GetAction (assembly) == AssemblyAction.Copy) {
|
||||
// Copy assemblies can still contain Type references with
|
||||
// type forwarders from Delete assemblies
|
||||
// thus try to resolve all the type references and see
|
||||
// if some changed the scope. if yes change the action to Save
|
||||
if (ResolveAllTypeReferences (assembly))
|
||||
Annotations.SetAction (assembly, AssemblyAction.Save);
|
||||
if ((Annotations.GetAction (assembly) == AssemblyAction.Copy) &&
|
||||
!Context.KeepTypeForwarderOnlyAssemblies) {
|
||||
// Copy assemblies can still contain Type references with
|
||||
// type forwarders from Delete assemblies
|
||||
// thus try to resolve all the type references and see
|
||||
// if some changed the scope. if yes change the action to Save
|
||||
if (ResolveAllTypeReferences (assembly))
|
||||
Annotations.SetAction (assembly, AssemblyAction.Save);
|
||||
}
|
||||
|
||||
AssemblyAction currentAction = Annotations.GetAction(assembly);
|
||||
|
||||
if ((currentAction == AssemblyAction.Link) || (currentAction == AssemblyAction.Save)) {
|
||||
// if we save (only or by linking) then unmarked exports (e.g. forwarders) must be cleaned
|
||||
// or they can point to nothing which will break later (e.g. when re-loading for stripping IL)
|
||||
// reference: https://bugzilla.xamarin.com/show_bug.cgi?id=36577
|
||||
if (assembly.MainModule.HasExportedTypes)
|
||||
SweepCollection(assembly.MainModule.ExportedTypes);
|
||||
}
|
||||
AssemblyAction currentAction = Annotations.GetAction(assembly);
|
||||
|
||||
if ((currentAction == AssemblyAction.Link) || (currentAction == AssemblyAction.Save)) {
|
||||
// if we save (only or by linking) then unmarked exports (e.g. forwarders) must be cleaned
|
||||
// or they can point to nothing which will break later (e.g. when re-loading for stripping IL)
|
||||
// reference: https://bugzilla.xamarin.com/show_bug.cgi?id=36577
|
||||
if (assembly.MainModule.HasExportedTypes)
|
||||
SweepCollection(assembly.MainModule.ExportedTypes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,7 +128,13 @@ namespace Mono.Linker.Steps {
|
||||
var references = assembly.MainModule.AssemblyReferences;
|
||||
for (int i = 0; i < references.Count; i++) {
|
||||
var reference = references [i];
|
||||
var r = Context.Resolver.Resolve (reference);
|
||||
AssemblyDefinition r = null;
|
||||
try {
|
||||
r = Context.Resolver.Resolve (reference);
|
||||
}
|
||||
catch (AssemblyResolutionException) {
|
||||
continue;
|
||||
}
|
||||
if (!AreSameReference (r.Name, target.Name))
|
||||
continue;
|
||||
|
||||
@@ -131,12 +146,16 @@ namespace Mono.Linker.Steps {
|
||||
// Copy means even if "unlinked" we still want that assembly to be saved back
|
||||
// to disk (OutputStep) without the (removed) reference
|
||||
Annotations.SetAction (assembly, AssemblyAction.Save);
|
||||
ResolveAllTypeReferences (assembly);
|
||||
if (!Context.KeepTypeForwarderOnlyAssemblies) {
|
||||
ResolveAllTypeReferences (assembly);
|
||||
}
|
||||
break;
|
||||
|
||||
case AssemblyAction.Save:
|
||||
case AssemblyAction.Link:
|
||||
ResolveAllTypeReferences (assembly);
|
||||
if (!Context.KeepTypeForwarderOnlyAssemblies) {
|
||||
ResolveAllTypeReferences (assembly);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return;
|
||||
@@ -175,6 +194,7 @@ namespace Mono.Linker.Steps {
|
||||
if ((td != null) && Annotations.IsMarked (td)) {
|
||||
scope = assembly.MainModule.ImportReference (td).Scope;
|
||||
hash.Add (td, scope);
|
||||
et.Scope = scope;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -190,19 +210,19 @@ namespace Mono.Linker.Steps {
|
||||
return changes;
|
||||
}
|
||||
|
||||
void SweepType (TypeDefinition type)
|
||||
protected virtual void SweepType (TypeDefinition type)
|
||||
{
|
||||
if (type.HasFields)
|
||||
SweepCollection (type.Fields);
|
||||
|
||||
if (type.HasMethods)
|
||||
SweepCollection (type.Methods);
|
||||
SweepMethods (type.Methods);
|
||||
|
||||
if (type.HasNestedTypes)
|
||||
SweepNestedTypes (type);
|
||||
}
|
||||
|
||||
void SweepNestedTypes (TypeDefinition type)
|
||||
protected void SweepNestedTypes (TypeDefinition type)
|
||||
{
|
||||
for (int i = 0; i < type.NestedTypes.Count; i++) {
|
||||
var nested = type.NestedTypes [i];
|
||||
@@ -214,7 +234,59 @@ namespace Mono.Linker.Steps {
|
||||
}
|
||||
}
|
||||
|
||||
void SweepCollection (IList list)
|
||||
void SweepMethods (Collection<MethodDefinition> methods)
|
||||
{
|
||||
SweepCollection (methods);
|
||||
if (sweepSymbols)
|
||||
SweepDebugInfo (methods);
|
||||
}
|
||||
|
||||
void SweepDebugInfo (Collection<MethodDefinition> methods)
|
||||
{
|
||||
List<ScopeDebugInformation> sweptScopes = null;
|
||||
foreach (var m in methods) {
|
||||
if (m.DebugInformation == null)
|
||||
continue;
|
||||
|
||||
var scope = m.DebugInformation.Scope;
|
||||
if (scope == null)
|
||||
continue;
|
||||
|
||||
if (sweptScopes == null) {
|
||||
sweptScopes = new List<ScopeDebugInformation> ();
|
||||
} else if (sweptScopes.Contains (scope)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
sweptScopes.Add (scope);
|
||||
|
||||
if (scope.HasConstants) {
|
||||
var constants = scope.Constants;
|
||||
for (int i = 0; i < constants.Count; ++i) {
|
||||
if (!Annotations.IsMarked (constants [i].ConstantType))
|
||||
constants.RemoveAt (i--);
|
||||
}
|
||||
}
|
||||
|
||||
var import = scope.Import;
|
||||
while (import != null) {
|
||||
if (import.HasTargets) {
|
||||
var targets = import.Targets;
|
||||
for (int i = 0; i < targets.Count; ++i) {
|
||||
var ttype = targets [i].Type;
|
||||
if (ttype != null && !Annotations.IsMarked (ttype))
|
||||
targets.RemoveAt (i--);
|
||||
|
||||
// TODO: Clear also AssemblyReference and Namespace when not marked
|
||||
}
|
||||
}
|
||||
|
||||
import = import.Parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void SweepCollection (IList list)
|
||||
{
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
if (!Annotations.IsMarked ((IMetadataTokenProvider) list [i]))
|
||||
|
||||
40
external/linker/linker/Mono.Linker.csproj
vendored
40
external/linker/linker/Mono.Linker.csproj
vendored
@@ -1,5 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="14.0">
|
||||
<!--
|
||||
TODO: Remove this workaround once supported.
|
||||
|
||||
The configuration isn't correctly set when the linker is
|
||||
restored as a P2P reference due to a nuget bug
|
||||
(https://github.com/NuGet/Home/issues/4873). As a workaround, we
|
||||
check NuGetRestoreTargets, which is set by the .NET Core restore
|
||||
targets.
|
||||
-->
|
||||
<PropertyGroup>
|
||||
<NetCoreBuild Condition=" $(Configuration.StartsWith('netcore')) Or '$(NuGetRestoreTargets)' != '' ">true</NetCoreBuild>
|
||||
<NetCoreBuild Condition=" '$(NetCoreBuild)' == '' ">false</NetCoreBuild>
|
||||
</PropertyGroup>
|
||||
<Import Project="NetCore.props" Condition=" $(NetCoreBuild) " />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
@@ -9,7 +23,8 @@
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Mono.Linker</RootNamespace>
|
||||
<AssemblyName>monolinker</AssemblyName>
|
||||
<AssemblyName Condition=" ! $(NetCoreBuild) ">monolinker</AssemblyName>
|
||||
<AssemblyName Condition=" $(NetCoreBuild) ">illink</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
@@ -29,7 +44,7 @@
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" Condition=" ! $(NetCoreBuild) " />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
@@ -37,7 +52,7 @@
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
<ItemGroup>
|
||||
<ItemGroup Condition=" ! $(Configuration.StartsWith('netcore')) ">
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml" />
|
||||
@@ -63,15 +78,18 @@
|
||||
<Compile Include="Mono.Linker\AssemblyAction.cs" />
|
||||
<Compile Include="Mono.Linker\AssemblyInfo.cs" />
|
||||
<Compile Include="Mono.Linker\AssemblyResolver.cs" />
|
||||
<Compile Include="Mono.Linker\DirectoryAssemblyResolver.cs" />
|
||||
<Compile Include="Mono.Linker\Driver.cs" />
|
||||
<Compile Include="Mono.Linker\LinkContext.cs" />
|
||||
<Compile Include="Mono.Linker\LoadException.cs" />
|
||||
<Compile Include="Mono.Linker\MarkException.cs" />
|
||||
<Compile Include="Mono.Linker\MethodAction.cs" />
|
||||
<Compile Include="Mono.Linker\Pipeline.cs" />
|
||||
<Compile Include="Mono.Linker\TypePreserve.cs" />
|
||||
<Compile Include="Mono.Linker\XApiReader.cs" />
|
||||
<Compile Include="Mono.Linker.Steps\TypeMapStep.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition=" '$(DoNotEmbedDescriptors)' == '' ">
|
||||
<ItemGroup Condition=" '$(DoNotEmbedDescriptors)' == '' AND ! $(NetCoreBuild) ">
|
||||
<EmbeddedResource Include="Descriptors\mscorlib.xml">
|
||||
<LogicalName>mscorlib.xml</LogicalName>
|
||||
</EmbeddedResource>
|
||||
@@ -91,14 +109,26 @@
|
||||
<LogicalName>System.Core.xml</LogicalName>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="Makefile" />
|
||||
<None Include="README" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\cecil\Mono.Cecil.csproj">
|
||||
<SetConfiguration Condition=" '$(Configuration)' == 'netcore_Debug' ">Configuration=netstandard_Debug</SetConfiguration>
|
||||
<SetConfiguration Condition=" '$(Configuration)' == 'netcore_Release' ">Configuration=netstandard_Release</SetConfiguration>
|
||||
<Project>{D68133BD-1E63-496E-9EDE-4FBDBF77B486}</Project>
|
||||
<Name>Mono.Cecil</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
<ItemGroup Condition=" $(NetCoreBuild) ">
|
||||
<ProjectReference Include="..\cecil\symbols\pdb\Mono.Cecil.Pdb.csproj">
|
||||
<SetConfiguration Condition=" '$(Configuration)' == 'netcore_Debug' ">Configuration=netstandard_Debug</SetConfiguration>
|
||||
<SetConfiguration Condition=" '$(Configuration)' == 'netcore_Release' ">Configuration=netstandard_Release</SetConfiguration>
|
||||
<Project>{63E6915C-7EA4-4D76-AB28-0D7191EEA626}</Project>
|
||||
<Name>Mono.Cecil.Pdb</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -78,6 +78,11 @@ namespace Mono.Linker {
|
||||
writer.WriteEndAttribute ();
|
||||
}
|
||||
|
||||
public ICollection<AssemblyDefinition> GetAssemblies ()
|
||||
{
|
||||
return assembly_actions.Keys;
|
||||
}
|
||||
|
||||
public AssemblyAction GetAction (AssemblyDefinition assembly)
|
||||
{
|
||||
AssemblyAction action;
|
||||
@@ -139,7 +144,32 @@ namespace Mono.Linker {
|
||||
|
||||
public void SetPreserve (TypeDefinition type, TypePreserve preserve)
|
||||
{
|
||||
preserved_types [type] = preserve;
|
||||
TypePreserve existing;
|
||||
if (preserved_types.TryGetValue (type, out existing))
|
||||
preserved_types [type] = ChoosePreserveActionWhichPreservesTheMost (existing, preserve);
|
||||
else
|
||||
preserved_types.Add (type, preserve);
|
||||
}
|
||||
|
||||
public static TypePreserve ChoosePreserveActionWhichPreservesTheMost (TypePreserve leftPreserveAction, TypePreserve rightPreserveAction)
|
||||
{
|
||||
if (leftPreserveAction == rightPreserveAction)
|
||||
return leftPreserveAction;
|
||||
|
||||
if (leftPreserveAction == TypePreserve.All || rightPreserveAction == TypePreserve.All)
|
||||
return TypePreserve.All;
|
||||
|
||||
if (leftPreserveAction == TypePreserve.Nothing)
|
||||
return rightPreserveAction;
|
||||
|
||||
if (rightPreserveAction == TypePreserve.Nothing)
|
||||
return leftPreserveAction;
|
||||
|
||||
if ((leftPreserveAction == TypePreserve.Methods && rightPreserveAction == TypePreserve.Fields) ||
|
||||
(leftPreserveAction == TypePreserve.Fields && rightPreserveAction == TypePreserve.Methods))
|
||||
return TypePreserve.All;
|
||||
|
||||
return rightPreserveAction;
|
||||
}
|
||||
|
||||
public TypePreserve GetPreserve (TypeDefinition type)
|
||||
@@ -316,9 +346,6 @@ namespace Mono.Linker {
|
||||
writer.WriteEndElement ();
|
||||
writer.WriteEndDocument ();
|
||||
writer.Flush ();
|
||||
writer.Close ();
|
||||
zipStream.Close ();
|
||||
|
||||
writer.Dispose ();
|
||||
zipStream.Dispose ();
|
||||
writer = null;
|
||||
|
||||
@@ -28,12 +28,17 @@
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Mono.Cecil;
|
||||
|
||||
namespace Mono.Linker {
|
||||
|
||||
#if NET_CORE
|
||||
public class AssemblyResolver : DirectoryAssemblyResolver {
|
||||
#else
|
||||
public class AssemblyResolver : BaseAssemblyResolver {
|
||||
#endif
|
||||
|
||||
IDictionary _assemblies;
|
||||
|
||||
@@ -42,7 +47,7 @@ namespace Mono.Linker {
|
||||
}
|
||||
|
||||
public AssemblyResolver ()
|
||||
: this (new Hashtable ())
|
||||
: this (new Dictionary<string, AssemblyDefinition> (StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -56,7 +61,7 @@ namespace Mono.Linker {
|
||||
AssemblyDefinition asm = (AssemblyDefinition) _assemblies [name.Name];
|
||||
if (asm == null) {
|
||||
asm = base.Resolve (name, parameters);
|
||||
_assemblies [name.Name] = asm;
|
||||
_assemblies [asm.Name.Name] = asm;
|
||||
}
|
||||
|
||||
return asm;
|
||||
|
||||
92
external/linker/linker/Mono.Linker/DirectoryAssemblyResolver.cs
vendored
Normal file
92
external/linker/linker/Mono.Linker/DirectoryAssemblyResolver.cs
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Mono.Collections.Generic;
|
||||
using Mono.Cecil;
|
||||
|
||||
#if NET_CORE
|
||||
namespace Mono.Linker {
|
||||
|
||||
public abstract class DirectoryAssemblyResolver : IAssemblyResolver {
|
||||
|
||||
readonly Collection<string> directories;
|
||||
|
||||
public void AddSearchDirectory (string directory)
|
||||
{
|
||||
directories.Add (directory);
|
||||
}
|
||||
|
||||
public void RemoveSearchDirectory (string directory)
|
||||
{
|
||||
directories.Remove (directory);
|
||||
}
|
||||
|
||||
public string [] GetSearchDirectories ()
|
||||
{
|
||||
return this.directories.ToArray ();
|
||||
}
|
||||
|
||||
protected DirectoryAssemblyResolver ()
|
||||
{
|
||||
directories = new Collection<string> (2) { "." };
|
||||
}
|
||||
|
||||
AssemblyDefinition GetAssembly (string file, ReaderParameters parameters)
|
||||
{
|
||||
if (parameters.AssemblyResolver == null)
|
||||
parameters.AssemblyResolver = this;
|
||||
|
||||
return ModuleDefinition.ReadModule (file, parameters).Assembly;
|
||||
}
|
||||
|
||||
public virtual AssemblyDefinition Resolve (AssemblyNameReference name)
|
||||
{
|
||||
return Resolve (name, new ReaderParameters ());
|
||||
}
|
||||
|
||||
public virtual AssemblyDefinition Resolve (AssemblyNameReference name, ReaderParameters parameters)
|
||||
{
|
||||
if (name == null)
|
||||
throw new ArgumentNullException ("name");
|
||||
if (parameters == null)
|
||||
parameters = new ReaderParameters ();
|
||||
|
||||
var assembly = SearchDirectory (name, directories, parameters);
|
||||
if (assembly != null)
|
||||
return assembly;
|
||||
|
||||
throw new AssemblyResolutionException (name);
|
||||
}
|
||||
|
||||
AssemblyDefinition SearchDirectory (AssemblyNameReference name, IEnumerable<string> directories, ReaderParameters parameters)
|
||||
{
|
||||
var extensions = new [] { ".dll", ".exe" };
|
||||
foreach (var directory in directories) {
|
||||
foreach (var extension in extensions) {
|
||||
string file = Path.Combine (directory, name.Name + extension);
|
||||
if (!File.Exists (file))
|
||||
continue;
|
||||
try {
|
||||
return GetAssembly (file, parameters);
|
||||
} catch (System.BadImageFormatException) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void Dispose ()
|
||||
{
|
||||
Dispose (true);
|
||||
GC.SuppressFinalize (this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose (bool disposing)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
27
external/linker/linker/Mono.Linker/Driver.cs
vendored
27
external/linker/linker/Mono.Linker/Driver.cs
vendored
@@ -38,7 +38,11 @@ namespace Mono.Linker {
|
||||
|
||||
public class Driver {
|
||||
|
||||
#if NET_CORE
|
||||
static readonly string _linker = "IL Linker";
|
||||
#else
|
||||
static readonly string _linker = "Mono CIL Linker";
|
||||
#endif
|
||||
|
||||
public static int Main (string [] args)
|
||||
{
|
||||
@@ -124,14 +128,21 @@ namespace Mono.Linker {
|
||||
case 's':
|
||||
custom_steps.Add (GetParam ());
|
||||
break;
|
||||
case 't':
|
||||
context.KeepTypeForwarderOnlyAssemblies = true;
|
||||
break;
|
||||
case 'x':
|
||||
foreach (string file in GetFiles (GetParam ()))
|
||||
p.PrependStep (new ResolveFromXmlStep (new XPathDocument (file)));
|
||||
resolver = true;
|
||||
break;
|
||||
case 'r':
|
||||
case 'a':
|
||||
var rootVisibility = (token[1] == 'r')
|
||||
? ResolveFromAssemblyStep.RootVisibility.PublicAndFamily
|
||||
: ResolveFromAssemblyStep.RootVisibility.Any;
|
||||
foreach (string file in GetFiles (GetParam ()))
|
||||
p.PrependStep (new ResolveFromAssemblyStep (file));
|
||||
p.PrependStep (new ResolveFromAssemblyStep (file, rootVisibility));
|
||||
resolver = true;
|
||||
break;
|
||||
case 'i':
|
||||
@@ -152,6 +163,9 @@ namespace Mono.Linker {
|
||||
if (!bool.Parse (GetParam ()))
|
||||
p.RemoveStep (typeof (RegenerateGuidStep));
|
||||
break;
|
||||
case 'v':
|
||||
context.KeepMembersForDebuggerAttributes = bool.Parse (GetParam ());
|
||||
break;
|
||||
default:
|
||||
Usage ("Unknown option: `" + token [1] + "'");
|
||||
break;
|
||||
@@ -169,7 +183,7 @@ namespace Mono.Linker {
|
||||
p.Process (context);
|
||||
}
|
||||
|
||||
static void AddCustomStep (Pipeline pipeline, string arg)
|
||||
protected static void AddCustomStep (Pipeline pipeline, string arg)
|
||||
{
|
||||
int pos = arg.IndexOf (":");
|
||||
if (pos == -1) {
|
||||
@@ -230,7 +244,7 @@ namespace Mono.Linker {
|
||||
return (string []) lines.ToArray (typeof (string));
|
||||
}
|
||||
|
||||
static I18nAssemblies ParseI18n (string str)
|
||||
protected static I18nAssemblies ParseI18n (string str)
|
||||
{
|
||||
I18nAssemblies assemblies = I18nAssemblies.None;
|
||||
string [] parts = str.Split (',');
|
||||
@@ -266,7 +280,11 @@ namespace Mono.Linker {
|
||||
Console.WriteLine (_linker);
|
||||
if (msg != null)
|
||||
Console.WriteLine ("Error: " + msg);
|
||||
#if NET_CORE
|
||||
Console.WriteLine ("illink [options] -x|-a|-i file");
|
||||
#else
|
||||
Console.WriteLine ("monolinker [options] -x|-a|-i file");
|
||||
#endif
|
||||
|
||||
Console.WriteLine (" --about About the {0}", _linker);
|
||||
Console.WriteLine (" --version Print the version number of the {0}", _linker);
|
||||
@@ -274,14 +292,17 @@ namespace Mono.Linker {
|
||||
Console.WriteLine (" -c Action on the core assemblies, skip, copy or link, default to skip");
|
||||
Console.WriteLine (" -p Action per assembly");
|
||||
Console.WriteLine (" -s Add a new step to the pipeline.");
|
||||
Console.WriteLine (" -t Keep assemblies in which only type forwarders are referenced.");
|
||||
Console.WriteLine (" -d Add a directory where the linker will look for assemblies");
|
||||
Console.WriteLine (" -b Generate debug symbols for each linked module (true or false)");
|
||||
Console.WriteLine (" -g Generate a new unique guid for each linked module (true or false)");
|
||||
Console.WriteLine (" -v Keep memebers needed by debugger attributes (true or false)");
|
||||
Console.WriteLine (" -l List of i18n assemblies to copy to the output directory");
|
||||
Console.WriteLine (" separated with a comma: none,all,cjk,mideast,other,rare,west");
|
||||
Console.WriteLine (" default is all");
|
||||
Console.WriteLine (" -x Link from an XML descriptor");
|
||||
Console.WriteLine (" -a Link from a list of assemblies");
|
||||
Console.WriteLine (" -r Link from a list of assemblies using roots visible outside of the assembly");
|
||||
Console.WriteLine (" -i Link from an mono-api-info descriptor");
|
||||
Console.WriteLine ("");
|
||||
|
||||
|
||||
@@ -28,8 +28,8 @@
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
|
||||
@@ -43,6 +43,8 @@ namespace Mono.Linker {
|
||||
string _outputDirectory;
|
||||
Hashtable _parameters;
|
||||
bool _linkSymbols;
|
||||
bool _keepTypeForwarderOnlyAssemblies;
|
||||
bool _keepMembersForDebuggerAttributes;
|
||||
|
||||
AssemblyResolver _resolver;
|
||||
|
||||
@@ -75,6 +77,18 @@ namespace Mono.Linker {
|
||||
set { _linkSymbols = value; }
|
||||
}
|
||||
|
||||
public bool KeepTypeForwarderOnlyAssemblies
|
||||
{
|
||||
get { return _keepTypeForwarderOnlyAssemblies; }
|
||||
set { _keepTypeForwarderOnlyAssemblies = value; }
|
||||
}
|
||||
|
||||
public bool KeepMembersForDebuggerAttributes
|
||||
{
|
||||
get { return _keepMembersForDebuggerAttributes; }
|
||||
set { _keepMembersForDebuggerAttributes = value; }
|
||||
}
|
||||
|
||||
public IDictionary Actions {
|
||||
get { return _actions; }
|
||||
}
|
||||
@@ -83,6 +97,10 @@ namespace Mono.Linker {
|
||||
get { return _resolver; }
|
||||
}
|
||||
|
||||
public ReaderParameters ReaderParameters {
|
||||
get { return _readerParameters; }
|
||||
}
|
||||
|
||||
public ISymbolReaderProvider SymbolReaderProvider {
|
||||
get { return _symbolReaderProvider; }
|
||||
set { _symbolReaderProvider = value; }
|
||||
@@ -101,15 +119,21 @@ namespace Mono.Linker {
|
||||
}
|
||||
|
||||
public LinkContext (Pipeline pipeline, AssemblyResolver resolver)
|
||||
: this(pipeline, resolver, new ReaderParameters
|
||||
{
|
||||
AssemblyResolver = resolver
|
||||
})
|
||||
{
|
||||
}
|
||||
|
||||
public LinkContext (Pipeline pipeline, AssemblyResolver resolver, ReaderParameters readerParameters)
|
||||
{
|
||||
_pipeline = pipeline;
|
||||
_resolver = resolver;
|
||||
_actions = new Hashtable ();
|
||||
_parameters = new Hashtable ();
|
||||
_annotations = new AnnotationStore ();
|
||||
_readerParameters = new ReaderParameters {
|
||||
AssemblyResolver = _resolver,
|
||||
};
|
||||
_readerParameters = readerParameters;
|
||||
}
|
||||
|
||||
public TypeDefinition GetType (string fullName)
|
||||
@@ -161,12 +185,12 @@ namespace Mono.Linker {
|
||||
}
|
||||
}
|
||||
|
||||
bool SeenFirstTime (AssemblyDefinition assembly)
|
||||
protected bool SeenFirstTime (AssemblyDefinition assembly)
|
||||
{
|
||||
return !_annotations.HasAction (assembly);
|
||||
}
|
||||
|
||||
public void SafeReadSymbols (AssemblyDefinition assembly)
|
||||
public virtual void SafeReadSymbols (AssemblyDefinition assembly)
|
||||
{
|
||||
if (!_linkSymbols)
|
||||
return;
|
||||
@@ -187,6 +211,19 @@ namespace Mono.Linker {
|
||||
} catch {}
|
||||
}
|
||||
|
||||
public virtual ICollection<AssemblyDefinition> ResolveReferences (AssemblyDefinition assembly)
|
||||
{
|
||||
List<AssemblyDefinition> references = new List<AssemblyDefinition> ();
|
||||
foreach (AssemblyNameReference reference in assembly.MainModule.AssemblyReferences) {
|
||||
try {
|
||||
references.Add (Resolve (reference));
|
||||
}
|
||||
catch (AssemblyResolutionException) {
|
||||
}
|
||||
}
|
||||
return references;
|
||||
}
|
||||
|
||||
static AssemblyNameReference GetReference (IMetadataScope scope)
|
||||
{
|
||||
AssemblyNameReference reference;
|
||||
@@ -199,7 +236,7 @@ namespace Mono.Linker {
|
||||
return reference;
|
||||
}
|
||||
|
||||
void SetAction (AssemblyDefinition assembly)
|
||||
protected void SetAction (AssemblyDefinition assembly)
|
||||
{
|
||||
AssemblyAction action = AssemblyAction.Link;
|
||||
|
||||
|
||||
17
external/linker/linker/Mono.Linker/LoadException.cs
vendored
Normal file
17
external/linker/linker/Mono.Linker/LoadException.cs
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
|
||||
namespace Mono.Linker
|
||||
{
|
||||
public class LoadException : Exception
|
||||
{
|
||||
public LoadException (string message)
|
||||
: base (message)
|
||||
{
|
||||
}
|
||||
|
||||
public LoadException (string message, Exception innerException)
|
||||
: base (message, innerException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
17
external/linker/linker/Mono.Linker/MarkException.cs
vendored
Normal file
17
external/linker/linker/Mono.Linker/MarkException.cs
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
|
||||
namespace Mono.Linker
|
||||
{
|
||||
public class MarkException : Exception
|
||||
{
|
||||
public MarkException (string message)
|
||||
: base (message)
|
||||
{
|
||||
}
|
||||
|
||||
public MarkException (string message, Exception innerException)
|
||||
: base (message, innerException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
10
external/linker/linker/Mono.Linker/Pipeline.cs
vendored
10
external/linker/linker/Mono.Linker/Pipeline.cs
vendored
@@ -65,6 +65,16 @@ namespace Mono.Linker {
|
||||
throw new InvalidOperationException (msg);
|
||||
}
|
||||
|
||||
public void AddStepBefore (IStep target, IStep step)
|
||||
{
|
||||
for (int i = 0; i < _steps.Count; i++) {
|
||||
if (_steps [i] == target) {
|
||||
_steps.Insert (i, step);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ReplaceStep (Type target, IStep step)
|
||||
{
|
||||
AddStepBefore (target, step);
|
||||
|
||||
13
external/linker/linker/NetCore.props
vendored
Normal file
13
external/linker/linker/NetCore.props
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<RuntimeFrameworkVersion>2.0.0-beta-001509-00</RuntimeFrameworkVersion>
|
||||
<DefineConstants>$(DefineConstants);NET_CORE</DefineConstants>
|
||||
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<AssemblyName>illink</AssemblyName>
|
||||
<OutputType>exe</OutputType>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
Reference in New Issue
Block a user