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:
authorSven Boemer <sbomer@gmail.com>2017-05-10 15:58:27 +0300
committerMarek Safar <marek.safar@gmail.com>2017-05-10 15:58:27 +0300
commit5fa598a5d5fdd0e769495717626db9f20852d3eb (patch)
treee505f73038812adf764faf310579ddbb51a8bf1f /linker
parent905fd565d6ff664c9cbe243fec0e50e4d716190c (diff)
Add support for writing pure IL for R2R assemblies (#99)
Diffstat (limited to 'linker')
-rw-r--r--linker/Mono.Linker.Steps/OutputStep.cs54
1 files changed, 53 insertions, 1 deletions
diff --git a/linker/Mono.Linker.Steps/OutputStep.cs b/linker/Mono.Linker.Steps/OutputStep.cs
index 47e2c3853..842434efd 100644
--- a/linker/Mono.Linker.Steps/OutputStep.cs
+++ b/linker/Mono.Linker.Steps/OutputStep.cs
@@ -27,15 +27,47 @@
//
using System;
+using System.Collections.Generic;
using System.IO;
using Mono.Cecil;
using Mono.Cecil.Cil;
+using Mono.Cecil.PE;
namespace Mono.Linker.Steps {
public class OutputStep : BaseStep {
+ private static Dictionary<UInt16, TargetArchitecture> architectureMap;
+
+ private enum NativeOSOverride {
+ Apple = 0x4644,
+ FreeBSD = 0xadc4,
+ Linux = 0x7b79,
+ NetBSD = 0x1993,
+ Default = 0
+ }
+
+ static TargetArchitecture CalculateArchitecture (TargetArchitecture readyToRunArch)
+ {
+ if (architectureMap == null) {
+ architectureMap = new Dictionary<UInt16, TargetArchitecture> ();
+ foreach (var os in Enum.GetValues (typeof (NativeOSOverride))) {
+ ushort osVal = (ushort) (NativeOSOverride) os;
+ foreach (var arch in Enum.GetValues (typeof (TargetArchitecture))) {
+ ushort archVal = (ushort) (TargetArchitecture)arch;
+ architectureMap.Add ((ushort) (archVal ^ osVal), (TargetArchitecture) arch);
+ }
+ }
+ }
+
+ TargetArchitecture pureILArch;
+ if (architectureMap.TryGetValue ((ushort) readyToRunArch, out pureILArch)) {
+ return pureILArch;
+ }
+ throw new BadImageFormatException ("unrecognized module attributes");
+ }
+
protected override void Process ()
{
CheckOutputDirectory ();
@@ -55,6 +87,26 @@ namespace Mono.Linker.Steps {
OutputAssembly (assembly);
}
+ static bool IsReadyToRun (ModuleDefinition module)
+ {
+ return (module.Attributes & ModuleAttributes.ILOnly) == 0 &&
+ (module.Attributes & (ModuleAttributes) 0x04) != 0;
+ }
+
+ void WriteAssembly (AssemblyDefinition assembly, string directory)
+ {
+ foreach (var module in assembly.Modules) {
+ // Write back pure IL even for R2R assemblies
+ if (IsReadyToRun (module)) {
+ module.Attributes |= ModuleAttributes.ILOnly;
+ module.Attributes ^= (ModuleAttributes) (uint) 0x04;
+ module.Architecture = CalculateArchitecture (module.Architecture);
+ }
+ }
+
+ assembly.Write (GetAssemblyFileName (assembly, directory), SaveSymbols (assembly));
+ }
+
void OutputAssembly (AssemblyDefinition assembly)
{
string directory = Context.OutputDirectory;
@@ -65,7 +117,7 @@ namespace Mono.Linker.Steps {
case AssemblyAction.Save:
case AssemblyAction.Link:
Context.Annotations.AddDependency (assembly);
- assembly.Write (GetAssemblyFileName (assembly, directory), SaveSymbols (assembly));
+ WriteAssembly (assembly, directory);
break;
case AssemblyAction.Copy:
Context.Annotations.AddDependency (assembly);