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
|
From 2cd8b35316e145e75b2329c0927dbee289c032e6 Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Wed, 23 Sep 2026 14:33:27 +0100
Subject: [PATCH] JavaScriptCore: disable linker relaxation for the LLInt asm
IPInt opcode handlers are padded to 256-byte aligned dispatch slots with
.balignw. On RISC-V the linker relaxes auipc+jalr/addi pairs into single
instructions, shrinking each handler by 4 bytes, and the padding is not
recomputed afterwards. Consecutive ipint_*_validate labels then sit 252
bytes apart and IPInt::initialize()'s VALIDATE_IPINT_OPCODE assertions
fire.
Wrap the LLInt asm block in .option norelax on RISCV64 so every dispatch
slot keeps its alignment.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
.../llint/LowLevelInterpreter.cpp | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter.cpp
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter.cpp
@@ -524,13 +524,30 @@ WTF_ALLOW_UNSAFE_BUFFER_USAGE_END
// the jsc_llint_begin and jsc_llint_end labels help lldb_webkit.py find the
// start and end of the llint instruction range quickly.
+// On RISC-V, the linker (mold) relaxes `auipc + jalr/addi` pairs into single
+// `j`/`addi`-via-gp instructions, shrinking IPInt opcode handlers by 4 bytes
+// each. The `.balignw 256` padding that follows each handler is not recomputed
+// after relaxation, so consecutive `ipint_*_validate` labels end up 252 bytes
+// apart instead of 256, and `IPInt::initialize()`'s `VALIDATE_IPINT_OPCODE`
+// asserts fire. Suppress relaxation across the entire LLInt asm to keep all
+// 256-byte-aligned dispatch slots intact.
+#if CPU(RISCV64)
+#define OFFLINE_ASM_BEGIN_OPTIONS ".option push\n.option norelax\n"
+#define OFFLINE_ASM_END_OPTIONS ".option pop\n"
+#else
+#define OFFLINE_ASM_BEGIN_OPTIONS ""
+#define OFFLINE_ASM_END_OPTIONS ""
+#endif
+
#define OFFLINE_ASM_BEGIN __asm__( \
+ OFFLINE_ASM_BEGIN_OPTIONS \
OFFLINE_ASM_GLOBAL_LABEL_IMPL(jsc_llint_begin, OFFLINE_ASM_NO_ALT_ENTRY_DIRECTIVE, OFFLINE_ASM_ALIGN4B, HIDE_SYMBOL) \
OFFLINE_ASM_BEGIN_SPACER
#define OFFLINE_ASM_END \
OFFLINE_ASM_BEGIN_SPACER \
OFFLINE_ASM_GLOBAL_LABEL_IMPL(jsc_llint_end, OFFLINE_ASM_NO_ALT_ENTRY_DIRECTIVE, OFFLINE_ASM_ALIGN4B, HIDE_SYMBOL) \
+ OFFLINE_ASM_END_OPTIONS \
);
#if ENABLE(LLINT_EMBEDDED_OPCODE_ID)
|