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:
authorDavid Wrighton <davidwr@microsoft.com>2017-06-13 03:23:48 +0300
committerDavid Wrighton <davidwr@microsoft.com>2017-06-13 03:23:48 +0300
commit72f780f9fe1cdafa37e76a378af68d4f378ef004 (patch)
tree9b2e2531994f96ca1cb0e462c8825d6bda132cac
parent7af7188d9eba6d062bb43b64717b713699ed7aec (diff)
Add support for jump stub generation in CoreRT
- Handle both indirect and direct symbol references - ARM, X86, and X64 architectures - First need for these is for a stub that has a well known name which jumps to a specific symbol - We will use these for custom linkage in scenarios involving multiple PE files on Windows [tfs-changeset: 1661486]
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/JumpStubNode.cs32
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NamedJumpStubNode.cs23
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs14
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/ARMEmitter.cs7
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/ARMJumpStubNode.cs24
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/TargetRegisterMap.cs2
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X64/X64Emitter.cs13
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X64/X64JumpStubNode.cs16
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X86/X86Emitter.cs13
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X86/X86JumpStubNode.cs16
-rw-r--r--src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj5
11 files changed, 160 insertions, 5 deletions
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/JumpStubNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/JumpStubNode.cs
new file mode 100644
index 000000000..6c8c687d9
--- /dev/null
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/JumpStubNode.cs
@@ -0,0 +1,32 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+
+using Internal.TypeSystem;
+
+using Internal.Text;
+
+namespace ILCompiler.DependencyAnalysis
+{
+ public abstract partial class JumpStubNode : AssemblyStubNode
+ {
+ private ISymbolNode _target;
+
+ public ISymbolNode Target
+ {
+ get
+ {
+ return _target;
+ }
+ }
+
+ public JumpStubNode(ISymbolNode target)
+ {
+ _target = target;
+ }
+
+ protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler);
+ }
+}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NamedJumpStubNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NamedJumpStubNode.cs
new file mode 100644
index 000000000..e3d4afaa4
--- /dev/null
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NamedJumpStubNode.cs
@@ -0,0 +1,23 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Internal.Text;
+
+namespace ILCompiler.DependencyAnalysis
+{
+ class NamedJumpStubNode : JumpStubNode
+ {
+ Utf8String _name;
+
+ public NamedJumpStubNode(string name, ISymbolNode target) : base(target)
+ {
+ _name = new Utf8String(name);
+ }
+
+ public override void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
+ {
+ sb.Append(_name);
+ }
+ }
+}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs
index 1f1b76c3c..2fce7836c 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs
@@ -401,7 +401,12 @@ namespace ILCompiler.DependencyAnalysis
Debug.Assert(TypeSystemContext.HasEagerStaticConstructor((MetadataType)method.OwningType));
return EagerCctorTable.NewNode(MethodEntrypoint(method));
});
-
+
+ _namedJumpStubNodes = new NodeCache<Tuple<string, ISymbolNode>, NamedJumpStubNode>((Tuple<string, ISymbolNode> id) =>
+ {
+ return new NamedJumpStubNode(id.Item1, id.Item2);
+ });
+
_vTableNodes = new NodeCache<TypeDesc, VTableSliceNode>((TypeDesc type ) =>
{
if (CompilationModuleGroup.ShouldProduceFullVTable(type))
@@ -934,6 +939,13 @@ namespace ILCompiler.DependencyAnalysis
return ReadOnlyDataBlob(symbolName, stringBytes, 1);
}
+ private NodeCache<Tuple<string, ISymbolNode>, NamedJumpStubNode> _namedJumpStubNodes;
+
+ public ISymbolNode NamedJumpStub(string name, ISymbolNode target)
+ {
+ return _namedJumpStubNodes.GetOrAdd(new Tuple<string, ISymbolNode>(name, target));
+ }
+
/// <summary>
/// Returns alternative symbol name that object writer should produce for given symbols
/// in addition to the regular one.
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/ARMEmitter.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/ARMEmitter.cs
index df063a9f8..38dd2edd7 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/ARMEmitter.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/ARMEmitter.cs
@@ -52,11 +52,18 @@ namespace ILCompiler.DependencyAnalysis.ARM
// b symbol
public void EmitJMP(ISymbolNode symbol)
{
+ Debug.Assert(!symbol.RepresentsIndirectionCell);
Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_THUMB_BRANCH24);
Builder.EmitByte(0);
Builder.EmitByte(0xF0);
Builder.EmitByte(0);
Builder.EmitByte(0xB8);
}
+
+ // bx reg
+ public void EmitJMP(Register destination)
+ {
+ Builder.EmitShort((short)(0x47 | ((byte)destination << 3)));
+ }
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/ARMJumpStubNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/ARMJumpStubNode.cs
new file mode 100644
index 000000000..afbc1a662
--- /dev/null
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/ARMJumpStubNode.cs
@@ -0,0 +1,24 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using ILCompiler.DependencyAnalysis.ARM;
+
+namespace ILCompiler.DependencyAnalysis
+{
+ public partial class JumpStubNode
+ {
+ protected override void EmitCode(NodeFactory factory, ref ARMEmitter encoder, bool relocsOnly)
+ {
+ if (!_target.RepresentsIndirectionCell)
+ {
+ encoder.EmitJMP(_target); // b methodEntryPoint
+ }
+ else
+ {
+ encoder.EmitMOV(encoder.TargetRegister.InterproceduralScratch, _target);
+ encoder.EmitJMP(encoder.TargetRegister.InterproceduralScratch);
+ }
+ }
+ }
+}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/TargetRegisterMap.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/TargetRegisterMap.cs
index 5e0fde4fa..6ac115a14 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/TargetRegisterMap.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_ARM/TargetRegisterMap.cs
@@ -16,12 +16,14 @@ namespace ILCompiler.DependencyAnalysis.ARM
public readonly Register Arg0;
public readonly Register Arg1;
public readonly Register Result;
+ public readonly Register InterproceduralScratch;
public TargetRegisterMap(TargetOS os)
{
Arg0 = Register.R0;
Arg1 = Register.R1;
Result = Register.R0;
+ InterproceduralScratch = Register.R12;
}
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X64/X64Emitter.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X64/X64Emitter.cs
index 3ca448c3f..76c7aa37f 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X64/X64Emitter.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X64/X64Emitter.cs
@@ -74,8 +74,17 @@ namespace ILCompiler.DependencyAnalysis.X64
public void EmitJMP(ISymbolNode symbol)
{
- Builder.EmitByte(0xE9);
- Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_REL32);
+ if (symbol.RepresentsIndirectionCell)
+ {
+ Builder.EmitByte(0xff);
+ Builder.EmitByte(0x25);
+ Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_REL32);
+ }
+ else
+ {
+ Builder.EmitByte(0xE9);
+ Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_REL32);
+ }
}
public void EmitINT3()
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X64/X64JumpStubNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X64/X64JumpStubNode.cs
new file mode 100644
index 000000000..ceaa37150
--- /dev/null
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X64/X64JumpStubNode.cs
@@ -0,0 +1,16 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using ILCompiler.DependencyAnalysis.X64;
+
+namespace ILCompiler.DependencyAnalysis
+{
+ public partial class JumpStubNode
+ {
+ protected override void EmitCode(NodeFactory factory, ref X64Emitter encoder, bool relocsOnly)
+ {
+ encoder.EmitJMP(_target);
+ }
+ }
+}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X86/X86Emitter.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X86/X86Emitter.cs
index 72068ff22..b44300b21 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X86/X86Emitter.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X86/X86Emitter.cs
@@ -28,8 +28,17 @@ namespace ILCompiler.DependencyAnalysis.X86
public void EmitJMP(ISymbolNode symbol)
{
- Builder.EmitByte(0xE9);
- Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_REL32);
+ if (symbol.RepresentsIndirectionCell)
+ {
+ Builder.EmitByte(0xff);
+ Builder.EmitByte(0x25);
+ Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_REL32);
+ }
+ else
+ {
+ Builder.EmitByte(0xE9);
+ Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_REL32);
+ }
}
private bool InSignedByteRange(int i)
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X86/X86JumpStubNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X86/X86JumpStubNode.cs
new file mode 100644
index 000000000..b95bd1a54
--- /dev/null
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/Target_X86/X86JumpStubNode.cs
@@ -0,0 +1,16 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using ILCompiler.DependencyAnalysis.X86;
+
+namespace ILCompiler.DependencyAnalysis
+{
+ public partial class JumpStubNode
+ {
+ protected override void EmitCode(NodeFactory factory, ref X86Emitter encoder, bool relocsOnly)
+ {
+ encoder.EmitJMP(_target);
+ }
+ }
+}
diff --git a/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj b/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj
index 475866398..25de949da 100644
--- a/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj
+++ b/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj
@@ -234,6 +234,8 @@
<Compile Include="Compiler\DependencyAnalysis\INodeWithDebugInfo.cs" />
<Compile Include="Compiler\DependencyAnalysis\IExportableSymbolNode.cs" />
<Compile Include="Compiler\DependencyAnalysis\ISymbolNode.cs" />
+ <Compile Include="Compiler\DependencyAnalysis\JumpStubNode.cs" />
+ <Compile Include="Compiler\DependencyAnalysis\NamedJumpStubNode.cs" />
<Compile Include="Compiler\DependencyAnalysis\NodeFactory.cs" />
<Compile Include="Compiler\DependencyAnalysis\NodeFactory.GenericLookups.cs" />
<Compile Include="Compiler\DependencyAnalysis\NodeFactory.NativeLayout.cs" />
@@ -258,6 +260,7 @@
<Compile Include="Compiler\DependencyAnalysis\VirtualMethodUseNode.cs" />
<Compile Include="Compiler\DependencyAnalysis\Target_X64\Register.cs" />
<Compile Include="Compiler\DependencyAnalysis\Target_X64\X64Emitter.cs" />
+ <Compile Include="Compiler\DependencyAnalysis\Target_X64\X64JumpStubNode.cs" />
<Compile Include="Compiler\DependencyAnalysis\Target_X64\X64ReadyToRunHelperNode.cs" />
<Compile Include="Compiler\DependencyAnalysis\InterfaceDispatchMapNode.cs" />
<Compile Include="Compiler\DependencyAnalysis\Target_X86\AddrMode.cs" />
@@ -265,12 +268,14 @@
<Compile Include="Compiler\DependencyAnalysis\Target_X86\X86UnboxingStubNode.cs" />
<Compile Include="Compiler\DependencyAnalysis\Target_X86\Register.cs" />
<Compile Include="Compiler\DependencyAnalysis\Target_X86\X86Emitter.cs" />
+ <Compile Include="Compiler\DependencyAnalysis\Target_X86\X86JumpStubNode.cs" />
<Compile Include="Compiler\DependencyAnalysis\Target_X86\X86ReadyToRunHelperNode.cs" />
<Compile Include="Compiler\DependencyAnalysis\Target_X86\X86ReadyToRunGenericHelperNode.cs" />
<Compile Include="Compiler\DependencyAnalysis\Target_ARM\TargetRegisterMap.cs" />
<Compile Include="Compiler\DependencyAnalysis\Target_ARM\ARMUnboxingStubNode.cs" />
<Compile Include="Compiler\DependencyAnalysis\Target_ARM\Register.cs" />
<Compile Include="Compiler\DependencyAnalysis\Target_ARM\ARMEmitter.cs" />
+ <Compile Include="Compiler\DependencyAnalysis\Target_ARM\ARMJumpStubNode.cs" />
<Compile Include="Compiler\DependencyAnalysis\Target_ARM\ARMReadyToRunHelperNode.cs" />
<Compile Include="Compiler\DependencyAnalysis\Target_ARM\ARMReadyToRunGenericHelperNode.cs" />
<Compile Include="Compiler\ExportedMethodsRootProvider.cs" />