Imported Upstream version 5.0.0.42

Former-commit-id: fd56571888259555122d8a0f58c68838229cea2b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2017-04-10 11:41:01 +00:00
parent 1190d13a04
commit 6bdd276d05
19939 changed files with 3099680 additions and 93811 deletions

71
external/linker/tuner/Mono.Tuner.csproj vendored Normal file
View File

@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{E97429BA-279A-4C1D-AE8A-8BD878C661D1}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Mono.Tuner</RootNamespace>
<AssemblyName>Mono.Tuner</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>True</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>False</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>True</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Mono.Tuner\AdjustVisibility.cs" />
<Compile Include="Mono.Tuner\CheckVisibility.cs" />
<Compile Include="Mono.Tuner\PrintStatus.cs" />
<Compile Include="Mono.Tuner\RemoveSerialization.cs" />
<Compile Include="Mono.Tuner\TunerAnnotations.cs" />
<Compile Include="Mono.Tuner\InjectSecurityAttributes.cs" />
<Compile Include="Mono.Tuner\MoonlightAssemblyStep.cs" />
<Compile Include="Mono.Tuner\FilterAttributes.cs" />
<Compile Include="Mono.Tuner\MoonlightA11yProcessor.cs" />
<Compile Include="Mono.Tuner\MoonlightA11yAssemblyStep.cs" />
<Compile Include="Mono.Tuner\MoonlightA11yUsageInspectionStep.cs" />
<Compile Include="Mono.Tuner\MoonlightA11yDescriptorGenerator.cs" />
<Compile Include="Mono.Tuner\MoonlightA11yApiMarker.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- 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">
</Target>
<Target Name="AfterBuild">
</Target>
-->
<ItemGroup>
<None Include="Makefile" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\linker\Mono.Linker.csproj">
<Project>{DD28E2B1-057B-4B4D-A04D-B2EBD9E76E46}</Project>
<Name>Mono.Linker</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\external\cecil\Mono.Cecil.csproj">
<Project>{D68133BD-1E63-496E-9EDE-4FBDBF77B486}</Project>
<Name>Mono.Cecil</Name>
</ProjectReference>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,164 @@
//
// AdjustVisibilityStep.cs
//
// Author:
// Jb Evain (jbevain@novell.com)
//
// (C) 2007 Novell, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections;
using System.Collections.Generic;
using Mono.Linker;
using Mono.Linker.Steps;
using Mono.Cecil;
namespace Mono.Tuner {
public class AdjustVisibility : BaseStep {
protected override void ProcessAssembly (AssemblyDefinition assembly)
{
if (Annotations.GetAction (assembly) != AssemblyAction.Link)
return;
ProcessTypes (assembly.MainModule.Types);
}
void ProcessTypes (ICollection types)
{
foreach (TypeDefinition type in types)
ProcessType (type);
}
void ProcessType (TypeDefinition type)
{
if (!IsPublic (type))
return;
if (!IsMarkedAsPublic (type)) {
SetInternalVisibility (type);
return;
}
if (type.IsEnum)
return;
ProcessFields (type.Fields);
ProcessMethods (type.Methods);
}
static bool IsPublic (TypeDefinition type)
{
return type.DeclaringType == null ? type.IsPublic : type.IsNestedPublic;
}
void SetInternalVisibility (TypeDefinition type)
{
type.Attributes &= ~TypeAttributes.VisibilityMask;
if (type.DeclaringType == null)
type.Attributes |= TypeAttributes.NotPublic;
else
type.Attributes |= TypeAttributes.NestedAssembly;
MarkInternalized (type);
}
void ProcessMethods (ICollection methods)
{
foreach (MethodDefinition method in methods)
ProcessMethod (method);
}
void ProcessMethod (MethodDefinition method)
{
if (IsMarkedAsPublic (method))
return;
if (method.IsPublic)
SetInternalVisibility (method);
else if (method.IsFamily || method.IsFamilyOrAssembly)
SetProtectedAndInternalVisibility (method);
}
void SetInternalVisibility (MethodDefinition method)
{
method.Attributes &= ~MethodAttributes.MemberAccessMask;
method.Attributes |= MethodAttributes.Assembly;
MarkInternalized (method);
}
void SetProtectedAndInternalVisibility (MethodDefinition method)
{
method.Attributes &= ~MethodAttributes.MemberAccessMask;
method.Attributes |= MethodAttributes.FamANDAssem;
MarkInternalized (method);
}
bool IsMarkedAsPublic (IMetadataTokenProvider provider)
{
return Annotations.IsPublic (provider);
}
void ProcessFields (IEnumerable<FieldDefinition> fields)
{
foreach (FieldDefinition field in fields)
ProcessField (field);
}
void ProcessField (FieldDefinition field)
{
if (IsMarkedAsPublic (field))
return;
if (field.IsPublic)
SetInternalVisibility (field);
else if (field.IsFamily || field.IsFamilyOrAssembly)
SetProtectedAndInternalVisibility (field);
}
void SetInternalVisibility (FieldDefinition field)
{
field.Attributes &= ~FieldAttributes.FieldAccessMask;
field.Attributes |= FieldAttributes.Assembly;
MarkInternalized (field);
}
void SetProtectedAndInternalVisibility (FieldDefinition field)
{
field.Attributes &= ~FieldAttributes.FieldAccessMask;
field.Attributes |= FieldAttributes.FamANDAssem;
MarkInternalized (field);
}
void MarkInternalized (IMetadataTokenProvider provider)
{
TunerAnnotations.Internalized (Context, provider);
}
}
}

View File

