Skip to content

Commit 3f2278e

Browse files
GeoffroyAubeyTautvydasZilys
authored andcommitted
Fix restriction on RWX pages on macOS arm64
Signed-off-by: Tautvydas Žilys <[email protected]>
1 parent 6d6f25c commit 3f2278e

File tree

7 files changed

+94
-0
lines changed

7 files changed

+94
-0
lines changed

mono/mini/exceptions-arm64.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ mono_arch_get_restore_context (MonoTrampInfo **info, gboolean aot)
3636

3737
size = 256;
3838
code = start = mono_global_codeman_reserve (size);
39+
MONO_SCOPE_ENABLE_JIT_WRITE();
3940

4041
arm_movx (code, ARMREG_IP0, ARMREG_R0);
4142
ctx_reg = ARMREG_IP0;
@@ -85,6 +86,7 @@ mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot)
8586

8687
size = 512;
8788
start = code = mono_global_codeman_reserve (size);
89+
MONO_SCOPE_ENABLE_JIT_WRITE();
8890

8991
/* Compute stack frame size and offsets */
9092
offset = 0;
@@ -171,6 +173,7 @@ get_throw_trampoline (int size, gboolean corlib, gboolean rethrow, gboolean llvm
171173
int i, offset, gregs_offset, fregs_offset, frame_size, num_fregs;
172174

173175
code = start = mono_global_codeman_reserve (size);
176+
MONO_SCOPE_ENABLE_JIT_WRITE();
174177

175178
/* We are being called by JITted code, the exception object/type token is in R0 */
176179

mono/mini/mini-arm64.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ static gpointer bp_trampoline;
5656

5757
static gboolean ios_abi;
5858

59+
#if defined(__APPLE__)
60+
__thread jit_protect_mode arm_current_jit_protect_mode = JPM_NONE;
61+
#endif
62+
5963
static __attribute__ ((__warn_unused_result__)) guint8* emit_load_regset (guint8 *code, guint64 regs, int basereg, int offset);
6064

6165
const char*
@@ -100,6 +104,8 @@ get_delegate_invoke_impl (gboolean has_target, gboolean param_count, guint32 *co
100104
{
101105
guint8 *code, *start;
102106

107+
MONO_SCOPE_ENABLE_JIT_WRITE();
108+
103109
if (has_target) {
104110
start = code = mono_global_codeman_reserve (12);
105111

@@ -5009,6 +5015,7 @@ mono_arch_build_imt_trampoline (MonoVTable *vtable, MonoDomain *domain, MonoIMTC
50095015
else
50105016
buf = mono_domain_code_reserve (domain, buf_len);
50115017
code = buf;
5018+
MONO_SCOPE_ENABLE_JIT_WRITE();
50125019

50135020
/*
50145021
* We are called by JITted code, which passes in the IMT argument in

mono/mini/mini-runtime.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2173,6 +2173,8 @@ mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, gboolean jit_
21732173
gpointer
21742174
mono_jit_compile_method (MonoMethod *method, MonoError *error)
21752175
{
2176+
MONO_SCOPE_ENABLE_JIT_WRITE();
2177+
21762178
gpointer code;
21772179

21782180
code = mono_jit_compile_method_with_opt (method, mono_get_optimizations_for_method (method, default_opt), FALSE, error);
@@ -2804,6 +2806,7 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec
28042806
if (!is_ok (error))
28052807
return NULL;
28062808
} else {
2809+
MONO_SCOPE_ENABLE_JIT_EXEC();
28072810
runtime_invoke = (MonoObject *(*)(MonoObject *, void **, MonoObject **, void *))info->runtime_invoke;
28082811

28092812
result = runtime_invoke ((MonoObject *)obj, params, exc, info->compiled_method);

mono/mini/mini.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2223,6 +2223,8 @@ mono_codegen (MonoCompile *cfg)
22232223
MonoDomain *code_domain;
22242224
guint unwindlen = 0;
22252225

2226+
MONO_SCOPE_ENABLE_JIT_WRITE();
2227+
22262228
if (mono_using_xdebug)
22272229
/*
22282230
* Recent gdb versions have trouble processing symbol files containing
@@ -3096,6 +3098,8 @@ init_backend (MonoBackend *backend)
30963098
MonoCompile*
30973099
mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFlags flags, int parts, int aot_method_index)
30983100
{
3101+
MONO_SCOPE_ENABLE_JIT_WRITE();
3102+
30993103
MonoMethodHeader *header;
31003104
MonoMethodSignature *sig;
31013105
MonoError err;

mono/mini/mini.h

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2886,4 +2886,66 @@ gboolean MONO_SIG_HANDLER_SIGNATURE (mono_chain_signal);
28862886
MonoGenericContext
28872887
mono_get_generic_context_from_stack_frame (MonoJitInfo *ji, gpointer generic_info);
28882888

2889+
#if defined(__APPLE__) && defined(__arm64__)
2890+
2891+
typedef enum {
2892+
JPM_NONE,
2893+
JPM_ENABLED,
2894+
JPM_DISABLED,
2895+
} jit_protect_mode;
2896+
2897+
extern __thread jit_protect_mode arm_current_jit_protect_mode;
2898+
2899+
static void mono_arm_jit_write_protect_enable()
2900+
{
2901+
if (__builtin_available(macOS 11, *)) {
2902+
if (arm_current_jit_protect_mode != JPM_ENABLED) {
2903+
pthread_jit_write_protect_np(1);
2904+
arm_current_jit_protect_mode = JPM_ENABLED;
2905+
}
2906+
}
2907+
}
2908+
2909+
static void mono_arm_jit_write_protect_disable()
2910+
{
2911+
if (__builtin_available(macOS 11, *)) {
2912+
if (arm_current_jit_protect_mode != JPM_DISABLED) {
2913+
pthread_jit_write_protect_np(0);
2914+
arm_current_jit_protect_mode = JPM_DISABLED;
2915+
}
2916+
}
2917+
}
2918+
2919+
#define MONO_SCOPE_ENABLE_JIT_WRITE() \
2920+
__attribute__((unused, cleanup(mono_arm_restore_jit_protect_mode))) \
2921+
jit_protect_mode scope_restrict_mode = arm_current_jit_protect_mode; \
2922+
mono_arm_jit_write_protect_disable(); \
2923+
2924+
#define MONO_SCOPE_ENABLE_JIT_EXEC() \
2925+
__attribute__((unused, cleanup(mono_arm_restore_jit_protect_mode))) \
2926+
jit_protect_mode scope_restrict_mode = arm_current_jit_protect_mode; \
2927+
mono_arm_jit_write_protect_enable(); \
2928+
2929+
static void mono_arm_restore_jit_protect_mode(jit_protect_mode* previous_jit_protect_mode)
2930+
{
2931+
if (*previous_jit_protect_mode == arm_current_jit_protect_mode)
2932+
return;
2933+
2934+
switch (*previous_jit_protect_mode)
2935+
{
2936+
case JPM_ENABLED:
2937+
mono_arm_jit_write_protect_enable();
2938+
break;
2939+
case JPM_DISABLED:
2940+
case JPM_NONE:
2941+
default:
2942+
mono_arm_jit_write_protect_disable();
2943+
}
2944+
}
2945+
2946+
#else
2947+
#define MONO_SCOPE_ENABLE_JIT_WRITE()
2948+
#define MONO_SCOPE_ENABLE_JIT_EXEC()
2949+
#endif
2950+
28892951
#endif /* __MONO_MINI_H__ */

mono/mini/tramp-arm64.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
void
3333
mono_arch_patch_callsite (guint8 *method_start, guint8 *code_ptr, guint8 *addr)
3434
{
35+
MONO_SCOPE_ENABLE_JIT_WRITE();
36+
3537
mono_arm_patch (code_ptr - 4, addr, MONO_R_ARM64_BL);
3638
mono_arch_flush_icache (code_ptr - 4, 4);
3739
}
@@ -113,6 +115,7 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
113115

114116
buf_len = 768;
115117
buf = code = mono_global_codeman_reserve (buf_len);
118+
MONO_SCOPE_ENABLE_JIT_WRITE();
116119

117120
/*
118121
* We are getting called by a specific trampoline, ip1 contains the trampoline argument.
@@ -328,6 +331,7 @@ mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_ty
328331
* Pass the argument in ip1, clobbering ip0.
329332
*/
330333
tramp = mono_get_trampoline_code (tramp_type);
334+
MONO_SCOPE_ENABLE_JIT_WRITE();
331335

332336
buf = code = mono_global_codeman_reserve (buf_len);
333337

@@ -352,6 +356,8 @@ mono_arch_get_unbox_trampoline (MonoMethod *m, gpointer addr)
352356
MonoDomain *domain = mono_domain_get ();
353357

354358
start = code = mono_domain_code_reserve (domain, size);
359+
MONO_SCOPE_ENABLE_JIT_WRITE();
360+
355361
code = mono_arm_emit_imm64 (code, ARMREG_IP0, (guint64)addr);
356362
arm_addx_imm (code, ARMREG_R0, ARMREG_R0, sizeof (MonoObject));
357363
arm_brx (code, ARMREG_IP0);
@@ -369,6 +375,8 @@ mono_arch_get_static_rgctx_trampoline (gpointer arg, gpointer addr)
369375
MonoDomain *domain = mono_domain_get ();
370376

371377
start = code = mono_domain_code_reserve (domain, buf_len);
378+
MONO_SCOPE_ENABLE_JIT_WRITE();
379+
372380
code = mono_arm_emit_imm64 (code, MONO_ARCH_RGCTX_REG, (guint64)arg);
373381
code = mono_arm_emit_imm64 (code, ARMREG_IP0, (guint64)addr);
374382
arm_brx (code, ARMREG_IP0);
@@ -407,6 +415,7 @@ mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot, MonoTrampInfo **info
407415

408416
buf_size = 64 + 16 * depth;
409417
code = buf = mono_global_codeman_reserve (buf_size);
418+
MONO_SCOPE_ENABLE_JIT_WRITE();
410419

411420
rgctx_null_jumps = g_malloc0 (sizeof (guint8*) * (depth + 2));
412421
njumps = 0;
@@ -493,6 +502,7 @@ mono_arch_create_general_rgctx_lazy_fetch_trampoline (MonoTrampInfo **info, gboo
493502
tramp_size = 32;
494503

495504
code = buf = mono_global_codeman_reserve (tramp_size);
505+
MONO_SCOPE_ENABLE_JIT_WRITE();
496506

497507
mono_add_unwind_op_def_cfa (unwind_ops, code, buf, ARMREG_SP, 0);
498508

@@ -531,6 +541,7 @@ mono_arch_create_sdb_trampoline (gboolean single_step, MonoTrampInfo **info, gbo
531541
MonoJumpInfo *ji = NULL;
532542

533543
code = buf = mono_global_codeman_reserve (tramp_size);
544+
MONO_SCOPE_ENABLE_JIT_WRITE();
534545

535546
/* Compute stack frame size and offsets */
536547
offset = 0;
@@ -631,6 +642,8 @@ mono_arch_get_enter_icall_trampoline (MonoTrampInfo **info)
631642
buf_len = 512 + 1024;
632643
start = code = (guint8 *) mono_global_codeman_reserve (buf_len);
633644

645+
MONO_SCOPE_ENABLE_JIT_WRITE();
646+
634647
/* save FP and LR */
635648
framesize += 2 * sizeof (mgreg_t);
636649

mono/mini/unwind.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,8 @@ mono_unwind_frame (guint8 *unwind_info, guint32 unwind_info_len,
518518
mgreg_t **save_locations, int save_locations_len,
519519
guint8 **out_cfa)
520520
{
521+
MONO_SCOPE_ENABLE_JIT_WRITE();
522+
521523
Loc locations [NUM_HW_REGS];
522524
guint8 reg_saved [NUM_HW_REGS];
523525
int pos, reg, hwreg, cfa_reg = -1, cfa_offset = 0, offset;

0 commit comments

Comments
 (0)