Skip to content

Commit a12ecf9

Browse files
authored
Update ImportThunk for community architectures to use PC-relative addressing (#121453)
1 parent f48fbe9 commit a12ecf9

File tree

7 files changed

+37
-111
lines changed

7 files changed

+37
-111
lines changed

src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -627,9 +627,9 @@ public static int GetSize(RelocType relocType)
627627
RelocType.IMAGE_REL_BASED_ARM64_PAGEOFFSET_12L => 4,
628628
RelocType.IMAGE_REL_BASED_THUMB_MOV32 => 8,
629629
RelocType.IMAGE_REL_BASED_THUMB_MOV32_PCREL => 8,
630-
RelocType.IMAGE_REL_BASED_LOONGARCH64_PC => 16,
631-
RelocType.IMAGE_REL_BASED_LOONGARCH64_JIR => 16,
632-
RelocType.IMAGE_REL_BASED_RISCV64_PC => 16,
630+
RelocType.IMAGE_REL_BASED_LOONGARCH64_PC => 8,
631+
RelocType.IMAGE_REL_BASED_LOONGARCH64_JIR => 8,
632+
RelocType.IMAGE_REL_BASED_RISCV64_PC => 8,
633633
_ => throw new NotSupportedException(),
634634
};
635635
}

src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_LoongArch64/LoongArch64Emitter.cs

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,16 @@ public void EmitLD(Register regDst, Register regSrc, int offset)
9292
Builder.EmitUInt((uint)(0x28c00000 | (uint)((offset & 0xfff) << 10) | ((uint)regSrc << 5) | (uint)regDst));
9393
}
9494

