Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix relocs errors on riscv64 #111317

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/coreclr/jit/emitriscv64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1627,7 +1627,11 @@ unsigned emitter::emitOutputCall(const insGroup* ig, BYTE* dst, instrDesc* id, c
int reg2 = ((int)addr & 1) + 10;
addr = addr ^ 1;

assert(isValidSimm32(addr - (ssize_t)dst));
if (!emitComp->opts.compReloc)
{
assert(isValidSimm32(addr - (ssize_t)dst));
am11 marked this conversation as resolved.
Show resolved Hide resolved
}

assert((addr & 1) == 0);

dst += 4;
Expand All @@ -1642,7 +1646,7 @@ unsigned emitter::emitOutputCall(const insGroup* ig, BYTE* dst, instrDesc* id, c
#endif
emitOutput_Instr(dst, 0x00000067 | (REG_DEFAULT_HELPER_CALL_TARGET << 15) | reg2 << 7);

emitRecordRelocation(dst - 4, (BYTE*)addr, IMAGE_REL_RISCV64_PC);
emitRecordRelocation(dst - 4, (BYTE*)addr, IMAGE_REL_RISCV64_JALR);
}
else
{
Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/pal/inc/rt/ntimage.h
Original file line number Diff line number Diff line change
Expand Up @@ -1024,7 +1024,8 @@ typedef IMAGE_RELOCATION UNALIGNED *PIMAGE_RELOCATION;
//
// RISCV64 relocation types
//
#define IMAGE_REL_RISCV64_PC 0x0003
#define IMAGE_REL_RISCV64_PC 0x0002
#define IMAGE_REL_RISCV64_JALR 0x0004

//
// CEF relocation types.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,41 @@ private static unsafe void PutRiscV64PC(uint* pCode, long imm32)
Debug.Assert(GetRiscV64PC(pCode) == imm32);
}

private static unsafe long GetRiscV64JALR(uint* pCode)
{
uint jalrInstr = *pCode;

// Extract the 12-bit signed immediate (bits 31:20 of the instruction).
long imm = (long)((jalrInstr >> 20) & 0xfff);

// Sign-extend the immediate.
if ((imm & 0x800) != 0)
imm |= 0xfffff000;

return imm;
am11 marked this conversation as resolved.
Show resolved Hide resolved
}

private static unsafe void PutRiscV64JALR(uint* pCode, long imm)
{
// Verify that we got a valid offset within the 12-bit signed immediate range.
Debug.Assert(imm >= -0x800 && imm < 0x800);

uint jalrInstr = *pCode;

Debug.Assert((jalrInstr & 0x7f) == 0x17); // JALR opcode
am11 marked this conversation as resolved.
Show resolved Hide resolved

// Extract the lower 12 bits of the immediate.
uint imm12 = (uint)(imm & 0xfff);

// Assemble the JALR instruction with the immediate.
jalrInstr &= ~0xfff00000;
jalrInstr |= (imm12 << 20);

*pCode = jalrInstr;

Debug.Assert(GetRiscV64JALR(pCode) == imm);
}

public Relocation(RelocType relocType, int offset, ISymbolNode target)
{
RelocType = relocType;
Expand Down Expand Up @@ -549,6 +584,9 @@ public static unsafe void WriteValue(RelocType relocType, void* location, long v
case RelocType.IMAGE_REL_BASED_RISCV64_PC:
PutRiscV64PC((uint*)location, value);
break;
case RelocType.IMAGE_REL_BASED_RISCV64_JALR:
PutRiscV64JALR((uint*)location, value);
break;
am11 marked this conversation as resolved.
Show resolved Hide resolved
default:
Debug.Fail("Invalid RelocType: " + relocType);
break;
Expand Down Expand Up @@ -616,6 +654,8 @@ public static unsafe long ReadValue(RelocType relocType, void* location)
return (long)GetLoongArch64JIR((uint*)location);
case RelocType.IMAGE_REL_BASED_RISCV64_PC:
return (long)GetRiscV64PC((uint*)location);
case RelocType.IMAGE_REL_BASED_RISCV64_JALR:
return (long)GetRiscV64JALR((uint*)location);
am11 marked this conversation as resolved.
Show resolved Hide resolved
default:
Debug.Fail("Invalid RelocType: " + relocType);
return 0;
Expand Down
5 changes: 4 additions & 1 deletion src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4026,12 +4026,15 @@ private static RelocType GetRelocType(TargetArchitecture targetArchitecture, ush
}
case TargetArchitecture.RiscV64:
{
const ushort IMAGE_REL_RISCV64_PC = 3;
const ushort IMAGE_REL_RISCV64_PC = 2;
const ushort IMAGE_REL_RISCV64_JALR = 4;

switch (fRelocType)
{
case IMAGE_REL_RISCV64_PC:
return RelocType.IMAGE_REL_BASED_RISCV64_PC;
case IMAGE_REL_RISCV64_JALR:
return RelocType.IMAGE_REL_BASED_RISCV64_JALR;
default:
Debug.Fail("Invalid RelocType: " + fRelocType);
return 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ private void EmitRelocationsRiscV64(int sectionIndex, List<SymbolicRelocation> r
{
IMAGE_REL_BASED_DIR64 => R_RISCV_64,
IMAGE_REL_BASED_HIGHLOW => R_RISCV_32,
IMAGE_REL_BASED_RELPTR32 => R_RISCV_RELATIVE,
IMAGE_REL_BASED_RELPTR32 => R_RISCV_64,
am11 marked this conversation as resolved.
Show resolved Hide resolved
IMAGE_REL_BASED_RISCV64_PC => R_RISCV_PCREL_HI20,
IMAGE_REL_BASED_RISCV64_JALR => R_RISCV_CALL32,
_ => throw new NotSupportedException("Unknown relocation type: " + symbolicRelocation.Type)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,12 @@ public void ProcessRelocation(RelocType relocationType, int sourceRVA, int targe
delta = targetRVA - sourceRVA;
break;
}
case RelocType.IMAGE_REL_BASED_RISCV64_JALR:
{
relocationLength = 8;
delta = targetRVA - sourceRVA;
break;
}

default:
throw new NotSupportedException();
Expand All @@ -257,7 +263,8 @@ public void ProcessRelocation(RelocType relocationType, int sourceRVA, int targe
(relocationType == RelocType.IMAGE_REL_BASED_ARM64_PAGEOFFSET_12A) ||
(relocationType == RelocType.IMAGE_REL_BASED_LOONGARCH64_PC) ||
(relocationType == RelocType.IMAGE_REL_BASED_LOONGARCH64_JIR) ||
(relocationType == RelocType.IMAGE_REL_BASED_RISCV64_PC)
(relocationType == RelocType.IMAGE_REL_BASED_RISCV64_PC) ||
(relocationType == RelocType.IMAGE_REL_BASED_RISCV64_JALR)
) && (value != 0))
{
throw new NotSupportedException();
Expand Down
Loading