Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/linker.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/linker
diff options
context:
space:
mode:
authorMike Voorhees <michaelv@unity3d.com>2017-07-15 00:15:11 +0300
committerMarek Safar <marek.safar@gmail.com>2017-07-26 18:15:03 +0300
commit3a8bd14a25c2b3b436b995521f645f17d41a394c (patch)
tree847c4b066e888ac98a64ff3e49dd2984c9a31d71 /linker
parent4ddb5a5309de6bc37a6095a02b5e5f2d439d734a (diff)
Run peverify on the output assemblies
Diffstat (limited to 'linker')
-rw-r--r--linker/Tests/Mono.Linker.Tests.Cases.Expectations/Assertions/SkipPeVerifyAttribute.cs25
-rw-r--r--linker/Tests/Mono.Linker.Tests.Cases.Expectations/Mono.Linker.Tests.Cases.Expectations.csproj1
-rw-r--r--linker/Tests/Mono.Linker.Tests.Cases/CoreLink/CopyOfCoreLibrariesKeepsUnusedTypes.cs3
-rw-r--r--linker/Tests/Mono.Linker.Tests.Cases/CoreLink/LinkingOfCoreLibrariesRemovesUnusedMethods.cs3
-rw-r--r--linker/Tests/Mono.Linker.Tests.Cases/CoreLink/LinkingOfCoreLibrariesRemovesUnusedTypes.cs3
-rw-r--r--linker/Tests/Mono.Linker.Tests.Cases/References/ReferencesAreRemovedWhenAllUsagesAreRemoved.cs2
-rw-r--r--linker/Tests/Mono.Linker.Tests.csproj1
-rw-r--r--linker/Tests/TestCasesRunner/PeVerifier.cs128
-rw-r--r--linker/Tests/TestCasesRunner/ResultChecker.cs8
9 files changed, 172 insertions, 2 deletions
diff --git a/linker/Tests/Mono.Linker.Tests.Cases.Expectations/Assertions/SkipPeVerifyAttribute.cs b/linker/Tests/Mono.Linker.Tests.Cases.Expectations/Assertions/SkipPeVerifyAttribute.cs
new file mode 100644
index 000000000..eaccabd25
--- /dev/null
+++ b/linker/Tests/Mono.Linker.Tests.Cases.Expectations/Assertions/SkipPeVerifyAttribute.cs
@@ -0,0 +1,25 @@
+using System;
+
+namespace Mono.Linker.Tests.Cases.Expectations.Assertions {
+
+ public enum SkipPeVerifyForToolchian
+ {
+ Pedump
+ }
+
+ [AttributeUsage (AttributeTargets.Class, AllowMultiple = true)]
+ public class SkipPeVerifyAttribute : BaseExpectedLinkedBehaviorAttribute
+ {
+ public SkipPeVerifyAttribute ()
+ {
+ }
+
+ public SkipPeVerifyAttribute (SkipPeVerifyForToolchian toolchain)
+ {
+ }
+
+ public SkipPeVerifyAttribute (string assemblyName)
+ {
+ }
+ }
+}
diff --git a/linker/Tests/Mono.Linker.Tests.Cases.Expectations/Mono.Linker.Tests.Cases.Expectations.csproj b/linker/Tests/Mono.Linker.Tests.Cases.Expectations/Mono.Linker.Tests.Cases.Expectations.csproj
index f4332245f..a18529218 100644
--- a/linker/Tests/Mono.Linker.Tests.Cases.Expectations/Mono.Linker.Tests.Cases.Expectations.csproj
+++ b/linker/Tests/Mono.Linker.Tests.Cases.Expectations/Mono.Linker.Tests.Cases.Expectations.csproj
@@ -49,6 +49,7 @@
<Compile Include="Assertions\RemovedAssemblyAttribute.cs" />
<Compile Include="Assertions\RemovedMemberInAssemblyAttribute.cs" />
<Compile Include="Assertions\RemovedTypeInAssemblyAttribute.cs" />
+ <Compile Include="Assertions\SkipPeVerifyAttribute.cs" />
<Compile Include="Metadata\BaseMetadataAttribute.cs" />
<Compile Include="Metadata\CoreLinkAttribute.cs" />
<Compile Include="Metadata\IncludeBlacklistStepAttribute.cs" />
diff --git a/linker/Tests/Mono.Linker.Tests.Cases/CoreLink/CopyOfCoreLibrariesKeepsUnusedTypes.cs b/linker/Tests/Mono.Linker.Tests.Cases/CoreLink/CopyOfCoreLibrariesKeepsUnusedTypes.cs
index 25ee13f24..498c88378 100644
--- a/linker/Tests/Mono.Linker.Tests.Cases/CoreLink/CopyOfCoreLibrariesKeepsUnusedTypes.cs
+++ b/linker/Tests/Mono.Linker.Tests.Cases/CoreLink/CopyOfCoreLibrariesKeepsUnusedTypes.cs
@@ -9,6 +9,9 @@ namespace Mono.Linker.Tests.Cases.CoreLink
// These types are normally removed when the core libraries are linked
[KeptTypeInAssembly ("mscorlib.dll", typeof (ConsoleKeyInfo))]
[KeptTypeInAssembly ("mscorlib.dll", typeof (System.Collections.ObjectModel.KeyedCollection<,>))]
+
+ // Can be removed once this bug is fixed https://bugzilla.xamarin.com/show_bug.cgi?id=58168
+ [SkipPeVerify (SkipPeVerifyForToolchian.Pedump)]
class CopyOfCoreLibrariesKeepsUnusedTypes
{
public static void Main()
diff --git a/linker/Tests/Mono.Linker.Tests.Cases/CoreLink/LinkingOfCoreLibrariesRemovesUnusedMethods.cs b/linker/Tests/Mono.Linker.Tests.Cases/CoreLink/LinkingOfCoreLibrariesRemovesUnusedMethods.cs
index 78b460939..5f2db3ddb 100644
--- a/linker/Tests/Mono.Linker.Tests.Cases/CoreLink/LinkingOfCoreLibrariesRemovesUnusedMethods.cs
+++ b/linker/Tests/Mono.Linker.Tests.Cases/CoreLink/LinkingOfCoreLibrariesRemovesUnusedMethods.cs
@@ -13,6 +13,9 @@ namespace Mono.Linker.Tests.Cases.CoreLink
// We can't check everything that should be removed, but we should be able to check a few niche things that
// we known should be removed which will at least verify that the core library was processed
[RemovedMemberInAssembly ("mscorlib.dll", typeof (Stack), ".ctor(System.Collections.ICollection)")]
+
+ // Can be removed once this bug is fixed https://bugzilla.xamarin.com/show_bug.cgi?id=58168
+ [SkipPeVerify (SkipPeVerifyForToolchian.Pedump)]
class LinkingOfCoreLibrariesRemovesUnusedMethods {
public static void Main()
{
diff --git a/linker/Tests/Mono.Linker.Tests.Cases/CoreLink/LinkingOfCoreLibrariesRemovesUnusedTypes.cs b/linker/Tests/Mono.Linker.Tests.Cases/CoreLink/LinkingOfCoreLibrariesRemovesUnusedTypes.cs
index c4d447e89..3b92282bf 100644
--- a/linker/Tests/Mono.Linker.Tests.Cases/CoreLink/LinkingOfCoreLibrariesRemovesUnusedTypes.cs
+++ b/linker/Tests/Mono.Linker.Tests.Cases/CoreLink/LinkingOfCoreLibrariesRemovesUnusedTypes.cs
@@ -16,6 +16,9 @@ namespace Mono.Linker.Tests.Cases.CoreLink {
[RemovedTypeInAssembly ("mscorlib.dll", typeof (System.Resources.ResourceWriter))]
[RemovedTypeInAssembly ("System.dll", typeof (System.CodeDom.Compiler.CodeCompiler))]
+
+ // Can be removed once this bug is fixed https://bugzilla.xamarin.com/show_bug.cgi?id=58168
+ [SkipPeVerify (SkipPeVerifyForToolchian.Pedump)]
class LinkingOfCoreLibrariesRemovesUnusedTypes {
public static void Main ()
{
diff --git a/linker/Tests/Mono.Linker.Tests.Cases/References/ReferencesAreRemovedWhenAllUsagesAreRemoved.cs b/linker/Tests/Mono.Linker.Tests.Cases/References/ReferencesAreRemovedWhenAllUsagesAreRemoved.cs
index 58968df67..2cc3f5c0d 100644
--- a/linker/Tests/Mono.Linker.Tests.Cases/References/ReferencesAreRemovedWhenAllUsagesAreRemoved.cs
+++ b/linker/Tests/Mono.Linker.Tests.Cases/References/ReferencesAreRemovedWhenAllUsagesAreRemoved.cs
@@ -10,6 +10,8 @@ namespace Mono.Linker.Tests.Cases.References {
[IncludeBlacklistStep("false")]
[Reference ("System.dll")]
[RemovedAssembly ("System.dll")]
+ // Can be removed once this bug is fixed https://bugzilla.xamarin.com/show_bug.cgi?id=58168
+ [SkipPeVerify(SkipPeVerifyForToolchian.Pedump)]
class ReferencesAreRemovedWhenAllUsagesAreRemoved {
public static void Main ()
{
diff --git a/linker/Tests/Mono.Linker.Tests.csproj b/linker/Tests/Mono.Linker.Tests.csproj
index 7e1b44418..bb3565063 100644
--- a/linker/Tests/Mono.Linker.Tests.csproj
+++ b/linker/Tests/Mono.Linker.Tests.csproj
@@ -72,6 +72,7 @@
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
+ <Compile Include="TestCasesRunner\PeVerifier.cs" />
<Compile Include="TestCases\TestSuites.cs" />
<Compile Include="TestCases\TestDatabase.cs" />
<Compile Include="Tests\PreserveActionComparisonTests.cs" />
diff --git a/linker/Tests/TestCasesRunner/PeVerifier.cs b/linker/Tests/TestCasesRunner/PeVerifier.cs
new file mode 100644
index 000000000..388fa1e5d
--- /dev/null
+++ b/linker/Tests/TestCasesRunner/PeVerifier.cs
@@ -0,0 +1,128 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using Microsoft.Win32;
+using Mono.Cecil;
+using Mono.Linker.Tests.Cases.Expectations.Assertions;
+using Mono.Linker.Tests.Extensions;
+using NUnit.Framework;
+
+namespace Mono.Linker.Tests.TestCasesRunner {
+ public class PeVerifier
+ {
+ private readonly string _peExecutable;
+
+ public PeVerifier ()
+ {
+ _peExecutable = Environment.OSVersion.Platform == PlatformID.Win32NT ? FindPeExecutableFromRegistry ().ToString () : "pedump";
+ }
+
+ public PeVerifier (string peExecutable)
+ {
+ _peExecutable = peExecutable;
+ }
+
+ public virtual void Check (LinkedTestCaseResult linkResult, AssemblyDefinition original)
+ {
+ bool skipCheckEntirely;
+ HashSet<string> assembliesToSkip;
+ ProcessSkipAttributes (linkResult, original, out skipCheckEntirely, out assembliesToSkip);
+
+ if (skipCheckEntirely)
+ return;
+
+ foreach (var file in linkResult.OutputAssemblyPath.Parent.Files ()) {
+ if (file.ExtensionWithDot != ".exe" && file.ExtensionWithDot != ".dll")
+ continue;
+
+ // Always skip the I18N assemblies, for some reason they end up in the output directory on OSX.
+ // verification of these fails due to native pointers
+ if (file.FileName.StartsWith ("I18N"))
+ continue;
+
+ if (assembliesToSkip.Contains (file.FileName))
+ continue;
+
+ CheckAssembly (file);
+ }
+ }
+
+ private void ProcessSkipAttributes (LinkedTestCaseResult linkResult, AssemblyDefinition original, out bool skipCheckEntirely, out HashSet<string> assembliesToSkip)
+ {
+ var peVerifyAttrs = original.MainModule.GetType (linkResult.TestCase.ReconstructedFullTypeName).CustomAttributes.Where (attr => attr.AttributeType.Name == nameof (SkipPeVerifyAttribute));
+ skipCheckEntirely = false;
+ assembliesToSkip = new HashSet<string> ();
+ foreach (var attr in peVerifyAttrs) {
+ var ctorArg = attr.ConstructorArguments.FirstOrDefault ();
+
+ if (!attr.HasConstructorArguments) {
+ skipCheckEntirely = true;
+ } else if (ctorArg.Type.Name == nameof (SkipPeVerifyForToolchian)) {
+ var skipToolchain = (SkipPeVerifyForToolchian)ctorArg.Value;
+
+ if (skipToolchain == SkipPeVerifyForToolchian.Pedump) {
+ if (Environment.OSVersion.Platform != PlatformID.Win32NT)
+ skipCheckEntirely = true;
+ }
+ else
+ throw new ArgumentException($"Unhandled platform and toolchain values of {Environment.OSVersion.Platform} and {skipToolchain}");
+ } else if (ctorArg.Type.Name == nameof (String)) {
+ assembliesToSkip.Add ((string)ctorArg.Value);
+ } else {
+ throw new ArgumentException($"Unhandled constructor argument type of {ctorArg.Type} on {nameof (SkipPeVerifyAttribute)}");
+ }
+ }
+ }
+
+ private void CheckAssembly (NPath assemblyPath)
+ {
+ var capturedOutput = new List<string> ();
+ var exeArgs = Environment.OSVersion.Platform == PlatformID.Win32NT ? $"/nologo {assemblyPath.InQuotes ()}" : $"--verify metadata,code {assemblyPath.InQuotes ()}";
+ var process = new Process ();
+ process.StartInfo.FileName = _peExecutable;
+ process.StartInfo.Arguments = exeArgs;
+ process.StartInfo.UseShellExecute = false;
+ process.StartInfo.CreateNoWindow = true;
+ process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
+ process.StartInfo.RedirectStandardOutput = true;
+ process.OutputDataReceived += (sender, args) => capturedOutput.Add (args.Data);
+ process.Start ();
+ process.BeginOutputReadLine ();
+ process.WaitForExit ();
+
+ if (process.ExitCode != 0) {
+ Assert.Fail ($"Invalid IL detected in {assemblyPath}\n{capturedOutput.Aggregate ((buff, s) => buff + Environment.NewLine + s)}");
+ }
+ }
+
+ public static NPath FindPeExecutableFromRegistry ()
+ {
+ if (Environment.OSVersion.Platform != PlatformID.Win32NT)
+ throw new InvalidOperationException ("This method should only be called on windows");
+
+ var key = Registry.LocalMachine.OpenSubKey (@"SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows");
+ foreach (var sdkKeyName in key.GetSubKeyNames ().OrderBy (name => new Version (name.TrimStart ('v').TrimEnd ('A'))).Reverse ()) {
+ var sdkKey = Registry.LocalMachine.OpenSubKey ($"SOFTWARE\\Wow6432Node\\Microsoft\\Microsoft SDKs\\Windows\\{sdkKeyName}");
+
+ var sdkDir = (string)sdkKey.GetValue ("InstallationFolder");
+ if (string.IsNullOrEmpty (sdkDir))
+ continue;
+
+ var binDir = sdkDir.ToNPath ().Combine ("bin");
+
+ if (!binDir.Exists ())
+ continue;
+
+ foreach (var netSdkDirs in binDir.Directories ().OrderBy (dir => dir.FileName)) {
+ var peVerifyPath = netSdkDirs.Combine ("PEVerify.exe");
+
+ if (peVerifyPath.FileExists ())
+ return peVerifyPath;
+ }
+ }
+
+ throw new InvalidOperationException ("Could not locate a peverify.exe executable");
+ }
+ }
+}
diff --git a/linker/Tests/TestCasesRunner/ResultChecker.cs b/linker/Tests/TestCasesRunner/ResultChecker.cs
index 9abf9dc73..fcc175346 100644
--- a/linker/Tests/TestCasesRunner/ResultChecker.cs
+++ b/linker/Tests/TestCasesRunner/ResultChecker.cs
@@ -12,16 +12,18 @@ namespace Mono.Linker.Tests.TestCasesRunner {
{
readonly BaseAssemblyResolver _originalsResolver;
readonly BaseAssemblyResolver _linkedResolver;
+ readonly PeVerifier _peVerifier;
public ResultChecker ()
- : this(new DefaultAssemblyResolver (), new DefaultAssemblyResolver ())
+ : this(new DefaultAssemblyResolver (), new DefaultAssemblyResolver (), new PeVerifier ())
{
}
- public ResultChecker (BaseAssemblyResolver originalsResolver, BaseAssemblyResolver linkedResolver)
+ public ResultChecker (BaseAssemblyResolver originalsResolver, BaseAssemblyResolver linkedResolver, PeVerifier peVerifier)
{
_originalsResolver = originalsResolver;
_linkedResolver = linkedResolver;
+ _peVerifier = peVerifier;
}
public virtual void Check (LinkedTestCaseResult linkResult)
@@ -41,6 +43,8 @@ namespace Mono.Linker.Tests.TestCasesRunner {
VerifyLinkingOfOtherAssemblies (original);
+ _peVerifier.Check (linkResult, original);
+
AdditionalChecking (linkResult, original, linked);
}
finally