95+
public void EmitLD(Register regDst, ISymbolNode symbol)
96+
{
97+
Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_LOONGARCH64_PC);
98+
// pcalau12i reg, off-hi-20bits
99+
EmitPCALAU12I(regDst);
100+
101+
// ld_d reg, reg, off-lo-12bits
102+
EmitLD(regDst, regDst, 0);
103+
}
104+
95105
public void EmitRET()
96106
{
97107
// jirl R0,R1,0
@@ -107,26 +117,10 @@ public void EmitJMP(ISymbolNode symbol)
107117
{
108118
if (symbol.RepresentsIndirectionCell)
109119
{
110-
Builder.RequireInitialPointerAlignment();
111-
112-
if (Builder.CountBytes % Builder.TargetPointerSize != 0)
113-
{
114-
// Emit a NOP instruction to align the 64-bit reloc below.
115-
EmitNOP();
116-
}
117-
118-
// pcaddi R21, 0
119-
EmitPCADDI(Register.R21);
120-
121-
EmitLD(Register.R21, Register.R21, 0x10);
122-
123-
// ld_d R21, R21, 0
124-
EmitLD(Register.R21, Register.R21, 0);
120+
EmitLD(Register.R21, symbol);
125121

126122
// jirl R0,R21,0
127123
EmitJMP(Register.R21);
128-
129-
Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_DIR64);
130124
}
131125
else
132126
{

src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_RiscV64/RiscV64Emitter.cs

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,15 @@ public void EmitJALR(Register regDst, Register regSrc, int offset)
8787
Builder.EmitUInt((uint)(0x00000067u | ((uint)regSrc << 15) | ((uint)regDst << 7) | (uint)((offset & 0xfff) << 20)));
8888
}
8989

90+
public void EmitLD(Register regDst, ISymbolNode symbol)
91+
{
92+
Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_RISCV64_PC);
93+
//auipc reg, off-hi-20bits
94+
EmitPC(regDst);
95+
//ld reg, off-lo-12bits(reg)
96+
EmitLD(regDst, regDst, 0);
97+
}
98+
9099
public void EmitRET()
91100
{
92101
// jalr x0,0(x1)
@@ -103,24 +112,9 @@ public void EmitJMP(ISymbolNode symbol)
103112
{
104113
if (symbol.RepresentsIndirectionCell)
105114
{
106-
Builder.RequireInitialPointerAlignment();
107-
108-
if (Builder.CountBytes % Builder.TargetPointerSize != 0)
109-
{
110-
// Emit a NOP instruction to align the 64-bit reloc below.
111-
EmitNOP();
112-
}
113-
114-
// auipc x29, 0
115-
EmitPC(Register.X29);
116-
// ld x29,16(x29)
117-
EmitLD(Register.X29, Register.X29, 16);
118-
// ld x29,0(x29)
119-
EmitLD(Register.X29, Register.X29, 0);
115+
EmitLD(Register.X29, symbol);
120116
// jalr x0,0(x29)
121117
EmitJALR(Register.X0, Register.X29, 0);
122-
123-
Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_DIR64);
124118
}
125119
else
126120
{

src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ImportThunk.cs

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@ enum Kind
2828

2929
private readonly ImportSectionNode _containingImportSection;
3030

31-
private readonly int _symbolOffset = 0;
32-
3331
/// <summary>
3432
/// Import thunks are used to call a runtime-provided helper which fixes up an indirection cell in a particular
3533
/// import section. Optionally they may also contain a relocation for a specific indirection cell to fix up.
@@ -62,21 +60,8 @@ public ImportThunk(NodeFactory factory, ReadyToRunHelper helperId, ImportSection
6260
{
6361
_thunkKind = Kind.Eager;
6462
}
65-
66-
if (_thunkKind != Kind.Eager
67-
&& factory.Target.Architecture is Internal.TypeSystem.TargetArchitecture.LoongArch64
68-
or Internal.TypeSystem.TargetArchitecture.RiscV64)
69-
{
70-
// We stuff the reloc to the module import pointer before the start of the thunk
71-
// to ensure alignment.
72-
// The thunk itself starts immediately after the reloc.
73-
// We don't need this for an Eager thunk.
74-
_symbolOffset = 8;
75-
}
7663
}
7764

78-
int ISymbolNode.Offset => base.Offset + _symbolOffset;
79-
8065
public override void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
8166
{
8267
sb.Append("DelayLoadHelper->"u8);

src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/Target_ARM64/ImportThunk.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,12 @@ protected override void EmitCode(NodeFactory factory, ref ARM64Emitter instructi
2020
instructionEncoder.EmitJMP(_helperCell);
2121
return;
2222
}
23-
2423
if (relocsOnly)
2524
{
2625
// When doing relocs only, we don't need to generate the actual instructions
27-
// as they will be ignored. Just emit the jump so we record the dependency.
26+
// as they will be ignored. Just emit the module import load and jump so we record the dependencies.
27+
instructionEncoder.EmitADRP(Register.X1, factory.ModuleImport);
28+
instructionEncoder.EmitLDR(Register.X1, Register.X1, factory.ModuleImport);
2829
instructionEncoder.EmitJMP(_helperCell);
2930
return;
3031
}

src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/Target_LoongArch64/ImportThunk.cs

Lines changed: 4 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,11 @@ protected override void EmitCode(NodeFactory factory, ref LoongArch64Emitter ins
2121
instructionEncoder.EmitJMP(_helperCell);
2222
return;
2323
}
24-
25-
instructionEncoder.Builder.RequireInitialPointerAlignment();
26-
Debug.Assert(instructionEncoder.Builder.CountBytes == 0);
27-
28-
instructionEncoder.Builder.EmitReloc(factory.ModuleImport, RelocType.IMAGE_REL_BASED_DIR64);
29-
30-
Debug.Assert(instructionEncoder.Builder.CountBytes == ((ISymbolNode)this).Offset);
31-
3224
if (relocsOnly)
3325
{
3426
// When doing relocs only, we don't need to generate the actual instructions
35-
// as they will be ignored. Just emit the jump so we record the dependency.
27+
// as they will be ignored. Just emit the module import load and jump so we record the dependencies.
28+
instructionEncoder.EmitLD(Register.R5, factory.ModuleImport);
3629
instructionEncoder.EmitJMP(_helperCell);
3730
return;
3831
}
@@ -50,32 +43,13 @@ protected override void EmitCode(NodeFactory factory, ref LoongArch64Emitter ins
5043
int index = _containingImportSection.IndexFromBeginningOfArray;
5144
instructionEncoder.EmitMOV(Register.R12, checked((ushort)index));
5245

53-
int offset = -instructionEncoder.Builder.CountBytes;
54-
55-
// get pc
56-
// pcaddi T1=R13, 0
57-
instructionEncoder.EmitPCADDI(Register.R13);
58-
59-
// load Module* -> T1
60-
instructionEncoder.EmitLD(Register.R13, Register.R13, offset);
61-
62-
// ld_d R13, R13, 0
63-
instructionEncoder.EmitLD(Register.R13, Register.R13, 0);
46+
instructionEncoder.EmitLD(Register.R13, factory.ModuleImport);
6447
break;
6548
}
6649

6750
case Kind.Lazy:
6851
{
69-
int offset = -instructionEncoder.Builder.CountBytes;
70-
// get pc
71-
// pcaddi R5, 0
72-
instructionEncoder.EmitPCADDI(Register.R5);
73-
74-
// load Module* -> R5=A1
75-
instructionEncoder.EmitLD(Register.R5, Register.R5, offset);
76-
77-
// ld_d R5, R5, 0
78-
instructionEncoder.EmitLD(Register.R5, Register.R5, 0);
52+
instructionEncoder.EmitLD(Register.R5, factory.ModuleImport);
7953
break;
8054
}
8155

src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/Target_RiscV64/ImportThunk.cs

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,11 @@ protected override void EmitCode(NodeFactory factory, ref RiscV64Emitter instruc
2121
return;
2222
}
2323

24-
instructionEncoder.Builder.RequireInitialPointerAlignment();
25-
Debug.Assert(instructionEncoder.Builder.CountBytes == 0);
26-
27-
instructionEncoder.Builder.EmitReloc(factory.ModuleImport, RelocType.IMAGE_REL_BASED_DIR64);
28-
29-
Debug.Assert(instructionEncoder.Builder.CountBytes == ((ISymbolNode)this).Offset);
30-
3124
if (relocsOnly)
3225
{
3326
// When doing relocs only, we don't need to generate the actual instructions
34-
// as they will be ignored. Just emit the jump so we record the dependency.
27+
// as they will be ignored. Just emit the module import load and jump so we record the dependencies.
28+
instructionEncoder.EmitLD(Register.X11, factory.ModuleImport);
3529
instructionEncoder.EmitJMP(_helperCell);
3630
return;
3731
}
@@ -51,31 +45,15 @@ protected override void EmitCode(NodeFactory factory, ref RiscV64Emitter instruc
5145
int index = _containingImportSection.IndexFromBeginningOfArray;
5246
instructionEncoder.EmitLI(Register.X5, index);
5347

54-
int offset = -instructionEncoder.Builder.CountBytes;
55-
56-
// get pc
57-
// auipc t1, 0
58-
instructionEncoder.EmitPC(Register.X6);
48+
// Move Module* -> t1
49+
instructionEncoder.EmitLD(Register.X6, factory.ModuleImport);
5950

60-
// load Module* -> t1
61-
instructionEncoder.EmitLD(Register.X6, Register.X6, offset);
62-
63-
// ld t1, t1, 0
64-
instructionEncoder.EmitLD(Register.X6, Register.X6, 0);
6551
break;
6652
}
6753
case Kind.Lazy:
6854
{
69-
int offset = -instructionEncoder.Builder.CountBytes;
70-
71-
// get pc
72-
instructionEncoder.EmitPC(Register.X11);
73-
74-
// load Module* -> a1
75-
instructionEncoder.EmitLD(Register.X11, Register.X11, offset);
76-
77-
// ld a1, a1, 0
78-
instructionEncoder.EmitLD(Register.X11, Register.X11, 0);
55+
// Load Module* -> a1
56+
instructionEncoder.EmitLD(Register.X11, factory.ModuleImport);
7957
break;
8058
}
8159
default:

0 commit comments

Comments
 (0)