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

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/ILVerify/src/Program.cs')
-rw-r--r--src/ILVerify/src/Program.cs112
1 files changed, 87 insertions, 25 deletions
diff --git a/src/ILVerify/src/Program.cs b/src/ILVerify/src/Program.cs
index d748084b8..36e978512 100644
--- a/src/ILVerify/src/Program.cs
+++ b/src/ILVerify/src/Program.cs
@@ -10,6 +10,7 @@ using System.Linq;
using System.Reflection;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
+using System.Text;
using System.Text.RegularExpressions;
using Internal.CommandLine;
using Internal.TypeSystem.Ecma;
@@ -20,6 +21,8 @@ namespace ILVerify
class Program : ResolverBase
{
private bool _help;
+ private bool _verbose;
+ private bool _printStatistics;
private AssemblyName _systemModule = new AssemblyName("mscorlib");
private Dictionary<string, string> _inputFilePaths = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); // map of simple name to file path
@@ -73,6 +76,8 @@ namespace ILVerify
syntax.DefineOption("include-file", ref includeFile, "Same as --include, but the regular expression(s) are declared line by line in the specified file.");
syntax.DefineOptionList("e|exclude", ref excludePatterns, "Skip methods/types/namespaces, which match the given regular expression(s)");
syntax.DefineOption("exclude-file", ref excludeFile, "Same as --exclude, but the regular expression(s) are declared line by line in the specified file.");
+ syntax.DefineOption("statistics", ref _printStatistics, "Print verification statistics");
+ syntax.DefineOption("v|verbose", ref _verbose, "Verbose output");
syntax.DefineParameterList("in", ref inputFiles, "Input file(s)");
});
@@ -99,6 +104,25 @@ namespace ILVerify
}
_excludePatterns = StringPatternsToRegexList(excludePatterns);
+ if (_verbose)
+ {
+ WriteLine();
+ foreach (var path in _inputFilePaths)
+ WriteLine($"Using input file '{path.Value}'");
+
+ WriteLine();
+ foreach (var path in _referenceFilePaths)
+ WriteLine($"Using reference file '{path.Value}'");
+
+ WriteLine();
+ foreach (var pattern in _includePatterns)
+ WriteLine($"Using include pattern '{pattern}'");
+
+ WriteLine();
+ foreach (var pattern in _excludePatterns)
+ WriteLine($"Using exclude pattern '{pattern}'");
+ }
+
return argSyntax;
}
@@ -119,19 +143,7 @@ namespace ILVerify
foreach (var kvp in _inputFilePaths)
{
- var results = VerifyAssembly(new AssemblyName(kvp.Key), out EcmaModule module);
- int numErrors = 0;
-
- foreach (var result in results)
- {
- numErrors++;
- PrintResult(result, module, kvp.Value);
- }
-
- if (numErrors > 0)
- WriteLine(numErrors + " Error(s) Verifying " + kvp.Value);
- else
- WriteLine("All Classes and Methods in " + kvp.Value + " Verified.");
+ VerifyAssembly(new AssemblyName(kvp.Key), kvp.Value);
}
return 0;
@@ -216,31 +228,84 @@ namespace ILVerify
Write(")");
}
- private IEnumerable<VerificationResult> VerifyAssembly(AssemblyName name, out EcmaModule module)
+ private void VerifyAssembly(AssemblyName name, string path)
{
- PEReader peReader = Resolve(name);
- module = _verifier.GetModule(peReader);
+ PEReader peReader = Resolve(name.Name);
+ EcmaModule module = _verifier.GetModule(peReader);
- return VerifyAssembly(peReader);
+ VerifyAssembly(peReader, module, path);
}
- private IEnumerable<VerificationResult> VerifyAssembly(PEReader peReader)
+ private void VerifyAssembly(PEReader peReader, EcmaModule module, string path)
{
+ int numErrors = 0;
+ int verifiedMethodCounter = 0;
+ int methodCounter = 0;
+
MetadataReader metadataReader = peReader.GetMetadataReader();
foreach (var methodHandle in metadataReader.MethodDefinitions)
{
- var methodName = metadataReader.GetString(metadataReader.GetMethodDefinition(methodHandle).Name);
- if (ShouldVerifyMethod(methodName))
+ // get fully qualified method name
+ var methodName = GetQualifiedMethodName(metadataReader, methodHandle);
+
+ bool verifying = ShouldVerifyMethod(methodName);
+ if (_verbose)
+ {
+ Write(verifying ? "Verifying " : "Skipping ");
+ WriteLine(methodName);
+ }
+
+ if (verifying)
{
var results = _verifier.Verify(peReader, methodHandle);
foreach (var result in results)
{
- yield return result;
+ PrintResult(result, module, path);
+ numErrors++;
}
+
+ verifiedMethodCounter++;
}
+
+ methodCounter++;
+ }
+
+ if (numErrors > 0)
+ WriteLine(numErrors + " Error(s) Verifying " + path);
+ else
+ WriteLine("All Classes and Methods in " + path + " Verified.");
+
+ if (_printStatistics)
+ {
+ WriteLine($"Methods found: {methodCounter}");
+ WriteLine($"Methods verified: {verifiedMethodCounter}");
}
}
+ /// <summary>
+ /// This method returns the fully qualified method name by concatenating assembly, type and method name.
+ /// This method exists to avoid additional assembly resolving, which might be triggered by calling
+ /// MethodDesc.ToString().
+ /// </summary>
+ private string GetQualifiedMethodName(MetadataReader metadataReader, MethodDefinitionHandle methodHandle)
+ {
+ var methodDef = metadataReader.GetMethodDefinition(methodHandle);
+ var typeDef = metadataReader.GetTypeDefinition(methodDef.GetDeclaringType());
+
+ var methodName = metadataReader.GetString(metadataReader.GetMethodDefinition(methodHandle).Name);
+ var typeName = metadataReader.GetString(typeDef.Name);
+ var namespaceName = metadataReader.GetString(typeDef.Namespace);
+ var assemblyName = metadataReader.GetString(metadataReader.IsAssembly ? metadataReader.GetAssemblyDefinition().Name : metadataReader.GetModuleDefinition().Name);
+
+ StringBuilder builder = new StringBuilder();
+ builder.Append($"[{assemblyName}]");
+ if (!string.IsNullOrEmpty(namespaceName))
+ builder.Append($"{namespaceName}.");
+ builder.Append($"{typeName}.{methodName}");
+
+ return builder.ToString();
+ }
+
private bool ShouldVerifyMethod(string methodName)
{
if (_includePatterns.Count > 0 && !_includePatterns.Any(p => p.IsMatch(methodName)))
@@ -256,11 +321,8 @@ namespace ILVerify
return true;
}
- protected override PEReader ResolveCore(AssemblyName name)
+ protected override PEReader ResolveCore(string simpleName)
{
- // Note: we use simple names instead of full names to resolve, because we can't get a full name from an assembly without reading it
- string simpleName = name.Name;
-
string path = null;
if (_inputFilePaths.TryGetValue(simpleName, out path) || _referenceFilePaths.TryGetValue(simpleName, out path))
{