1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
// 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 class AssemblyStubNode : ObjectNode, ISymbolDefinitionNode
{
public AssemblyStubNode()
{
}
/// <summary>
/// Gets a value indicating whether the stub's address is visible from managed code
/// and could be a target of a managed calli.
/// </summary>
protected virtual bool IsVisibleFromManagedCode => true;
public override ObjectNodeSection Section => ObjectNodeSection.TextSection;
public override bool StaticDependenciesAreComputed => true;
public abstract void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb);
public int Offset => 0;
public override bool IsShareable => false;
public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
{
// If the address is expected to be visible from managed code, we need to align
// at the managed code boundaries to prevent the stub from being confused with
// a fat fuction pointer. Otherwise we can align tighter.
int alignment = IsVisibleFromManagedCode ?
factory.Target.MinimumFunctionAlignment :
factory.Target.MinimumCodeAlignment;
switch (factory.Target.Architecture)
{
case TargetArchitecture.X64:
X64.X64Emitter x64Emitter = new X64.X64Emitter(factory, relocsOnly);
EmitCode(factory, ref x64Emitter, relocsOnly);
x64Emitter.Builder.RequireInitialAlignment(alignment);
x64Emitter.Builder.AddSymbol(this);
return x64Emitter.Builder.ToObjectData();
case TargetArchitecture.X86:
X86.X86Emitter x86Emitter = new X86.X86Emitter(factory, relocsOnly);
EmitCode(factory, ref x86Emitter, relocsOnly);
x86Emitter.Builder.RequireInitialAlignment(alignment);
x86Emitter.Builder.AddSymbol(this);
return x86Emitter.Builder.ToObjectData();
case TargetArchitecture.ARM:
case TargetArchitecture.ARMEL:
ARM.ARMEmitter armEmitter = new ARM.ARMEmitter(factory, relocsOnly);
EmitCode(factory, ref armEmitter, relocsOnly);
armEmitter.Builder.RequireInitialAlignment(alignment);
armEmitter.Builder.AddSymbol(this);
return armEmitter.Builder.ToObjectData();
case TargetArchitecture.ARM64:
ARM64.ARM64Emitter arm64Emitter = new ARM64.ARM64Emitter(factory, relocsOnly);
EmitCode(factory, ref arm64Emitter, relocsOnly);
arm64Emitter.Builder.RequireInitialAlignment(alignment);
arm64Emitter.Builder.AddSymbol(this);
return arm64Emitter.Builder.ToObjectData();
default:
throw new NotImplementedException();
}
}
protected abstract void EmitCode(NodeFactory factory, ref X64.X64Emitter instructionEncoder, bool relocsOnly);
protected abstract void EmitCode(NodeFactory factory, ref X86.X86Emitter instructionEncoder, bool relocsOnly);
protected abstract void EmitCode(NodeFactory factory, ref ARM.ARMEmitter instructionEncoder, bool relocsOnly);
protected abstract void EmitCode(NodeFactory factory, ref ARM64.ARM64Emitter instructionEncoder, bool relocsOnly);
}
}
|