@@ -0,0 +1,164 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Mono.Linker;
using Mono.Linker.Steps;
using Mono.Cecil;
namespace Mono.Tuner {
public abstract class ApplyPreserveAttributeBase : BaseSubStep {
// set 'removeAttribute' to true if you want the preserved attribute to be removed from the final assembly
protected abstract bool IsPreservedAttribute (ICustomAttributeProvider provider, CustomAttribute attribute, out bool removeAttribute);
public override SubStepTargets Targets {
get {
return SubStepTargets.Type
| SubStepTargets.Field
| SubStepTargets.Method
| SubStepTargets.Property
| SubStepTargets.Event;
}
}
public override bool IsActiveFor (AssemblyDefinition assembly)
{
return !Profile.IsSdkAssembly (assembly) && Annotations.GetAction (assembly) == AssemblyAction.Link;
}
public override void ProcessType (TypeDefinition type)
{
TryApplyPreserveAttribute (type);
}
public override void ProcessField (FieldDefinition field)
{
foreach (var attribute in GetPreserveAttributes (field))
Mark (field, attribute);
}
public override void ProcessMethod (MethodDefinition method)
{
MarkMethodIfPreserved (method);
}
public override void ProcessProperty (PropertyDefinition property)
{
foreach (var attribute in GetPreserveAttributes (property)) {
MarkMethod (property.GetMethod, attribute);
MarkMethod (property.SetMethod, attribute);
}
}
public override void ProcessEvent (EventDefinition @event)
{
foreach (var attribute in GetPreserveAttributes (@event)) {
MarkMethod (@event.AddMethod, attribute);
MarkMethod (@event.InvokeMethod, attribute);
MarkMethod (@event.RemoveMethod, attribute);
}
}
void MarkMethodIfPreserved (MethodDefinition method)
{
foreach (var attribute in GetPreserveAttributes (method))
MarkMethod (method, attribute);
}
void MarkMethod (MethodDefinition method, CustomAttribute preserve_attribute)
{
if (method == null)
return;
Mark (method, preserve_attribute);
Annotations.SetAction (method, MethodAction.Parse);
}
void Mark (IMetadataTokenProvider provider, CustomAttribute preserve_attribute)
{
if (IsConditionalAttribute (preserve_attribute)) {
PreserveConditional (provider);
return;
}
PreserveUnconditional (provider);
}
void PreserveConditional (IMetadataTokenProvider provider)
{
var method = provider as MethodDefinition;
if (method == null) {
// workaround to support (uncommon but valid) conditional fields form [Preserve]
PreserveUnconditional (provider);
return;
}
Annotations.AddPreservedMethod (method.DeclaringType, method);
}
static bool IsConditionalAttribute (CustomAttribute attribute)
{
if (attribute == null)
return false;
foreach (var named_argument in attribute.Fields)
if (named_argument.Name == "Conditional")
return (bool) named_argument.Argument.Value;
return false;
}
void PreserveUnconditional (IMetadataTokenProvider provider)
{
Annotations.Mark (provider);
var member = provider as IMemberDefinition;
if (member == null || member.DeclaringType == null)
return;
Mark (member.DeclaringType, null);
}
void TryApplyPreserveAttribute (TypeDefinition type)
{
foreach (var attribute in GetPreserveAttributes (type)) {
Annotations.Mark (type);
if (!attribute.HasFields)
continue;
foreach (var named_argument in attribute.Fields)
if (named_argument.Name == "AllMembers" && (bool)named_argument.Argument.Value)
Annotations.SetPreserve (type, TypePreserve.All);
}
}
List<CustomAttribute> GetPreserveAttributes (ICustomAttributeProvider provider)
{
List<CustomAttribute> attrs = new List<CustomAttribute> ();
if (!provider.HasCustomAttributes)
return attrs;
var attributes = provider.CustomAttributes;
for (int i = attributes.Count - 1; i >= 0; i--) {
var attribute = attributes [i];
bool remote_attribute;
if (!IsPreservedAttribute (provider, attribute, out remote_attribute))
continue;
attrs.Add (attribute);
if (remote_attribute)
attributes.RemoveAt (i);
}
return attrs;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,375 @@
//
// CheckVisibility.cs
//
// Author:
// Jb Evain (jbevain@novell.com)
//
// (C) 2007 Novell, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections;
using System.Text;
using Mono.Linker;
using Mono.Linker.Steps;
using Mono.Cecil;
using Mono.Cecil.Cil;
namespace Mono.Tuner {
public class CheckVisibility : BaseStep {
bool throw_on_error;
protected override void Process ()
{
throw_on_error = GetThrowOnVisibilityErrorParameter ();
}
bool GetThrowOnVisibilityErrorParameter ()
{
try {
return bool.Parse (Context.GetParameter ("throw_on_visibility_error"));
} catch {
return false;
}
}
protected override void ProcessAssembly (AssemblyDefinition assembly)
{
if (assembly.Name.Name == "mscorlib" || assembly.Name.Name == "smcs")
return;
if (Annotations.GetAction (assembly) != AssemblyAction.Link)
return;
Report ("in assembly {0}", assembly.Name);
foreach (ModuleDefinition module in assembly.Modules)
foreach (TypeDefinition type in module.Types)
CheckType (type);
}
void CheckType (TypeDefinition type)
{
if (!IsVisibleFrom (type, type.BaseType)) {
ReportError ("Base type `{0}` of type `{1}` is not visible",
type.BaseType, type);
}
CheckInterfaces (type);
CheckFields (type);
CheckMethods (type);
}
void CheckInterfaces (TypeDefinition type)
{
foreach (var iface in type.Interfaces) {
if (!IsVisibleFrom (type, iface.InterfaceType)) {
ReportError ("Interface `{0}` implemented by `{1}` is not visible",
iface, type);
}
}
}
static bool IsPublic (TypeDefinition type)
{
return (type.DeclaringType == null && type.IsPublic) || type.IsNestedPublic;
}
static bool AreInDifferentAssemblies (TypeDefinition type, TypeDefinition target)
{
if (type.Module.Assembly.Name.FullName == target.Module.Assembly.Name.FullName)
return false;
return !IsInternalVisibleTo (target.Module.Assembly, type.Module.Assembly);
}
static bool IsInternalVisibleTo (AssemblyDefinition assembly, AssemblyDefinition candidate)
{
foreach (CustomAttribute attribute in assembly.CustomAttributes) {
if (!IsInternalsVisibleToAttribute (attribute))
continue;
if (attribute.ConstructorArguments.Count == 0)
continue;
string signature = (string) attribute.ConstructorArguments [0].Value;
if (InternalsVisibleToSignatureMatch (signature, candidate.Name))
return true;
}
return false;
}
static bool InternalsVisibleToSignatureMatch (string signature, AssemblyNameReference reference)
{
int pos = signature.IndexOf (",");
if (pos == -1)
return signature == reference.Name;
string assembly_name = signature.Substring (0, pos);
pos = signature.IndexOf ("=");
if (pos == -1)
throw new ArgumentException ();
string public_key = signature.Substring (pos + 1).ToLower ();
return assembly_name == reference.Name && public_key == ToPublicKeyString (reference.PublicKey);
}
static string ToPublicKeyString (byte [] public_key)
{
StringBuilder signature = new StringBuilder (public_key.Length);
for (int i = 0; i < public_key.Length; i++)
signature.Append (public_key [i].ToString ("x2"));
return signature.ToString ();
}
static bool IsInternalsVisibleToAttribute (CustomAttribute attribute)
{
return attribute.Constructor.DeclaringType.FullName == "System.Runtime.CompilerServices.InternalsVisibleToAttribute";
}
bool IsVisibleFrom (TypeDefinition type, TypeReference reference)
{
if (reference == null)
return true;
if (reference is GenericParameter || reference.GetElementType () is GenericParameter)
return true;
TypeDefinition other = reference.Resolve ();
if (other == null)
return true;
if (!AreInDifferentAssemblies (type, other))
return true;
if (IsPublic (other))
return true;
return false;
}
bool IsVisibleFrom (TypeDefinition type, MethodReference reference)
{
if (reference == null)
return true;
MethodDefinition meth = reference.Resolve ();
if (meth == null)
return true;
TypeDefinition dec = (TypeDefinition) meth.DeclaringType;
if (!IsVisibleFrom (type, dec))
return false;
if (meth.IsPublic)
return true;
if (type == dec || IsNestedIn (type, dec))
return true;
if (meth.IsFamily && InHierarchy (type, dec))
return true;
if (meth.IsFamilyOrAssembly && (!AreInDifferentAssemblies (type, dec) || InHierarchy (type, dec)))
return true;
if (meth.IsFamilyAndAssembly && (!AreInDifferentAssemblies (type, dec) && InHierarchy (type, dec)))
return true;
if (!AreInDifferentAssemblies (type, dec) && meth.IsAssembly)
return true;
return false;
}
bool IsVisibleFrom (TypeDefinition type, FieldReference reference)
{
if (reference == null)
return true;
FieldDefinition field = reference.Resolve ();
if (field == null)
return true;
TypeDefinition dec = (TypeDefinition) field.DeclaringType;
if (!IsVisibleFrom (type, dec))
return false;
if (field.IsPublic)
return true;
if (type == dec || IsNestedIn (type, dec))
return true;
if (field.IsFamily && InHierarchy (type, dec))
return true;
if (field.IsFamilyOrAssembly && (!AreInDifferentAssemblies (type, dec) || InHierarchy (type, dec)))
return true;
if (field.IsFamilyAndAssembly && (!AreInDifferentAssemblies (type, dec) && InHierarchy (type, dec)))
return true;
if (!AreInDifferentAssemblies (type, dec) && field.IsAssembly)
return true;
return false;
}
static bool IsNestedIn (TypeDefinition type, TypeDefinition other)
{
TypeDefinition declaring = type.DeclaringType;
if (declaring == null)
return false;
if (declaring == other)
return true;
if (declaring.DeclaringType == null)
return false;
return IsNestedIn (declaring, other);
}
static bool InHierarchy (TypeDefinition type, TypeDefinition other)
{
if (type.BaseType == null)
return false;
TypeDefinition baseType = type.BaseType.Resolve ();
if (baseType == other)
return true;
return InHierarchy (baseType, other);
}
static void Report (string pattern, params object [] parameters)
{
Console.WriteLine ("[check] " + pattern, parameters);
}
void ReportError (string pattern, params object [] parameters)
{
Report (pattern, parameters);
if (throw_on_error)
throw new VisibilityErrorException (string.Format (pattern, parameters));
}
void CheckFields (TypeDefinition type)
{
foreach (FieldDefinition field in type.Fields) {
if (!IsVisibleFrom (type, field.FieldType)) {
ReportError ("Field `{0}` of type `{1}` is not visible from `{2}`",
field.Name, field.FieldType, type);
}
}
}
void CheckMethods (TypeDefinition type)
{
CheckMethods (type, type.Methods);
}
void CheckMethods (TypeDefinition type, ICollection methods)
{
foreach (MethodDefinition method in methods) {
if (!IsVisibleFrom (type, method.ReturnType)) {
ReportError ("Method return type `{0}` in method `{1}` is not visible",
method.ReturnType, method);
}
foreach (ParameterDefinition parameter in method.Parameters) {
if (!IsVisibleFrom (type, parameter.ParameterType)) {
ReportError ("Parameter `{0}` of type `{1}` in method `{2}` is not visible.",
parameter.Index, parameter.ParameterType, method);
}
}
if (method.HasBody)
CheckBody (method);
}
}
void CheckBody (MethodDefinition method)
{
TypeDefinition type = (TypeDefinition) method.DeclaringType;
foreach (VariableDefinition variable in method.Body.Variables) {
if (!IsVisibleFrom ((TypeDefinition) method.DeclaringType, variable.VariableType)) {
ReportError ("Variable `{0}` of type `{1}` from method `{2}` is not visible",
variable.Index, variable.VariableType, method);
}
}
foreach (Instruction instr in method.Body.Instructions) {
switch (instr.OpCode.OperandType) {
case OperandType.InlineType:
case OperandType.InlineMethod:
case OperandType.InlineField:
case OperandType.InlineTok:
bool error = false;
TypeReference type_ref = instr.Operand as TypeReference;
if (type_ref != null)
error = !IsVisibleFrom (type, type_ref);
MethodReference meth_ref = instr.Operand as MethodReference;
if (meth_ref != null)
error = !IsVisibleFrom (type, meth_ref);
FieldReference field_ref = instr.Operand as FieldReference;
if (field_ref != null)
error = !IsVisibleFrom (type, field_ref);
if (error) {
ReportError ("Operand `{0}` of type {1} at offset 0x{2} in method `{3}` is not visible",
instr.Operand, instr.OpCode.OperandType, instr.Offset.ToString ("x4"), method);
}
break;
default:
continue;
}
}
}
class VisibilityErrorException : Exception {
public VisibilityErrorException (string message)
: base (message)
{
}
}
}
}

View File

@@ -0,0 +1,93 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Mono.Linker;
using Mono.Linker.Steps;
using Mono.Cecil;
using Mono.Cecil.Cil;
namespace Mono.Tuner {
public class CustomizeActions : BaseStep {
readonly bool link_sdk_only;
readonly HashSet<string> skipped_assemblies;
public CustomizeActions (bool link_sdk_only, IEnumerable<string> skipped_assemblies)
{
this.link_sdk_only = link_sdk_only;
this.skipped_assemblies = new HashSet<string> (skipped_assemblies);
}
protected override void ProcessAssembly (AssemblyDefinition assembly)
{
if (!IsSkipped (assembly) && IsLinked (assembly)) {
if (!Annotations.HasAction (assembly)) // stray assembly not picked up when resolving references
Annotations.SetAction (assembly, AssemblyAction.Link);
return;
}
ProcessUserAssembly (assembly);
}
protected virtual bool IsPreservedAttribute (CustomAttribute attribute)
{
// [assembly: Preserve (type)] does not preserve all the code in the assembly, in fact it might
// not preserve anything in _this_ assembly, but something in a separate assembly (reference)
if (attribute.HasConstructorArguments)
return false;
return (attribute.AttributeType.Name == "PreserveAttribute");
}
protected virtual bool IsLinkerSafeAttribute (CustomAttribute attribute)
{
return (attribute.AttributeType.Name == "LinkerSafeAttribute");
}
const ModuleAttributes Supported = ModuleAttributes.ILOnly | ModuleAttributes.Required32Bit |
ModuleAttributes.Preferred32Bit | ModuleAttributes.StrongNameSigned;
protected virtual bool IsSkipped (AssemblyDefinition assembly)
{
// Cecil can't save back mixed-mode assemblies - so we can't link them
if ((assembly.MainModule.Attributes & ~Supported) != 0)
return true;
if (assembly.HasCustomAttributes) {
foreach (var ca in assembly.CustomAttributes) {
if (IsPreservedAttribute (ca))
return true;
}
}
return skipped_assemblies.Contains (assembly.Name.Name);
}
protected virtual bool IsLinked (AssemblyDefinition assembly)
{
// LinkAll
if (!link_sdk_only)
return true;
// Link SDK : applies to BCL/SDK and product assembly (e.g. monotouch.dll)
if (Profile.IsSdkAssembly (assembly))
return true;
if (Profile.IsProductAssembly (assembly))
return true;
// the assembly can be marked with [LinkAssembly]
if (assembly.HasCustomAttributes) {
foreach (var ca in assembly.CustomAttributes) {
if (IsLinkerSafeAttribute (ca))
return true;
}
}
return false;
}
protected void ProcessUserAssembly (AssemblyDefinition assembly)
{
ResolveFromAssemblyStep.ProcessLibrary (Context, assembly);
}
}
}

View File

@@ -0,0 +1,288 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Mono.Linker;
using Mono.Linker.Steps;
using Mono.Cecil;
namespace Mono.Tuner {
[Flags]
public enum SubStepTargets {
None = 0,
Assembly = 1,
Type = 2,
Field = 4,
Method = 8,
Property = 16,
Event = 32,
}
public interface ISubStep {
SubStepTargets Targets { get; }
void Initialize (LinkContext context);
bool IsActiveFor (AssemblyDefinition assembly);
void ProcessAssembly (AssemblyDefinition assembly);
void ProcessType (TypeDefinition type);
void ProcessField (FieldDefinition field);
void ProcessMethod (MethodDefinition method);
void ProcessProperty (PropertyDefinition property);
void ProcessEvent (EventDefinition @event);
}
public abstract class BaseSubStep : ISubStep {
protected LinkContext context;
public AnnotationStore Annotations {
get { return context.Annotations; }
}
public abstract SubStepTargets Targets { get; }
public virtual void Initialize (LinkContext context)
{
this.context = context;
}
public virtual bool IsActiveFor (AssemblyDefinition assembly)
{
return true;
}
public virtual void ProcessAssembly (AssemblyDefinition assembly)
{
}
public virtual void ProcessType (TypeDefinition type)
{
}
public virtual void ProcessField (FieldDefinition field)
{
}
public virtual void ProcessMethod (MethodDefinition method)
{
}
public virtual void ProcessProperty (PropertyDefinition property)
{
}
public virtual void ProcessEvent (EventDefinition @event)
{
}
}
public class SubStepDispatcher : IStep, IEnumerable<ISubStep> {
List<ISubStep> substeps = new List<ISubStep> ();
List<ISubStep> on_assemblies;
List<ISubStep> on_types;
List<ISubStep> on_fields;
List<ISubStep> on_methods;
List<ISubStep> on_properties;
List<ISubStep> on_events;
public void Add (ISubStep substep)
{
substeps.Add (substep);
}
public void Process (LinkContext context)
{
InitializeSubSteps (context);
BrowseAssemblies (context.GetAssemblies ());
}
static bool HasSubSteps (List<ISubStep> substeps)
{
return substeps != null && substeps.Count > 0;
}
void BrowseAssemblies (IEnumerable<AssemblyDefinition> assemblies)
{
foreach (var assembly in assemblies) {
CategorizeSubSteps (assembly);
if (HasSubSteps (on_assemblies))
DispatchAssembly (assembly);
if (!ShouldDispatchTypes ())
continue;
BrowseTypes (assembly.MainModule.Types);
}
}
bool ShouldDispatchTypes ()
{
return HasSubSteps (on_types)
|| HasSubSteps (on_fields)
|| HasSubSteps (on_methods)
|| HasSubSteps (on_properties)
|| HasSubSteps (on_events);
}
void BrowseTypes (ICollection types)
{
foreach (TypeDefinition type in types) {
DispatchType (type);
if (type.HasFields && HasSubSteps (on_fields))
BrowseFields (type.Fields);
if (type.HasMethods && HasSubSteps (on_methods))
BrowseMethods (type.Methods);
if (type.HasProperties && HasSubSteps (on_properties))
BrowseProperties (type.Properties);
if (type.HasEvents && HasSubSteps (on_events))
BrowseEvents (type.Events);
if (type.HasNestedTypes)
BrowseTypes (type.NestedTypes);
}
}
void BrowseFields (ICollection fields)
{
foreach (FieldDefinition field in fields)
DispatchField (field);
}
void BrowseMethods (ICollection methods)
{
foreach (MethodDefinition method in methods)
DispatchMethod (method);
}
void BrowseProperties (ICollection properties)
{
foreach (PropertyDefinition property in properties)
DispatchProperty (property);
}
void BrowseEvents (ICollection events)
{
foreach (EventDefinition @event in events)
DispatchEvent (@event);
}
void DispatchAssembly (AssemblyDefinition assembly)
{
foreach (var substep in on_assemblies) {
var bs = substep as BaseSubStep;
if (bs != null)
bs.Annotations.Push (substep);
substep.ProcessAssembly (assembly);
if (bs != null)
bs.Annotations.Pop ();
}
}
void DispatchType (TypeDefinition type)
{
foreach (var substep in on_types) {
var bs = substep as BaseSubStep;
if (bs != null)
bs.Annotations.Push (substep);
substep.ProcessType (type);
if (bs != null)
bs.Annotations.Pop ();
}
}
void DispatchField (FieldDefinition field)
{
foreach (var substep in on_fields)
substep.ProcessField (field);
}
void DispatchMethod (MethodDefinition method)
{
foreach (var substep in on_methods)
substep.ProcessMethod (method);
}
void DispatchProperty (PropertyDefinition property)
{
foreach (var substep in on_properties)
substep.ProcessProperty (property);
}
void DispatchEvent (EventDefinition @event)
{
foreach (var substep in on_events)
substep.ProcessEvent (@event);
}
void InitializeSubSteps (LinkContext context)
{
foreach (var substep in substeps)
substep.Initialize (context);
}
void CategorizeSubSteps (AssemblyDefinition assembly)
{
on_assemblies = null;
on_types = null;
on_fields = null;
on_methods = null;
on_properties = null;
on_events = null;
foreach (var substep in substeps)
CategorizeSubStep (substep, assembly);
}
void CategorizeSubStep (ISubStep substep, AssemblyDefinition assembly)
{
if (!substep.IsActiveFor (assembly))
return;
CategorizeTarget (substep, SubStepTargets.Assembly, ref on_assemblies);
CategorizeTarget (substep, SubStepTargets.Type, ref on_types);
CategorizeTarget (substep, SubStepTargets.Field, ref on_fields);
CategorizeTarget (substep, SubStepTargets.Method, ref on_methods);
CategorizeTarget (substep, SubStepTargets.Property, ref on_properties);
CategorizeTarget (substep, SubStepTargets.Event, ref on_events);
}
static void CategorizeTarget (ISubStep substep, SubStepTargets target, ref List<ISubStep> list)
{
if (!Targets (substep, target))
return;
if (list == null)
list = new List<ISubStep> ();
list.Add (substep);
}
static bool Targets (ISubStep substep, SubStepTargets target)
{
return (substep.Targets & target) == target;
}
IEnumerator IEnumerable.GetEnumerator ()
{
return GetEnumerator ();
}
public IEnumerator<ISubStep> GetEnumerator ()
{
return substeps.GetEnumerator ();
}
}
}

View File

@@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using Mono.Cecil;
using Mono.Linker;
namespace Mono.Tuner {
public static partial class Extensions {
public static bool TryGetLinkedAssembly (this LinkContext context, string name, out AssemblyDefinition assembly)
{
assembly = GetAssembly (context, name);
if (assembly == null)
return false;
return context.Annotations.GetAction (assembly) == AssemblyAction.Link;
}
public static AssemblyDefinition GetAssembly (this LinkContext context, string assembly_name)
{
foreach (var assembly in context.GetAssemblies ())
if (assembly.Name.Name == assembly_name)
return assembly;
return null;
}
// note: direct check, no inheritance
public static bool Is (this TypeReference type, string @namespace, string name)
{
return ((type != null) && (type.Name == name) && (type.Namespace == @namespace));
}
}
}

View File

@@ -0,0 +1,157 @@
//
// FilterAttributes.cs
//
// Author:
// Jb Evain (jbevain@novell.com)
//
// (C) 2009 Novell, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections;
using Mono.Linker;
using Mono.Linker.Steps;
using Mono.Cecil;
namespace Mono.Tuner {
public class FilterAttributes : BaseStep {
static Hashtable attributes = new Hashtable ();
static FilterAttributes ()
{
FilterAttribute ("System.Runtime.InteropServices.ComVisibleAttribute");
}
static void FilterAttribute (string fullname)
{
attributes.Add (fullname, null);
}
protected override void ProcessAssembly (AssemblyDefinition assembly)
{
if (Annotations.GetAction (assembly) != AssemblyAction.Link)
return;
Filter (assembly);
foreach (ModuleDefinition module in assembly.Modules)
ProcessModule (module);
}
static void ProcessModule (ModuleDefinition module)
{
Filter (module);
foreach (TypeDefinition type in module.Types)
ProcessType (type);
}
static void ProcessType (TypeDefinition type)
{
if (type.HasFields)
ProcessFields (type.Fields);
if (type.HasMethods)
ProcessMethods (type.Methods);
if (type.HasEvents)
ProcessEvents (type.Events);
if (type.HasProperties)
ProcessProperties (type.Properties);
ProcessGenericParameters (type);
}
static void ProcessFields (ICollection fields)
{
foreach (FieldDefinition field in fields)
Filter (field);
}
static void ProcessMethods (ICollection methods)
{
foreach (MethodDefinition method in methods)
ProcessMethod (method);
}
static void ProcessMethod (MethodDefinition method)
{
ProcessGenericParameters (method);
Filter (method.MethodReturnType);
if (method.HasParameters)
ProcessParameters (method.Parameters);
}
static void ProcessParameters (ICollection parameters)
{
foreach (ParameterDefinition parameter in parameters)
Filter (parameter);
}
static void ProcessGenericParameters (IGenericParameterProvider provider)
{
if (!provider.HasGenericParameters)
return;
foreach (GenericParameter parameter in provider.GenericParameters)
Filter (parameter);
}
static void ProcessEvents (ICollection events)
{
foreach (EventDefinition @event in events)
Filter (@event);
}
static void ProcessProperties (ICollection properties)
{
foreach (PropertyDefinition property in properties)
Filter (property);
}
static void Filter (ICustomAttributeProvider provider)
{
if (!provider.HasCustomAttributes)
return;
for (int i = 0; i < provider.CustomAttributes.Count; i++) {
CustomAttribute attribute = provider.CustomAttributes [i];
if (!IsFilteredAttribute (attribute))
continue;
provider.CustomAttributes.RemoveAt (i--);
}
}
static bool IsFilteredAttribute (CustomAttribute attribute)
{
return attributes.Contains (attribute.Constructor.DeclaringType.FullName);
}
}
}

View File

@@ -0,0 +1,20 @@
using System;
using Mono.Linker;
using Mono.Linker.Steps;
using Mono.Cecil;
namespace Mono.Tuner {
public class FixModuleFlags : BaseStep {
protected override void ProcessAssembly (AssemblyDefinition assembly)
{
if (Annotations.GetAction (assembly) != AssemblyAction.Link)
return;
assembly.MainModule.Attributes = ModuleAttributes.ILOnly;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,149 @@
//
// MarkNSObjectsBase.cs
//
// Authors:
// Jb Evain (jbevain@novell.com)
// Sebastien Pouliot <sebastien@xamarin.com>
//
// (C) 2009 Novell, Inc.
// Copyright (C) 2011 Xamarin, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Mono.Linker;
using Mono.Linker.Steps;
using Mono.Tuner;
using Mono.Cecil;
namespace Mono.Tuner {
public abstract class MarkNSObjectsBase : BaseSubStep {
protected abstract string ExportAttribute { get; }
public override SubStepTargets Targets {
get { return SubStepTargets.Type; }
}
public override void ProcessType (TypeDefinition type)
{
if (!IsProductType (type)) {
Annotations.Mark (type);
Annotations.SetPreserve (type, TypePreserve.All);
} else
PreserveProductType (type);
}
void PreserveProductType (TypeDefinition type)
{
PreserveIntPtrConstructor (type);
PreserveExportedMethods (type);
}
void PreserveExportedMethods (TypeDefinition type)
{
if (!type.HasMethods)
return;
foreach (var method in type.GetMethods ()) {
if (!IsExportedMethod (method))
continue;
if (!IsOverridenInUserCode (method))
continue;
PreserveMethod (type, method);
}
}
bool IsOverridenInUserCode (MethodDefinition method)
{
if (!method.IsVirtual)
return false;
var overrides = Annotations.GetOverrides (method);
if (overrides == null || overrides.Count == 0)
return false;
foreach (MethodDefinition @override in overrides)
if (!IsProductMethod (@override))
return true;
return false;
}
bool IsExportedMethod (MethodDefinition method)
{
return HasExportAttribute (method);
}
bool HasExportAttribute (ICustomAttributeProvider provider)
{
if (!provider.HasCustomAttributes)
return false;
foreach (CustomAttribute attribute in provider.CustomAttributes)
if (attribute.AttributeType.FullName == ExportAttribute)
return true;
return false;
}
void PreserveIntPtrConstructor (TypeDefinition type)
{
if (!type.HasMethods)
return;
foreach (MethodDefinition constructor in type.GetConstructors ()) {
if (!constructor.HasParameters)
continue;
if (constructor.Parameters.Count != 1 || constructor.Parameters [0].ParameterType.FullName != "System.IntPtr")
continue;
PreserveMethod (type, constructor);
break; // only one .ctor can match this
}
}
void PreserveMethod (TypeDefinition type, MethodDefinition method)
{
Annotations.AddPreservedMethod (type, method);
}
static bool IsProductMethod (MethodDefinition method)
{
return IsProductType (method.DeclaringType);
}
static bool IsProductType (TypeDefinition type)
{
return Profile.IsProductAssembly (type.Module.Assembly);
}
}
}

View File

@@ -0,0 +1,88 @@
//
// MoonlightA11yApiMarker.cs
//
// Author:
// Andrés G. Aragoneses (aaragoneses@novell.com)
//
// (C) 2009 Novell, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections;
using System.Xml;
using Mono.Linker;
using Mono.Linker.Steps;
using Mono.Cecil;
namespace Mono.Tuner {
public class MoonlightA11yApiMarker : MarkStep {
bool IsA11yAssembly (AssemblyDefinition assembly)
{
return assembly.ToString ().Contains ("DummyEntry") || assembly.ToString ().Contains ("MoonAtkBridge");
}
protected override void InitializeAssembly (AssemblyDefinition assembly)
{
if (IsA11yAssembly (assembly))
base.InitializeAssembly (assembly);
}
protected override void EnqueueMethod (MethodDefinition method)
{
if (IsA11yAssembly (method.DeclaringType.Module.Assembly))
base.EnqueueMethod (method);
else
Annotations.Mark (method);
}
protected override bool IgnoreScope (IMetadataScope scope)
{
return false;
}
protected override TypeDefinition MarkType (TypeReference reference)
{
if (reference == null)
throw new ArgumentNullException ("reference");
reference = GetOriginalType (reference);
if (reference is GenericParameter)
return null;
TypeDefinition type = reference.Resolve ();
if (type == null)
throw new ResolutionException (reference);
if (CheckProcessed (type))
return type;
Annotations.Mark (type);
return type;
}
}
}

View File

@@ -0,0 +1,54 @@
//
// MoonlightA11yAssemblyStep.cs
//
// Author:
// Andrés G. Aragoneses (aaragoneses@novell.com)
//
// (C) 2009 Novell, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections;
using System.IO;
using Mono.Linker;
using Mono.Linker.Steps;
using Mono.Cecil;
namespace Mono.Tuner {
public class MoonlightA11yAssemblyStep : MoonlightAssemblyStep {
protected override void CustomizePipeline (Pipeline pipeline)
{
pipeline.RemoveStep (typeof (LoadI18nAssemblies));
pipeline.RemoveStep (typeof (BlacklistStep));
pipeline.RemoveStep (typeof (MarkStep));
pipeline.RemoveStep (typeof (SweepStep));
pipeline.RemoveStep (typeof (CleanStep));
pipeline.RemoveStep (typeof (RegenerateGuidStep));
pipeline.AddStepBefore (typeof (OutputStep), new MoonlightA11yProcessor ());
}
}
}

View File

@@ -0,0 +1,337 @@
//
// MoonlightA11yDescriptorGenerator.cs
//
// Author:
// Andrés G. Aragoneses (aaragoneses@novell.com)
//
// (C) 2009 Novell, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using System.Text;
using System.Xml;
using System.Xml.XPath;
using Mono.Linker;
using Mono.Linker.Steps;
using Mono.Cecil;
namespace Mono.Tuner {
public class MoonlightA11yDescriptorGenerator : BaseStep {
XmlTextWriter writer = null;
protected override void ProcessAssembly (AssemblyDefinition assembly)
{
if (assembly.Name.Name == "MoonAtkBridge" || assembly.Name.Name == "System.Windows" ||
assembly.Name.Name.Contains ("Dummy"))
return;
if (writer == null) {
if (!Directory.Exists (Context.OutputDirectory))
Directory.CreateDirectory (Context.OutputDirectory);
string file_name = "descriptors.xml";
string file_path = Path.Combine (Context.OutputDirectory, file_name);
if (File.Exists (file_path))
File.Delete (file_path);
FileStream xml_file = new FileStream (file_path, FileMode.OpenOrCreate);
Console.WriteLine ("Created file {0}", file_name);
Console.Write ("Writing contents...");
writer = new XmlTextWriter (xml_file, System.Text.Encoding.UTF8);
writer.Formatting = Formatting.Indented;
writer.WriteStartElement("linker");
}
SortedDictionary <TypeDefinition, IList> types = ScanAssembly (assembly);
if (types != null && types.Count > 0) {
writer.WriteStartElement("assembly");
writer.WriteAttributeString ("fullname", assembly.Name.Name);
foreach (TypeDefinition type in types.Keys) {
IList members = types [type];
if (members != null && members.Count > 0) {
writer.WriteStartElement("type");
writer.WriteAttributeString ("fullname", type.FullName);
foreach (IMetadataTokenProvider member in members) {
MethodDefinition method = member as MethodDefinition;
if (method != null) {
writer.WriteStartElement("method");
writer.WriteAttributeString ("signature",
method.ReturnType.FullName + " " +
method.Name + GetMethodParams (method));
writer.WriteEndElement ();
continue;
}
FieldDefinition field = member as FieldDefinition;
if (field != null) {
writer.WriteStartElement("field");
writer.WriteAttributeString ("signature", field.DeclaringType.FullName + " " + field.Name);
writer.WriteEndElement ();
}
}
writer.WriteEndElement ();
}
}
writer.WriteEndElement ();
Console.WriteLine ();
}
}
protected override void EndProcess ()
{
Console.WriteLine ();
foreach (FileStream stream in streams)
stream.Close ();
if (writer != null) {
writer.WriteEndElement ();
writer.Close ();
writer = null;
}
}
//this is almost the ToString method of MethodDefinition...
private string GetMethodParams (MethodDefinition method)
{
string @params = "(";
if (method.HasParameters) {
for (int i = 0; i < method.Parameters.Count; i++) {
if (i > 0)
@params += ",";
@params += method.Parameters [i].ParameterType.FullName;
}
}
@params += ")";
return @params;
}
SortedDictionary<TypeDefinition, IList> /*,List<IAnnotationProvider>>*/ ScanAssembly (AssemblyDefinition assembly)
{
if (Annotations.GetAction (assembly) != AssemblyAction.Link)
return null;
SortedDictionary<TypeDefinition, IList> members_used = new SortedDictionary<TypeDefinition, IList> (new TypeComparer ());
foreach (TypeDefinition type in assembly.MainModule.Types) {
IList used_providers = FilterPublicMembers (ScanType (type));
if (used_providers.Count > 0)
members_used [type] = used_providers;
else if (IsInternal (type, true) &&
Annotations.IsMarked (type))
throw new NotSupportedException (String.Format ("The type {0} is used while its API is not", type.ToString ()));
}
return members_used;
}
IList ScanType (TypeDefinition type)
{
return ExtractUsedProviders (type.Methods, type.Fields);
}
static IList FilterPublicMembers (IList members)
{
IList new_list = new ArrayList ();
foreach (MemberReference item in members)
if (IsInternal (item, true))
new_list.Add (item);
return new_list;
}
static string [] master_infos = Directory.GetFiles (Environment.CurrentDirectory, "*.info");
static string FindMasterInfoFile (string name)
{
if (master_infos.Length == 0)
throw new Exception ("No masterinfo files found in current directory");
foreach (string file in master_infos) {
if (file.EndsWith (name + ".info"))
return file;
}
return null;
}
const string xpath_init = "assemblies/assembly/namespaces/namespace[@name='{0}']/classes/class[@name='{1}']";
static string GetXPathSearchForType (TypeDefinition type)
{
TypeDefinition parent_type = type;
string xpath = String.Empty;
while (parent_type.DeclaringType != null) {
xpath = String.Format ("/classes/class[@name='{0}']", parent_type.Name) + xpath;
parent_type = parent_type.DeclaringType;
}
return String.Format (xpath_init, parent_type.Namespace, parent_type.Name) + xpath;
}
static bool IsInternal (MemberReference member, bool master_info)
{
TypeDefinition type = null;
string master_info_file = null;
if (member is TypeDefinition) {
type = member as TypeDefinition;
if (!master_info)
return (!type.IsNested && !type.IsPublic) ||
(type.IsNested && (!type.IsNestedPublic || IsInternal (type.DeclaringType, false)));
master_info_file = FindMasterInfoFile (type.Module.Assembly.Name.Name);
if (master_info_file == null)
return IsInternal (member, false);
return !NodeExists (master_info_file, GetXPathSearchForType (type));
}
type = member.DeclaringType.Resolve ();
if (IsInternal (type, master_info))
return true;
MethodDefinition method = member as MethodDefinition;
FieldDefinition field = member as FieldDefinition;
if (field == null && method == null)
throw new System.NotSupportedException ("Members to scan should be methods or fields");
if (!master_info) {
if (method != null)
return !method.IsPublic;
return !field.IsPublic;
}
master_info_file = FindMasterInfoFile (type.Module.Assembly.Name.Name);
if (master_info_file == null)
return IsInternal (member, false);
string xpath_type = GetXPathSearchForType (type);
string name;
if (field != null)
name = field.Name;
else {
name = method.ToString ();
//lame, I know...
name = WackyOutArgs (WackyCommas (name.Substring (name.IndexOf ("::") + 2)
.Replace ("/", "+") // nested classes
.Replace ('<', '[').Replace ('>', ']'))); //generic params
}
if (field != null || !IsPropertyMethod (method))
return !NodeExists (master_info_file, xpath_type + String.Format ("/*/*[@name='{0}']", name));
return !NodeExists (master_info_file, xpath_type + String.Format ("/properties/*/*/*[@name='{0}']", name));
}
//at some point I want to get rid of this method and ask cecil's maintainer to spew commas in a uniform way...
static string WackyCommas (string method)
{
string outstring = String.Empty;
bool square_bracket = false;
foreach (char c in method) {
if (c == '[')
square_bracket = true;
else if (c == ']')
square_bracket = false;
outstring = outstring + c;
if (c == ',' && !square_bracket)
outstring = outstring + " ";
}
return outstring;
}
//ToString() spews & but not 'out' keyword
static string WackyOutArgs (string method)
{
return Regex.Replace (method, @"\w+&", delegate (Match m) { return "out " + m.ToString (); });
}
//copied from MarkStep (violating DRY unless I can put this in a better place... Cecil?)
static bool IsPropertyMethod (MethodDefinition md)
{
return (md.SemanticsAttributes & MethodSemanticsAttributes.Getter) != 0 ||
(md.SemanticsAttributes & MethodSemanticsAttributes.Setter) != 0;
}
static Dictionary<string, XPathNavigator> navs = new Dictionary<string, XPathNavigator> ();
static List<FileStream> streams = new List<FileStream> ();
static bool NodeExists (string file, string xpath)
{
Console.Write (".");
//Console.WriteLine ("Looking for node {0} in file {1}", xpath, file.Substring (file.LastIndexOf ("/") + 1));
XPathNavigator nav = null;
if (!navs.TryGetValue (file, out nav)) {
FileStream stream = new FileStream (file, FileMode.Open);
XPathDocument document = new XPathDocument (stream);
nav = document.CreateNavigator ();
streams.Add (stream);
navs [file] = nav;
}
return nav.SelectSingleNode (xpath) != null;
}
IList /*List<IAnnotationProvider>*/ ExtractUsedProviders (params IList[] members)
{
IList used = new ArrayList ();
if (members == null || members.Length == 0)
return used;
foreach (IList members_list in members)
foreach (IMetadataTokenProvider provider in members_list)
if (Annotations.IsMarked (provider))
used.Add (provider);
return used;
}
class TypeComparer : IComparer <TypeDefinition> {
public int Compare (TypeDefinition x, TypeDefinition y)
{
return string.Compare (x.ToString (), y.ToString ());
}
}
}
}

View File

@@ -0,0 +1,179 @@
//
// MoonlightA11yProcessor.cs
//
// Author:
// Andrés G. Aragoneses (aaragoneses@novell.com)
//
// (C) 2009 Novell, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Linq;
using Mono.Cecil;
using Mono.Linker;
namespace Mono.Tuner {
public class MoonlightA11yProcessor : InjectSecurityAttributes {
protected override bool ConditionToProcess ()
{
return true;
}
protected override void ProcessAssembly (AssemblyDefinition assembly)
{
if (Annotations.GetAction (assembly) != AssemblyAction.Link)
return;
_assembly = assembly;
// remove existing [SecurityCritical] and [SecuritySafeCritical]
RemoveSecurityAttributes ();
// add [SecurityCritical]
AddSecurityAttributes ();
// convert all public members into internal
MakeApiInternal ();
}
void MakeApiInternal ()
{
foreach (TypeDefinition type in _assembly.MainModule.Types) {
if (type.IsPublic)
type.IsPublic = false;
if (type.HasMethods && !type.Name.EndsWith ("Adapter"))
foreach (MethodDefinition ctor in type.Methods.Where (m => m.IsConstructor))
if (ctor.IsPublic)
ctor.IsAssembly = true;
if (type.HasMethods)
foreach (MethodDefinition method in type.Methods.Where (m => !m.IsConstructor))
if (method.IsPublic)
method.IsAssembly = true;
}
}
void AddSecurityAttributes ()
{
foreach (TypeDefinition type in _assembly.MainModule.Types) {
AddCriticalAttribute (type);
if (type.HasMethods)
foreach (MethodDefinition ctor in type.Methods.Where (m => m.IsConstructor))
AddCriticalAttribute (ctor);
if (type.HasMethods)
foreach (MethodDefinition method in type.Methods.Where (m => !m.IsConstructor)) {
MethodDefinition parent = null;
//TODO: take in account generic params
if (!method.HasGenericParameters) {
/*
* we need to scan base methods because the CoreCLR complains about SC attribs added
* to overriden methods whose base (virtual or interface) method is not marked as SC
* with TypeLoadExceptions
*/
parent = GetBaseMethod (type, method);
}
//if there's no base method
if (parent == null ||
//if it's our bridge assembly, we're sure it will (finally, at the end of the linking process) have the SC attrib
_assembly.MainModule.Types.Contains (parent.DeclaringType) ||
//if the type is in the moonlight assemblies, check if it has the SC attrib
HasSecurityAttribute (parent, AttributeType.Critical))
AddCriticalAttribute (method);
}
}
}
MethodDefinition GetBaseMethod (TypeDefinition finalType, MethodDefinition final)
{
// both GetOverridenMethod and GetInterfaceMethod return null if there is no base method
return GetOverridenMethod (finalType, final) ?? GetInterfaceMethod (finalType, final);
}
//note: will not return abstract methods
MethodDefinition GetOverridenMethod (TypeDefinition finalType, MethodDefinition final)
{
TypeReference baseType = finalType.BaseType;
while (baseType != null && baseType.Resolve () != null) {
foreach (MethodDefinition method in baseType.Resolve ().Methods) {
if (!method.IsVirtual || method.Name != final.Name)
continue;
//TODO: should we discard them?
if (method.IsAbstract)
continue;
if (HasSameSignature (method, final))
return method;
}
baseType = baseType.Resolve().BaseType;
}
return null;
}
MethodDefinition GetInterfaceMethod (TypeDefinition finalType, MethodDefinition final)
{
TypeDefinition baseType = finalType;
while (baseType != null) {
if (baseType.HasInterfaces)
foreach (var @interface in baseType.Interfaces)
foreach (MethodDefinition method in @interface.InterfaceType.Resolve ().Methods)
if (method.Name == final.Name && HasSameSignature (method, final))
return method;
baseType = baseType.BaseType == null ? null : baseType.BaseType.Resolve ();
}
return null;
}
bool HasSameSignature (MethodDefinition method1, MethodDefinition method2)
{
if (method1.ReturnType.FullName != method2.ReturnType.FullName)
return false;
if (method1.Parameters.Count != method2.Parameters.Count)
return false;
for (int i = 0; i < method1.Parameters.Count; i++) {
if (method1.Parameters [i].ParameterType.FullName !=
method2.Parameters [i].ParameterType.FullName)
return false;
}
return true;
}
}
}

View File

@@ -0,0 +1,52 @@
//
// MoonlightA11yUsageInspectionStep.cs
//
// Author:
// Andrés G. Aragoneses (aaragoneses@novell.com)
//
// (C) 2009 Novell, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections;
using System.IO;
using Mono.Linker;
using Mono.Linker.Steps;
using Mono.Cecil;
namespace Mono.Tuner {
public class MoonlightA11yUsageInspectionStep : MoonlightAssemblyStep {
protected override void CustomizePipeline (Pipeline pipeline)
{
pipeline.ReplaceStep (typeof (MarkStep), new MoonlightA11yApiMarker ());
pipeline.ReplaceStep (typeof (SweepStep), new MoonlightA11yDescriptorGenerator ());
pipeline.RemoveStep (typeof (LoadI18nAssemblies));
pipeline.RemoveStep (typeof (CleanStep));
pipeline.RemoveStep (typeof (RegenerateGuidStep));
pipeline.RemoveStep (typeof (OutputStep));
}
}
}

View File

@@ -0,0 +1,66 @@
//
// MoonlightAssemblyStep.cs
//
// Author:
// Jb Evain (jbevain@novell.com)
//
// (C) 2009 Novell, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections;
using System.IO;
using Mono.Linker;
using Mono.Linker.Steps;
using Mono.Cecil;
namespace Mono.Tuner {
public class MoonlightAssemblyStep : IStep {
public void Process (LinkContext context)
{
CustomizePipeline (context.Pipeline);
ProcessAssemblies (context);
}
static void ProcessAssemblies (LinkContext context)
{
foreach (AssemblyDefinition assembly in context.GetAssemblies ())
context.Annotations.SetAction (assembly, AssemblyAction.Link);
}
protected virtual void CustomizePipeline (Pipeline pipeline)
{
pipeline.RemoveStep (typeof (LoadI18nAssemblies));
pipeline.RemoveStep (typeof (BlacklistStep));
pipeline.RemoveStep (typeof (TypeMapStep));
pipeline.RemoveStep (typeof (MarkStep));
pipeline.RemoveStep (typeof (SweepStep));
pipeline.RemoveStep (typeof (CleanStep));
pipeline.RemoveStep (typeof (RegenerateGuidStep));
pipeline.AddStepBefore (typeof (OutputStep), new InjectSecurityAttributes ());
}
}
}

View File

@@ -0,0 +1,122 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Mono.Linker;
using Mono.Linker.Steps;
using Mono.Cecil;
using Mono.Cecil.Cil;
namespace Mono.Tuner {
public class PreserveCrypto : IStep {
AnnotationStore annotations;
public void Process (LinkContext context)
{
annotations = context.Annotations;
ProcessCorlib (context);
ProcessSystemCore (context);
}
void ProcessCorlib (LinkContext context)
{
AssemblyDefinition corlib;
if (!context.TryGetLinkedAssembly ("mscorlib", out corlib))
return;
AddPreserveInfo (corlib, "DES", "DESCryptoServiceProvider");
AddPreserveInfo (corlib, "DSA", "DSACryptoServiceProvider");
AddPreserveInfo (corlib, "RandomNumberGenerator", "RNGCryptoServiceProvider");
AddPreserveInfo (corlib, "SHA1", "SHA1CryptoServiceProvider");
AddPreserveInfo (corlib, "SHA1", "SHA1Managed");
AddPreserveInfo (corlib, "MD5", "MD5CryptoServiceProvider");
AddPreserveInfo (corlib, "RC2", "RC2CryptoServiceProvider");
AddPreserveInfo (corlib, "TripleDES", "TripleDESCryptoServiceProvider");
AddPreserveInfo (corlib, "Rijndael", "RijndaelManaged");
AddPreserveInfo (corlib, "RIPEMD160", "RIPEMD160Managed");
AddPreserveInfo (corlib, "SHA256", "SHA256Managed");
AddPreserveInfo (corlib, "SHA384", "SHA384Managed");
AddPreserveInfo (corlib, "SHA512", "SHA512Managed");
AddPreserveInfo (corlib, "HMAC", "HMACMD5");
AddPreserveInfo (corlib, "HMAC", "HMACRIPEMD160");
AddPreserveInfo (corlib, "HMAC", "HMACSHA1");
AddPreserveInfo (corlib, "HMAC", "HMACSHA256");
AddPreserveInfo (corlib, "HMAC", "HMACSHA384");
AddPreserveInfo (corlib, "HMAC", "HMACSHA512");
AddPreserveInfo (corlib, "HMACMD5", "MD5CryptoServiceProvider");
AddPreserveInfo (corlib, "HMACRIPEMD160", "RIPEMD160Managed");
AddPreserveInfo (corlib, "HMACSHA1", "SHA1CryptoServiceProvider");
AddPreserveInfo (corlib, "HMACSHA1", "SHA1Managed");
AddPreserveInfo (corlib, "HMACSHA256", "SHA256Managed");
AddPreserveInfo (corlib, "HMACSHA384", "SHA384Managed");
AddPreserveInfo (corlib, "HMACSHA512", "SHA512Managed");
TryAddPreserveInfo (corlib, "Aes", "AesManaged");
var corlibAes = GetCryptoType (corlib, "Aes");
Preserve (corlibAes, GetCryptoType (corlib, "AesManaged"));
AssemblyDefinition syscore;
if (context.TryGetLinkedAssembly ("System.Core", out syscore))
Preserve (corlibAes, GetCryptoType (syscore, "AesCryptoServiceProvider"));
}
void ProcessSystemCore (LinkContext context)
{
AssemblyDefinition syscore;
if (!context.TryGetLinkedAssembly ("System.Core", out syscore))
return;
// AddPreserveInfo (syscore, "Aes", "AesCryptoServiceProvider");
TryAddPreserveInfo (syscore, "Aes", "AesManaged");
}
bool TryAddPreserveInfo (AssemblyDefinition assembly, string name, string type)
{
var marker = GetCryptoType (assembly, name);
if (marker == null)
return false;
var implementation = GetCryptoType (assembly, type);
if (implementation == null)
return false;
Preserve (marker, implementation);
return true;
}
void AddPreserveInfo (AssemblyDefinition assembly, string name, string type)
{
var marker = GetCryptoType (assembly, name);
if (marker == null)
throw new ArgumentException (name);
var implementation = GetCryptoType (assembly, type);
if (implementation == null)
throw new ArgumentException (type);
Preserve (marker, implementation);
}
void Preserve (TypeDefinition marker, TypeDefinition implementation)
{
if (marker == null || implementation == null)
return;
foreach (var constructor in implementation.GetConstructors ())
annotations.AddPreservedMethod (marker, constructor);
}
TypeDefinition GetCryptoType (AssemblyDefinition assembly, string name)
{
return assembly.MainModule.GetType ("System.Security.Cryptography." + name);
}
}
}

View File

@@ -0,0 +1,83 @@
using System;
using System.IO;
using System.Xml.XPath;
using Mono.Linker;
using Mono.Linker.Steps;
using Mono.Cecil;
namespace Mono.Tuner {
public class PreserveHttps : BaseStep {
static string [] types = new [] {
"System.Net.WebRequest",
"System.Net.WebClient",
"System.Net.Security.RemoteCertificateValidationCallback",
"System.Web.Services.Protocols.WebClientProtocol",
"System.Security.Cryptography.X509Certificates.X509Certificate",
"System.ServiceModel.ClientBase`1",
"System.Web.Services.WebServiceBindingAttribute",
"System.Web.Services.Protocols.SoapHttpClientProtocol",
"System.Xml.XmlDocument"
};
bool need_https;
protected override void ProcessAssembly (AssemblyDefinition assembly)
{
if (need_https)
return;
if (Profile.IsSdkAssembly (assembly) || Profile.IsProductAssembly (assembly))
return;
if (HasNeededReference (assembly.MainModule))
need_https = true;
}
static bool HasNeededReference (ModuleDefinition module)
{
foreach (var type in types)
if (module.HasTypeReference (type))
return true;
return false;
}
protected override void EndProcess ()
{
if (!need_https)
return;
var mono_security = Context.Resolve ("Mono.Security");
if (mono_security == null)
return;
if (Annotations.GetAction (mono_security) != AssemblyAction.Link)
return;
var xml_preserve = CreatePreserveStep ();
Context.Pipeline.AddStepAfter (typeof (PreserveHttps), xml_preserve);
// Context.Pipeline.AddStepAfter (xml_preserve, new PreserveCrypto ());
}
static IStep CreatePreserveStep ()
{
return new ResolveFromXmlStep (
new XPathDocument (
new StringReader (descriptor)));
}
const string descriptor = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
<linker>
<assembly fullname=""Mono.Security"">
<type fullname=""Mono.Security.Protocol.Tls.HttpsClientStream"" />
<type fullname=""Mono.Security.Protocol.Tls.SslClientStream"" />
<type fullname=""Mono.Security.Protocol.Tls.SslStreamBase"" />
</assembly>
</linker>
";
}
}

Some files were not shown because too many files have changed in this diff Show More