Skip to content

Fix relocs errors on riscv64 #111317

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

Merged
merged 23 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
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->IsTargetAbi(CORINFO_NATIVEAOT_ABI))
{
assert(isValidSimm32(addr - (ssize_t)dst));
}

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;
}

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

// 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;
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);
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 @@ -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