diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp
index df5bbae20bd95..12baec4bc9db0 100644
--- a/src/coreclr/jit/emitriscv64.cpp
+++ b/src/coreclr/jit/emitriscv64.cpp
@@ -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));
+ }
+
assert((addr & 1) == 0);
dst += 4;
diff --git a/src/coreclr/jit/emitriscv64.h b/src/coreclr/jit/emitriscv64.h
index 6c73f3fe577fc..c56d6f943fbe8 100644
--- a/src/coreclr/jit/emitriscv64.h
+++ b/src/coreclr/jit/emitriscv64.h
@@ -195,11 +195,11 @@ static bool isValidSimm21(ssize_t value)
return -(((int)1) << 20) <= value && value < (((int)1) << 20);
};
-// Returns true if 'value' is a legal signed immediate 32 bit encoding.
+// Returns true if 'value' is a legal signed immediate 32-bit encoding with the offset adjustment.
static bool isValidSimm32(ssize_t value)
{
- return -(((ssize_t)1) << 31) <= value && value < (((ssize_t)1) << 31);
-};
+ return (-(((ssize_t)1) << 31) - 0x800) <= value && value < (((ssize_t)1) << 31) - 0x800;
+}
// Returns the number of bits used by the given 'size'.
inline static unsigned getBitWidth(emitAttr size)
diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
index d2fe6e75e1db6..1aa55ee427eb9 100644
--- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
+++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
@@ -179,7 +179,6 @@ The .NET Foundation licenses this file to you under the MIT license.
-
@@ -222,6 +221,7 @@ The .NET Foundation licenses this file to you under the MIT license.
+
diff --git a/src/coreclr/nativeaot/Runtime/riscv64/ExceptionHandling.S b/src/coreclr/nativeaot/Runtime/riscv64/ExceptionHandling.S
index 36707233d18f5..50330ce381089 100644
--- a/src/coreclr/nativeaot/Runtime/riscv64/ExceptionHandling.S
+++ b/src/coreclr/nativeaot/Runtime/riscv64/ExceptionHandling.S
@@ -328,7 +328,7 @@
// Normal case where a valid return address location is hijacked
sd a1, 0(a3)
- tail ClearThreadState
+ tail LOCAL_LABEL(ClearThreadState)
LOCAL_LABEL(TailCallWasHijacked):
diff --git a/src/coreclr/nativeaot/Runtime/riscv64/UniversalTransition.S b/src/coreclr/nativeaot/Runtime/riscv64/UniversalTransition.S
index 45d61e749700f..f6c619d867ae9 100644
--- a/src/coreclr/nativeaot/Runtime/riscv64/UniversalTransition.S
+++ b/src/coreclr/nativeaot/Runtime/riscv64/UniversalTransition.S
@@ -136,6 +136,11 @@
mv a1, t1 // Second parameter to target function
jalr t0, t1, 0 // Jump to the function in t1
+ // We cannot make the label public as that tricks DIA stackwalker into thinking
+ // it's the beginning of a method. For this reason we export an auxiliary variable
+ // holding the address instead.
+ ALTERNATE_ENTRY ReturnFrom\FunctionName
+
// Restore the result address from t2
mv t2, a0 // Move result to t2
@@ -169,7 +174,6 @@
.endm
-
// To enable proper step-in behavior in the debugger, we need to have two instances
// of the thunk. For the first one, the debugger steps into the call in the function,
// for the other, it steps over it.
diff --git a/src/coreclr/nativeaot/Runtime/unix/unixasmmacrosriscv64.inc b/src/coreclr/nativeaot/Runtime/unix/unixasmmacrosriscv64.inc
index 5f6bd84a09476..0bb8f96a640db 100644
--- a/src/coreclr/nativeaot/Runtime/unix/unixasmmacrosriscv64.inc
+++ b/src/coreclr/nativeaot/Runtime/unix/unixasmmacrosriscv64.inc
@@ -44,18 +44,12 @@ C_FUNC(\Name):
.endm
.macro PREPARE_EXTERNAL_VAR Name, HelperReg
- lui \HelperReg, %hi(C_FUNC(\Name))
- addi \HelperReg, \HelperReg, %lo(C_FUNC(\Name))
-.endm
-
-.macro PREPARE_EXTERNAL_VAR_INDIRECT Name, HelperReg
- lui \HelperReg, %hi(C_FUNC(\Name))
- ld \HelperReg, %lo(C_FUNC(\Name))(\HelperReg)
+ la \HelperReg, C_FUNC(\Name) // Resolves the address in one step
.endm
.macro PREPARE_EXTERNAL_VAR_INDIRECT_W Name, HelperReg
- lui \HelperReg, %hi(C_FUNC(\Name))
- lw \HelperReg, %lo(C_FUNC(\Name))(\HelperReg)
+ la \HelperReg, C_FUNC(\Name)
+ lw \HelperReg, 0(\HelperReg)
.endm
.macro PROLOG_STACK_ALLOC Size
diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ObjectDataBuilder.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ObjectDataBuilder.cs
index daa917e6b9fa8..53e4671b57a58 100644
--- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ObjectDataBuilder.cs
+++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ObjectDataBuilder.cs
@@ -301,7 +301,6 @@ public void EmitReloc(ISymbolNode symbol, RelocType relocType, int delta = 0)
case RelocType.IMAGE_REL_BASED_LOONGARCH64_JIR:
case RelocType.IMAGE_REL_BASED_RISCV64_PC:
- case RelocType.IMAGE_REL_BASED_RISCV64_JALR:
Debug.Assert(delta == 0);
// Do not vacate space for this kind of relocation, because
// the space is embedded in the instruction.
diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs
index 68e299378af59..90b1d496e41aa 100644
--- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs
+++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs
@@ -20,7 +20,6 @@ public enum RelocType
IMAGE_REL_BASED_LOONGARCH64_PC = 0x16, // LoongArch64: pcalau12i+imm12
IMAGE_REL_BASED_LOONGARCH64_JIR = 0x17, // LoongArch64: pcaddu18i+jirl
IMAGE_REL_BASED_RISCV64_PC = 0x18, // RiscV64: auipc
- IMAGE_REL_BASED_RISCV64_JALR = 0x19, // RiscV64: jalr (indirect jump)
IMAGE_REL_BASED_RELPTR32 = 0x7C, // 32-bit relative address from byte starting reloc
// This is a special NGEN-specific relocation type
// for relative pointer (used to make NGen relocation
@@ -470,7 +469,7 @@ private static unsafe int GetRiscV64PC(uint* pCode)
private static unsafe void PutRiscV64PC(uint* pCode, long imm32)
{
// Verify that we got a valid offset
- Debug.Assert((int)imm32 == imm32);
+ Debug.Assert((imm32 >= (long)-0x80000000 - 0x800) && (imm32 < (long)0x80000000 - 0x800));
int doff = (int)(imm32 & 0xfff);
uint auipcInstr = *pCode;
diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_RiscV64/RiscV64Emitter.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_RiscV64/RiscV64Emitter.cs
index 6b547abefb190..aed078619dfd1 100644
--- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_RiscV64/RiscV64Emitter.cs
+++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_RiscV64/RiscV64Emitter.cs
@@ -111,7 +111,7 @@ public void EmitJMP(ISymbolNode symbol)
}
else
{
- Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_RISCV64_JALR);
+ Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_RISCV64_PC);
EmitPC(Register.X29); // auipc x29, 0
EmitJALR(Register.X0, Register.X29, 0); // jalr x0, 0(x29)
}
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/ElfObjectWriter.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/ElfObjectWriter.cs
index d39e095db8247..e318cccff2411 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/ElfObjectWriter.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/ElfObjectWriter.cs
@@ -552,9 +552,8 @@ private void EmitRelocationsRiscV64(int sectionIndex, List 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_RISCV64_PC => R_RISCV_PCREL_HI20,
- IMAGE_REL_BASED_RISCV64_JALR => R_RISCV_CALL32,
+ IMAGE_REL_BASED_RELPTR32 => R_RISCV_64_LO12,
+ IMAGE_REL_BASED_RISCV64_PC => R_RISCV_64_HI20,
_ => throw new NotSupportedException("Unknown relocation type: " + symbolicRelocation.Type)
};