diff options
author | Zoltan Varga <vargaz@gmail.com> | 2021-02-03 22:43:48 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-03 22:43:48 +0300 |
commit | 43190aeb5f7e4d7e0185d3b656054bf232219fe2 (patch) | |
tree | cfb25621bd646cece9dbd764372bdb60381170bf | |
parent | 91a7a1ba961e81b0f9d012743535ef20fa725826 (diff) |
Initial arm64e support (#20818)
* Fix the c++ build.
* Remove some unused prototypes.
* Initial arm64e support.
-rw-r--r-- | mono/arch/arm64/arm64-codegen.h | 12 | ||||
-rw-r--r-- | mono/metadata/threads.c | 6 | ||||
-rw-r--r-- | mono/mini/aot-compiler.c | 38 | ||||
-rw-r--r-- | mono/mini/aot-runtime.c | 52 | ||||
-rw-r--r-- | mono/mini/debugger-agent.c | 4 | ||||
-rw-r--r-- | mono/mini/driver.c | 8 | ||||
-rw-r--r-- | mono/mini/exceptions-arm64.c | 30 | ||||
-rw-r--r-- | mono/mini/image-writer.c | 2 | ||||
-rw-r--r-- | mono/mini/interp/interp.c | 1 | ||||
-rw-r--r-- | mono/mini/mini-arm64.c | 99 | ||||
-rw-r--r-- | mono/mini/mini-arm64.h | 4 | ||||
-rw-r--r-- | mono/mini/mini-exceptions.c | 16 | ||||
-rw-r--r-- | mono/mini/mini-generic-sharing.c | 10 | ||||
-rw-r--r-- | mono/mini/mini-posix.c | 1 | ||||
-rw-r--r-- | mono/mini/mini-runtime.c | 23 | ||||
-rw-r--r-- | mono/mini/mini-runtime.h | 9 | ||||
-rw-r--r-- | mono/mini/mini-trampolines.c | 6 | ||||
-rw-r--r-- | mono/mini/mini.c | 11 | ||||
-rw-r--r-- | mono/mini/mini.h | 17 | ||||
-rw-r--r-- | mono/mini/tramp-arm64-gsharedvt.c | 6 | ||||
-rw-r--r-- | mono/mini/tramp-arm64.c | 59 | ||||
-rw-r--r-- | mono/utils/Makefile.am | 3 | ||||
-rw-r--r-- | mono/utils/ftnptr.h | 43 | ||||
-rw-r--r-- | mono/utils/mach-support-arm64.c | 8 | ||||
-rw-r--r-- | mono/utils/mono-context.c | 17 | ||||
-rw-r--r-- | mono/utils/mono-sigcontext.h | 19 | ||||
-rw-r--r-- | mono/utils/mono-state.c | 28 |
27 files changed, 375 insertions, 157 deletions
diff --git a/mono/arch/arm64/arm64-codegen.h b/mono/arch/arm64/arm64-codegen.h index d35fda11752..00cd5b9ed8d 100644 --- a/mono/arch/arm64/arm64-codegen.h +++ b/mono/arch/arm64/arm64-codegen.h @@ -903,4 +903,16 @@ arm_encode_arith_imm (int imm, guint32 *shift) #define arm_blrabz(p, rn) arm_format_blra ((p), 0, 1, (rn), 0b11111) #define arm_blrab(p, rn, rm) arm_format_blra ((p), 1, 1, (rn), (rm)) +/* AUTIA */ + +#define arm_format_autia(p, crm, op2) arm_emit ((p), (0b11010101000000110010000000011111 << 0) | ((crm) << 8) | ((op2) << 5)) + +#define arm_autiasp(p) arm_format_autia ((p), 0b0011, 0b101) + +/* AUTIB */ + +#define arm_format_autib(p, crm, op2) arm_emit ((p), (0b11010101000000110010000000011111 << 0) | ((crm) << 8) | ((op2) << 5)) + +#define arm_autibsp(p) arm_format_autib ((p), 0b0011, 0b111) + #endif /* __arm_CODEGEN_H__ */ diff --git a/mono/metadata/threads.c b/mono/metadata/threads.c index 1cd60174174..f106af5707c 100644 --- a/mono/metadata/threads.c +++ b/mono/metadata/threads.c @@ -46,6 +46,7 @@ #include <mono/utils/os-event.h> #include <mono/utils/mono-threads-debug.h> #include <mono/utils/unlocked.h> +#include <mono/utils/ftnptr.h> #include <mono/metadata/w32handle.h> #include <mono/metadata/w32event.h> #include <mono/metadata/w32mutex.h> @@ -5652,6 +5653,11 @@ mono_jit_info_match (MonoJitInfo *ji, gpointer ip) { if (!ji) return FALSE; + +#ifdef MONO_ARCH_ENABLE_PTRAUTH + g_assert_not_reached (); +#endif + return ji->code_start <= ip && (char*)ip < (char*)ji->code_start + ji->code_size; } diff --git a/mono/mini/aot-compiler.c b/mono/mini/aot-compiler.c index 2dca457eed6..e384ef6c099 100644 --- a/mono/mini/aot-compiler.c +++ b/mono/mini/aot-compiler.c @@ -1303,7 +1303,11 @@ static void arm64_emit_plt_entry (MonoAotCompile *acfg, const char *got_symbol, int offset, int info_offset) { arm64_emit_load_got_slot (acfg, ARMREG_R16, offset / sizeof (target_mgreg_t)); +#ifdef MONO_ARCH_ENABLE_PTRAUTH + fprintf (acfg->fp, "braaz x16\n"); +#else fprintf (acfg->fp, "br x16\n"); +#endif /* Used by mono_aot_get_plt_info_offset () */ fprintf (acfg->fp, "%s %d\n", acfg->inst_directive, info_offset); } @@ -1327,7 +1331,7 @@ arm64_emit_tramp_page_common_code (MonoAotCompile *acfg, int pagesize, int arg_r arm_ldrp (code, arg_reg, ARMREG_IP0, 0); /* Address */ arm_ldrp (code, ARMREG_IP0, ARMREG_IP0, TARGET_SIZEOF_VOID_P); - arm_brx (code, ARMREG_IP0); + code = mono_arm_emit_brx (code, ARMREG_IP0); /* Emit it */ emit_code_bytes (acfg, buf, code - buf); @@ -1436,7 +1440,7 @@ arm64_emit_specific_trampoline_pages (MonoAotCompile *acfg) arm_subx (code, ARMREG_IP0, ARMREG_IP0, ARMREG_IP1); /* Address */ arm_ldrp (code, ARMREG_IP0, ARMREG_IP0, 0); - arm_brx (code, ARMREG_IP0); + code = mono_arm_emit_brx (code, ARMREG_IP0); /* Emit it */ emit_code_bytes (acfg, buf, code - buf); @@ -1483,13 +1487,13 @@ arm64_emit_specific_trampoline_pages (MonoAotCompile *acfg) arm_ldrp (code, ARMREG_IP0, ARMREG_IP1, TARGET_SIZEOF_VOID_P); /* Load vtable slot */ arm_ldrp (code, ARMREG_IP0, ARMREG_IP0, 0); - arm_brx (code, ARMREG_IP0); + code = mono_arm_emit_brx (code, ARMREG_IP0); /* No match */ mono_arm_patch (labels [2], code, MONO_R_ARM64_CBZ); /* Load fail addr */ arm_ldrp (code, ARMREG_IP0, ARMREG_IP1, TARGET_SIZEOF_VOID_P); - arm_brx (code, ARMREG_IP0); + code = mono_arm_emit_brx (code, ARMREG_IP0); emit_code_bytes (acfg, buf, code - buf); @@ -1506,7 +1510,11 @@ arm64_emit_specific_trampoline (MonoAotCompile *acfg, int offset, int *tramp_siz arm64_emit_load_got_slot (acfg, ARMREG_R17, offset + 1); /* Load generic trampoline address from first GOT slot */ arm64_emit_load_got_slot (acfg, ARMREG_R16, offset); +#ifdef MONO_ARCH_ENABLE_PTRAUTH + fprintf (acfg->fp, "braaz x16\n"); +#else fprintf (acfg->fp, "br x16\n"); +#endif *tramp_size = 7 * 4; } @@ -1527,7 +1535,11 @@ arm64_emit_static_rgctx_trampoline (MonoAotCompile *acfg, int offset, int *tramp arm64_emit_load_got_slot (acfg, MONO_ARCH_RGCTX_REG, offset); /* Load generic trampoline address from second GOT slot */ arm64_emit_load_got_slot (acfg, ARMREG_R16, offset + 1); +#ifdef MONO_ARCH_ENABLE_PTRAUTH + fprintf (acfg->fp, "braaz x16\n"); +#else fprintf (acfg->fp, "br x16\n"); +#endif *tramp_size = 7 * 4; } @@ -1561,13 +1573,13 @@ arm64_emit_imt_trampoline (MonoAotCompile *acfg, int offset, int *tramp_size) arm_ldrp (code, ARMREG_IP0, ARMREG_IP1, TARGET_SIZEOF_VOID_P); /* Load vtable slot */ arm_ldrp (code, ARMREG_IP0, ARMREG_IP0, 0); - arm_brx (code, ARMREG_IP0); + code = mono_arm_emit_brx (code, ARMREG_IP0); /* No match */ mono_arm_patch (labels [2], code, MONO_R_ARM64_CBZ); /* Load fail addr */ arm_ldrp (code, ARMREG_IP0, ARMREG_IP1, TARGET_SIZEOF_VOID_P); - arm_brx (code, ARMREG_IP0); + code = mono_arm_emit_brx (code, ARMREG_IP0); emit_code_bytes (acfg, buf, code - buf); @@ -1582,7 +1594,11 @@ arm64_emit_gsharedvt_arg_trampoline (MonoAotCompile *acfg, int offset, int *tram arm64_emit_load_got_slot (acfg, ARMREG_R17, offset); /* Load generic trampoline address from second GOT slot */ arm64_emit_load_got_slot (acfg, ARMREG_R16, offset + 1); +#ifdef MONO_ARCH_ENABLE_PTRAUTH + fprintf (acfg->fp, "braaz x16\n"); +#else fprintf (acfg->fp, "br x16\n"); +#endif *tramp_size = 7 * 4; } @@ -7601,7 +7617,7 @@ emit_trampoline_full (MonoAotCompile *acfg, MonoTrampInfo *info, gboolean emit_t g_assert (info); name = info->name; - code = info->code; + code = (guint8*)MINI_FTNPTR_TO_ADDR (info->code); code_size = info->code_size; ji = info->ji; unwind_ops = info->unwind_ops; @@ -12389,6 +12405,8 @@ compile_asm (MonoAotCompile *acfg) #define AS_OPTIONS "-arch i386" #elif defined(TARGET_X86) && !defined(TARGET_MACH) #define AS_OPTIONS "--32" +#elif defined(MONO_ARCH_ENABLE_PTRAUTH) +#define AS_OPTIONS "-arch arm64e" #else #define AS_OPTIONS "" #endif @@ -12418,7 +12436,11 @@ compile_asm (MonoAotCompile *acfg) #define LD_OPTIONS "--shared" #elif defined(TARGET_ARM64) && defined(TARGET_OSX) #define LD_NAME "clang" +#if defined(TARGET_OSX) && __has_feature(ptrauth_intrinsics) +#define LD_OPTIONS "--shared -arch arm64e" +#else #define LD_OPTIONS "--shared" +#endif #elif defined(TARGET_WIN32_MSVC) #define LD_NAME "link.exe" #define LD_OPTIONS "/DLL /MACHINE:X64 /NOLOGO /INCREMENTAL:NO" @@ -12461,7 +12483,7 @@ compile_asm (MonoAotCompile *acfg) } #ifdef TARGET_OSX - g_string_append (acfg->as_args, "-c -x assembler"); + g_string_append (acfg->as_args, "-c -x assembler "); #endif command = g_strdup_printf ("\"%s%s\" %s %s -o %s %s", tool_prefix, AS_NAME, AS_OPTIONS, diff --git a/mono/mini/aot-runtime.c b/mono/mini/aot-runtime.c index 7c644f40273..884c5f2a708 100644 --- a/mono/mini/aot-runtime.c +++ b/mono/mini/aot-runtime.c @@ -127,6 +127,7 @@ struct MonoAotModule { gpointer weak_field_indexes; guint8 *method_flags_table; /* Maps method indexes to their code */ + /* Raw pointer on arm64e */ gpointer *methods; /* Sorted array of method addresses */ gpointer *sorted_methods; @@ -3304,6 +3305,8 @@ decode_exception_debug_info (MonoAotModule *amodule, MonoDomain *domain, int this_reg = 0, this_offset = 0; gboolean async; + code = (guint8*)MINI_FTNPTR_TO_ADDR (code); + /* Load the method info from the AOT file */ async = mono_thread_info_is_async_context (); @@ -3427,6 +3430,7 @@ decode_exception_debug_info (MonoAotModule *amodule, MonoDomain *domain, } else { len = mono_jit_info_size (flags, num_clauses, num_holes); jinfo = (MonoJitInfo *)alloc0_jit_info_data (domain, len, async); + /* The jit info table needs to sort addresses so it contains non-authenticated pointers on arm64e */ mono_jit_info_init (jinfo, method, code, code_len, flags, num_clauses, num_holes); for (i = 0; i < jinfo->num_clauses; ++i) { @@ -3442,9 +3446,9 @@ decode_exception_debug_info (MonoAotModule *amodule, MonoDomain *domain, ei->exvar_offset = decode_value (p, &p); #endif - if (ei->flags == MONO_EXCEPTION_CLAUSE_FILTER || ei->flags == MONO_EXCEPTION_CLAUSE_FINALLY) + if (ei->flags == MONO_EXCEPTION_CLAUSE_FILTER || ei->flags == MONO_EXCEPTION_CLAUSE_FINALLY) { ei->data.filter = code + decode_value (p, &p); - else { + } else { int len = decode_value (p, &p); if (len > 0) { @@ -3460,6 +3464,15 @@ decode_exception_debug_info (MonoAotModule *amodule, MonoDomain *domain, ei->try_start = code + decode_value (p, &p); ei->try_end = code + decode_value (p, &p); ei->handler_start = code + decode_value (p, &p); + + /* Keep try_start/end non-authenticated, they are never branched to */ + //ei->try_start = MINI_ADDR_TO_FTNPTR (ei->try_start); + //ei->try_end = MINI_ADDR_TO_FTNPTR (ei->try_end); + ei->handler_start = MINI_ADDR_TO_FTNPTR (ei->handler_start); + if (ei->flags == MONO_EXCEPTION_CLAUSE_FILTER) + ei->data.filter = MINI_ADDR_TO_FTNPTR (ei->data.filter); + else if (ei->flags == MONO_EXCEPTION_CLAUSE_FINALLY) + ei->data.handler_end = MINI_ADDR_TO_FTNPTR (ei->data.handler_end); } jinfo->unwind_info = unwind_info; @@ -3754,6 +3767,7 @@ mono_aot_find_jit_info (MonoDomain *domain, MonoImage *image, gpointer addr) guint8 *code1, *code2; int methods_len, i; gboolean async; + gpointer orig_addr; if (!amodule) return NULL; @@ -3764,6 +3778,9 @@ mono_aot_find_jit_info (MonoDomain *domain, MonoImage *image, gpointer addr) /* FIXME: */ return NULL; + orig_addr = addr; + addr = MINI_FTNPTR_TO_ADDR (addr); + if (!amodule_contains_code_addr (amodule, (guint8 *)addr)) return NULL; @@ -4367,7 +4384,7 @@ load_method (MonoDomain *domain, MonoAotModule *amodule, MonoImage *image, MonoM if (!code) { if (method_index < amodule->info.nmethods) - code = (guint8 *)amodule->methods [method_index]; + code = (guint8*)MINI_ADDR_TO_FTNPTR ((guint8 *)amodule->methods [method_index]); else return NULL; @@ -5933,8 +5950,7 @@ get_new_specific_trampoline_from_page (gpointer tramp, gpointer arg) data [0] = arg; data [1] = tramp; /*g_warning ("new trampoline at %p for data %p, tramp %p (stored at %p)", code, arg, tramp, data);*/ - return code; - + return MINI_ADDR_TO_FTNPTR (code); } static gpointer @@ -5949,8 +5965,7 @@ get_new_rgctx_trampoline_from_page (gpointer tramp, gpointer arg) data [0] = arg; data [1] = tramp; /*g_warning ("new rgctx trampoline at %p for data %p, tramp %p (stored at %p)", code, arg, tramp, data);*/ - return code; - + return MINI_ADDR_TO_FTNPTR (code); } static gpointer @@ -5964,8 +5979,7 @@ get_new_imt_trampoline_from_page (gpointer arg) data = (gpointer*)((char*)code - MONO_AOT_TRAMP_PAGE_SIZE); data [0] = arg; /*g_warning ("new imt trampoline at %p for data %p, (stored at %p)", code, arg, data);*/ - return code; - + return MINI_ADDR_TO_FTNPTR (code); } static gpointer @@ -5980,7 +5994,7 @@ get_new_gsharedvt_arg_trampoline_from_page (gpointer tramp, gpointer arg) data [0] = arg; data [1] = tramp; /*g_warning ("new rgctx trampoline at %p for data %p, tramp %p (stored at %p)", code, arg, tramp, data);*/ - return code; + return MINI_ADDR_TO_FTNPTR (code); } static gpointer @@ -5994,7 +6008,7 @@ get_new_unbox_arbitrary_trampoline_frome_page (gpointer addr) data = (gpointer*)((char*)code - MONO_AOT_TRAMP_PAGE_SIZE); data [0] = addr; - return code; + return MINI_ADDR_TO_FTNPTR (code); } /* Return a given kind of trampoline */ @@ -6096,7 +6110,7 @@ mono_aot_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_typ if (code_len) *code_len = tramp_size; - return code; + return MINI_ADDR_TO_FTNPTR (code); } gpointer @@ -6116,7 +6130,7 @@ mono_aot_get_static_rgctx_trampoline (gpointer ctx, gpointer addr) } /* The caller expects an ftnptr */ - return mono_create_ftnptr (mono_domain_get (), code); + return mono_create_ftnptr (mono_domain_get (), MINI_ADDR_TO_FTNPTR (code)); } gpointer @@ -6134,7 +6148,7 @@ mono_aot_get_unbox_arbitrary_trampoline (gpointer addr) } /* The caller expects an ftnptr */ - return mono_create_ftnptr (mono_domain_get (), code); + return mono_create_ftnptr (mono_domain_get (), MINI_ADDR_TO_FTNPTR (code)); } static int @@ -6233,6 +6247,8 @@ mono_aot_get_unbox_trampoline (MonoMethod *method, gpointer addr) code = ((gpointer*)(amodule->info.llvm_unbox_trampolines))[unbox_tramp_idx]; g_assert (code); + code = MINI_ADDR_TO_FTNPTR (code); + mono_memory_barrier (); amodule->unbox_tramp_per_method [method_index] = code; @@ -6277,6 +6293,8 @@ mono_aot_get_unbox_trampoline (MonoMethod *method, gpointer addr) g_assert (code); + code = MINI_ADDR_TO_FTNPTR (code); + tinfo = mono_tramp_info_create (NULL, (guint8 *)code, 0, NULL, NULL); gpointer const symbol_addr = read_unwind_info (amodule, tinfo, "unbox_trampoline_p"); @@ -6388,7 +6406,7 @@ mono_aot_get_imt_trampoline (MonoVTable *vtable, MonoDomain *domain, MonoIMTChec amodule->got [got_offset] = buf; } - return code; + return MINI_ADDR_TO_FTNPTR (code); } gpointer @@ -6408,7 +6426,7 @@ mono_aot_get_gsharedvt_arg_trampoline (gpointer arg, gpointer addr) } /* The caller expects an ftnptr */ - return mono_create_ftnptr (mono_domain_get (), code); + return mono_create_ftnptr (mono_domain_get (), MINI_ADDR_TO_FTNPTR (code)); } #ifdef MONO_ARCH_HAVE_FTNPTR_ARG_TRAMPOLINE @@ -6429,7 +6447,7 @@ mono_aot_get_ftnptr_arg_trampoline (gpointer arg, gpointer addr) } /* The caller expects an ftnptr */ - return mono_create_ftnptr (mono_domain_get (), code); + return mono_create_ftnptr (mono_domain_get (), MINI_ADDR_TO_FTNPTR (code)); } #endif diff --git a/mono/mini/debugger-agent.c b/mono/mini/debugger-agent.c index b99451a1e7f..c68454d8133 100644 --- a/mono/mini/debugger-agent.c +++ b/mono/mini/debugger-agent.c @@ -2184,7 +2184,7 @@ thread_interrupt (DebuggerTlsData *tls, MonoThreadInfo *info, MonoJitInfo *ji) g_assert (info); - ip = MONO_CONTEXT_GET_IP (&mono_thread_info_get_suspend_state (info)->ctx); + ip = MINI_FTNPTR_TO_ADDR (MONO_CONTEXT_GET_IP (&mono_thread_info_get_suspend_state (info)->ctx)); tid = mono_thread_info_get_tid (info); // FIXME: Races when the thread leaves managed code before hitting a single step @@ -2295,7 +2295,7 @@ debugger_interrupt_critical (MonoThreadInfo *info, gpointer user_data) /* not attached */ ji = NULL; } else { - ji = mono_jit_info_table_find_internal ( domain, MONO_CONTEXT_GET_IP (&mono_thread_info_get_suspend_state (info)->ctx), TRUE, TRUE); + ji = mono_jit_info_table_find_internal (domain, MINI_FTNPTR_TO_ADDR (MONO_CONTEXT_GET_IP (&mono_thread_info_get_suspend_state (info)->ctx)), TRUE, TRUE); } /* This is signal safe */ diff --git a/mono/mini/driver.c b/mono/mini/driver.c index 932a56b3a8f..472df6f48d3 100644 --- a/mono/mini/driver.c +++ b/mono/mini/driver.c @@ -545,10 +545,12 @@ mini_regression_step (MonoImage *image, int verbose, int *total_run, int *total, ERROR_DECL (error); func = (TestMethod)mono_aot_get_method (mono_get_root_domain (), method, error); mono_error_cleanup (error); - if (!func) - func = (TestMethod)(gpointer)cfg->native_code; + if (!func) { + func = (TestMethod)MINI_ADDR_TO_FTNPTR (cfg->native_code); + } #else - func = (TestMethod)(gpointer)cfg->native_code; + func = (TestMethod)(gpointer)cfg->native_code; + func = MINI_ADDR_TO_FTNPTR (func); #endif func = (TestMethod)mono_create_ftnptr (mono_get_root_domain (), (gpointer)func); } diff --git a/mono/mini/exceptions-arm64.c b/mono/mini/exceptions-arm64.c index 3c06a2ac070..0e786809d0d 100644 --- a/mono/mini/exceptions-arm64.c +++ b/mono/mini/exceptions-arm64.c @@ -60,7 +60,7 @@ mono_arch_get_restore_context (MonoTrampInfo **info, gboolean aot) /* Restore sp, ctx is no longer valid */ arm_movspx (code, ARMREG_SP, ARMREG_IP0); /* Branch to pc */ - arm_brx (code, ARMREG_IP1); + code = mono_arm_emit_brx (code, ARMREG_IP1); /* Not reached */ arm_brk (code, 0); @@ -71,7 +71,7 @@ mono_arch_get_restore_context (MonoTrampInfo **info, gboolean aot) if (info) *info = mono_tramp_info_create ("restore_context", start, code - start, ji, unwind_ops); - return start; + return MINI_ADDR_TO_FTNPTR (start); } gpointer @@ -135,7 +135,7 @@ mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot) arm_ldrx (code, ARMREG_FP, ARMREG_R0, MONO_STRUCT_OFFSET (MonoContext, regs) + (ARMREG_FP * 8)); /* Make the call */ - arm_blrx (code, ARMREG_R1); + code = mono_arm_emit_blrx (code, ARMREG_R1); /* For filters, the result is in R0 */ /* Restore fp */ @@ -162,7 +162,7 @@ mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot) if (info) *info = mono_tramp_info_create ("call_filter", start, code - start, ji, unwind_ops); - return start; + return MINI_ADDR_TO_FTNPTR (start); } static gpointer @@ -255,7 +255,7 @@ get_throw_trampoline (int size, gboolean corlib, gboolean rethrow, gboolean llvm code = mono_arm_emit_imm64 (code, ARMREG_LR, (guint64)icall_func); } - arm_blrx (code, ARMREG_LR); + code = mono_arm_emit_blrx (code, ARMREG_LR); /* This shouldn't return */ arm_brk (code, 0x0); @@ -266,7 +266,7 @@ get_throw_trampoline (int size, gboolean corlib, gboolean rethrow, gboolean llvm if (info) *info = mono_tramp_info_create (tramp_name, start, code - start, ji, unwind_ops); - return start; + return MINI_ADDR_TO_FTNPTR (start); } gpointer @@ -434,8 +434,6 @@ mono_arch_unwind_frame (MonoDomain *domain, MonoJitTlsData *jit_tls, host_mgreg_t **save_locations, StackFrameInfo *frame) { - gpointer ip = MONO_CONTEXT_GET_IP (ctx); - memset (frame, 0, sizeof (StackFrameInfo)); frame->ji = ji; @@ -447,7 +445,6 @@ mono_arch_unwind_frame (MonoDomain *domain, MonoJitTlsData *jit_tls, guint32 unwind_info_len; guint8 *unwind_info; - if (ji->is_trampoline) frame->type = FRAME_TYPE_TRAMPOLINE; else @@ -460,6 +457,7 @@ mono_arch_unwind_frame (MonoDomain *domain, MonoJitTlsData *jit_tls, for (int i = 0; i < 8; i++) (regs + MONO_MAX_IREGS) [i] = *((host_mgreg_t*)&new_ctx->fregs [8 + i]); + gpointer ip = MINI_FTNPTR_TO_ADDR (MONO_CONTEXT_GET_IP (ctx)); gboolean success = mono_unwind_frame (unwind_info, unwind_info_len, (guint8*)ji->code_start, (guint8*)ji->code_start + ji->code_size, (guint8*)ip, NULL, regs, MONO_MAX_IREGS + 8, @@ -550,8 +548,10 @@ mono_arch_handle_exception (void *ctx, gpointer obj) /* The others in registers */ UCONTEXT_REG_R0 (sigctx) = (gsize)obj; - UCONTEXT_REG_PC (sigctx) = (gsize)handle_signal_exception; - UCONTEXT_REG_SP (sigctx) = UCONTEXT_REG_SP (sigctx) - MONO_ARCH_REDZONE_SIZE; + gpointer addr = (gpointer)handle_signal_exception; + UCONTEXT_REG_SET_PC (sigctx, addr); + host_mgreg_t sp = UCONTEXT_REG_SP (sigctx) - MONO_ARCH_REDZONE_SIZE; + UCONTEXT_REG_SET_SP (sigctx, sp); #endif return TRUE; @@ -597,11 +597,15 @@ mono_arch_setup_resume_sighandler_ctx (MonoContext *ctx, gpointer func) void mono_arch_undo_ip_adjustment (MonoContext *ctx) { - ctx->pc++; + gpointer pc = (gpointer)ctx->pc; + pc = (gpointer)((guint64)MINI_FTNPTR_TO_ADDR (pc) + 1); + ctx->pc = (host_mgreg_t)MINI_ADDR_TO_FTNPTR (pc); } void mono_arch_do_ip_adjustment (MonoContext *ctx) { - ctx->pc--; + gpointer pc = (gpointer)ctx->pc; + pc = (gpointer)((guint64)MINI_FTNPTR_TO_ADDR (pc) - 1); + ctx->pc = (host_mgreg_t)MINI_ADDR_TO_FTNPTR (pc); } diff --git a/mono/mini/image-writer.c b/mono/mini/image-writer.c index b191269667a..97d1a042c0f 100644 --- a/mono/mini/image-writer.c +++ b/mono/mini/image-writer.c @@ -167,7 +167,7 @@ struct _MonoImageWriter { }; static G_GNUC_UNUSED int -ilog2(register int value) +ilog2(int value) { int count = -1; while (value & ~0xf) count += 4, value >>= 4; diff --git a/mono/mini/interp/interp.c b/mono/mini/interp/interp.c index 2c7a77e3e05..d80d5201afc 100644 --- a/mono/mini/interp/interp.c +++ b/mono/mini/interp/interp.c @@ -2151,6 +2151,7 @@ do_icall_wrapper (InterpFrame *frame, MonoMethodSignature *sig, int op, stackval interp_pop_lmf (&ext); goto exit_icall; // prevent unused label warning in some configurations + /* If an exception is thrown from native code, execution will continue here */ exit_icall: return NULL; } diff --git a/mono/mini/mini-arm64.c b/mono/mini/mini-arm64.c index 91c841f0b54..3e5b8985d64 100644 --- a/mono/mini/mini-arm64.c +++ b/mono/mini/mini-arm64.c @@ -55,8 +55,10 @@ static gpointer ss_trampoline; static gpointer bp_trampoline; static gboolean ios_abi; +static gboolean enable_ptrauth; static __attribute__ ((__warn_unused_result__)) guint8* emit_load_regset (guint8 *code, guint64 regs, int basereg, int offset); +static guint8* emit_blrx (guint8 *code, int reg); const char* mono_arch_regname (int reg) @@ -122,7 +124,7 @@ get_delegate_invoke_impl (gboolean has_target, gboolean param_count, guint32 *co /* Replace the this argument with the target */ arm_ldrx (code, ARMREG_IP0, ARMREG_R0, MONO_STRUCT_OFFSET (MonoDelegate, method_ptr)); arm_ldrx (code, ARMREG_R0, ARMREG_R0, MONO_STRUCT_OFFSET (MonoDelegate, target)); - arm_brx (code, ARMREG_IP0); + code = mono_arm_emit_brx (code, ARMREG_IP0); g_assert ((code - start) <= 12); } else { @@ -135,7 +137,7 @@ get_delegate_invoke_impl (gboolean has_target, gboolean param_count, guint32 *co /* slide down the arguments */ for (i = 0; i < param_count; ++i) arm_movx (code, i, i + 1); - arm_brx (code, ARMREG_IP0); + code = mono_arm_emit_brx (code, ARMREG_IP0); g_assert ((code - start) <= size); } @@ -144,7 +146,7 @@ get_delegate_invoke_impl (gboolean has_target, gboolean param_count, guint32 *co if (code_size) *code_size = code - start; - return start; + return MINI_ADDR_TO_FTNPTR (start); } /* @@ -247,14 +249,17 @@ mono_arch_cpu_init (void) void mono_arch_init (void) { +#if defined(TARGET_IOS) || defined(TARGET_WATCHOS) || defined(TARGET_OSX) + ios_abi = TRUE; +#endif +#ifdef MONO_ARCH_ENABLE_PTRAUTH + enable_ptrauth = TRUE; +#endif + if (!mono_aot_only) bp_trampoline = mini_get_breakpoint_trampoline (); mono_arm_gsharedvt_init (); - -#if defined(TARGET_IOS) || defined(TARGET_WATCHOS) || defined(TARGET_OSX) - ios_abi = TRUE; -#endif } void @@ -935,6 +940,7 @@ arm_patch_full (MonoCompile *cfg, MonoDomain *domain, guint8 *code, guint8 *targ { switch (relocation) { case MONO_R_ARM64_B: + target = MINI_FTNPTR_TO_ADDR (target); if (arm_is_bl_disp (code, target)) { arm_b (code, target); } else { @@ -968,6 +974,7 @@ arm_patch_full (MonoCompile *cfg, MonoDomain *domain, guint8 *code, guint8 *targ break; } case MONO_R_ARM64_BL: + target = MINI_FTNPTR_TO_ADDR (target); if (arm_is_bl_disp (code, target)) { arm_bl (code, target); } else { @@ -1006,6 +1013,7 @@ mono_arch_patch_code_new (MonoCompile *cfg, MonoDomain *domain, guint8 *code, Mo case MONO_PATCH_INFO_METHOD_JUMP: /* ji->relocation is not set by the caller */ arm_patch_full (cfg, domain, ip, (guint8*)target, MONO_R_ARM64_B); + mono_arch_flush_icache (ip, 8); break; default: arm_patch_full (cfg, domain, ip, (guint8*)target, ji->relocation); @@ -3378,7 +3386,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) arm_ldrx (code, ARMREG_IP1, ARMREG_IP1, 0); /* Call it if it is non-null */ arm_cbzx (code, ARMREG_IP1, code + 8); - arm_blrx (code, ARMREG_IP1); + code = mono_arm_emit_blrx (code, ARMREG_IP1); } mono_add_seq_point (cfg, bb, ins, code - cfg->native_code); @@ -3395,7 +3403,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) /* Skip the load if its 0 */ arm_cbzx (code, ARMREG_IP1, code + 8); /* Call the breakpoint trampoline */ - arm_blrx (code, ARMREG_IP1); + code = mono_arm_emit_blrx (code, ARMREG_IP1); } else { MonoInst *var = cfg->arch.bp_tramp_var; @@ -4373,7 +4381,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) case OP_FCALL_REG: case OP_RCALL_REG: case OP_VCALL2_REG: - arm_blrx (code, sreg1); + code = mono_arm_emit_blrx (code, sreg1); code = emit_move_return_value (cfg, code, ins); break; case OP_VOIDCALL_MEMBASE: @@ -4383,7 +4391,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) case OP_RCALL_MEMBASE: case OP_VCALL2_MEMBASE: code = emit_ldrx (code, ARMREG_IP0, ins->inst_basereg, ins->inst_offset); - arm_blrx (code, ARMREG_IP0); + code = mono_arm_emit_blrx (code, ARMREG_IP0); code = emit_move_return_value (cfg, code, ins); break; @@ -4458,6 +4466,10 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) /* Destroy frame */ code = mono_arm_emit_destroy_frame (code, cfg->stack_offset, free_reg); + if (enable_ptrauth) + /* There is no retab to authenticate lr */ + arm_autibsp (code); + switch (ins->opcode) { case OP_TAILCALL: if (cfg->compile_aot) { @@ -4472,7 +4484,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) // fallthrough case OP_TAILCALL_MEMBASE: case OP_TAILCALL_REG: - arm_brx (code, branch_reg); + code = mono_arm_emit_brx (code, branch_reg); break; default: @@ -4546,7 +4558,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) code = mono_arm_emit_load_regarray (code, 0x1ff, ARMREG_LR, MONO_STRUCT_OFFSET (DynCallArgs, regs)); /* Make the call */ - arm_blrx (code, ARMREG_IP1); + code = mono_arm_emit_blrx (code, ARMREG_IP1); /* Save result */ code = emit_ldrx (code, ARMREG_LR, var->inst_basereg, var->inst_offset); @@ -5019,6 +5031,38 @@ emit_store_regset_cfa (MonoCompile *cfg, guint8 *code, guint64 regs, int basereg return code; } +static guint8* +emit_blrx (guint8 *code, int reg) +{ + if (enable_ptrauth) + arm_blraaz (code, reg); + else + arm_blrx (code, reg); + return code; +} + +guint8* +mono_arm_emit_blrx (guint8 *code, int reg) +{ + return emit_blrx (code, reg); +} + +static guint8* +emit_brx (guint8 *code, int reg) +{ + if (enable_ptrauth) + arm_braaz (code, reg); + else + arm_brx (code, reg); + return code; +} + +guint8* +mono_arm_emit_brx (guint8 *code, int reg) +{ + return emit_brx (code, reg); +} + /* * emit_setup_lmf: * @@ -5068,6 +5112,9 @@ mono_arch_emit_prolog (MonoCompile *cfg) cfa_offset = 0; mono_emit_unwind_op_def_cfa (cfg, code, ARMREG_SP, 0); + if (enable_ptrauth) + arm_pacibsp (code); + /* Setup frame */ if (arm_is_ldpx_imm (-cfg->stack_offset)) { arm_stpx_pre (code, ARMREG_FP, ARMREG_LR, ARMREG_SP, -cfg->stack_offset); @@ -5226,7 +5273,10 @@ mono_arch_emit_epilog (MonoCompile *cfg) /* Destroy frame */ code = mono_arm_emit_destroy_frame (code, cfg->stack_offset, (1 << ARMREG_IP0) | (1 << ARMREG_IP1)); - arm_retx (code, ARMREG_LR); + if (enable_ptrauth) + arm_retab (code); + else + arm_retx (code, ARMREG_LR); g_assert (code - (cfg->native_code + cfg->code_len) < max_epilog_size); @@ -5394,27 +5444,27 @@ mono_arch_build_imt_trampoline (MonoVTable *vtable, MonoDomain *domain, MonoIMTC /* Jump to target if equals */ if (item->has_target_code) { code = emit_imm64 (code, ARMREG_IP0, (guint64)item->value.target_code); - arm_brx (code, ARMREG_IP0); + code = mono_arm_emit_brx (code, ARMREG_IP0); } else { guint64 imm = (guint64)&(vtable->vtable [item->value.vtable_slot]); code = emit_imm64 (code, ARMREG_IP0, imm); arm_ldrx (code, ARMREG_IP0, ARMREG_IP0, 0); - arm_brx (code, ARMREG_IP0); + code = mono_arm_emit_brx (code, ARMREG_IP0); } if (fail_case) { arm_patch_rel (item->jmp_code, code, MONO_R_ARM64_BCC); item->jmp_code = NULL; code = emit_imm64 (code, ARMREG_IP0, (guint64)fail_tramp); - arm_brx (code, ARMREG_IP0); + code = mono_arm_emit_brx (code, ARMREG_IP0); } } else { guint64 imm = (guint64)&(vtable->vtable [item->value.vtable_slot]); code = emit_imm64 (code, ARMREG_IP0, imm); arm_ldrx (code, ARMREG_IP0, ARMREG_IP0, 0); - arm_brx (code, ARMREG_IP0); + code = mono_arm_emit_brx (code, ARMREG_IP0); } } else { code = emit_imm64 (code, ARMREG_IP0, (guint64)item->key); @@ -5434,7 +5484,7 @@ mono_arch_build_imt_trampoline (MonoVTable *vtable, MonoDomain *domain, MonoIMTC MINI_END_CODEGEN (buf, code - buf, MONO_PROFILER_CODE_BUFFER_IMT_TRAMPOLINE, NULL); - return buf; + return MINI_ADDR_TO_FTNPTR (buf); } GSList * @@ -5460,12 +5510,14 @@ mono_arch_build_imt_trampoline (MonoVTable *vtable, MonoDomain *domain, MonoIMTC void mono_arch_set_breakpoint (MonoJitInfo *ji, guint8 *ip) { - guint8 *code = ip; + guint8 *code = MINI_FTNPTR_TO_ADDR (ip); guint32 native_offset = ip - (guint8*)ji->code_start; if (ji->from_aot) { SeqPointInfo *info = mono_arch_get_seq_point_info (mono_domain_get (), (guint8*)ji->code_start); + if (enable_ptrauth) + NOT_IMPLEMENTED; g_assert (native_offset % 4 == 0); g_assert (info->bp_addrs [native_offset / 4] == 0); info->bp_addrs [native_offset / 4] = (guint8*)mini_get_breakpoint_trampoline (); @@ -5473,7 +5525,7 @@ mono_arch_set_breakpoint (MonoJitInfo *ji, guint8 *ip) /* ip points to an ldrx */ code += 4; mono_codeman_enable_write (); - arm_blrx (code, ARMREG_IP0); + code = mono_arm_emit_blrx (code, ARMREG_IP0); mono_codeman_disable_write (); mono_arch_flush_icache (ip, code - ip); } @@ -5482,12 +5534,15 @@ mono_arch_set_breakpoint (MonoJitInfo *ji, guint8 *ip) void mono_arch_clear_breakpoint (MonoJitInfo *ji, guint8 *ip) { - guint8 *code = ip; + guint8 *code = MINI_FTNPTR_TO_ADDR (ip); if (ji->from_aot) { guint32 native_offset = ip - (guint8*)ji->code_start; SeqPointInfo *info = mono_arch_get_seq_point_info (mono_domain_get (), (guint8*)ji->code_start); + if (enable_ptrauth) + NOT_IMPLEMENTED; + g_assert (native_offset % 4 == 0); info->bp_addrs [native_offset / 4] = NULL; } else { diff --git a/mono/mini/mini-arm64.h b/mono/mini/mini-arm64.h index 4074aa8b43f..244857326b2 100644 --- a/mono/mini/mini-arm64.h +++ b/mono/mini/mini-arm64.h @@ -284,6 +284,10 @@ guint8* mono_arm_emit_load_regarray (guint8 *code, guint64 regs, int basereg, in /* MonoJumpInfo **ji */ guint8* mono_arm_emit_aotconst (gpointer ji, guint8 *code, guint8 *code_start, int dreg, guint32 patch_type, gconstpointer data); +guint8* mono_arm_emit_brx (guint8 *code, int reg); + +guint8* mono_arm_emit_blrx (guint8 *code, int reg); + void mono_arm_patch (guint8 *code, guint8 *target, int relocation); void mono_arm_throw_exception (gpointer arg, host_mgreg_t pc, host_mgreg_t *int_regs, gdouble *fp_regs, gboolean corlib, gboolean rethrow, gboolean preserve_ips); diff --git a/mono/mini/mini-exceptions.c b/mono/mini/mini-exceptions.c index b26c6334224..dd119b6805b 100644 --- a/mono/mini/mini-exceptions.c +++ b/mono/mini/mini-exceptions.c @@ -359,6 +359,8 @@ is_address_protected (MonoJitInfo *ji, MonoJitExceptionInfo *ei, gpointer ip) guint32 offset; guint16 clause; + ip = MINI_FTNPTR_TO_ADDR (ip); + if (ei->try_start > ip || ip >= ei->try_end) return FALSE; @@ -578,6 +580,7 @@ mono_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInfo *re else real_ip = (const char*)ip; + real_ip = (const char*)MINI_FTNPTR_TO_ADDR (real_ip); if ((real_ip >= start) && (real_ip <= start + ji->code_size)) offset = real_ip - start; else @@ -2000,6 +2003,11 @@ mini_jit_info_table_find_ext (MonoDomain *domain, gpointer addr, gboolean allow_ if (out_domain) *out_domain = NULL; + // FIXME: Transition all callers to this function + // or add it to mono_jit_info_table_find + ji = mono_jit_info_table_find_internal (domain, addr, TRUE, allow_trampolines); + addr = MINI_FTNPTR_TO_ADDR (addr); + ji = mono_jit_info_table_find_internal (domain, addr, TRUE, allow_trampolines); if (ji) { if (out_domain) @@ -3570,7 +3578,7 @@ find_last_handler_block (StackFrameInfo *frame, MonoContext *ctx, gpointer data) if (!ji) return FALSE; - ip = MONO_CONTEXT_GET_IP (ctx); + ip = MINI_FTNPTR_TO_ADDR (MONO_CONTEXT_GET_IP (ctx)); for (i = 0; i < ji->num_clauses; ++i) { MonoJitExceptionInfo *ei = ji->clauses + i; @@ -3578,7 +3586,7 @@ find_last_handler_block (StackFrameInfo *frame, MonoContext *ctx, gpointer data) continue; /*If ip points to the first instruction it means the handler block didn't start so we can leave its execution to the EH machinery*/ - if (ei->handler_start <= ip && ip < ei->data.handler_end) { + if (MINI_FTNPTR_TO_ADDR (ei->handler_start) <= ip && ip < MINI_FTNPTR_TO_ADDR (ei->data.handler_end)) { pdata->ji = ji; pdata->ei = ei; pdata->ctx = *ctx; @@ -3597,13 +3605,13 @@ install_handler_block_guard (MonoJitInfo *ji, MonoContext *ctx) gpointer ip; guint8 *bp; - ip = MONO_CONTEXT_GET_IP (ctx); + ip = MINI_FTNPTR_TO_ADDR (MONO_CONTEXT_GET_IP (ctx)); for (i = 0; i < ji->num_clauses; ++i) { clause = &ji->clauses [i]; if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY) continue; - if (clause->handler_start <= ip && clause->data.handler_end > ip) + if (MINI_FTNPTR_TO_ADDR (clause->handler_start) <= ip && MINI_FTNPTR_TO_ADDR (clause->data.handler_end) > ip) break; } diff --git a/mono/mini/mini-generic-sharing.c b/mono/mini/mini-generic-sharing.c index 2ad21ecc1b5..37507f22422 100644 --- a/mono/mini/mini-generic-sharing.c +++ b/mono/mini/mini-generic-sharing.c @@ -2417,7 +2417,7 @@ instantiate_info (MonoDomain *domain, MonoRuntimeGenericContextInfoTemplate *oti sig = mono_method_signature_internal (jinfo_get_method (callee_ji)); gpointer out_wrapper = mini_get_gsharedvt_wrapper (FALSE, NULL, sig, gsig, -1, FALSE); - MonoFtnDesc *out_wrapper_arg = mini_llvmonly_create_ftndesc (domain, callee_ji->code_start, mini_method_get_rgctx (method)); + MonoFtnDesc *out_wrapper_arg = mini_llvmonly_create_ftndesc (domain, jinfo_get_ftnptr (callee_ji), mini_method_get_rgctx (method)); /* Returns an ftndesc */ addr = mini_llvmonly_create_ftndesc (domain, out_wrapper, out_wrapper_arg); @@ -2465,11 +2465,11 @@ instantiate_info (MonoDomain *domain, MonoRuntimeGenericContextInfoTemplate *oti * might not exist at all in IL, so the AOT compiler cannot generate the wrappers * for it. */ - addr = mini_llvmonly_create_ftndesc (domain, callee_ji->code_start, mini_method_get_rgctx (method)); + addr = mini_llvmonly_create_ftndesc (domain, jinfo_get_ftnptr (callee_ji), mini_method_get_rgctx (method)); } else if (mini_is_gsharedvt_variable_signature (gsig)) { - gpointer in_wrapper = mini_get_gsharedvt_wrapper (TRUE, callee_ji->code_start, sig, gsig, -1, FALSE); + gpointer in_wrapper = mini_get_gsharedvt_wrapper (TRUE, jinfo_get_ftnptr (callee_ji), sig, gsig, -1, FALSE); - gpointer in_wrapper_arg = mini_llvmonly_create_ftndesc (domain, callee_ji->code_start, mini_method_get_rgctx (method)); + gpointer in_wrapper_arg = mini_llvmonly_create_ftndesc (domain, jinfo_get_ftnptr (callee_ji), mini_method_get_rgctx (method)); addr = mini_llvmonly_create_ftndesc (domain, in_wrapper, in_wrapper_arg); } else { @@ -2480,7 +2480,7 @@ instantiate_info (MonoDomain *domain, MonoRuntimeGenericContextInfoTemplate *oti sig = mono_method_signature_internal (method); gsig = mono_method_signature_internal (jinfo_get_method (callee_ji)); - addr = mini_get_gsharedvt_wrapper (TRUE, callee_ji->code_start, sig, gsig, -1, FALSE); + addr = mini_get_gsharedvt_wrapper (TRUE, jinfo_get_ftnptr (callee_ji), sig, gsig, -1, FALSE); sig = mono_method_signature_internal (method); gsig = call_sig; diff --git a/mono/mini/mini-posix.c b/mono/mini/mini-posix.c index c0cd9afb39e..cd83a4d1161 100644 --- a/mono/mini/mini-posix.c +++ b/mono/mini/mini-posix.c @@ -854,6 +854,7 @@ dump_memory_around_ip (MonoContext *mctx) gpointer native_ip = MONO_CONTEXT_GET_IP (mctx); if (native_ip) { + native_ip = MINI_FTNPTR_TO_ADDR (native_ip); g_async_safe_printf ("Memory around native instruction pointer (%p):", native_ip); mono_dump_mem (((guint8 *) native_ip) - 0x10, 0x40); } else { diff --git a/mono/mini/mini-runtime.c b/mono/mini/mini-runtime.c index 89e34286aae..c1b4c128781 100644 --- a/mono/mini/mini-runtime.c +++ b/mono/mini/mini-runtime.c @@ -495,7 +495,7 @@ register_trampoline_jit_info (MonoDomain *domain, MonoTrampInfo *info) MonoJitInfo *ji; ji = (MonoJitInfo *)mono_domain_alloc0 (domain, mono_jit_info_size ((MonoJitInfoFlags)0, 0, 0)); - mono_jit_info_init (ji, NULL, info->code, info->code_size, (MonoJitInfoFlags)0, 0, 0); + mono_jit_info_init (ji, NULL, (guint8*)MINI_FTNPTR_TO_ADDR (info->code), info->code_size, (MonoJitInfoFlags)0, 0, 0); ji->d.tramp_info = info; ji->is_trampoline = TRUE; @@ -2357,7 +2357,7 @@ create_jit_info_for_trampoline (MonoMethod *wrapper, MonoTrampInfo *info) jinfo = (MonoJitInfo *)mono_domain_alloc0 (domain, MONO_SIZEOF_JIT_INFO); jinfo->d.method = wrapper; - jinfo->code_start = info->code; + jinfo->code_start = MINI_FTNPTR_TO_ADDR (info->code); jinfo->code_size = info->code_size; jinfo->unwind_info = mono_cache_unwind_info (uw_info, info_len); @@ -2602,7 +2602,9 @@ lookup_start: if (!mono_runtime_class_init_full (vtable, error)) return NULL; MONO_PROFILER_RAISE (jit_done, (method, info)); - return mono_create_ftnptr (target_domain, info->code_start); + + code = MINI_ADDR_TO_FTNPTR (info->code_start); + return mono_create_ftnptr (target_domain, code); } } @@ -2632,7 +2634,7 @@ lookup_start: * The suspend code needs to be able to lookup these methods by ip in async context, * so preload their jit info. */ - MonoJitInfo *ji = mono_jit_info_table_find (domain, code); + MonoJitInfo *ji = mini_jit_info_table_find (domain, code, NULL); g_assert (ji); } @@ -2905,7 +2907,7 @@ mono_jit_find_compiled_method_with_jit_info (MonoDomain *domain, MonoMethod *met mono_atomic_inc_i32 (&mono_jit_stats.methods_lookups); if (ji) *ji = info; - return info->code_start; + return MINI_ADDR_TO_FTNPTR (info->code_start); } } @@ -3595,8 +3597,10 @@ MONO_SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler) } #endif - if (domain) - ji = mono_jit_info_table_find_internal (domain, mono_arch_ip_from_context (ctx), TRUE, TRUE); + if (domain) { + gpointer ip = MINI_FTNPTR_TO_ADDR (mono_arch_ip_from_context (ctx)); + ji = mono_jit_info_table_find_internal (domain, ip, TRUE, TRUE); + } #ifdef MONO_ARCH_SIGSEGV_ON_ALTSTACK if (mono_handle_soft_stack_ovf (jit_tls, ji, ctx, info, (guint8*)info->si_addr)) @@ -3821,12 +3825,13 @@ mini_init_delegate (MonoDelegateHandle delegate, MonoObjectHandle target, gpoint if (!method) { MonoJitInfo *ji; + gpointer lookup_addr = MINI_FTNPTR_TO_ADDR (addr); g_assert (addr); - ji = mono_jit_info_table_find_internal (domain, mono_get_addr_from_ftnptr (addr), TRUE, TRUE); + ji = mono_jit_info_table_find_internal (domain, mono_get_addr_from_ftnptr (lookup_addr), TRUE, TRUE); /* Shared code */ if (!ji && domain != mono_get_root_domain ()) - ji = mono_jit_info_table_find_internal (mono_get_root_domain (), mono_get_addr_from_ftnptr (addr), TRUE, TRUE); + ji = mono_jit_info_table_find_internal (mono_get_root_domain (), mono_get_addr_from_ftnptr (lookup_addr), TRUE, TRUE); if (ji) { if (ji->is_trampoline) { /* Could be an unbox trampoline etc. */ diff --git a/mono/mini/mini-runtime.h b/mono/mini/mini-runtime.h index 58e5a845204..e44e7bde11a 100644 --- a/mono/mini/mini-runtime.h +++ b/mono/mini/mini-runtime.h @@ -22,7 +22,6 @@ typedef struct GHashTable *jump_target_got_slot_hash; GHashTable *jump_target_hash; /* Maps methods/klasses to the address of the given type of trampoline */ - GHashTable *class_init_trampoline_hash; GHashTable *jump_trampoline_hash; GHashTable *jit_trampoline_hash; GHashTable *delegate_trampoline_hash; @@ -438,6 +437,12 @@ jinfo_get_method (MonoJitInfo *ji) return mono_jit_info_get_method (ji); } +static inline gpointer +jinfo_get_ftnptr (MonoJitInfo *ji) +{ + return MINI_ADDR_TO_FTNPTR (ji->code_start); +} + /* main function */ MONO_API int mono_main (int argc, char* argv[]); MONO_API void mono_set_defaults (int verbose_level, guint32 opts); @@ -637,7 +642,7 @@ void mini_register_sigterm_handler (void); mono_codeman_disable_write (); \ mono_arch_flush_icache ((buf), (size)); \ if ((int)type != -1) \ - MONO_PROFILER_RAISE (jit_code_buffer, ((buf), (size), (type), (arg))); \ + MONO_PROFILER_RAISE (jit_code_buffer, ((buf), (size), (MonoProfilerCodeBufferType)(type), (arg))); \ } while (0) #endif /* __MONO_MINI_RUNTIME_H__ */ diff --git a/mono/mini/mini-trampolines.c b/mono/mini/mini-trampolines.c index 7f120d21680..3b657b2ab27 100644 --- a/mono/mini/mini-trampolines.c +++ b/mono/mini/mini-trampolines.c @@ -1384,7 +1384,7 @@ mono_create_jump_trampoline (MonoDomain *domain, MonoMethod *method, gboolean ad g_assert (code_size); ji = (MonoJitInfo *)m_method_alloc0 (domain, method, MONO_SIZEOF_JIT_INFO); - ji->code_start = code; + ji->code_start = MINI_FTNPTR_TO_ADDR (code); ji->code_size = code_size; ji->d.method = method; @@ -1396,10 +1396,10 @@ mono_create_jump_trampoline (MonoDomain *domain, MonoMethod *method, gboolean ad mono_jit_info_table_add (domain, ji); mono_domain_lock (domain); - g_hash_table_insert (domain_jit_info (domain)->jump_trampoline_hash, method, ji->code_start); + g_hash_table_insert (domain_jit_info (domain)->jump_trampoline_hash, method, code); mono_domain_unlock (domain); - return ji->code_start; + return code; } static void diff --git a/mono/mini/mini.c b/mono/mini/mini.c index efd6e0edaf4..d12f3b07ed7 100644 --- a/mono/mini/mini.c +++ b/mono/mini/mini.c @@ -2716,6 +2716,15 @@ create_jit_info (MonoCompile *cfg, MonoMethod *method_to_compile) } ei->data.handler_end = cfg->native_code + end_offset; } + + /* Keep try_start/end non-authenticated, they are never branched to */ + //ei->try_start = MINI_ADDR_TO_FTNPTR (ei->try_start); + //ei->try_end = MINI_ADDR_TO_FTNPTR (ei->try_end); + ei->handler_start = MINI_ADDR_TO_FTNPTR (ei->handler_start); + if (ei->flags == MONO_EXCEPTION_CLAUSE_FILTER) + ei->data.filter = MINI_ADDR_TO_FTNPTR (ei->data.filter); + else if (ei->flags == MONO_EXCEPTION_CLAUSE_FINALLY) + ei->data.handler_end = MINI_ADDR_TO_FTNPTR (ei->data.handler_end); } } @@ -4209,7 +4218,7 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in if (!mono_runtime_class_init_full (vtable, error)) return NULL; } - return code; + return MINI_ADDR_TO_FTNPTR (code); } /* diff --git a/mono/mini/mini.h b/mono/mini/mini.h index 7b4bbf9f02c..6027a5a32d6 100644 --- a/mono/mini/mini.h +++ b/mono/mini/mini.h @@ -14,6 +14,7 @@ #ifdef HAVE_SYS_TYPES_H #include <sys/types.h> #endif + #include <mono/utils/mono-forward-internal.h> #include <mono/metadata/loader.h> #include <mono/metadata/mempool.h> @@ -39,6 +40,7 @@ #include <mono/utils/mono-jemalloc.h> #include <mono/utils/mono-conc-hashtable.h> #include <mono/utils/mono-signal-handler.h> +#include <mono/utils/ftnptr.h> #include <mono/metadata/icalls.h> // Forward declare so that mini-*.h can have pointers to them. @@ -2198,19 +2200,14 @@ gpointer mono_create_jump_trampoline (MonoDomain *domain, MonoMethod *method, gboolean add_sync_wrapper, MonoError *error); -gpointer mono_create_class_init_trampoline (MonoVTable *vtable); gpointer mono_create_jit_trampoline (MonoDomain *domain, MonoMethod *method, MonoError *error); gpointer mono_create_jit_trampoline_from_token (MonoImage *image, guint32 token); gpointer mono_create_delegate_trampoline (MonoDomain *domain, MonoClass *klass); MonoDelegateTrampInfo* mono_create_delegate_trampoline_info (MonoDomain *domain, MonoClass *klass, MonoMethod *method); gpointer mono_create_delegate_virtual_trampoline (MonoDomain *domain, MonoClass *klass, MonoMethod *method); gpointer mono_create_rgctx_lazy_fetch_trampoline (guint32 offset); -gpointer mono_create_monitor_enter_trampoline (void); -gpointer mono_create_monitor_enter_v4_trampoline (void); -gpointer mono_create_monitor_exit_trampoline (void); gpointer mono_create_static_rgctx_trampoline (MonoMethod *m, gpointer addr); gpointer mono_create_ftnptr_arg_trampoline (gpointer arg, gpointer addr); -MonoVTable* mono_find_class_init_trampoline_by_addr (gconstpointer addr); guint32 mono_find_rgctx_lazy_fetch_trampoline_by_addr (gconstpointer addr); gpointer mono_magic_trampoline (host_mgreg_t *regs, guint8 *code, gpointer arg, guint8* tramp); #ifndef DISABLE_REMOTING @@ -2221,17 +2218,11 @@ gpointer mono_aot_trampoline (host_mgreg_t *regs, guint8 *code, guint8 guint8* tramp); gpointer mono_aot_plt_trampoline (host_mgreg_t *regs, guint8 *code, guint8 *token_info, guint8* tramp); -void mono_class_init_trampoline (host_mgreg_t *regs, guint8 *code, MonoVTable *vtable, guint8 *tramp); -void mono_generic_class_init_trampoline (host_mgreg_t *regs, guint8 *code, MonoVTable *vtable, guint8 *tramp); -void mono_monitor_enter_trampoline (host_mgreg_t *regs, guint8 *code, MonoObject *obj, guint8 *tramp); -void mono_monitor_enter_v4_trampoline (host_mgreg_t *regs, guint8 *code, MonoObject *obj, guint8 *tramp); -void mono_monitor_exit_trampoline (host_mgreg_t *regs, guint8 *code, MonoObject *obj, guint8 *tramp); gconstpointer mono_get_trampoline_func (MonoTrampolineType tramp_type); gpointer mini_get_vtable_trampoline (MonoVTable *vt, int slot_index); const char* mono_get_generic_trampoline_simple_name (MonoTrampolineType tramp_type); const char* mono_get_generic_trampoline_name (MonoTrampolineType tramp_type); char* mono_get_rgctx_fetch_trampoline_name (int slot); -gpointer mini_get_nullified_class_init_trampoline (void); gpointer mini_get_single_step_trampoline (void); gpointer mini_get_breakpoint_trampoline (void); gpointer mini_add_method_trampoline (MonoMethod *m, gpointer compiled_method, gboolean add_static_rgctx_tramp, gboolean add_unbox_tramp); @@ -2370,10 +2361,7 @@ void mono_arch_exceptions_init (void); guchar* mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInfo **info, gboolean aot); gpointer mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot, MonoTrampInfo **info, gboolean aot); gpointer mono_arch_create_general_rgctx_lazy_fetch_trampoline (MonoTrampInfo **info, gboolean aot); -gpointer mono_arch_get_nullified_class_init_trampoline (MonoTrampInfo **info); guint8* mono_arch_create_sdb_trampoline (gboolean single_step, MonoTrampInfo **info, gboolean aot); -gpointer mono_arch_create_monitor_enter_trampoline (MonoTrampInfo **info, gboolean is_v4, gboolean aot); -gpointer mono_arch_create_monitor_exit_trampoline (MonoTrampInfo **info, gboolean aot); guint8 *mono_arch_create_llvm_native_thunk (MonoDomain *domain, guint8* addr); gpointer mono_arch_get_get_tls_tramp (void); GList *mono_arch_get_allocatable_int_vars (MonoCompile *cfg); @@ -2485,7 +2473,6 @@ gpointer mono_arch_get_llvm_imt_trampoline (MonoDomain *domain, MonoMethod gpointer mono_arch_get_gsharedvt_arg_trampoline (MonoDomain *domain, gpointer arg, gpointer addr); void mono_arch_patch_callsite (guint8 *method_start, guint8 *code, guint8 *addr); void mono_arch_patch_plt_entry (guint8 *code, gpointer *got, host_mgreg_t *regs, guint8 *addr); -void mono_arch_nullify_class_init_trampoline(guint8 *code, host_mgreg_t *regs); int mono_arch_get_this_arg_reg (guint8 *code); gpointer mono_arch_get_this_arg_from_call (host_mgreg_t *regs, guint8 *code); gpointer mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_target); diff --git a/mono/mini/tramp-arm64-gsharedvt.c b/mono/mini/tramp-arm64-gsharedvt.c index 269624c259d..ec263e38cbd 100644 --- a/mono/mini/tramp-arm64-gsharedvt.c +++ b/mono/mini/tramp-arm64-gsharedvt.c @@ -42,7 +42,7 @@ mono_arch_get_gsharedvt_arg_trampoline (MonoDomain *domain, gpointer arg, gpoint code = mono_arm_emit_imm64 (code, ARMREG_IP1, (guint64)arg); code = mono_arm_emit_imm64 (code, ARMREG_IP0, (guint64)addr); - arm_brx (code, ARMREG_IP0); + code = mono_arm_emit_brx (code, ARMREG_IP0); g_assert ((code - buf) < buf_len); @@ -308,7 +308,7 @@ mono_arch_get_gsharedvt_trampoline (MonoTrampInfo **info, gboolean aot) code = mono_arm_emit_aotconst (&ji, code, buf, ARMREG_IP0, MONO_PATCH_INFO_JIT_ICALL_ADDR, GUINT_TO_POINTER (MONO_JIT_ICALL_mono_arm_start_gsharedvt_call)); else code = mono_arm_emit_imm64 (code, ARMREG_IP0, (guint64)mono_arm_start_gsharedvt_call); - arm_blrx (code, ARMREG_IP0); + code = mono_arm_emit_blrx (code, ARMREG_IP0); /* Make the real method call */ /* R0 contains the addr to call */ @@ -325,7 +325,7 @@ mono_arch_get_gsharedvt_trampoline (MonoTrampInfo **info, gboolean aot) /* Clear callee reg area */ arm_addx_imm (code, ARMREG_SP, ARMREG_SP, ((n_arg_regs + n_arg_fregs) * sizeof (target_mgreg_t)) + 8); /* Make the call */ - arm_blrx (code, ARMREG_IP1); + code = mono_arm_emit_blrx (code, ARMREG_IP1); br_ret_index = 0; bcc_ret_index = 0; diff --git a/mono/mini/tramp-arm64.c b/mono/mini/tramp-arm64.c index cab924cf773..55522902801 100644 --- a/mono/mini/tramp-arm64.c +++ b/mono/mini/tramp-arm64.c @@ -194,7 +194,7 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf tramp = (guint8*)mono_get_lmf_addr; code = mono_arm_emit_imm64 (code, ARMREG_IP0, (guint64)tramp); } - arm_blrx (code, ARMREG_IP0); + code = mono_arm_emit_blrx (code, ARMREG_IP0); /* r0 contains the address of the tls slot holding the current lmf */ /* ip0 = lmf */ arm_addx_imm (code, ARMREG_IP0, ARMREG_FP, lmf_offset); @@ -229,7 +229,7 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf tramp = (guint8*)mono_get_trampoline_func (tramp_type); code = mono_arm_emit_imm64 (code, ARMREG_IP0, (guint64)tramp); } - arm_blrx (code, ARMREG_IP0); + code = mono_arm_emit_blrx (code, ARMREG_IP0); /* Save the result */ arm_strx (code, ARMREG_R0, ARMREG_FP, res_offset); @@ -253,7 +253,7 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf } else { code = mono_arm_emit_imm64 (code, ARMREG_IP0, (guint64)mono_thread_force_interruption_checkpoint_noraise); } - arm_blrx (code, ARMREG_IP0); + code = mono_arm_emit_blrx (code, ARMREG_IP0); /* Check whenever there is an exception to be thrown */ labels [0] = code; arm_cbnzx (code, ARMREG_R0, 0); @@ -277,10 +277,11 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf /* Cleanup frame */ code = mono_arm_emit_destroy_frame (code, frame_size, ((1 << ARMREG_IP0))); - if (tramp_type == MONO_TRAMPOLINE_RGCTX_LAZY_FETCH) + if (tramp_type == MONO_TRAMPOLINE_RGCTX_LAZY_FETCH) { arm_retx (code, ARMREG_LR); - else - arm_brx (code, ARMREG_IP1); + } else { + code = mono_arm_emit_brx (code, ARMREG_IP1); + } /* Exception case */ mono_arm_patch (labels [0], code, MONO_R_ARM64_CBZ); @@ -303,7 +304,7 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf } arm_ldrx (code, ARMREG_IP0, ARMREG_IP0, 0); /* lr contains the return address, the trampoline will use it as the throw site */ - arm_brx (code, ARMREG_IP0); + code = mono_arm_emit_brx (code, ARMREG_IP0); g_assert ((code - buf) < buf_len); @@ -314,7 +315,7 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf *info = mono_tramp_info_create (tramp_name, buf, code - buf, ji, unwind_ops); } - return buf; + return (guchar*)MINI_ADDR_TO_FTNPTR (buf); } gpointer @@ -336,7 +337,7 @@ mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_ty code = mono_arm_emit_imm64 (code, ARMREG_IP1, (guint64)arg1); code = mono_arm_emit_imm64 (code, ARMREG_IP0, (guint64)tramp); - arm_brx (code, ARMREG_IP0); + code = mono_arm_emit_brx (code, ARMREG_IP0); g_assert ((code - buf) < buf_len); @@ -345,7 +346,7 @@ mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_ty if (code_len) *code_len = code - buf; - return buf; + return (gpointer)MINI_ADDR_TO_FTNPTR (buf); } gpointer @@ -360,15 +361,17 @@ mono_arch_get_unbox_trampoline (MonoMethod *m, gpointer addr) MINI_BEGIN_CODEGEN (); + // FIXME: Maybe make a normal non-ptrauth call ? + code = mono_arm_emit_imm64 (code, ARMREG_IP0, (guint64)addr); arm_addx_imm (code, ARMREG_R0, ARMREG_R0, MONO_ABI_SIZEOF (MonoObject)); - arm_brx (code, ARMREG_IP0); + code = mono_arm_emit_brx (code, ARMREG_IP0); g_assert ((code - start) <= size); MINI_END_CODEGEN (start, code - start, MONO_PROFILER_CODE_BUFFER_UNBOX_TRAMPOLINE, m); - return start; + return (gpointer)MINI_ADDR_TO_FTNPTR (start); } gpointer @@ -376,7 +379,6 @@ mono_arch_get_static_rgctx_trampoline (MonoMemoryManager *mem_manager, gpointer { guint8 *code, *start; guint32 buf_len = 32; - MonoDomain *domain = mono_domain_get (); start = code = mono_mem_manager_code_reserve (mem_manager, buf_len); @@ -384,13 +386,13 @@ mono_arch_get_static_rgctx_trampoline (MonoMemoryManager *mem_manager, gpointer code = mono_arm_emit_imm64 (code, MONO_ARCH_RGCTX_REG, (guint64)arg); code = mono_arm_emit_imm64 (code, ARMREG_IP0, (guint64)addr); - arm_brx (code, ARMREG_IP0); + code = mono_arm_emit_brx (code, ARMREG_IP0); MINI_END_CODEGEN (start, code - start, MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE, NULL); g_assert ((code - start) <= buf_len); - return start; + return (gpointer)MINI_ADDR_TO_FTNPTR (start); } gpointer @@ -481,7 +483,7 @@ mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot, MonoTrampInfo **info tramp = (guint8*)mono_arch_create_specific_trampoline (GUINT_TO_POINTER (slot), MONO_TRAMPOLINE_RGCTX_LAZY_FETCH, mem_manager, &code_len); code = mono_arm_emit_imm64 (code, ARMREG_IP0, (guint64)tramp); } - arm_brx (code, ARMREG_IP0); + code = mono_arm_emit_brx (code, ARMREG_IP0); g_assert (code - buf <= buf_size); @@ -493,7 +495,7 @@ mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot, MonoTrampInfo **info g_free (name); } - return buf; + return (gpointer)MINI_ADDR_TO_FTNPTR (buf); } gpointer @@ -519,7 +521,7 @@ mono_arch_create_general_rgctx_lazy_fetch_trampoline (MonoTrampInfo **info, gboo arm_ldrx (code, ARMREG_IP0, MONO_ARCH_RGCTX_REG, 8); /* The vtable/mrgctx is in R0 */ g_assert (MONO_ARCH_VTABLE_REG == ARMREG_R0); - arm_brx (code, ARMREG_IP0); + code = mono_arm_emit_brx (code, ARMREG_IP0); g_assert (code - buf <= tramp_size); @@ -528,7 +530,7 @@ mono_arch_create_general_rgctx_lazy_fetch_trampoline (MonoTrampInfo **info, gboo if (info) *info = mono_tramp_info_create ("rgctx_fetch_trampoline_general", buf, code - buf, ji, unwind_ops); - return buf; + return (gpointer)MINI_ADDR_TO_FTNPTR (buf); } /* @@ -607,7 +609,7 @@ mono_arch_create_sdb_trampoline (gboolean single_step, MonoTrampInfo **info, gbo code = mono_arm_emit_imm64 (code, ARMREG_IP0, (guint64)addr); } - arm_blrx (code, ARMREG_IP0); + code = mono_arm_emit_blrx (code, ARMREG_IP0); /* Restore ctx */ /* Save fp/pc into the frame block */ @@ -629,7 +631,7 @@ mono_arch_create_sdb_trampoline (gboolean single_step, MonoTrampInfo **info, gbo const char *tramp_name = single_step ? "sdb_single_step_trampoline" : "sdb_breakpoint_trampoline"; *info = mono_tramp_info_create (tramp_name, buf, code - buf, ji, unwind_ops); - return buf; + return (guint8*)MINI_ADDR_TO_FTNPTR (buf); } /* @@ -711,7 +713,7 @@ mono_arch_get_interp_to_native_trampoline (MonoTrampInfo **info) arm_ldrx (code, ARMREG_IP0, ARMREG_FP, off_targetaddr); /* call into native function */ - arm_blrx (code, ARMREG_IP0); + code = mono_arm_emit_blrx (code, ARMREG_IP0); /* load CallContext* */ arm_ldrx (code, ARMREG_IP0, ARMREG_FP, off_methodargs); @@ -736,7 +738,7 @@ mono_arch_get_interp_to_native_trampoline (MonoTrampInfo **info) if (info) *info = mono_tramp_info_create ("interp_to_native_trampoline", start, code - start, ji, unwind_ops); - return start; + return (guint8*)MINI_ADDR_TO_FTNPTR (start); #else g_assert_not_reached (); return NULL; @@ -792,7 +794,7 @@ mono_arch_get_native_to_interp_trampoline (MonoTrampInfo **info) arm_addx_imm (code, ARMREG_R0, ARMREG_FP, ccontext_offset); arm_ldrp (code, ARMREG_R1, MONO_ARCH_RGCTX_REG, MONO_STRUCT_OFFSET (MonoFtnDesc, arg)); arm_ldrp (code, ARMREG_IP0, MONO_ARCH_RGCTX_REG, MONO_STRUCT_OFFSET (MonoFtnDesc, addr)); - arm_blrx (code, ARMREG_IP0); + code = mono_arm_emit_blrx (code, ARMREG_IP0); /* load the return values from the context */ for (i = 0; i < PARAM_REGS; i++) @@ -813,7 +815,7 @@ mono_arch_get_native_to_interp_trampoline (MonoTrampInfo **info) if (info) *info = mono_tramp_info_create ("native_to_interp_trampoline", start, code - start, ji, unwind_ops); - return start; + return (guint8*)MINI_ADDR_TO_FTNPTR (start); #else g_assert_not_reached (); return NULL; @@ -857,13 +859,6 @@ mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot, MonoTrampInfo **info return NULL; } -gpointer -mono_arch_get_nullified_class_init_trampoline (MonoTrampInfo **info) -{ - g_assert_not_reached (); - return NULL; -} - guint8* mono_arch_create_sdb_trampoline (gboolean single_step, MonoTrampInfo **info, gboolean aot) { diff --git a/mono/utils/Makefile.am b/mono/utils/Makefile.am index 8d9bd115981..3a737bd43bb 100644 --- a/mono/utils/Makefile.am +++ b/mono/utils/Makefile.am @@ -236,7 +236,8 @@ monoutils_sources = \ ward.h \ options.h \ options-def.h \ - options.c + options.c \ + ftnptr.h arch_sources = diff --git a/mono/utils/ftnptr.h b/mono/utils/ftnptr.h new file mode 100644 index 00000000000..81788407af0 --- /dev/null +++ b/mono/utils/ftnptr.h @@ -0,0 +1,43 @@ +#ifndef __MONO_UTILS_FTNPTR_H__ +#define __MONO_UTILS_FTNPTR_H__ + +#include <config.h> + +#if defined(TARGET_OSX) +#if __has_feature(ptrauth_intrinsics) +#define MONO_ARCH_ENABLE_PTRAUTH 1 +#include <ptrauth.h> +#endif +#endif + +/* + * This is a general function pointer type. On most platforms, + * it is equal to the function's address in memory, except: + * - on wasm, its equal to the function's wasm index + * - on arm64e, its an authenticated pointer. + */ +typedef gpointer MonoFtnPtr; + +/* + * Authenticated pointer support for arm64e. + * Pointers are in their authenticated form in most parts of the runtime code, + * except the parts which needs their numerical value i.e. codegen, jit info + * table, EH, etc. + * FIXME: + * - use returns in trampolines as well + * - clean up ifdefs + */ +#if defined(MONO_ARCH_ENABLE_PTRAUTH) +/* + * Convert a raw pointer to a function to a C function pointer. + */ +#define MINI_ADDR_TO_FTNPTR(addr) (MonoFtnPtr)ptrauth_sign_unauthenticated ((addr), ptrauth_key_function_pointer, NULL) + +#define MINI_FTNPTR_TO_ADDR(addr) ptrauth_strip ((addr), ptrauth_key_function_pointer) +#else +#define MINI_ADDR_TO_FTNPTR(addr) ((MonoFtnPtr)(addr)) +#define MINI_FTNPTR_TO_ADDR(addr) ((gpointer)(addr)) +#endif + +#endif + diff --git a/mono/utils/mach-support-arm64.c b/mono/utils/mach-support-arm64.c index 2cf906679dc..c2e6319052d 100644 --- a/mono/utils/mach-support-arm64.c +++ b/mono/utils/mach-support-arm64.c @@ -63,10 +63,18 @@ mono_mach_arch_thread_states_to_mono_context (thread_state_t state, thread_state for (i = 0; i < 29; ++i) context->regs [i] = arch_state->ts_64.__x [i]; +#if __has_feature(ptrauth_calls) + /* arm64e */ + context->regs [ARMREG_R29] = __darwin_arm_thread_state64_get_fp (arch_state->ts_64); + context->regs [ARMREG_R30] = __darwin_arm_thread_state64_get_lr (arch_state->ts_64); + context->regs [ARMREG_SP] = __darwin_arm_thread_state64_get_sp (arch_state->ts_64); + context->pc = (host_mgreg_t)__darwin_arm_thread_state64_get_pc_fptr (arch_state->ts_64); +#else context->regs [ARMREG_R29] = arch_state->ts_64.__fp; context->regs [ARMREG_R30] = arch_state->ts_64.__lr; context->regs [ARMREG_SP] = arch_state->ts_64.__sp; context->pc = arch_state->ts_64.__pc; +#endif for (i = 0; i < 32; ++i) context->fregs [i] = arch_fpstate->__v [i]; diff --git a/mono/utils/mono-context.c b/mono/utils/mono-context.c index b77c4b2d747..403a6c8fa6f 100644 --- a/mono/utils/mono-context.c +++ b/mono/utils/mono-context.c @@ -515,6 +515,7 @@ mono_monoctx_to_sigctx (MonoContext *mctx, void *ctx) #elif (defined(__aarch64__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_ARM64)) #include <mono/utils/mono-context.h> +#include <mono/utils/ftnptr.h> void mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx) @@ -525,6 +526,12 @@ mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx) memcpy (mctx->regs, UCONTEXT_GREGS (sigctx), sizeof (host_mgreg_t) * 31); mctx->pc = UCONTEXT_REG_PC (sigctx); mctx->regs [ARMREG_SP] = UCONTEXT_REG_SP (sigctx); +#ifdef UCONTEXT_REG_LR + mctx->regs [ARMREG_LR] = UCONTEXT_REG_LR (sigctx); +#endif +#ifdef MONO_ARCH_ENABLE_PTRAUTH + mctx->regs [ARMREG_FP] = (host_mgreg_t)ptrauth_strip ((void*)mctx->regs [ARMREG_FP], ptrauth_key_frame_pointer); +#endif #ifdef __linux__ struct fpsimd_context *fpctx = (struct fpsimd_context*)&((ucontext_t*)sigctx)->uc_mcontext.__reserved; int i; @@ -543,9 +550,15 @@ mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx) #ifdef MONO_CROSS_COMPILE g_assert_not_reached (); #else +#ifdef MONO_ARCH_ENABLE_PTRAUTH memcpy (UCONTEXT_GREGS (sigctx), mctx->regs, sizeof (host_mgreg_t) * 31); - UCONTEXT_REG_PC (sigctx) = mctx->pc; - UCONTEXT_REG_SP (sigctx) = mctx->regs [ARMREG_SP]; + UCONTEXT_REG_SET_PC (sigctx, (gpointer)mctx->pc); + UCONTEXT_REG_SET_SP (sigctx, mctx->regs [ARMREG_SP]); +#else + memcpy (UCONTEXT_GREGS (sigctx), mctx->regs, sizeof (host_mgreg_t) * 31); + UCONTEXT_REG_SET_PC (sigctx, mctx->pc); + UCONTEXT_REG_SET_SP (sigctx, mctx->regs [ARMREG_SP]); +#endif #endif } diff --git a/mono/utils/mono-sigcontext.h b/mono/utils/mono-sigcontext.h index 98e8e5e59a2..699af6e37d1 100644 --- a/mono/utils/mono-sigcontext.h +++ b/mono/utils/mono-sigcontext.h @@ -463,9 +463,19 @@ typedef struct ucontext { #elif defined(__APPLE__) #include <machine/_mcontext.h> #include <sys/_types/_ucontext64.h> + /* mach/arm/_structs.h */ +#if __has_feature(ptrauth_calls) + #define UCONTEXT_REG_PC(ctx) (host_mgreg_t)__darwin_arm_thread_state64_get_pc_fptr (((ucontext64_t*)(ctx))->uc_mcontext64->__ss) + #define UCONTEXT_REG_SP(ctx) __darwin_arm_thread_state64_get_sp (((ucontext64_t*)(ctx))->uc_mcontext64->__ss) + #define UCONTEXT_REG_LR(ctx) __darwin_arm_thread_state64_get_lr (((ucontext64_t*)(ctx))->uc_mcontext64->__ss) + #define UCONTEXT_REG_SET_PC(ctx,val) __darwin_arm_thread_state64_set_pc_fptr (((ucontext64_t*)(ctx))->uc_mcontext64->__ss, (val)) + #define UCONTEXT_REG_SET_SP(ctx, val) __darwin_arm_thread_state64_set_sp (((ucontext64_t*)(ctx))->uc_mcontext64->__ss, (val)) +#else #define UCONTEXT_REG_PC(ctx) (((ucontext64_t*)(ctx))->uc_mcontext64->__ss.__pc) #define UCONTEXT_REG_SP(ctx) (((ucontext64_t*)(ctx))->uc_mcontext64->__ss.__sp) +#endif + #define UCONTEXT_REG_R0(ctx) (((ucontext64_t*)(ctx))->uc_mcontext64->__ss.__x [ARMREG_R0]) #define UCONTEXT_GREGS(ctx) (&(((ucontext64_t*)(ctx))->uc_mcontext64->__ss.__x)) #elif defined(__FreeBSD__) @@ -483,6 +493,15 @@ typedef struct ucontext { #define UCONTEXT_GREGS(ctx) (&(((ucontext_t*)(ctx))->uc_mcontext.regs)) #endif +#ifndef UCONTEXT_REG_SET_PC +#define UCONTEXT_REG_SET_PC(ctx, val) do { \ + UCONTEXT_REG_PC (ctx) = (val); \ + } while (0) +#define UCONTEXT_REG_SET_SP(ctx, val) do { \ + UCONTEXT_REG_SP (ctx) = (val); \ + } while (0) +#endif + #elif defined(__mips__) # if HAVE_UCONTEXT_H diff --git a/mono/utils/mono-state.c b/mono/utils/mono-state.c index 7333818f3a2..e33f6c028c1 100644 --- a/mono/utils/mono-state.c +++ b/mono/utils/mono-state.c @@ -142,7 +142,7 @@ typedef struct { } MonoSummaryTimeline; static const char *configured_timeline_dir; -static MonoSummaryTimeline log; +static MonoSummaryTimeline mlog; static void file_for_stage_breadcrumb (const char *directory, MonoSummaryStage stage, gchar *buff, size_t sizeof_buff) @@ -178,7 +178,7 @@ static void create_stage_breadcrumb (void) { char out_file [200]; - file_for_stage_breadcrumb (log.directory, log.level, out_file, sizeof(out_file)); + file_for_stage_breadcrumb (mlog.directory, mlog.level, out_file, sizeof(out_file)); create_breadcrumb (out_file); } @@ -186,7 +186,7 @@ static void create_dump_reason_breadcrumb (const char *dump_reason) { char out_file [200]; - file_for_dump_reason_breadcrumb (log.directory, dump_reason, out_file, sizeof(out_file)); + file_for_dump_reason_breadcrumb (mlog.directory, dump_reason, out_file, sizeof(out_file)); create_breadcrumb (out_file); } @@ -194,7 +194,7 @@ void mono_create_crash_hash_breadcrumb (MonoThreadSummary *thread) { char out_file [200]; - file_for_hash_breadcrumb (log.directory, thread->hashes, out_file, sizeof(out_file)); + file_for_hash_breadcrumb (mlog.directory, thread->hashes, out_file, sizeof(out_file)); create_breadcrumb (out_file); } @@ -213,12 +213,12 @@ mono_summarize_set_timeline_dir (const char *directory) void mono_summarize_timeline_start (const char *dump_reason) { - memset (&log, 0, sizeof (log)); + memset (&mlog, 0, sizeof (mlog)); if (!configured_timeline_dir) return; - log.directory = configured_timeline_dir; + mlog.directory = configured_timeline_dir; create_dump_reason_breadcrumb (dump_reason); mono_summarize_timeline_phase_log (MonoSummarySetup); } @@ -232,11 +232,11 @@ mono_summarize_double_fault_log (void) void mono_summarize_timeline_phase_log (MonoSummaryStage next) { - if (!log.directory) + if (!mlog.directory) return; MonoSummaryStage out_level; - switch (log.level) { + switch (mlog.level) { case MonoSummaryNone: out_level = MonoSummarySetup; break; @@ -276,25 +276,25 @@ mono_summarize_timeline_phase_log (MonoSummaryStage next) break; case MonoSummaryDone: - g_async_safe_printf ("Trying to log crash reporter timeline, already at done %d\n", log.level); + g_async_safe_printf ("Trying to log crash reporter timeline, already at done %d\n", mlog.level); return; default: - g_async_safe_printf ("Trying to log crash reporter timeline, illegal state %d\n", log.level); + g_async_safe_printf ("Trying to log crash reporter timeline, illegal state %d\n", mlog.level); return; } g_assertf(out_level == next || next == MonoSummaryDoubleFault, "Log Error: Log transition to %d, actual expected next step is %d\n", next, out_level); - log.level = out_level; + mlog.level = out_level; create_stage_breadcrumb (); // To check, comment out normally // DO NOT MERGE UNCOMMENTED // As this does a lot of FILE io // - // g_assert (out_level == mono_summarize_timeline_read_level (log.directory, FALSE)); + // g_assert (out_level == mono_summarize_timeline_read_level (mlog.directory, FALSE)); if (out_level == MonoSummaryDone) - memset (&log, 0, sizeof (log)); + memset (&mlog, 0, sizeof (mlog)); return; } @@ -376,7 +376,7 @@ mono_summarize_timeline_read_level (const char *directory, gboolean clear) char out_file [200]; if (!directory) - directory = log.directory; + directory = mlog.directory; if (!directory) return MonoSummaryNone; |