Imported Upstream version 5.12.0.220

Former-commit-id: c477e03582759447177c6d4bf412cd2355aad476
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2018-04-24 09:31:23 +00:00
parent 8bd104cef2
commit 8fc30896db
1200 changed files with 29534 additions and 26161 deletions

View File

@@ -21,18 +21,12 @@ investigate bugs, regressions and problems.
License
=======
The Mono runtime, compilers, and tools and most of the class libraries
are licensed under the MIT license. But include some bits of code
licensed under different licenses. The exact list is [available here] (https://github.com/mono/mono/blob/master/LICENSE).
Different parts of Mono use different licenses. The actual details of
which licenses are used for which parts are detailed on the LICENSE
file in this directory.
Check the [LICENSE](https://github.com/mono/linker/blob/master/LICENSE) file.
CLA
=======
Contributions are now taken under the [.NET Foundation CLA] (https://cla2.dotnetfoundation.org/).
Contributions are now taken under the [.NET Foundation CLA](https://cla.dotnetfoundation.org/).
Testing
=======

View File

@@ -27,6 +27,10 @@ bin/
**/Dependencies/*.dll
# corebuild build/test artifacts
corebuild/Tools
corebuild/bootstrap.log
/corebuild/global.json
corebuild/global.json
corebuild/**/bin
corebuild/**/obj
corebuild/testbin

View File

@@ -1,73 +0,0 @@
Guidelines
==========
When contributing to the Mono project, please follow the [Mono Coding
Guidelines][1]. We have been using a coding style for many years,
please make your patches conform to these guidelines.
[1]: http://www.mono-project.com/community/contributing/coding-guidelines/
Etiquette
=========
In general, we do not accept patches that merely shuffle code around,
split classes in multiple files, reindent the code or are the result
of running a refactoring tool on the source code. This is done for
three reasons: (a) we have our own coding guidelines; (b) Some modules
are imported from upstream sources and we want to respect their coding
guidelines and (c) it destroys valuable history that is often used to
investigate bugs, regressions and problems.
License
=======
The Mono runtime, compilers, and tools and most of the class libraries
are licensed under the MIT license. But include some bits of code
licensed under different licenses. The exact list is [available here] (https://github.com/mono/mono/blob/master/LICENSE).
Different parts of Mono use different licenses. The actual details of
which licenses are used for which parts are detailed on the LICENSE
file in this directory.
CLA
=======
Contributions are now taken under the [.NET Foundation CLA] (https://cla2.dotnetfoundation.org/).
Testing
=======
Pull requests go through testing on our [Jenkins server][2]. We will
usually only merge a pull request if it causes no regressions in a
test run there.
When you submit a pull request, one of two things happens:
* If you are a new contributor, Jenkins will ask for permissions (on
the pull request) to test it. A maintainer will reply to approve
the test run if they find the patch appropriate. After you have
submitted a few patches, a maintainer will whitelist you so that
all of your future pull requests are tested automatically.
* If you are a well-known, whitelisted contributor, Jenkins will go
ahead and test your pull request as soon as a test machine is
available.
When your pull request has been built, Jenkins will update the build
status of your pull request. If it succeeded and we like the changes,
a maintainer will likely merge it. Otherwise, you can amend your pull
request to fix build breakage and Jenkins will test it again.
[2]: http://jenkins.mono-project.com/
# Inactivity
Occasionally, a pull request sits for several months without any
response from the author. This isn't necessarily an issue, but we may
sometimes decide to close pull requests that have not seen any
progress for a long time. This is in interest of keeping the pull
request list clean so that other pull requests don't get lost in the
clutter.
If we do close your pull request due to inactivity, you're more than
welcome to submit it anew after you address any comments or issues that
were brought up on the original pull request.

View File

@@ -1,11 +1,21 @@
# IL linker
# [IL Linker](linker/README.md)
The linker is a tool one can use to only ship the minimal possible IL code and metadata that a set of
The IL Linker is a tool one can use to only ship the minimal possible IL code and metadata that a set of
programs might require to run as opposed to the full libraries.
It is used by the various Xamarin products to extract only the bits of code that are needed to run
an application on Android, iOS and other platforms.
### Build & Test Status
# [Analyzer](analyzer/README.md)
The analyzer is a tool to analyze dependencies which were recorded during linker processing and led linker to mark an item to keep it in the resulting linked assembly.
It can be used to better understand dependencies between different metadata members to help further reduce the linked output.
## How to build the IL Linker
TODO
## Build & Test Status
[![Build Status](https://jenkins.mono-project.com/buildStatus/icon?job=test-linker-mainline)](https://jenkins.mono-project.com/job/test-linker-mainline/)

View File

@@ -15,7 +15,7 @@ namespace LinkerAnalyzer
{
public class ConsoleDependencyGraph : DependencyGraph
{
public bool Tree = false;
public bool Tree;
public bool FlatDeps;
public void ShowDependencies (string raw, List<VertexData> verticesList, string searchString)
@@ -48,16 +48,25 @@ namespace LinkerAnalyzer
Console.WriteLine ();
foreach (var d in flatDeps) {
var dSize = SpaceAnalyzer == null ? 0 : SpaceAnalyzer.GetSize (d.Item1);
if (first) {
Console.WriteLine ($"Distance | {d.Item1.value} [total deps: {flatDeps.Count}]");
var sizeStr = dSize > 0 ? $" [size: {dSize}]" : "";
Console.WriteLine ($"Distance | {d.Item1.value} [total deps: {flatDeps.Count}]{sizeStr}");
Line ();
first = false;
continue;
}
Console.WriteLine ($"{string.Format ("{0,8}", d.Item2)} | {d.Item1.value}");
var sizeStr2 = dSize > 0 ? $" [size: {dSize}]" : "";
Console.WriteLine ($"{string.Format ("{0,8}", d.Item2)} | {d.Item1.value}{d.Item1.DepsCount}{sizeStr2}");
}
}
string SizeString (VertexData vertex)
{
return SpaceAnalyzer == null ?
"" : string.Format (" size: {0}", SpaceAnalyzer.GetSize (vertex));
}
public void ShowDependencies (VertexData vertex)
{
if (FlatDeps) {
@@ -73,7 +82,7 @@ namespace LinkerAnalyzer
int i = 0;
foreach (int index in vertex.parentIndexes) {
Console.WriteLine ("Dependency #{0}", ++i);
Console.WriteLine ("\t{0}", vertex.value);
Console.WriteLine ($"\t{vertex.value}{SizeString (vertex)}");
var childVertex = Vertex (index);
Console.WriteLine ("\t| {0}{1}", childVertex.value, childVertex.DepsCount);
while (childVertex.parentIndexes != null) {
@@ -166,7 +175,7 @@ namespace LinkerAnalyzer
Console.WriteLine ();
}
void Header (string header, params object[] values)
static public void Header (string header, params object[] values)
{
string formatted = string.Format (header, values);
Console.WriteLine ();

View File

@@ -34,6 +34,7 @@ namespace LinkerAnalyzer.Core
public List<VertexData> Types = new List<VertexData> ();
Dictionary<string, int> indexes = new Dictionary<string, int> ();
protected Dictionary<string, int> counts = new Dictionary<string, int> ();
internal SpaceAnalyzer SpaceAnalyzer { get; set; }
public void Load (string filename)
{

View File

@@ -0,0 +1,153 @@
// SpaceAnalyzer.cs
//
// Author:
// Radek Doulik <radou@microsoft.com>
//
// Copyright (C) 2018 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 System;
using System.Collections.Generic;
using Mono.Cecil;
namespace LinkerAnalyzer.Core
{
public class SpaceAnalyzer
{
string assembliesDirectory;
List<AssemblyDefinition> assemblies = new List<AssemblyDefinition> ();
readonly Dictionary<string, int> sizes = new Dictionary<string, int> ();
public SpaceAnalyzer (string assembliesDirectory)
{
this.assembliesDirectory = assembliesDirectory;
}
static bool IsAssemblyBound (TypeDefinition td)
{
do {
if (td.IsNestedPrivate || td.IsNestedAssembly || td.IsNestedFamilyAndAssembly)
return true;
td = td.DeclaringType;
} while (td != null);
return false;
}
string GetTypeKey (TypeDefinition td)
{
if (td == null)
return "";
var addAssembly = td.IsNotPublic || IsAssemblyBound (td);
var addition = addAssembly ? $":{td.Module}" : "";
return $"{td.MetadataToken.TokenType}:{td}{addition}";
}
string GetKey (IMetadataTokenProvider provider)
{
return $"{provider.MetadataToken.TokenType}:{provider}";
}
int GetMethodSize (MethodDefinition method)
{
var key = GetKey (method);
if (sizes.ContainsKey (key))
return sizes [key];
var msize = method.Body.CodeSize;
msize += method.Name.Length;
sizes.Add (key, msize);
return msize;
}
int ProcessType (TypeDefinition type)
{
int size = type.Name.Length;
foreach (var field in type.Fields)
size += field.Name.Length;
foreach (var method in type.Methods) {
method.Resolve ();
if (method.Body != null)
size += GetMethodSize (method);
}
var resolvedType = type.Resolve ();
try {
sizes.Add (GetTypeKey (type), size);
} catch (ArgumentException e) {
Console.WriteLine ($"\nWarning: duplicated type '{type}' scope '{type.Scope}'\n{e}");
}
return size;
}
public void LoadAssemblies (bool verbose = true)
{
if (verbose) {
ConsoleDependencyGraph.Header ("Space analyzer");
Console.WriteLine ("Load assemblies from {0}", assembliesDirectory);
} else
Console.Write ("Analyzing assemblies .");
var resolver = new DefaultAssemblyResolver ();
resolver.AddSearchDirectory (assembliesDirectory);
int totalSize = 0;
foreach (var file in System.IO.Directory.GetFiles (assembliesDirectory, "*.dll")) {
if (verbose)
Console.WriteLine ($"Analyzing {file}");
else
Console.Write (".");
ReaderParameters parameters = new ReaderParameters () { ReadingMode = ReadingMode.Immediate, AssemblyResolver = resolver};
var assembly = AssemblyDefinition.ReadAssembly (file, parameters);
assemblies.Add (assembly);
foreach (var module in assembly.Modules) {
foreach (var type in module.Types) {
totalSize += ProcessType (type);
foreach (var child in type.NestedTypes)
totalSize += ProcessType (child);
}
}
}
if (verbose)
Console.WriteLine ("Total known size: {0}", totalSize);
else
System.Console.WriteLine ();
}
public int GetSize (VertexData vertex)
{
if (sizes.ContainsKey (vertex.value))
return sizes [vertex.value];
return 0;
}
}
}

View File

@@ -23,23 +23,23 @@ namespace LinkerAnalyzer
bool showRawDeps = false;
string rawName = null;
bool showRoots = false;
bool showSpaceUsage = false;
bool showStat = false;
bool showTypes = false;
bool reduceToTree = false;
bool verbose = false;
bool flatDeps = false;
string linkedPath = null;
var optionsParser = new OptionSet () {
{ "a|alldeps", "show all dependencies", v => { showAllDeps = v != null; } },
{ "h|help", "show this message and exit.", v => showUsage = v != null },
{ "l|linkedpath=", "sets the linked assemblies directory path. Enables displaying size estimates.", v => { linkedPath = v; } },
{ "r|rawdeps=", "show raw vertex dependencies. Raw vertex VALUE is in the raw format written by linker to the dependency XML file. VALUE can be regular expression", v => { showRawDeps = v != null; rawName = v; } },
{ "roots", "show root dependencies.", v => showRoots = v != null },
{ "stat", "show statistic of loaded dependencies.", v => showStat = v != null },
{ "tree", "reduce the dependency graph to the tree.", v => reduceToTree = v != null },
{ "types", "show all types dependencies.", v => showTypes = v != null },
{ "t|typedeps=", "show type dependencies. The VALUE can be regular expression", v => { showTypeDeps = v != null; typeName = v; } },
//{ "u|spaceusage", "show space analysis.", v => showSpaceUsage = v != null },
{ "f|flat", "show all dependencies per vertex and their distance", v => flatDeps = v != null },
{ "v|verbose", "be more verbose. Enables stat and roots options.", v => verbose = v != null },
};
@@ -61,9 +61,9 @@ namespace LinkerAnalyzer
ConsoleDependencyGraph deps = new ConsoleDependencyGraph () { Tree = reduceToTree, FlatDeps = flatDeps };
deps.Load (dependencyFile);
if (showSpaceUsage) {
// SpaceAnalyzer sa = new SpaceAnalyzer (System.IO.Path.GetDirectoryName (dependencyFile));
// sa.LoadAssemblies (verbose);
if (linkedPath != null) {
deps.SpaceAnalyzer = new SpaceAnalyzer (linkedPath);
deps.SpaceAnalyzer.LoadAssemblies (verbose);
}
if (verbose) {

View File

@@ -1,3 +1,5 @@
# Linker Analyzer
Linker analyzer is a command line tool to analyze dependencies, which
were recorded during linker processing, and led linker to mark an item
to keep it in the resulting linked assembly.
@@ -7,8 +9,7 @@ dumped during the linker run. The vertices of this graph are the items
of interest like assemblies, types, methods, fields, linker steps,
etc. The edges represent the dependencies.
How to dump dependencies
------------------------
## How to dump dependencies
The linker analyzer needs a linker dependencies file as an input. It
can be retrieved by enabling dependencies dumping during linking of a
@@ -25,8 +26,7 @@ the project like this:
After a successful build, there will be a linker-dependencies.xml.gz
file created, containing the information for the analyzer.
How to use the analyzer
-----------------------
## How to use the analyzer
Let say you would like to know, why a type, Android.App.Activity for
example, was marked by the linker. So run the analyzer like this:
@@ -48,11 +48,7 @@ Dependency #1
| Other:Mono.Linker.Steps.ResolveFromAssemblyStep
```
The output contains dependencies string(s), starting with the type and
continuing with the item of interest, which depends on the type. The
dependency could be result of multiple reasons. For example the type
was referenced from a method, or the type was listed in the linker xml
file to be protected.
The output contains dependencies string(s), starting with the type and continuing with the item of interest, which depends on the type. The dependency could be a result of multiple reasons. For example, the type was referenced from a method, or the type was listed in the linker XML descriptor file.
In our example there is only one dependency string called `Dependency
#1`. It shows us that the type `Android.App.Activity` was marked
@@ -91,8 +87,7 @@ Dependency #2
| Other:Mono.Linker.Steps.ResolveFromAssemblyStep
```
Known issues
------------
### Known issues
Sometimes the linker processing is not straight forward and the
marking is postponed, like processing of some of the methods. They are
@@ -100,8 +95,8 @@ queued to be processed later. In such case the dependencies are
"interrupted" and the dependecy string for the method usually shows
just dependency on the Mark step.
Command line help
-----------------
# Command line help
```
Usage:

View File

@@ -31,11 +31,16 @@
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Xml" />
<ProjectReference Include="../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>

View File

@@ -569,6 +569,9 @@ namespace Mono.Cecil.Cil {
if (hash_algo == DocumentHashAlgorithm.SHA1)
return hash_sha1;
if (hash_algo == DocumentHashAlgorithm.SHA256)
return hash_sha256;
return new Guid ();
}

View File

@@ -1000,7 +1000,7 @@ namespace Mono.Cecil {
public static bool IsPortablePdb (string fileName)
{
using (var file = new FileStream (fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var file = new FileStream (fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
return IsPortablePdb (file);
}

View File

@@ -28,6 +28,7 @@ namespace Mono.Cecil.PE {
public string RuntimeVersion;
public TargetArchitecture Architecture;
public ModuleCharacteristics Characteristics;
public ushort LinkerVersion;
public ImageDebugHeader DebugHeader;

View File

@@ -81,8 +81,8 @@ namespace Mono.Cecil.PE {
// Characteristics 2
ushort characteristics = ReadUInt16 ();
ushort subsystem, dll_characteristics;
ReadOptionalHeaders (out subsystem, out dll_characteristics);
ushort subsystem, dll_characteristics, linker_version;
ReadOptionalHeaders (out subsystem, out dll_characteristics, out linker_version);
ReadSections (sections);
ReadCLIHeader ();
ReadMetadata ();
@@ -90,6 +90,7 @@ namespace Mono.Cecil.PE {
image.Kind = GetModuleKind (characteristics, subsystem);
image.Characteristics = (ModuleCharacteristics) dll_characteristics;
image.LinkerVersion = linker_version;
}
TargetArchitecture ReadArchitecture ()
@@ -108,7 +109,7 @@ namespace Mono.Cecil.PE {
return ModuleKind.Console;
}
void ReadOptionalHeaders (out ushort subsystem, out ushort dll_characteristics)
void ReadOptionalHeaders (out ushort subsystem, out ushort dll_characteristics, out ushort linker)
{
// - PEOptionalHeader
// - StandardFieldsHeader
@@ -118,8 +119,7 @@ namespace Mono.Cecil.PE {
// pe32 || pe64
// LMajor 1
// LMinor 1
linker = ReadUInt16 ();
// CodeSize 4
// InitializedDataSize 4
// UninitializedDataSize4
@@ -142,7 +142,7 @@ namespace Mono.Cecil.PE {
// ImageSize 4
// HeaderSize 4
// FileChecksum 4
Advance (66);
Advance (64);
// SubSystem 2
subsystem = ReadUInt16 ();

View File

@@ -218,9 +218,8 @@ namespace Mono.Cecil.PE {
void WriteOptionalHeaders ()
{
WriteUInt16 ((ushort) (!pe64 ? 0x10b : 0x20b)); // Magic
WriteByte (8); // LMajor
WriteByte (0); // LMinor
WriteUInt16 ((ushort) (!pe64 ? 0x10b : 0x20b)); // Magic
WriteUInt16 (module.linker_version);
WriteUInt32 (text.SizeOfRawData); // CodeSize
WriteUInt32 ((reloc != null ? reloc.SizeOfRawData : 0)
+ (rsrc != null ? rsrc.SizeOfRawData : 0)); // InitializedDataSize

View File

@@ -2414,10 +2414,12 @@ namespace Mono.Cecil {
var signature = CreateSignatureWriter ();
signature.WriteUInt32 ((uint) async_method.catch_handler.Offset + 1);
for (int i = 0; i < async_method.yields.Count; i++) {
signature.WriteUInt32 ((uint) async_method.yields [i].Offset);
signature.WriteUInt32 ((uint) async_method.resumes [i].Offset);
signature.WriteCompressedUInt32 (async_method.resume_methods [i].MetadataToken.RID);
if (!async_method.yields.IsNullOrEmpty ()) {
for (int i = 0; i < async_method.yields.Count; i++) {
signature.WriteUInt32 ((uint) async_method.yields [i].Offset);
signature.WriteUInt32 ((uint) async_method.resumes [i].Offset);
signature.WriteCompressedUInt32 (async_method.resume_methods [i].MetadataToken.RID);
}
}
AddCustomDebugInformation (provider, async_method, signature);

View File

@@ -9,7 +9,7 @@
//
using System;
using System.Diagnostics;
using Mono.Collections.Generic;
namespace Mono.Cecil {
@@ -68,6 +68,7 @@ namespace Mono.Cecil {
Collection<CustomAttributeArgument> ConstructorArguments { get; }
}
[DebuggerDisplay ("{AttributeType}")]
public sealed class CustomAttribute : ICustomAttribute {
internal CustomAttributeValueProjection projection;

View File

@@ -276,6 +276,7 @@ namespace Mono.Cecil {
TargetArchitecture architecture;
ModuleAttributes attributes;
ModuleCharacteristics characteristics;
internal ushort linker_version = 8;
Guid mvid;
internal uint timestamp;
@@ -350,7 +351,7 @@ namespace Mono.Cecil {
set { characteristics = value; }
}
[Obsolete("Use FileName")]
[Obsolete ("Use FileName")]
public string FullyQualifiedName {
get { return file_name; }
}
@@ -607,6 +608,7 @@ namespace Mono.Cecil {
this.architecture = image.Architecture;
this.attributes = image.Attributes;
this.characteristics = image.Characteristics;
this.linker_version = image.LinkerVersion;
this.file_name = image.FileName;
this.timestamp = image.Timestamp;

View File

@@ -38,6 +38,7 @@ namespace Mono.Cecil {
public enum ModuleAttributes {
ILOnly = 1,
Required32Bit = 2,
ILLibrary = 4,
StrongNameSigned = 8,
Preferred32Bit = 0x00020000,
}

View File

@@ -9,7 +9,7 @@
//
using System;
using System.Diagnostics;
using Mono.Collections.Generic;
namespace Mono.Cecil {
@@ -38,6 +38,7 @@ namespace Mono.Cecil {
Collection<SecurityDeclaration> SecurityDeclarations { get; }
}
[DebuggerDisplay ("{AttributeType}")]
public sealed class SecurityAttribute : ICustomAttribute {
TypeReference attribute_type;

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