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:
authorNeale Ferguson <neale@sinenomine.net>2021-02-17 02:54:21 +0300
committerGitHub <noreply@github.com>2021-02-17 02:54:21 +0300
commitc868a253f451000af8f7060ab0ea605bc58593ce (patch)
tree0a7966fa39a1b96eb6b3da47b9166691a9b6bd3d
parentd6c2313a95058e9d6ee8d4b9b33cbaf9dfec1048 (diff)
s390x: Trampoline fixes and implement mono_arch_patch_code_new (#20852)
- Fixes some lack of casting warnings - Fix formatting - Sometimes a trampoline may be more than 4GB away from its target. We need to detect this and use a load/branch rather than a jump relative - Implement `mono_arch_patch_code_new` in lieu of `mono_arch_patch_code`
-rw-r--r--mono/mini/mini-s390x.c140
-rw-r--r--mono/mini/mini-s390x.h1
-rw-r--r--mono/mini/tramp-s390x.c47
3 files changed, 101 insertions, 87 deletions
diff --git a/mono/mini/mini-s390x.c b/mono/mini/mini-s390x.c
index 612dcb0f5a8..138f64e82cc 100644
--- a/mono/mini/mini-s390x.c
+++ b/mono/mini/mini-s390x.c
@@ -1051,9 +1051,9 @@ get_call_info (MonoMemPool *mp, MonoMethodSignature *sig)
size_data *sz;
if (mp)
- cinfo = mono_mempool_alloc0 (mp, sizeof (CallInfo) + sizeof (ArgInfo) * nParm);
+ cinfo = (CallInfo *) mono_mempool_alloc0 (mp, sizeof (CallInfo) + sizeof (ArgInfo) * nParm);
else
- cinfo = g_malloc0 (sizeof (CallInfo) + sizeof (ArgInfo) * nParm);
+ cinfo = (CallInfo *) g_malloc0 (sizeof (CallInfo) + sizeof (ArgInfo) * nParm);
fr = 0;
gr = s390_r2;
@@ -3485,7 +3485,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
s390_lg (code, ins->dreg, s390_r13, s390_r1, 0);
}
break;
- case OP_TLS_SET: {
+ case OP_TLS_SET: {
if (s390_is_imm16 (ins->inst_offset)) {
s390_lghi (code, s390_r13, ins->inst_offset);
} else if (s390_is_imm32 (ins->inst_offset)) {
@@ -3565,7 +3565,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
mono_add_patch_info (cfg, code - cfg->native_code,
MONO_PATCH_INFO_METHOD_JUMP,
call->method);
- s390_jcl (code, S390_CC_UN, 0);
+ S390_BR_TEMPLATE (code, s390_r1);
}
}
}
@@ -5350,67 +5350,65 @@ mono_arch_register_lowlevel_calls (void)
*/
void
-mono_arch_patch_code (MonoCompile *cfg, MonoMethod *method, MonoDomain *domain,
- guint8 *code, MonoJumpInfo *ji, gboolean run_cctors,
- MonoError *error)
+mono_arch_patch_code_new (MonoCompile *cfg, MonoDomain *domain,
+ guint8 *code, MonoJumpInfo *ji, gpointer target)
{
- MonoJumpInfo *patch_info;
-
- error_init (error);
-
- for (patch_info = ji; patch_info; patch_info = patch_info->next) {
- unsigned char *ip = patch_info->ip.i + code;
- gconstpointer target = NULL;
-
- target = mono_resolve_patch_target (method, domain, code,
- patch_info, run_cctors, error);
- return_if_nok (error);
-
- switch (patch_info->type) {
- case MONO_PATCH_INFO_IP:
- case MONO_PATCH_INFO_LDSTR:
- case MONO_PATCH_INFO_TYPE_FROM_HANDLE:
- case MONO_PATCH_INFO_LDTOKEN:
- case MONO_PATCH_INFO_EXC:
- s390_patch_addr (ip, (guint64) target);
- continue;
- case MONO_PATCH_INFO_SPECIFIC_TRAMPOLINE_LAZY_FETCH_ADDR:
- case MONO_PATCH_INFO_METHOD:
- case MONO_PATCH_INFO_JIT_ICALL_ID:
- case MONO_PATCH_INFO_JIT_ICALL_ADDR:
- case MONO_PATCH_INFO_RGCTX_FETCH:
- case MONO_PATCH_INFO_ABS: {
- S390_EMIT_CALL (ip, target);
- continue;
- }
- case MONO_PATCH_INFO_SWITCH:
- /*----------------------------------*/
- /* ip points at the basr r13,0/j +4 */
- /* instruction the vtable value */
- /* follows this (i.e. ip+6) */
- /*----------------------------------*/
- S390_EMIT_LOAD (ip, target);
- continue;
- case MONO_PATCH_INFO_METHODCONST:
- case MONO_PATCH_INFO_CLASS:
- case MONO_PATCH_INFO_IMAGE:
- case MONO_PATCH_INFO_FIELD:
- case MONO_PATCH_INFO_IID:
- case MONO_PATCH_INFO_EXC_NAME:
- target = S390_RELATIVE(target, ip);
- s390_patch_rel (ip, (guint64) target);
- continue;
- case MONO_PATCH_INFO_R4:
- case MONO_PATCH_INFO_R8:
- g_assert_not_reached ();
- continue;
- default:
- target = S390_RELATIVE(target, ip);
- ip += 2;
- s390_patch_rel (ip, (guint64) target);
- case MONO_PATCH_INFO_NONE:
- break;
+ unsigned char *ip = ji->ip.i + code;
+ uintptr_t displace;
+
+ switch (ji->type) {
+ case MONO_PATCH_INFO_IP:
+ case MONO_PATCH_INFO_LDSTR:
+ case MONO_PATCH_INFO_TYPE_FROM_HANDLE:
+ case MONO_PATCH_INFO_LDTOKEN:
+ case MONO_PATCH_INFO_EXC:
+ s390_patch_addr (ip, (guint64) target);
+ break;
+ case MONO_PATCH_INFO_SPECIFIC_TRAMPOLINE_LAZY_FETCH_ADDR:
+ case MONO_PATCH_INFO_METHOD:
+ case MONO_PATCH_INFO_JIT_ICALL_ID:
+ case MONO_PATCH_INFO_JIT_ICALL_ADDR:
+ case MONO_PATCH_INFO_RGCTX_FETCH:
+ case MONO_PATCH_INFO_ABS: {
+ S390_EMIT_CALL (ip, target);
+ break;
+ }
+ case MONO_PATCH_INFO_SWITCH:
+ /*----------------------------------*/
+ /* ip points at the basr r13,0/j +4 */
+ /* instruction the vtable value */
+ /* follows this (i.e. ip+6) */
+ /*----------------------------------*/
+ S390_EMIT_LOAD (ip, target);
+ break;
+ case MONO_PATCH_INFO_METHODCONST:
+ case MONO_PATCH_INFO_CLASS:
+ case MONO_PATCH_INFO_IMAGE:
+ case MONO_PATCH_INFO_FIELD:
+ case MONO_PATCH_INFO_IID:
+ case MONO_PATCH_INFO_EXC_NAME:
+ target = S390_RELATIVE(target, ip);
+ s390_patch_rel (ip, (guint64) target);
+ break;
+ case MONO_PATCH_INFO_R4:
+ case MONO_PATCH_INFO_R8:
+ g_assert_not_reached ();
+ break;
+ case MONO_PATCH_INFO_METHOD_JUMP:
+ displace = (uintptr_t) S390_RELATIVE(target, ip);
+ if ((displace >= INT_MIN) && (displace <= INT_MAX))
+ s390_jg (ip, (gint32) displace);
+ else {
+ S390_SET (ip, s390_r1, target);
+ s390_br (ip, s390_r1);
}
+ break;
+ case MONO_PATCH_INFO_NONE:
+ break;
+ default:
+ target = S390_RELATIVE(target, ip);
+ ip += 2;
+ s390_patch_rel (ip, (guint64) target);
}
}
@@ -5450,7 +5448,7 @@ mono_arch_emit_prolog (MonoCompile *cfg)
if (method->save_lmf)
cfg->code_size += 200;
- cfg->native_code = code = g_malloc (cfg->code_size);
+ cfg->native_code = code = (guint8 *) g_malloc (cfg->code_size);
/**
* Create unwind information
@@ -6247,7 +6245,7 @@ get_delegate_invoke_impl (MonoTrampInfo **info, gboolean has_target, MonoMethodS
if (has_target) {
int size = 32;
- start = code = mono_global_codeman_reserve (size);
+ start = code = (guint8 *) mono_global_codeman_reserve (size);
/* Replace the this argument with the target */
s390_lg (code, s390_r1, 0, s390_r2, MONO_STRUCT_OFFSET (MonoDelegate, method_ptr));
@@ -6262,7 +6260,7 @@ get_delegate_invoke_impl (MonoTrampInfo **info, gboolean has_target, MonoMethodS
CallInfo *cinfo = get_call_info (NULL, sig);
size = 32 + sig->param_count * 8;
- start = code = mono_global_codeman_reserve (size);
+ start = code = (guint8 *) mono_global_codeman_reserve (size);
s390_lg (code, s390_r1, 0, s390_r2, MONO_STRUCT_OFFSET (MonoDelegate, method_ptr));
/* slide down the arguments */
@@ -6364,7 +6362,7 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
return cached;
if (mono_ee_features.use_aot_trampolines) {
- start = mono_aot_get_trampoline ("delegate_invoke_impl_has_target");
+ start = (guint8 *) mono_aot_get_trampoline ("delegate_invoke_impl_has_target");
} else {
MonoTrampInfo *info;
start = get_delegate_invoke_impl (&info, TRUE, sig, FALSE);
@@ -6390,7 +6388,7 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
if (mono_ee_features.use_aot_trampolines) {
char *name = g_strdup_printf ("delegate_invoke_impl_target_%d", sig->param_count);
- start = mono_aot_get_trampoline (name);
+ start = (guint8 *) mono_aot_get_trampoline (name);
g_free (name);
} else {
MonoTrampInfo *info;
@@ -6427,7 +6425,7 @@ mono_arch_get_delegate_virtual_invoke_impl (MonoMethodSignature *sig, MonoMethod
guint8 *code, *start;
int size = 40;
- start = code = mono_global_codeman_reserve (size);
+ start = code = (guint8 *) mono_global_codeman_reserve (size);
/*
* Replace the "this" argument with the target
@@ -6516,10 +6514,10 @@ mono_arch_build_imt_trampoline (MonoVTable *vtable, MonoDomain *domain,
}
if (fail_tramp) {
- code = mono_method_alloc_generic_virtual_trampoline (mono_domain_ambient_memory_manager (domain), size);
+ code = (guint8 *) mono_method_alloc_generic_virtual_trampoline (mono_domain_ambient_memory_manager (domain), size);
} else {
MonoMemoryManager *mem_manager = m_class_get_mem_manager (domain, vtable->klass);
- code = mono_mem_manager_code_reserve (mem_manager, size);
+ code = (guint8 *) mono_mem_manager_code_reserve (mem_manager, size);
}
start = code;
diff --git a/mono/mini/mini-s390x.h b/mono/mini/mini-s390x.h
index 2b94792bd47..aaa5c33b642 100644
--- a/mono/mini/mini-s390x.h
+++ b/mono/mini/mini-s390x.h
@@ -81,6 +81,7 @@ struct SeqPointInfo {
#define MONO_ARCH_HAVE_SDB_TRAMPOLINES 1
#define MONO_ARCH_HAVE_SETUP_RESUME_FROM_SIGNAL_HANDLER_CTX 1
#define MONO_ARCH_HAVE_UNWIND_BACKTRACE 1
+#define MONO_ARCH_HAVE_PATCH_CODE_NEW 1
#define S390_STACK_ALIGNMENT 8
#define S390_FIRST_ARG_REG s390_r2
diff --git a/mono/mini/tramp-s390x.c b/mono/mini/tramp-s390x.c
index 8695f380a74..7c08412863d 100644
--- a/mono/mini/tramp-s390x.c
+++ b/mono/mini/tramp-s390x.c
@@ -106,7 +106,7 @@ mono_arch_get_unbox_trampoline (MonoMethod *m, gpointer addr)
MonoMemoryManager *mem_manager = m_method_get_mem_manager (domain, m);
char trampName[128];
- start = code = mono_mem_manager_code_reserve (mem_manager, 28);
+ start = code = (guint8 *) mono_mem_manager_code_reserve (mem_manager, 28);
S390_SET (code, s390_r1, addr);
s390_aghi (code, this_pos, MONO_ABI_SIZEOF (MonoObject));
@@ -317,7 +317,7 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
/* Now we'll create in 'buf' the S/390 trampoline code. This
is the trampoline code common to all methods */
- code = buf = mono_global_codeman_reserve(512);
+ code = buf = (guint8 *) mono_global_codeman_reserve(512);
if (tramp_type == MONO_TRAMPOLINE_JUMP)
has_caller = 0;
@@ -399,7 +399,7 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
/*---------------------------------------------------------------*/
/* save method info */
/*---------------------------------------------------------------*/
- s390_lg (buf, s390_r1, 0, LMFReg, G_STRUCT_OFFSET(MonoLMF, gregs[1]));
+ s390_lg (buf, s390_r1, 0, LMFReg, G_STRUCT_OFFSET(MonoLMF, gregs[0]));
s390_stg (buf, s390_r1, 0, LMFReg, G_STRUCT_OFFSET(MonoLMF, method));
/*---------------------------------------------------------------*/
@@ -435,7 +435,7 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
}
/* Arg 3: Trampoline argument */
- s390_lg (buf, s390_r4, 0, LMFReg, G_STRUCT_OFFSET(MonoLMF, gregs[1]));
+ s390_lg (buf, s390_r4, 0, LMFReg, G_STRUCT_OFFSET(MonoLMF, gregs[0]));
/* Arg 4: trampoline address. */
S390_SET (buf, s390_r5, buf);
@@ -534,7 +534,7 @@ void
mono_arch_invalidate_method (MonoJitInfo *ji, void *func, gpointer func_arg)
{
/* FIXME: This is not thread safe */
- guint8 *code = ji->code_start;
+ guint8 *code = (guint8 *) ji->code_start;
S390_SET (code, s390_r1, func);
S390_SET (code, s390_r2, func_arg);
@@ -556,7 +556,7 @@ gpointer
mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_type, MonoMemoryManager *mem_manager, guint32 *code_len)
{
guint8 *code, *buf, *tramp;
- gint32 displace;
+ gint64 displace;
tramp = mono_get_trampoline_code (tramp_type);
@@ -565,11 +565,16 @@ mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_ty
/* purpose is to provide the generic part with the */
/* MonoMethod *method pointer. We'll use r1 to keep it. */
/*----------------------------------------------------------*/
- code = buf = mono_mem_manager_code_reserve (mem_manager, SPECIFIC_TRAMPOLINE_SIZE);
+ code = buf = (guint8 *) mono_mem_manager_code_reserve (mem_manager, SPECIFIC_TRAMPOLINE_SIZE);
- S390_SET (buf, s390_r1, arg1);
+ S390_SET (buf, s390_r0, arg1);
displace = (tramp - buf) / 2;
- s390_jg (buf, displace);
+ if ((displace >= INT_MIN) && (displace <= INT_MAX))
+ s390_jg (buf, (gint32) displace);
+ else {
+ S390_SET (buf, s390_r1, tramp);
+ s390_br (buf, s390_r1);
+ }
/* Flush instruction cache, since we've generated code */
mono_arch_flush_icache (code, buf - code);
@@ -602,7 +607,7 @@ mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot, MonoTrampInfo **info
guint8 *tramp;
guint8 *code, *buf;
guint8 **rgctx_null_jumps;
- gint32 displace;
+ gint64 displace;
int tramp_size,
depth,
index,
@@ -630,11 +635,11 @@ mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot, MonoTrampInfo **info
else
tramp_size += 12;
- code = buf = mono_global_codeman_reserve (tramp_size);
+ code = buf = (guint8 *) mono_global_codeman_reserve (tramp_size);
unwind_ops = mono_arch_get_cie_program ();
- rgctx_null_jumps = g_malloc (sizeof (guint8*) * (depth + 2));
+ rgctx_null_jumps = (guint8 **) g_malloc (sizeof (guint8*) * (depth + 2));
if (mrgctx) {
/* get mrgctx ptr */
@@ -690,7 +695,12 @@ mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot, MonoTrampInfo **info
/* jump to the actual trampoline */
displace = (tramp - code) / 2;
- s390_jg (code, displace);
+ if ((displace >= INT_MIN) && (displace <= INT_MAX))
+ s390_jg (code, displace);
+ else {
+ S390_SET (code, s390_r1, tramp);
+ s390_br (code, s390_r1);
+ }
mono_arch_flush_icache (buf, code - buf);
MONO_PROFILER_RAISE (jit_code_buffer, (buf, code - buf, MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE, NULL));
@@ -719,17 +729,22 @@ gpointer
mono_arch_get_static_rgctx_trampoline (MonoMemoryManager *mem_manager, gpointer arg, gpointer addr)
{
guint8 *code, *start;
- gint32 displace;
+ gint64 displace;
int buf_len;
MonoDomain *domain = mono_domain_get ();
buf_len = 32;
- start = code = mono_mem_manager_code_reserve (mem_manager, buf_len);
+ start = code = (guint8 *) mono_mem_manager_code_reserve (mem_manager, buf_len);
S390_SET (code, MONO_ARCH_RGCTX_REG, arg);
displace = ((uintptr_t) addr - (uintptr_t) code) / 2;
- s390_jg (code, displace);
+ if ((displace >= INT_MIN) && (displace <= INT_MAX))
+ s390_jg (code, (gint32) displace);
+ else {
+ S390_SET (code, s390_r1, addr);
+ s390_br (code, s390_r1);
+ }
g_assert ((code - start) < buf_len);
mono_arch_flush_icache (start, code - start);