Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZoltan Varga <vargaz@gmail.com>2021-02-03 22:43:48 +0300
committerGitHub <noreply@github.com>2021-02-03 22:43:48 +0300
commit43190aeb5f7e4d7e0185d3b656054bf232219fe2 (patch)
treecfb25621bd646cece9dbd764372bdb60381170bf
parent91a7a1ba961e81b0f9d012743535ef20fa725826 (diff)
Initial arm64e support (#20818)
* Fix the c++ build. * Remove some unused prototypes. * Initial arm64e support.
-rw-r--r--mono/arch/arm64/arm64-codegen.h12
-rw-r--r--mono/metadata/threads.c6
-rw-r--r--mono/mini/aot-compiler.c38
-rw-r--r--mono/mini/aot-runtime.c52
-rw-r--r--mono/mini/debugger-agent.c4
-rw-r--r--mono/mini/driver.c8
-rw-r--r--mono/mini/exceptions-arm64.c30
-rw-r--r--mono/mini/image-writer.c2
-rw-r--r--mono/mini/interp/interp.c1
-rw-r--r--mono/mini/mini-arm64.c99
-rw-r--r--mono/mini/mini-arm64.h4
-rw-r--r--mono/mini/mini-exceptions.c16
-rw-r--r--mono/mini/mini-generic-sharing.c10
-rw-r--r--mono/mini/mini-posix.c1
-rw-r--r--mono/mini/mini-runtime.c23
-rw-r--r--mono/mini/mini-runtime.h9
-rw-r--r--mono/mini/mini-trampolines.c6
-rw-r--r--mono/mini/mini.c11
-rw-r--r--mono/mini/mini.h17
-rw-r--r--mono/mini/tramp-arm64-gsharedvt.c6
-rw-r--r--mono/mini/tramp-arm64.c59
-rw-r--r--mono/utils/Makefile.am3
-rw-r--r--mono/utils/ftnptr.h43
-rw-r--r--mono/utils/mach-support-arm64.c8
-rw-r--r--mono/utils/mono-context.c17
-rw-r--r--mono/utils/mono-sigcontext.h19
-rw-r--r--mono/utils/mono-state.c28
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;