You've already forked linux-packaging-mono
Imported Upstream version 6.12.0.86
Former-commit-id: 7a84ce7d08c42c458ac8e74b27186ca863315d79
This commit is contained in:
parent
92747312ea
commit
0b380204a4
@@ -1,18 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="$(MSBuildThisFileDirectory)../../eng/Versions.props" Condition=" '$(ArcadeBuild)' != 'true' " />
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netcoreapp2.0;net472</TargetFrameworks>
|
||||
<TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netcoreapp2.0</TargetFrameworks>
|
||||
<TargetFrameworks>netcoreapp3.0;net472</TargetFrameworks>
|
||||
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
|
||||
<BaseOutputPath>bin/</BaseOutputPath>
|
||||
<PackageOutputPath>$(BaseOutputPath)nupkgs</PackageOutputPath>
|
||||
<IsPackable>true</IsPackable>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<Description>MSBuild tasks for running the IL Linker</Description>
|
||||
<Authors>$(AssemblyName)</Authors>
|
||||
<!-- Don't include the build output. Instead, we want to include
|
||||
the TargetFramework-specific publish output. -->
|
||||
<IncludeBuildOutput>false</IncludeBuildOutput>
|
||||
<!-- Suppress NuGet warning for package which sets IncludeBuildOutput=false, see https://github.com/NuGet/Home/issues/8583 -->
|
||||
<NoWarn>$(NoWarn);NU5128</NoWarn>
|
||||
<!-- We want to package the tasks package together with its
|
||||
transitive dependencies and the linker, without marking them
|
||||
as dependencies in the tasks package.
|
||||
@@ -78,11 +75,8 @@
|
||||
</Target>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../linker/Mono.Linker.csproj"
|
||||
PrivateAssets="All"
|
||||
Condition=" '$(TargetFramework)' == 'netcoreapp2.0' " />
|
||||
<ProjectReference Include="../../external/cecil/Mono.Cecil.csproj"
|
||||
PrivateAssets="All" />
|
||||
<ProjectReference Include="../linker/Mono.Linker.csproj" PrivateAssets="All" />
|
||||
<ProjectReference Include="../../external/cecil/Mono.Cecil.csproj" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -90,16 +84,10 @@
|
||||
<!-- We use private assets for the Microsoft.Build packages to
|
||||
prevent them from being published with the tasks dll, because
|
||||
these are already a part of the SDK. -->
|
||||
<PackageReference Include="Microsoft.Build.Framework" Version="$(MicrosoftBuildFrameworkVersion)"
|
||||
PrivateAssets="All"
|
||||
ExcludeAssets="Runtime" />
|
||||
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="$(MicrosoftBuildUtilitiesCoreVersion)"
|
||||
PrivateAssets="All"
|
||||
ExcludeAssets="Runtime" />
|
||||
<PackageReference Include="System.Reflection.Metadata" Version="$(SystemReflectionMetadataVersion)"
|
||||
Condition=" '$(TargetFramework)' == 'net472' "
|
||||
PrivateAssets="All"
|
||||
Publish="True" />
|
||||
<PackageReference Include="Microsoft.Build.Framework" Version="$(MicrosoftBuildFrameworkVersion)" PrivateAssets="All" ExcludeAssets="Runtime" />
|
||||
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="$(MicrosoftBuildUtilitiesCoreVersion)" PrivateAssets="All" ExcludeAssets="Runtime" />
|
||||
<PackageReference Include="System.Reflection.Metadata" Version="$(SystemReflectionMetadataVersion)" Condition=" '$(TargetFramework)' == 'net472' " PrivateAssets="All" Publish="True" />
|
||||
|
||||
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" PrivateAssets="All" Version="1.0.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<_LinkTaskDirectoryRoot>$(MSBuildThisFileDirectory)../tools/</_LinkTaskDirectoryRoot>
|
||||
<_LinkTaskTFM Condition=" '$(MSBuildRuntimeType)' == 'Core' ">netcoreapp2.0</_LinkTaskTFM>
|
||||
<_LinkTaskTFM Condition=" '$(MSBuildRuntimeType)' == 'Core' ">netcoreapp3.0</_LinkTaskTFM>
|
||||
<_LinkTaskTFM Condition=" '$(_LinkTaskTFM)' == '' ">net46</_LinkTaskTFM>
|
||||
<_LinkTaskDirectory>$(_LinkTaskDirectoryRoot)$(_LinkTaskTFM)/</_LinkTaskDirectory>
|
||||
<LinkTaskDllPath Condition=" '$(LinkTaskDllPath)' == '' ">$(_LinkTaskDirectory)ILLink.Tasks.dll</LinkTaskDllPath>
|
||||
|
||||
2
external/linker/src/ILLink.Tasks/LinkTask.cs
vendored
2
external/linker/src/ILLink.Tasks/LinkTask.cs
vendored
@@ -111,7 +111,7 @@ namespace ILLink.Tasks
|
||||
|
||||
var taskDirectory = Path.GetDirectoryName (Assembly.GetExecutingAssembly ().Location);
|
||||
// The linker always runs on .NET Core, even when using desktop MSBuild to host ILLink.Tasks.
|
||||
_illinkPath = Path.Combine (Path.GetDirectoryName (taskDirectory), "netcoreapp2.0", "illink.dll");
|
||||
_illinkPath = Path.Combine (Path.GetDirectoryName (taskDirectory), "netcoreapp3.0", "illink.dll");
|
||||
return _illinkPath;
|
||||
}
|
||||
set => _illinkPath = value;
|
||||
|
||||
@@ -13,7 +13,7 @@ Copyright (c) .NET Foundation. All rights reserved.
|
||||
|
||||
<PropertyGroup>
|
||||
<_ILLinkTasksDirectoryRoot Condition=" '$(_ILLinkTasksDirectoryRoot)' == '' ">$(MSBuildThisFileDirectory)../tools/</_ILLinkTasksDirectoryRoot>
|
||||
<_ILLinkTasksTFM Condition=" '$(MSBuildRuntimeType)' == 'Core' ">netcoreapp2.0</_ILLinkTasksTFM>
|
||||
<_ILLinkTasksTFM Condition=" '$(MSBuildRuntimeType)' == 'Core' ">netcoreapp3.0</_ILLinkTasksTFM>
|
||||
<_ILLinkTasksTFM Condition=" '$(_ILLinkTasksTFM)' == '' ">net472</_ILLinkTasksTFM>
|
||||
<_ILLinkTasksDirectory>$(_ILLinkTasksDirectoryRoot)$(_ILLinkTasksTFM)/</_ILLinkTasksDirectory>
|
||||
<ILLinkTasksAssembly Condition=" '$(ILLinkTasksAssembly)' == '' ">$(_ILLinkTasksDirectory)ILLink.Tasks.dll</ILLinkTasksAssembly>
|
||||
|
||||
60
external/linker/src/analyzer/analyzer.csproj
vendored
60
external/linker/src/analyzer/analyzer.csproj
vendored
@@ -1,49 +1,37 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||
<ProjectGuid>{4F328B3E-39C1-4E48-8093-F24390C58A5E}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>LinkerAnalyzer</RootNamespace>
|
||||
<AssemblyName>illinkanalyzer</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
|
||||
<Configurations>Debug;Release</Configurations>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug</OutputPath>
|
||||
<DefineConstants>DEBUG;</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<ExternalConsole>true</ExternalConsole>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
|
||||
<PropertyGroup Condition="'$(MonoBuild)' == ''">
|
||||
<DefineConstants>$(DefineConstants);FEATURE_ILLINK</DefineConstants>
|
||||
<TargetFrameworks>netcoreapp3.0;net471</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release</OutputPath>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<ExternalConsole>true</ExternalConsole>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
|
||||
<PropertyGroup Condition="'$(MonoBuild)' != ''">
|
||||
<TargetFrameworks>net471</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
|
||||
<DebugSymbols Condition="'$(DebugSymbols)' == ''">true</DebugSymbols>
|
||||
<Optimize Condition="'$(Optimize)' == ''">false</Optimize>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
||||
<Optimize Condition="'$(Optimize)' == ''">true</Optimize>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Xml" />
|
||||
<ProjectReference Include="../../external/cecil/Mono.Cecil.csproj">
|
||||
<Project>{D68133BD-1E63-496E-9EDE-4FBDBF77B486}</Project>
|
||||
<Name>Mono.Cecil</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ConsoleDependencyGraph.cs" />
|
||||
<Compile Include="Main.cs" />
|
||||
<Compile Include="LinkerAnalyzerCore\DependencyGraph.cs" />
|
||||
<Compile Include="LinkerAnalyzerCore\SpaceAnalyzer.cs" />
|
||||
<Compile Include="common\Mono.Options\Options.cs">
|
||||
<Link>Options.cs</Link>
|
||||
</Compile>
|
||||
|
||||
<ItemGroup Condition="'$(MonoBuild)' == ''">
|
||||
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" PrivateAssets="All" Version="1.0.0" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
|
||||
</Project>
|
||||
@@ -46,11 +46,11 @@ namespace Mono.Linker.Steps {
|
||||
continue;
|
||||
|
||||
try {
|
||||
Context.LogMessage ("Processing resource linker descriptor: {0}", name);
|
||||
Context.LogMessage ($"Processing resource linker descriptor: {name}");
|
||||
AddToPipeline (GetResolveStep (name));
|
||||
} catch (XmlException ex) {
|
||||
/* This could happen if some broken XML file is included. */
|
||||
Context.LogMessage ("Error processing {0}: {1}", name, ex);
|
||||
Context.LogMessage ($"Error processing {name}: {ex}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,12 +62,12 @@ namespace Mono.Linker.Steps {
|
||||
.Where (res => ShouldProcessAssemblyResource (GetAssemblyName (res.Name)))
|
||||
.Cast<EmbeddedResource> ()) {
|
||||
try {
|
||||
Context.LogMessage ("Processing embedded resource linker descriptor: {0}", rsc.Name);
|
||||
Context.LogMessage ($"Processing embedded resource linker descriptor: {rsc.Name}");
|
||||
|
||||
AddToPipeline (GetExternalResolveStep (rsc, asm));
|
||||
} catch (XmlException ex) {
|
||||
/* This could happen if some broken XML file is embedded. */
|
||||
Context.LogMessage ("Error processing {0}: {1}", rsc.Name, ex);
|
||||
Context.LogMessage ($"Error processing {rsc.Name}: {ex}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -127,14 +127,14 @@ namespace Mono.Linker.Steps {
|
||||
protected static XPathDocument GetExternalDescriptor (EmbeddedResource resource)
|
||||
{
|
||||
using (var sr = new StreamReader (resource.GetResourceStream ())) {
|
||||
return new XPathDocument (new StringReader (sr.ReadToEnd ()));
|
||||
return new XPathDocument (sr);
|
||||
}
|
||||
}
|
||||
|
||||
static XPathDocument GetDescriptor (string descriptor)
|
||||
{
|
||||
using (StreamReader sr = new StreamReader (GetResource (descriptor))) {
|
||||
return new XPathDocument (new StringReader (sr.ReadToEnd ()));
|
||||
return new XPathDocument (sr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
310
external/linker/src/linker/Linker.Steps/BodySubstituterStep.cs
vendored
Normal file
310
external/linker/src/linker/Linker.Steps/BodySubstituterStep.cs
vendored
Normal file
@@ -0,0 +1,310 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Globalization;
|
||||
using System.Xml.XPath;
|
||||
using Mono.Cecil;
|
||||
|
||||
namespace Mono.Linker.Steps
|
||||
{
|
||||
public class BodySubstituterStep : BaseStep
|
||||
{
|
||||
protected override void Process ()
|
||||
{
|
||||
var files = Context.Substitutions;
|
||||
if (files == null)
|
||||
return;
|
||||
|
||||
foreach (var file in files) {
|
||||
try {
|
||||
ReadSubstitutionFile (GetSubstitutions (file));
|
||||
} catch (Exception ex) when (!(ex is XmlResolutionException)) {
|
||||
throw new XmlResolutionException ($"Failed to process XML substitution '{file}'", ex);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static XPathDocument GetSubstitutions (string substitutionsFile)
|
||||
{
|
||||
using (FileStream fs = File.OpenRead (substitutionsFile)) {
|
||||
return GetSubstitutions (fs);
|
||||
}
|
||||
}
|
||||
|
||||
static XPathDocument GetSubstitutions (Stream substitutions)
|
||||
{
|
||||
using (StreamReader sr = new StreamReader (substitutions)) {
|
||||
return new XPathDocument (sr);
|
||||
}
|
||||
}
|
||||
|
||||
void ReadSubstitutionFile (XPathDocument document)
|
||||
{
|
||||
XPathNavigator nav = document.CreateNavigator ();
|
||||
|
||||
// Initial structure check
|
||||
if (!nav.MoveToChild ("linker", ""))
|
||||
return;
|
||||
|
||||
// TODO: Add handling for feature
|
||||
|
||||
ProcessAssemblies (nav.SelectChildren ("assembly", ""));
|
||||
}
|
||||
|
||||
void ProcessAssemblies (XPathNodeIterator iterator)
|
||||
{
|
||||
while (iterator.MoveNext ()) {
|
||||
var name = GetAssemblyName (iterator.Current);
|
||||
|
||||
var cache = Context.Resolver.AssemblyCache;
|
||||
|
||||
if (!cache.TryGetValue (name.Name, out AssemblyDefinition assembly)) {
|
||||
Context.LogMessage (MessageImportance.Low, $"Could not match assembly '{name.FullName}' for substitution");
|
||||
continue;
|
||||
}
|
||||
|
||||
ProcessAssembly (assembly, iterator);
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessAssembly (AssemblyDefinition assembly, XPathNodeIterator iterator)
|
||||
{
|
||||
ProcessTypes (assembly, iterator.Current.SelectChildren ("type", ""));
|
||||
}
|
||||
|
||||
void ProcessTypes (AssemblyDefinition assembly, XPathNodeIterator iterator)
|
||||
{
|
||||
while (iterator.MoveNext ()) {
|
||||
XPathNavigator nav = iterator.Current;
|
||||
|
||||
string fullname = GetAttribute (nav, "fullname");
|
||||
|
||||
TypeDefinition type = assembly.MainModule.GetType (fullname);
|
||||
|
||||
if (type == null) {
|
||||
Context.LogMessage (MessageImportance.Low, $"Could not resolve type '{fullname}' for substitution");
|
||||
continue;
|
||||
}
|
||||
|
||||
ProcessType (type, nav);
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessType (TypeDefinition type, XPathNavigator nav)
|
||||
{
|
||||
if (!nav.HasChildren)
|
||||
return;
|
||||
|
||||
XPathNodeIterator methods = nav.SelectChildren ("method", "");
|
||||
if (methods.Count > 0)
|
||||
ProcessMethods (type, methods);
|
||||
|
||||
var fields = nav.SelectChildren ("field", "");
|
||||
if (fields.Count > 0) {
|
||||
while (fields.MoveNext ())
|
||||
ProcessField (type, fields);
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessMethods (TypeDefinition type, XPathNodeIterator iterator)
|
||||
{
|
||||
while (iterator.MoveNext ())
|
||||
ProcessMethod (type, iterator);
|
||||
}
|
||||
|
||||
void ProcessMethod (TypeDefinition type, XPathNodeIterator iterator)
|
||||
{
|
||||
string signature = GetAttribute (iterator.Current, "signature");
|
||||
if (string.IsNullOrEmpty (signature))
|
||||
return;
|
||||
|
||||
MethodDefinition method = FindMethod (type, signature);
|
||||
if (method == null) {
|
||||
Context.LogMessage (MessageImportance.Normal, $"Could not find method '{signature}' for substitution");
|
||||
return;
|
||||
}
|
||||
|
||||
string action = GetAttribute (iterator.Current, "body");
|
||||
switch (action) {
|
||||
case "remove":
|
||||
Annotations.SetAction (method, MethodAction.ConvertToThrow);
|
||||
return;
|
||||
case "stub":
|
||||
string value = GetAttribute (iterator.Current, "value");
|
||||
if (value != "") {
|
||||
if (!TryConvertValue (value, method.ReturnType, out object res)) {
|
||||
Context.LogMessage (MessageImportance.High, $"Invalid value for '{signature}' stub");
|
||||
return;
|
||||
}
|
||||
|
||||
Annotations.SetMethodStubValue (method, res);
|
||||
}
|
||||
|
||||
Annotations.SetAction (method, MethodAction.ConvertToStub);
|
||||
return;
|
||||
default:
|
||||
Context.LogMessage (MessageImportance.High, $"Unknown body modification '{action}' for '{signature}'");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessField (TypeDefinition type, XPathNodeIterator iterator)
|
||||
{
|
||||
string name = GetAttribute (iterator.Current, "name");
|
||||
if (string.IsNullOrEmpty (name))
|
||||
return;
|
||||
|
||||
var field = type.Fields.FirstOrDefault (f => f.Name == name);
|
||||
if (field == null) {
|
||||
Context.LogMessage (MessageImportance.Normal, $"Could not find field '{name}' for substitution.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!field.IsStatic || field.IsLiteral) {
|
||||
Context.LogMessage (MessageImportance.Normal, $"Substituted field '{name}' needs to be static field.");
|
||||
return;
|
||||
}
|
||||
|
||||
string value = GetAttribute (iterator.Current, "value");
|
||||
if (string.IsNullOrEmpty (value)) {
|
||||
Context.LogMessage (MessageImportance.High, $"Missing 'value' attribute for field '{field}'.");
|
||||
return;
|
||||
}
|
||||
if (!TryConvertValue (value, field.FieldType, out object res)) {
|
||||
Context.LogMessage (MessageImportance.High, $"Invalid value for '{field}': '{value}'.");
|
||||
return;
|
||||
}
|
||||
|
||||
Annotations.SetFieldValue (field, res);
|
||||
|
||||
string init = GetAttribute (iterator.Current, "initialize");
|
||||
if (init?.ToLowerInvariant () == "true") {
|
||||
Annotations.SetSubstitutedInit (field);
|
||||
}
|
||||
}
|
||||
|
||||
static bool TryConvertValue (string value, TypeReference target, out object result)
|
||||
{
|
||||
switch (target.MetadataType) {
|
||||
case MetadataType.Boolean:
|
||||
if (bool.TryParse (value, out bool bvalue)) {
|
||||
result = bvalue ? 1 : 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
goto case MetadataType.Int32;
|
||||
|
||||
case MetadataType.Byte:
|
||||
if (!byte.TryParse (value, NumberStyles.Integer, CultureInfo.InvariantCulture, out byte byteresult))
|
||||
break;
|
||||
|
||||
result = (int) byteresult;
|
||||
return true;
|
||||
|
||||
case MetadataType.SByte:
|
||||
if (!sbyte.TryParse (value, NumberStyles.Integer, CultureInfo.InvariantCulture, out sbyte sbyteresult))
|
||||
break;
|
||||
|
||||
result = (int) sbyteresult;
|
||||
return true;
|
||||
|
||||
case MetadataType.Int16:
|
||||
if (!short.TryParse (value, NumberStyles.Integer, CultureInfo.InvariantCulture, out short shortresult))
|
||||
break;
|
||||
|
||||
result = (int) shortresult;
|
||||
return true;
|
||||
|
||||
case MetadataType.UInt16:
|
||||
if (!ushort.TryParse (value, NumberStyles.Integer, CultureInfo.InvariantCulture, out ushort ushortresult))
|
||||
break;
|
||||
|
||||
result = (int) ushortresult;
|
||||
return true;
|
||||
|
||||
case MetadataType.Int32:
|
||||
if (!int.TryParse (value, NumberStyles.Integer, CultureInfo.InvariantCulture, out int iresult))
|
||||
break;
|
||||
|
||||
result = iresult;
|
||||
return true;
|
||||
|
||||
case MetadataType.UInt32:
|
||||
if (!uint.TryParse (value, NumberStyles.Integer, CultureInfo.InvariantCulture, out uint uresult))
|
||||
break;
|
||||
|
||||
result = (int)uresult;
|
||||
return true;
|
||||
|
||||
case MetadataType.Double:
|
||||
if (!double.TryParse (value, NumberStyles.Float, CultureInfo.InvariantCulture, out double dresult))
|
||||
break;
|
||||
|
||||
result = dresult;
|
||||
return true;
|
||||
|
||||
case MetadataType.Single:
|
||||
if (!float.TryParse (value, NumberStyles.Float, CultureInfo.InvariantCulture, out float fresult))
|
||||
break;
|
||||
|
||||
result = fresult;
|
||||
return true;
|
||||
|
||||
case MetadataType.Int64:
|
||||
if (!long.TryParse (value, NumberStyles.Integer, CultureInfo.InvariantCulture, out long lresult))
|
||||
break;
|
||||
|
||||
result = lresult;
|
||||
return true;
|
||||
|
||||
case MetadataType.UInt64:
|
||||
if (!ulong.TryParse (value, NumberStyles.Integer, CultureInfo.InvariantCulture, out ulong ulresult))
|
||||
break;
|
||||
|
||||
result = (long)ulresult;
|
||||
return true;
|
||||
|
||||
case MetadataType.Char:
|
||||
if (!char.TryParse (value, out char chresult))
|
||||
break;
|
||||
|
||||
result = (int) chresult;
|
||||
return true;
|
||||
|
||||
case MetadataType.String:
|
||||
if (value is string || value == null) {
|
||||
result = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
result = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
static MethodDefinition FindMethod (TypeDefinition type, string signature)
|
||||
{
|
||||
if (!type.HasMethods)
|
||||
return null;
|
||||
|
||||
foreach (MethodDefinition meth in type.Methods)
|
||||
if (signature == ResolveFromXmlStep.GetMethodSignature (meth, includeGenericParameters: true))
|
||||
return meth;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static AssemblyNameReference GetAssemblyName (XPathNavigator nav)
|
||||
{
|
||||
return AssemblyNameReference.Parse (GetAttribute (nav, "fullname"));
|
||||
}
|
||||
|
||||
static string GetAttribute (XPathNavigator nav, string attribute)
|
||||
{
|
||||
return nav.GetAttribute (attribute, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
@@ -26,10 +27,65 @@ namespace Mono.Linker.Steps {
|
||||
ProcessMethod (method);
|
||||
}
|
||||
|
||||
if (type.HasFields && Annotations.HasSubstitutedInit (type)) {
|
||||
AddFieldsInitializations (type);
|
||||
}
|
||||
|
||||
foreach (var nested in type.NestedTypes)
|
||||
ProcessType (nested);
|
||||
}
|
||||
|
||||
void AddFieldsInitializations (TypeDefinition type)
|
||||
{
|
||||
Instruction ret;
|
||||
ILProcessor processor;
|
||||
|
||||
var cctor = type.Methods.FirstOrDefault (MethodDefinitionExtensions.IsStaticConstructor);
|
||||
if (cctor == null) {
|
||||
type.Attributes |= TypeAttributes.BeforeFieldInit;
|
||||
|
||||
var method = new MethodDefinition (".cctor",
|
||||
MethodAttributes.Static | MethodAttributes.Private | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName | MethodAttributes.HideBySig,
|
||||
assembly.MainModule.TypeSystem.Void);
|
||||
|
||||
type.Methods.Add (method);
|
||||
|
||||
processor = method.Body.GetILProcessor ();
|
||||
ret = Instruction.Create (OpCodes.Ret);
|
||||
processor.Append (ret);
|
||||
} else {
|
||||
ret = cctor.Body.Instructions.Last (l => l.OpCode.Code == Code.Ret);
|
||||
var body = cctor.Body;
|
||||
processor = cctor.Body.GetILProcessor ();
|
||||
|
||||
for (int i = 0; i < body.Instructions.Count; ++i) {
|
||||
var instr = body.Instructions [i];
|
||||
if (instr.OpCode.Code != Code.Stsfld)
|
||||
continue;
|
||||
|
||||
var field = (FieldReference)instr.Operand;
|
||||
if (!Annotations.HasSubstitutedInit (field.Resolve ()))
|
||||
continue;
|
||||
|
||||
processor.Replace (instr, Instruction.Create (OpCodes.Pop));
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var field in type.Fields) {
|
||||
if (!Annotations.HasSubstitutedInit (field))
|
||||
continue;
|
||||
|
||||
Context.Annotations.TryGetFieldUserValue (field, out object value);
|
||||
|
||||
var valueInstr = CreateConstantResultInstruction (field.FieldType, value);
|
||||
if (valueInstr == null)
|
||||
throw new NotImplementedException (field.FieldType.ToString ());
|
||||
|
||||
processor.InsertBefore (ret, valueInstr);
|
||||
processor.InsertBefore (ret, Instruction.Create (OpCodes.Stsfld, field));
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessMethod (MethodDefinition method)
|
||||
{
|
||||
switch (Annotations.GetAction (method)) {
|
||||
@@ -39,9 +95,6 @@ namespace Mono.Linker.Steps {
|
||||
case MethodAction.ConvertToThrow:
|
||||
RewriteBodyToLinkedAway (method);
|
||||
break;
|
||||
case MethodAction.ConvertToFalse:
|
||||
RewriteBodyToFalse (method);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,28 +118,28 @@ namespace Mono.Linker.Steps {
|
||||
method.ClearDebugInformation();
|
||||
}
|
||||
|
||||
protected virtual void RewriteBodyToFalse (MethodDefinition method)
|
||||
{
|
||||
if (!method.IsIL)
|
||||
throw new NotImplementedException ();
|
||||
|
||||
method.Body = CreateReturnFalseBody (method);
|
||||
|
||||
method.ClearDebugInformation();
|
||||
}
|
||||
|
||||
MethodBody CreateThrowLinkedAwayBody (MethodDefinition method)
|
||||
{
|
||||
var body = new MethodBody (method);
|
||||
var il = body.GetILProcessor ();
|
||||
MethodReference ctor;
|
||||
|
||||
// Makes the body verifiable
|
||||
if (method.IsConstructor && !method.DeclaringType.IsValueType) {
|
||||
ctor = assembly.MainModule.ImportReference (Context.MarkedKnownMembers.ObjectCtor);
|
||||
|
||||
il.Emit (OpCodes.Ldarg_0);
|
||||
il.Emit (OpCodes.Call, ctor);
|
||||
}
|
||||
|
||||
// import the method into the current assembly
|
||||
MethodReference ctor = Context.MarkedKnownMembers.NotSupportedExceptionCtorString;
|
||||
ctor = Context.MarkedKnownMembers.NotSupportedExceptionCtorString;
|
||||
ctor = assembly.MainModule.ImportReference (ctor);
|
||||
|
||||
il.Emit (OpCodes.Ldstr, "Linked away");
|
||||
il.Emit (OpCodes.Newobj, ctor);
|
||||
il.Emit (OpCodes.Throw);
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
@@ -98,8 +151,11 @@ namespace Mono.Linker.Steps {
|
||||
throw new NotImplementedException ();
|
||||
|
||||
var il = body.GetILProcessor ();
|
||||
if (method.IsInstanceConstructor ()) {
|
||||
if (method.IsInstanceConstructor () && !method.DeclaringType.IsValueType) {
|
||||
var base_ctor = method.DeclaringType.BaseType.GetDefaultInstanceConstructor();
|
||||
if (base_ctor == null)
|
||||
throw new NotSupportedException ($"Cannot replace constructor for '{method.DeclaringType}' when no base default constructor exists");
|
||||
|
||||
base_ctor = assembly.MainModule.ImportReference (base_ctor);
|
||||
|
||||
il.Emit (OpCodes.Ldarg_0);
|
||||
@@ -109,27 +165,114 @@ namespace Mono.Linker.Steps {
|
||||
switch (method.ReturnType.MetadataType) {
|
||||
case MetadataType.Void:
|
||||
break;
|
||||
case MetadataType.Boolean:
|
||||
il.Emit (OpCodes.Ldc_I4_0);
|
||||
break;
|
||||
default:
|
||||
throw new NotImplementedException (method.ReturnType.FullName);
|
||||
var instruction = CreateConstantResultInstruction (Context, method);
|
||||
if (instruction != null) {
|
||||
il.Append (instruction);
|
||||
} else {
|
||||
StubComplexBody (method, body, il);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
il.Emit (OpCodes.Ret);
|
||||
return body;
|
||||
}
|
||||
|
||||
MethodBody CreateReturnFalseBody (MethodDefinition method)
|
||||
static void StubComplexBody (MethodDefinition method, MethodBody body, ILProcessor il)
|
||||
{
|
||||
if (method.ReturnType.MetadataType != MetadataType.Boolean)
|
||||
throw new NotImplementedException ();
|
||||
switch (method.ReturnType.MetadataType) {
|
||||
case MetadataType.MVar:
|
||||
case MetadataType.ValueType:
|
||||
var vd = new VariableDefinition (method.ReturnType);
|
||||
body.Variables.Add (vd);
|
||||
body.InitLocals = true;
|
||||
|
||||
var body = new MethodBody (method);
|
||||
var il = body.GetILProcessor ();
|
||||
il.Emit (OpCodes.Ldc_I4_0);
|
||||
il.Emit (OpCodes.Ret);
|
||||
return body;
|
||||
il.Emit (OpCodes.Ldloca_S, vd);
|
||||
il.Emit (OpCodes.Initobj, method.ReturnType);
|
||||
il.Emit (OpCodes.Ldloc_0);
|
||||
return;
|
||||
case MetadataType.Pointer:
|
||||
case MetadataType.IntPtr:
|
||||
case MetadataType.UIntPtr:
|
||||
il.Emit (OpCodes.Ldc_I4_0);
|
||||
il.Emit (OpCodes.Conv_I);
|
||||
return;
|
||||
}
|
||||
|
||||
throw new NotImplementedException (method.FullName);
|
||||
}
|
||||
|
||||
public static Instruction CreateConstantResultInstruction (LinkContext context, MethodDefinition method)
|
||||
{
|
||||
context.Annotations.TryGetMethodStubValue (method, out object value);
|
||||
return CreateConstantResultInstruction (method.ReturnType, value);
|
||||
}
|
||||
|
||||
public static Instruction CreateConstantResultInstruction (TypeReference rtype, object value = null)
|
||||
{
|
||||
switch (rtype.MetadataType) {
|
||||
case MetadataType.ValueType:
|
||||
var definition = rtype.Resolve ();
|
||||
if (definition?.IsEnum == true) {
|
||||
rtype = definition.GetEnumUnderlyingType ();
|
||||
}
|
||||
|
||||
break;
|
||||
case MetadataType.GenericInstance:
|
||||
rtype = rtype.Resolve ();
|
||||
break;
|
||||
}
|
||||
|
||||
switch (rtype.MetadataType) {
|
||||
case MetadataType.Boolean:
|
||||
if (value is int bintValue && bintValue == 1)
|
||||
return Instruction.Create (OpCodes.Ldc_I4_1);
|
||||
|
||||
return Instruction.Create (OpCodes.Ldc_I4_0);
|
||||
|
||||
case MetadataType.String:
|
||||
if (value is string svalue)
|
||||
return Instruction.Create (OpCodes.Ldstr, svalue);
|
||||
|
||||
return Instruction.Create (OpCodes.Ldnull);
|
||||
|
||||
case MetadataType.Object:
|
||||
case MetadataType.Array:
|
||||
case MetadataType.Class:
|
||||
Debug.Assert (value == null);
|
||||
return Instruction.Create (OpCodes.Ldnull);
|
||||
|
||||
case MetadataType.Double:
|
||||
if (value is double dvalue)
|
||||
return Instruction.Create (OpCodes.Ldc_R8, dvalue);
|
||||
|
||||
return Instruction.Create (OpCodes.Ldc_R8, 0.0);
|
||||
|
||||
case MetadataType.Single:
|
||||
if (value is float fvalue)
|
||||
return Instruction.Create (OpCodes.Ldc_R4, fvalue);
|
||||
|
||||
return Instruction.Create (OpCodes.Ldc_R4, 0.0f);
|
||||
|
||||
case MetadataType.Char:
|
||||
case MetadataType.Byte:
|
||||
case MetadataType.SByte:
|
||||
case MetadataType.Int16:
|
||||
case MetadataType.UInt16:
|
||||
case MetadataType.Int32:
|
||||
case MetadataType.UInt32:
|
||||
if (value is int intValue)
|
||||
return Instruction.Create (OpCodes.Ldc_I4, intValue);
|
||||
|
||||
return Instruction.Create (OpCodes.Ldc_I4_0);
|
||||
|
||||
case MetadataType.UInt64:
|
||||
case MetadataType.Int64:
|
||||
return Instruction.Create (OpCodes.Ldc_I8, 0L);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
3229
external/linker/src/linker/Linker.Steps/MarkStep.cs
vendored
3229
external/linker/src/linker/Linker.Steps/MarkStep.cs
vendored
File diff suppressed because it is too large
Load Diff
1
external/linker/src/linker/Linker.Steps/MarkStep.cs.REMOVED.git-id
vendored
Normal file
1
external/linker/src/linker/Linker.Steps/MarkStep.cs.REMOVED.git-id
vendored
Normal file
@@ -0,0 +1 @@
|
||||
55bd31187c808a0374d8d10665a723aa621c5bab
|
||||
@@ -259,7 +259,7 @@ namespace Mono.Linker.Steps
|
||||
{
|
||||
if (method.Name == "get_UseManagedCollation")
|
||||
{
|
||||
annotations.SetAction(method, MethodAction.ConvertToFalse);
|
||||
annotations.SetAction(method, MethodAction.ConvertToStub);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
1295
external/linker/src/linker/Linker.Steps/RemoveUnreachableBlocksStep.cs
vendored
Normal file
1295
external/linker/src/linker/Linker.Steps/RemoveUnreachableBlocksStep.cs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -63,8 +63,13 @@ namespace Mono.Linker.Steps
|
||||
if (_assembly != null)
|
||||
Context.Resolver.CacheAssembly (_assembly);
|
||||
|
||||
AssemblyDefinition assembly = _assembly ?? Context.Resolve (_file);
|
||||
var ignoreUnresolved = Context.Resolver.IgnoreUnresolved;
|
||||
if (_rootVisibility == RootVisibility.PublicAndFamily) {
|
||||
Context.Resolver.IgnoreUnresolved = false;
|
||||
}
|
||||
|
||||
AssemblyDefinition assembly = _assembly ?? Context.Resolve (_file);
|
||||
Context.Resolver.IgnoreUnresolved = ignoreUnresolved;
|
||||
if (_rootVisibility != RootVisibility.Any && HasInternalsVisibleTo (assembly)) {
|
||||
_rootVisibility = RootVisibility.PublicAndFamilyAndAssembly;
|
||||
}
|
||||
|
||||
@@ -462,18 +462,23 @@ namespace Mono.Linker.Steps {
|
||||
{
|
||||
if (type.HasMethods)
|
||||
foreach (MethodDefinition meth in type.Methods)
|
||||
if (signature == GetMethodSignature (meth))
|
||||
if (signature == GetMethodSignature (meth, false))
|
||||
return meth;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static string GetMethodSignature (MethodDefinition meth)
|
||||
public static string GetMethodSignature (MethodDefinition meth, bool includeGenericParameters)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder ();
|
||||
sb.Append (meth.ReturnType.FullName);
|
||||
sb.Append (" ");
|
||||
sb.Append (meth.Name);
|
||||
if (includeGenericParameters && meth.HasGenericParameters) {
|
||||
sb.Append ("`");
|
||||
sb.Append (meth.GenericParameters.Count);
|
||||
}
|
||||
|
||||
sb.Append ("(");
|
||||
if (meth.HasParameters) {
|
||||
for (int i = 0; i < meth.Parameters.Count; i++) {
|
||||
|
||||
49
external/linker/src/linker/Linker/Annotations.cs
vendored
49
external/linker/src/linker/Linker/Annotations.cs
vendored
@@ -39,6 +39,10 @@ namespace Mono.Linker {
|
||||
|
||||
protected readonly Dictionary<AssemblyDefinition, AssemblyAction> assembly_actions = new Dictionary<AssemblyDefinition, AssemblyAction> ();
|
||||
protected readonly Dictionary<MethodDefinition, MethodAction> method_actions = new Dictionary<MethodDefinition, MethodAction> ();
|
||||
protected readonly Dictionary<MethodDefinition, object> method_stub_values = new Dictionary<MethodDefinition, object> ();
|
||||
protected readonly Dictionary<FieldDefinition, object> field_values = new Dictionary<FieldDefinition, object> ();
|
||||
protected readonly HashSet<FieldDefinition> field_init = new HashSet<FieldDefinition> ();
|
||||
protected readonly HashSet<TypeDefinition> fieldType_init = new HashSet<TypeDefinition> ();
|
||||
protected readonly HashSet<IMetadataTokenProvider> marked = new HashSet<IMetadataTokenProvider> ();
|
||||
protected readonly HashSet<IMetadataTokenProvider> processed = new HashSet<IMetadataTokenProvider> ();
|
||||
protected readonly Dictionary<TypeDefinition, TypePreserve> preserved_types = new Dictionary<TypeDefinition, TypePreserve> ();
|
||||
@@ -71,14 +75,13 @@ namespace Mono.Linker {
|
||||
[Obsolete ("Use Tracer in LinkContext directly")]
|
||||
public void PrepareDependenciesDump ()
|
||||
{
|
||||
Tracer.Start ();
|
||||
Tracer.AddRecorder (new XmlDependencyRecorder (context));
|
||||
}
|
||||
|
||||
[Obsolete ("Use Tracer in LinkContext directly")]
|
||||
public void PrepareDependenciesDump (string filename)
|
||||
{
|
||||
Tracer.DependenciesFileName = filename;
|
||||
Tracer.Start ();
|
||||
Tracer.AddRecorder (new XmlDependencyRecorder (context, filename));
|
||||
}
|
||||
|
||||
public ICollection<AssemblyDefinition> GetAssemblies ()
|
||||
@@ -119,6 +122,36 @@ namespace Mono.Linker {
|
||||
method_actions [method] = action;
|
||||
}
|
||||
|
||||
public void SetMethodStubValue (MethodDefinition method, object value)
|
||||
{
|
||||
method_stub_values [method] = value;
|
||||
}
|
||||
|
||||
public void SetFieldValue (FieldDefinition field, object value)
|
||||
{
|
||||
field_values [field] = value;
|
||||
}
|
||||
|
||||
public void SetSubstitutedInit (FieldDefinition field)
|
||||
{
|
||||
field_init.Add (field);
|
||||
}
|
||||
|
||||
public bool HasSubstitutedInit (FieldDefinition field)
|
||||
{
|
||||
return field_init.Contains (field);
|
||||
}
|
||||
|
||||
public void SetSubstitutedInit (TypeDefinition type)
|
||||
{
|
||||
fieldType_init.Add (type);
|
||||
}
|
||||
|
||||
public bool HasSubstitutedInit (TypeDefinition type)
|
||||
{
|
||||
return fieldType_init.Contains (type);
|
||||
}
|
||||
|
||||
public void Mark (IMetadataTokenProvider provider)
|
||||
{
|
||||
marked.Add (provider);
|
||||
@@ -233,6 +266,16 @@ namespace Mono.Linker {
|
||||
return preserved_types.TryGetValue (type, out preserve);
|
||||
}
|
||||
|
||||
public bool TryGetMethodStubValue (MethodDefinition method, out object value)
|
||||
{
|
||||
return method_stub_values.TryGetValue (method, out value);
|
||||
}
|
||||
|
||||
public bool TryGetFieldUserValue (FieldDefinition field, out object value)
|
||||
{
|
||||
return field_values.TryGetValue (field, out value);
|
||||
}
|
||||
|
||||
public HashSet<string> GetResourcesToRemove (AssemblyDefinition assembly)
|
||||
{
|
||||
HashSet<string> resources;
|
||||
|
||||
19
external/linker/src/linker/Linker/BCL.cs
vendored
19
external/linker/src/linker/Linker/BCL.cs
vendored
@@ -60,22 +60,27 @@ namespace Mono.Linker
|
||||
return true;
|
||||
}
|
||||
|
||||
static readonly string[] corlibNames = new [] {
|
||||
"mscorlib",
|
||||
"System.Runtime",
|
||||
"System.Private.CoreLib",
|
||||
"netstandard"
|
||||
};
|
||||
|
||||
public static TypeDefinition FindPredefinedType (string ns, string name, LinkContext context)
|
||||
{
|
||||
var cache = context.Resolver.AssemblyCache;
|
||||
|
||||
AssemblyDefinition corlib;
|
||||
TypeDefinition type = null;
|
||||
if (cache.TryGetValue ("mscorlib", out corlib)) {
|
||||
type = corlib.MainModule.GetType (ns, name);
|
||||
foreach (var corlibName in corlibNames) {
|
||||
if (!cache.TryGetValue (corlibName, out AssemblyDefinition corlib))
|
||||
continue;
|
||||
|
||||
TypeDefinition type = corlib.MainModule.GetType (ns, name);
|
||||
// The assembly could be a facade with type forwarders, in which case we don't find the type in this assembly.
|
||||
if (type != null)
|
||||
return type;
|
||||
}
|
||||
|
||||
if (cache.TryGetValue ("System.Private.CoreLib", out corlib))
|
||||
return corlib.MainModule.GetType (ns, name);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
698
external/linker/src/linker/Linker/Driver.cs
vendored
698
external/linker/src/linker/Linker/Driver.cs
vendored
File diff suppressed because it is too large
Load Diff
44
external/linker/src/linker/Linker/IDependencyRecorder.cs
vendored
Normal file
44
external/linker/src/linker/Linker/IDependencyRecorder.cs
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// IDependencyRecorder.cs
|
||||
//
|
||||
// Copyright (C) 2017 Microsoft Corporation (http://www.microsoft.com)
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
namespace Mono.Linker
|
||||
{
|
||||
/// <summary>
|
||||
/// Abstraction exposed by the linker (mostly MarkStep, but not only) - it will call this interface
|
||||
/// every time it finds a dependency between two parts of the dependency graph.
|
||||
/// </summary>
|
||||
public interface IDependencyRecorder
|
||||
{
|
||||
/// <summary>
|
||||
/// Reports a dependency detected by the linker.
|
||||
/// </summary>
|
||||
/// <param name="source">The source of the dependency (for example the caller method).</param>
|
||||
/// <param name="target">The target of the dependency (for example the callee method).</param>
|
||||
/// <param name="marked">true if the target is also marked by the MarkStep.</param>
|
||||
/// <remarks>The source and target are typically Cecil metadata objects (MethodDefinition, TypeDefinition, ...)
|
||||
/// but they can also be the linker steps or really any other object.</remarks>
|
||||
void RecordDependency (object source, object target, bool marked);
|
||||
}
|
||||
}
|
||||
62
external/linker/src/linker/Linker/IReflectionPatternRecorder.cs
vendored
Normal file
62
external/linker/src/linker/Linker/IReflectionPatternRecorder.cs
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
//
|
||||
// IReflectionPatternRecorder.cs
|
||||
//
|
||||
// Copyright (C) 2017 Microsoft Corporation (http://www.microsoft.com)
|
||||
//
|
||||
// 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 Mono.Cecil;
|
||||
|
||||
namespace Mono.Linker
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface which is called every time the linker inspects a pattern of code involving reflection to determine a more complex
|
||||
/// dependency.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The rules are such that if a given callsite of a "reflectionMethod" gets examined
|
||||
/// linker will always report it one way or another:
|
||||
/// - it will either call RecognizedReflectionAccessPattern method when it can figure out exactly the dependency.
|
||||
/// - or it will call UnrecognizedReflectionAccessPattern with an optional message describing why it could not recognize
|
||||
/// the pattern.
|
||||
/// </remarks>
|
||||
public interface IReflectionPatternRecorder
|
||||
{
|
||||
/// <summary>
|
||||
/// Called when the linker recognized a reflection access pattern (and thus was able to correctly apply marking to the accessed item).
|
||||
/// </summary>
|
||||
/// <param name="sourceMethod">The method which contains the reflection access pattern.</param>
|
||||
/// <param name="reflectionMethod">The reflection method which is at the heart of the access pattern.</param>
|
||||
/// <param name="accessedItem">The item accessed through reflection. This can be one of:
|
||||
/// TypeDefinition, MethodDefinition, PropertyDefinition, FieldDefinition, EventDefinition.</param>
|
||||
void RecognizedReflectionAccessPattern (MethodDefinition sourceMethod, MethodDefinition reflectionMethod, IMemberDefinition accessedItem);
|
||||
|
||||
/// <summary>
|
||||
/// Called when the linker detected a reflection access but was not able to recognize the entire pattern.
|
||||
/// </summary>
|
||||
/// <param name="sourceMethod">The method which contains the reflection access code.</param>
|
||||
/// <param name="reflectionMethod">The reflection method which is at the heart of the access code.</param>
|
||||
/// <param name="message">Humanly readable message describing what failed during the pattern recognition.</param>
|
||||
/// <remarks>This effectively means that there's a potential hole in the linker marking - some items which are accessed only through
|
||||
/// reflection may not be marked correctly and thus may fail at runtime.</remarks>
|
||||
void UnrecognizedReflectionAccessPattern (MethodDefinition sourceMethod, MethodDefinition reflectionMethod, string message);
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ namespace Mono.Linker
|
||||
{
|
||||
public MethodDefinition NotSupportedExceptionCtorString { get; set; }
|
||||
public MethodDefinition DisablePrivateReflectionAttributeCtor { get; set; }
|
||||
public MethodDefinition ObjectCtor { get; set; }
|
||||
|
||||
public static bool IsNotSupportedExceptionCtorString (MethodDefinition method)
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user