mirror of
https://github.com/VSadov/Satori.git
synced 2025-06-10 18:11:04 +09:00
[mono] Add thunking to s390x for calls that will be patched (#52783)
Merge https://github.com/mono/mono/pull/21052 into dotnet runtime. This fixes sporadic crashes due to code being patched non-atomically.
This commit is contained in:
parent
f64f12aa83
commit
9cb0ab915e
5 changed files with 492 additions and 265 deletions
|
@ -61,7 +61,6 @@
|
|||
|
||||
#include "mini.h"
|
||||
#include "mini-s390x.h"
|
||||
#include "support-s390x.h"
|
||||
#include "mini-runtime.h"
|
||||
#include "aot-runtime.h"
|
||||
#include "mono/utils/mono-tls-inline.h"
|
||||
|
@ -119,7 +118,7 @@ mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot)
|
|||
|
||||
inited = 1;
|
||||
/* call_filter (MonoContext *ctx, unsigned long eip, gpointer exc) */
|
||||
code = start = mono_global_codeman_reserve (512);
|
||||
code = start = (guint8 *) mono_global_codeman_reserve (512);
|
||||
|
||||
mono_add_unwind_op_def_cfa (unwind_ops, code, start, STK_BASE, S390_CFA_OFFSET);
|
||||
s390_stmg (code, s390_r6, s390_r15, STK_BASE, S390_REG_SAVE_OFFSET);
|
||||
|
@ -314,7 +313,7 @@ mono_arch_get_throw_exception_generic (int size, MonoTrampInfo **info, int corli
|
|||
MonoJumpInfo *ji = NULL;
|
||||
GSList *unwind_ops = NULL;
|
||||
|
||||
code = start = mono_global_codeman_reserve(size);
|
||||
code = start = (guint8 *) mono_global_codeman_reserve(size);
|
||||
|
||||
mono_add_unwind_op_def_cfa (unwind_ops, code, start, STK_BASE, S390_CFA_OFFSET);
|
||||
s390_stmg (code, s390_r6, s390_r15, STK_BASE, S390_REG_SAVE_OFFSET);
|
||||
|
@ -569,7 +568,7 @@ mono_arch_unwind_frame (MonoJitTlsData *jit_tls,
|
|||
memcpy(new_ctx->uc_mcontext.fpregs.fprs, (*lmf)->fregs, sizeof((*lmf)->fregs));
|
||||
MONO_CONTEXT_SET_BP (new_ctx, (*lmf)->ebp);
|
||||
MONO_CONTEXT_SET_IP (new_ctx, (*lmf)->eip - 2);
|
||||
*lmf = (*lmf)->previous_lmf;
|
||||
*lmf = (struct MonoLMF *) (*lmf)->previous_lmf;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -31,8 +31,9 @@ if (ins->inst_true_bb->native_offset) { \
|
|||
s390_jcl (code, cond, displace); \
|
||||
} \
|
||||
} else { \
|
||||
mono_add_patch_info (cfg, code - cfg->native_code, \
|
||||
MONO_PATCH_INFO_BB, ins->inst_true_bb); \
|
||||
mono_add_patch_info_rel (cfg, code - cfg->native_code, \
|
||||
MONO_PATCH_INFO_BB, ins->inst_true_bb, \
|
||||
MONO_R_S390_RELINS); \
|
||||
s390_jcl (code, cond, 0); \
|
||||
} \
|
||||
}
|
||||
|
@ -49,8 +50,9 @@ if (ins->inst_target_bb->native_offset) { \
|
|||
s390_jcl (code, S390_CC_UN, displace); \
|
||||
} \
|
||||
} else { \
|
||||
mono_add_patch_info (cfg, code - cfg->native_code, \
|
||||
MONO_PATCH_INFO_BB, ins->inst_target_bb); \
|
||||
mono_add_patch_info_rel (cfg, code - cfg->native_code, \
|
||||
MONO_PATCH_INFO_BB, ins->inst_target_bb, \
|
||||
MONO_R_S390_RELINS); \
|
||||
s390_jcl (code, S390_CC_UN, 0); \
|
||||
} \
|
||||
}
|
||||
|
@ -79,8 +81,9 @@ if (ins->inst_true_bb->native_offset) { \
|
|||
} \
|
||||
} else { \
|
||||
s390_##cmp (code, ins->sreg1, ins->sreg2); \
|
||||
mono_add_patch_info (cfg, code - cfg->native_code, \
|
||||
MONO_PATCH_INFO_BB, ins->inst_true_bb); \
|
||||
mono_add_patch_info_rel (cfg, code - cfg->native_code, \
|
||||
MONO_PATCH_INFO_BB, ins->inst_true_bb, \
|
||||
MONO_R_S390_RELINS); \
|
||||
s390_jcl (code, ins->sreg3, 0); \
|
||||
} \
|
||||
}
|
||||
|
@ -119,8 +122,9 @@ if (ins->inst_true_bb->native_offset) { \
|
|||
S390_SET (code, s390_r0, ins->backend.data); \
|
||||
s390_##cmp (code, ins->sreg1, s390_r0); \
|
||||
} \
|
||||
mono_add_patch_info (cfg, code - cfg->native_code, \
|
||||
MONO_PATCH_INFO_BB, ins->inst_true_bb); \
|
||||
mono_add_patch_info_rel (cfg, code - cfg->native_code, \
|
||||
MONO_PATCH_INFO_BB, ins->inst_true_bb, \
|
||||
MONO_R_S390_RELINS); \
|
||||
s390_jcl (code, ins->sreg3, 0); \
|
||||
} \
|
||||
}
|
||||
|
@ -255,7 +259,6 @@ if (ins->inst_true_bb->native_offset) { \
|
|||
|
||||
#include "mini-s390x.h"
|
||||
#include "cpu-s390x.h"
|
||||
#include "support-s390x.h"
|
||||
#include "jit-icalls.h"
|
||||
#include "ir-emit.h"
|
||||
#include "mini-gc.h"
|
||||
|
@ -341,6 +344,11 @@ static CallInfo * get_call_info (MonoMemPool *, MonoMethodSignature *);
|
|||
static guchar * emit_float_to_int (MonoCompile *, guchar *, int, int, int, gboolean);
|
||||
static __inline__ void emit_unwind_regs(MonoCompile *, guint8 *, int, int, long);
|
||||
static void compare_and_branch(MonoBasicBlock *, MonoInst *, int, gboolean);
|
||||
static __inline__ guint8 * emit_call(MonoCompile *, guint8 *, MonoJumpInfoType, gconstpointer);
|
||||
static guint8 * emit_thunk(guint8 *, gconstpointer);
|
||||
static void create_thunk(MonoCompile *, guint8 *, guint8 *, gpointer);
|
||||
static void update_thunk(MonoCompile *, guint8 *, gpointer);
|
||||
static void emit_patch_full (MonoCompile *, MonoJumpInfo *, guint8 *, gpointer, int);
|
||||
|
||||
/*========================= End of Prototypes ======================*/
|
||||
|
||||
|
@ -2595,10 +2603,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
|
|||
}
|
||||
break;
|
||||
case OP_BREAK: {
|
||||
mono_add_patch_info (cfg, code - cfg->native_code,
|
||||
MONO_PATCH_INFO_JIT_ICALL_ID,
|
||||
GUINT_TO_POINTER (MONO_JIT_ICALL_mono_break));
|
||||
S390_CALL_TEMPLATE (code, s390_r14);
|
||||
code = emit_call (cfg, code, MONO_PATCH_INFO_JIT_ICALL_ID,
|
||||
GUINT_TO_POINTER (MONO_JIT_ICALL_mono_break));
|
||||
}
|
||||
break;
|
||||
case OP_ADDCC: {
|
||||
|
@ -3562,10 +3568,11 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
|
|||
s390_br (code, s390_r1);
|
||||
}
|
||||
} else {
|
||||
mono_add_patch_info (cfg, code - cfg->native_code,
|
||||
mono_add_patch_info_rel (cfg, code - cfg->native_code,
|
||||
MONO_PATCH_INFO_METHOD_JUMP,
|
||||
call->method);
|
||||
call->method, MONO_R_S390_THUNKED);
|
||||
S390_BR_TEMPLATE (code, s390_r1);
|
||||
cfg->thunk_area += THUNK_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3585,10 +3592,9 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
|
|||
}
|
||||
break;
|
||||
case OP_FCALL: {
|
||||
call = (MonoCallInst*)ins;
|
||||
|
||||
mono_call_add_patch_info (cfg, call, code - cfg->native_code);
|
||||
S390_CALL_TEMPLATE (code, s390_r14);
|
||||
MonoCallInst *call = (MonoCallInst *) ins;
|
||||
const MonoJumpInfoTarget patch = mono_call_to_patch (call);
|
||||
code = emit_call (cfg, code, patch.type, patch.target);
|
||||
if (!cfg->r4fp && call->signature->ret->type == MONO_TYPE_R4)
|
||||
s390_ldebr (code, s390_f0, s390_f0);
|
||||
}
|
||||
|
@ -3599,9 +3605,9 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
|
|||
case OP_VOIDCALL:
|
||||
case OP_RCALL:
|
||||
case OP_CALL: {
|
||||
call = (MonoCallInst*)ins;
|
||||
mono_call_add_patch_info (cfg, call, code - cfg->native_code);
|
||||
S390_CALL_TEMPLATE (code, s390_r14);
|
||||
MonoCallInst *call = (MonoCallInst *) ins;
|
||||
const MonoJumpInfoTarget patch = mono_call_to_patch (call);
|
||||
code = emit_call (cfg, code, patch.type, patch.target);
|
||||
}
|
||||
break;
|
||||
case OP_FCALL_REG: {
|
||||
|
@ -3714,16 +3720,14 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
|
|||
break;
|
||||
case OP_THROW: {
|
||||
s390_lgr (code, s390_r2, ins->sreg1);
|
||||
mono_add_patch_info (cfg, code-cfg->native_code, MONO_PATCH_INFO_JIT_ICALL_ID,
|
||||
GUINT_TO_POINTER (MONO_JIT_ICALL_mono_arch_throw_exception));
|
||||
S390_CALL_TEMPLATE(code, s390_r14);
|
||||
code = emit_call (cfg, code, MONO_PATCH_INFO_JIT_ICALL_ID,
|
||||
GUINT_TO_POINTER (MONO_JIT_ICALL_mono_arch_throw_exception));
|
||||
}
|
||||
break;
|
||||
case OP_RETHROW: {
|
||||
s390_lgr (code, s390_r2, ins->sreg1);
|
||||
mono_add_patch_info (cfg, code-cfg->native_code, MONO_PATCH_INFO_JIT_ICALL_ID,
|
||||
GUINT_TO_POINTER (MONO_JIT_ICALL_mono_arch_rethrow_exception));
|
||||
S390_CALL_TEMPLATE(code, s390_r14);
|
||||
code = emit_call (cfg, code, MONO_PATCH_INFO_JIT_ICALL_ID,
|
||||
GUINT_TO_POINTER (MONO_JIT_ICALL_mono_arch_rethrow_exception));
|
||||
}
|
||||
break;
|
||||
case OP_START_HANDLER: {
|
||||
|
@ -3755,8 +3759,9 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
|
|||
}
|
||||
break;
|
||||
case OP_CALL_HANDLER: {
|
||||
mono_add_patch_info (cfg, code-cfg->native_code,
|
||||
MONO_PATCH_INFO_BB, ins->inst_target_bb);
|
||||
mono_add_patch_info_rel (cfg, code-cfg->native_code,
|
||||
MONO_PATCH_INFO_BB, ins->inst_target_bb,
|
||||
MONO_R_S390_DIRECT);
|
||||
s390_brasl (code, s390_r14, 0);
|
||||
for (GList *tmp = ins->inst_eh_blocks; tmp != bb->clause_holes; tmp = tmp->prev)
|
||||
mono_cfg_add_try_hole (cfg, ((MonoLeaveClause *) tmp->data)->clause, code, bb);
|
||||
|
@ -3853,9 +3858,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
|
|||
s390_tm (code, ins->sreg1, byte_offset, bitmask);
|
||||
s390_jo (code, 0); CODEPTR(code, jump);
|
||||
|
||||
mono_add_patch_info (cfg, code-cfg->native_code, MONO_PATCH_INFO_JIT_ICALL_ID,
|
||||
GUINT_TO_POINTER (MONO_JIT_ICALL_mono_generic_class_init));
|
||||
S390_CALL_TEMPLATE(code, s390_r14);
|
||||
code = emit_call (cfg, code, MONO_PATCH_INFO_JIT_ICALL_ID,
|
||||
GUINT_TO_POINTER (MONO_JIT_ICALL_mono_generic_class_init));
|
||||
|
||||
PTRSLOT (code, jump);
|
||||
|
||||
|
@ -4668,9 +4672,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
|
|||
|
||||
s390_ltg (code, s390_r0, 0, ins->sreg1, 0);
|
||||
s390_jz (code, 0); CODEPTR(code, br);
|
||||
mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_JIT_ICALL_ID,
|
||||
GUINT_TO_POINTER (MONO_JIT_ICALL_mono_threads_state_poll));
|
||||
S390_CALL_TEMPLATE (code, s390_r14);
|
||||
code = emit_call (cfg, code, MONO_PATCH_INFO_JIT_ICALL_ID,
|
||||
GUINT_TO_POINTER (MONO_JIT_ICALL_mono_threads_state_poll));
|
||||
PTRSLOT (code, br);
|
||||
break;
|
||||
}
|
||||
|
@ -5335,14 +5338,62 @@ mono_arch_register_lowlevel_calls (void)
|
|||
|
||||
/**
|
||||
*
|
||||
* @brief Architecture-specific patching
|
||||
* @param[in] @cfg - Compilation control block
|
||||
* @param[in] @code - Start of code
|
||||
* @param[in] @target - Target of patch
|
||||
* @param[in] @relo - Relocation type
|
||||
*
|
||||
* Perform patching action
|
||||
*/
|
||||
|
||||
static void
|
||||
emit_patch_full (MonoCompile *cfg, MonoJumpInfo *ji, guint8 *code,
|
||||
gpointer target, int relo)
|
||||
{
|
||||
guint8 *ip = ji->ip.i + code;
|
||||
|
||||
switch (relo) {
|
||||
case MONO_R_S390_RELINS :
|
||||
target = S390_RELATIVE(target, ip);
|
||||
ip += 2;
|
||||
s390_patch_rel (ip, (guint64) target);
|
||||
break;
|
||||
case MONO_R_S390_THUNKED :
|
||||
if (cfg)
|
||||
create_thunk(cfg, ip, code, target);
|
||||
else
|
||||
update_thunk(cfg, code, target);
|
||||
break;
|
||||
case MONO_R_S390_DIRECT :
|
||||
S390_EMIT_CALL (ip, target);
|
||||
break;
|
||||
case MONO_R_S390_ADDR :
|
||||
s390_patch_addr (ip, (guint64) target);
|
||||
break;
|
||||
case MONO_R_S390_SWITCH :
|
||||
S390_EMIT_LOAD (ip, target);
|
||||
break;
|
||||
case MONO_R_S390_REL :
|
||||
target = S390_RELATIVE(target, ip);
|
||||
s390_patch_rel (ip, (guint64) target);
|
||||
break;
|
||||
default :
|
||||
g_assert_not_reached();
|
||||
}
|
||||
}
|
||||
|
||||
/*========================= End of Function ========================*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Architecture-specific patching of instructions and data
|
||||
*
|
||||
* @param[in] @cfg - Compile control block
|
||||
* @param[in] @method - Current method
|
||||
* @param[in] @code - Current innstruction pointer
|
||||
* @param[in] @code - Current code block
|
||||
* @param[in] @ji - Jump information
|
||||
* @param[in] @run_cctors - Whether class constructors need to be initialized
|
||||
* @param[in] @error - Error control block
|
||||
* @param[in] @target - Target of patch
|
||||
*
|
||||
* Process the patch data created during the instruction build process.
|
||||
* This resolves jumps, calls, variables etc.
|
||||
|
@ -5351,33 +5402,28 @@ mono_arch_register_lowlevel_calls (void)
|
|||
void
|
||||
mono_arch_patch_code_new (MonoCompile *cfg, guint8 *code, MonoJumpInfo *ji, gpointer target)
|
||||
{
|
||||
unsigned char *ip = ji->ip.i + code;
|
||||
gint64 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);
|
||||
emit_patch_full (cfg, ji, code, target, MONO_R_S390_ADDR);
|
||||
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_BB:
|
||||
case MONO_PATCH_INFO_JIT_ICALL_ADDR:
|
||||
case MONO_PATCH_INFO_RGCTX_FETCH:
|
||||
case MONO_PATCH_INFO_ABS: {
|
||||
S390_EMIT_CALL (ip, target);
|
||||
case MONO_PATCH_INFO_JIT_ICALL_ID:
|
||||
case MONO_PATCH_INFO_METHOD:
|
||||
emit_patch_full (cfg, ji, code, target, ji->relocation);
|
||||
break;
|
||||
case MONO_PATCH_INFO_METHOD_JUMP:
|
||||
case MONO_PATCH_INFO_RGCTX_FETCH:
|
||||
case MONO_PATCH_INFO_SPECIFIC_TRAMPOLINE_LAZY_FETCH_ADDR:
|
||||
case MONO_PATCH_INFO_ABS:
|
||||
emit_patch_full (cfg, ji, code, target, MONO_R_S390_THUNKED);
|
||||
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);
|
||||
emit_patch_full(cfg, ji, code, target, MONO_R_S390_SWITCH);
|
||||
break;
|
||||
case MONO_PATCH_INFO_METHODCONST:
|
||||
case MONO_PATCH_INFO_CLASS:
|
||||
|
@ -5385,28 +5431,12 @@ mono_arch_patch_code_new (MonoCompile *cfg, guint8 *code, MonoJumpInfo *ji, gpoi
|
|||
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 = (gint64) 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);
|
||||
}
|
||||
emit_patch_full(cfg, ji, code, target, MONO_R_S390_REL);
|
||||
break;
|
||||
case MONO_PATCH_INFO_NONE:
|
||||
break;
|
||||
default:
|
||||
target = S390_RELATIVE(target, ip);
|
||||
ip += 2;
|
||||
s390_patch_rel (ip, (guint64) target);
|
||||
emit_patch_full (cfg, ji, code, target, MONO_R_S390_RELINS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5675,10 +5705,8 @@ if ((strcmp(method->klass->name_space,"") == 0) &&
|
|||
/*
|
||||
* On return from this call r2 have the address of the &lmf
|
||||
*/
|
||||
mono_add_patch_info (cfg, code - cfg->native_code,
|
||||
MONO_PATCH_INFO_JIT_ICALL_ID,
|
||||
GUINT_TO_POINTER (MONO_JIT_ICALL_mono_tls_get_lmf_addr_extern));
|
||||
S390_CALL_TEMPLATE(code, s390_r1);
|
||||
code = emit_call (cfg, code, MONO_PATCH_INFO_JIT_ICALL_ID,
|
||||
GUINT_TO_POINTER (MONO_JIT_ICALL_mono_tls_get_lmf_addr_extern));
|
||||
|
||||
/*
|
||||
* Set lmf.lmf_addr = jit_tls->lmf
|
||||
|
@ -5899,6 +5927,9 @@ mono_arch_emit_epilog (MonoCompile *cfg)
|
|||
/* Restore the unwind state to be the same as before the epilog */
|
||||
mono_emit_unwind_op_restore_state (cfg, code);
|
||||
|
||||
/* Round up for start of any thunk entries */
|
||||
code = (guint8 *) ((((uintptr_t) code + 7) >> 3) << 3);
|
||||
|
||||
set_code_cursor (cfg, code);
|
||||
|
||||
}
|
||||
|
@ -5985,7 +6016,9 @@ mono_arch_emit_exceptions (MonoCompile *cfg)
|
|||
patch_info->type = MONO_PATCH_INFO_JIT_ICALL_ID;
|
||||
patch_info->data.jit_icall_id = MONO_JIT_ICALL_mono_arch_throw_corlib_exception;
|
||||
patch_info->ip.i = code - cfg->native_code;
|
||||
patch_info->relocation = MONO_R_S390_THUNKED;
|
||||
S390_BR_TEMPLATE (code, s390_r1);
|
||||
cfg->thunk_area += THUNK_SIZE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -5994,6 +6027,10 @@ mono_arch_emit_exceptions (MonoCompile *cfg)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Round up for start of any thunk entries */
|
||||
code = (guint8 *) ((((uintptr_t) code + 7) >> 3) << 3);
|
||||
|
||||
set_code_cursor (cfg, code);
|
||||
}
|
||||
|
||||
|
@ -7003,3 +7040,146 @@ mono_arch_load_function (MonoJitICallId jit_icall_id)
|
|||
}
|
||||
|
||||
/*========================= End of Function ========================*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Emit call to thunked code
|
||||
*
|
||||
* @param[in] @cfg - configuration data
|
||||
* @param[inout] @code - where to emit call
|
||||
* @param[in] @call - call instruction
|
||||
* @returns Pointer to next code area
|
||||
*
|
||||
*/
|
||||
|
||||
static __inline__ guint8*
|
||||
emit_call (MonoCompile *cfg, guint8 *code, MonoJumpInfoType type, gconstpointer target)
|
||||
{
|
||||
mono_add_patch_info_rel (cfg, code-cfg->native_code, type,
|
||||
target, MONO_R_S390_THUNKED);
|
||||
S390_CALL_TEMPLATE (code, s390_r14);
|
||||
cfg->thunk_area += THUNK_SIZE;
|
||||
return code;
|
||||
}
|
||||
|
||||
/*========================= End of Function ========================*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Emit thunk for an indirect call
|
||||
*
|
||||
* @param[inout] @code - where to emit thunk
|
||||
* @param[in] @target - thunk target
|
||||
* @returns Pointer to next code area
|
||||
*
|
||||
*/
|
||||
|
||||
static guint8*
|
||||
emit_thunk (guint8 *code, gconstpointer target)
|
||||
{
|
||||
*(guint64*)code = (guint64)target;
|
||||
code += sizeof (guint64);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
/*========================= End of Function ========================*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Create thunk
|
||||
*
|
||||
* @param[in] @cfg - Compiler configuration
|
||||
* @param[inout] @code - where to emit thunk
|
||||
* @param[in] @target - thunk target
|
||||
*
|
||||
* Create a new thunk
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
create_thunk (MonoCompile *cfg, guint8 *ip, guint8 *code, gpointer target)
|
||||
{
|
||||
guint8 *thunks;
|
||||
int thunks_size;
|
||||
|
||||
/*
|
||||
* This can be called multiple times during JITting,
|
||||
* save the current position in cfg->arch to avoid
|
||||
* doing a O(n^2) search.
|
||||
*/
|
||||
if (!cfg->arch.thunks) {
|
||||
cfg->arch.thunks = cfg->thunks;
|
||||
cfg->arch.thunks_size = cfg->thunk_area;
|
||||
}
|
||||
thunks = (guint8 *) cfg->arch.thunks;
|
||||
thunks_size = cfg->arch.thunks_size;
|
||||
if (!thunks_size) {
|
||||
g_print ("thunk failed %p->%p, thunk space=%d method %s", code, target, thunks_size, mono_method_full_name (cfg->method, TRUE));
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
g_assert (*(guint64 *)thunks == 0);
|
||||
emit_thunk (thunks, target);
|
||||
|
||||
cfg->arch.thunks += THUNK_SIZE;
|
||||
cfg->arch.thunks_size -= THUNK_SIZE;
|
||||
|
||||
S390_EMIT_CALL(ip, thunks);
|
||||
}
|
||||
|
||||
/*========================= End of Function ========================*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Update thunk
|
||||
*
|
||||
* @param[in] @cfg - Compiler configuration
|
||||
* @param[inout] @code - where to emit thunk
|
||||
* @param[in] @target - thunk target
|
||||
*
|
||||
* Update an existing thunk
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
update_thunk (MonoCompile *cfg, guint8 *code, gpointer target)
|
||||
{
|
||||
MonoJitInfo *ji;
|
||||
MonoThunkJitInfo *info;
|
||||
guint8 *thunks;
|
||||
guint8 *orig_target;
|
||||
guint8 *target_thunk;
|
||||
int thunks_size;
|
||||
|
||||
ji = mini_jit_info_table_find ((char*)code);
|
||||
g_assert (ji);
|
||||
info = mono_jit_info_get_thunk_info (ji);
|
||||
g_assert (info);
|
||||
|
||||
thunks = (guint8*)ji->code_start + info->thunks_offset;
|
||||
thunks_size = info->thunks_size;
|
||||
|
||||
/*
|
||||
* We're pointing at the start of jump to thunk,
|
||||
* but mono_arch_get_call_target expects we're pointing
|
||||
* after the branch so we adjust
|
||||
*/
|
||||
orig_target = mono_arch_get_call_target (code + 6);
|
||||
|
||||
target_thunk = NULL;
|
||||
if (orig_target >= thunks && orig_target < thunks + thunks_size) {
|
||||
/* The call already points to a thunk, because of trampolines etc. */
|
||||
target_thunk = orig_target;
|
||||
} else {
|
||||
g_print ("thunk failed %p->%p, thunk space=%d method %s",
|
||||
code, target, thunks_size,
|
||||
cfg ? mono_method_full_name (cfg->method, TRUE)
|
||||
: mono_method_full_name (jinfo_get_method (ji), TRUE));
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
emit_thunk (target_thunk, target);
|
||||
}
|
||||
|
||||
/*========================= End of Function ========================*/
|
||||
|
|
|
@ -38,6 +38,8 @@ typedef struct MonoCompileArch {
|
|||
int fpSize; /** Size of floating point save area */
|
||||
MonoInst *ss_tramp_var; /** Single-step variable */
|
||||
MonoInst *bp_tramp_var; /** Breakpoint variable */
|
||||
guint8 *thunks; /** Thunking area */
|
||||
int thunks_size; /** Size of thunking area */
|
||||
} MonoCompileArch;
|
||||
|
||||
typedef struct
|
||||
|
@ -90,6 +92,17 @@ struct SeqPointInfo {
|
|||
|
||||
#define S390_FP_SAVE_MASK 0xf0
|
||||
|
||||
/* Thunk: 8 byte pointer */
|
||||
#define THUNK_SIZE 8
|
||||
|
||||
/* Relocation types */
|
||||
#define MONO_R_S390_RELINS 1 /* JGxx - relative jump */
|
||||
#define MONO_R_S390_THUNKED 2 /* Thunked call */
|
||||
#define MONO_R_S390_DIRECT 3 /* Direct call */
|
||||
#define MONO_R_S390_ADDR 4 /* Address */
|
||||
#define MONO_R_S390_SWITCH 5 /* Switch */
|
||||
#define MONO_R_S390_REL 6 /* Relative displacement */
|
||||
|
||||
/*===============================================*/
|
||||
/* Definitions used by mini-codegen.c */
|
||||
/*===============================================*/
|
||||
|
@ -166,13 +179,13 @@ struct SeqPointInfo {
|
|||
|
||||
#define MONO_ARCH_INIT_TOP_LMF_ENTRY(lmf) do { (lmf)->ebp = -1; } while (0)
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* */
|
||||
/* Name - s390_patch_rel */
|
||||
/* */
|
||||
/* Function - Patch the code with a given offset. */
|
||||
/* */
|
||||
/*------------------------------------------------------------------*/
|
||||
/**
|
||||
*
|
||||
* @brief Patch the code with a given offset
|
||||
* @param[in] @code - Area to patch
|
||||
* @param[in] @target - Value to patch with
|
||||
*
|
||||
*/
|
||||
|
||||
static void inline
|
||||
s390_patch_rel (guchar *code, guint64 target)
|
||||
|
@ -186,13 +199,13 @@ s390_patch_rel (guchar *code, guint64 target)
|
|||
|
||||
/*========================= End of Function ========================*/
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* */
|
||||
/* Name - s390_patch_addr */
|
||||
/* */
|
||||
/* Function - Patch the code with a given address. */
|
||||
/* */
|
||||
/*------------------------------------------------------------------*/
|
||||
/**
|
||||
*
|
||||
* @brief Patch the code with a given address
|
||||
* @param[in] @code - Area to patch
|
||||
* @param[in] @target - Address to patch with
|
||||
*
|
||||
*/
|
||||
|
||||
static void inline
|
||||
s390_patch_addr (guchar *code, guint64 target)
|
||||
|
@ -248,4 +261,92 @@ s390_patch_addr (guchar *code, guint64 target)
|
|||
|
||||
/*========================= End of Function ========================*/
|
||||
|
||||
#define S390_SET(loc, dr, v) \
|
||||
do { \
|
||||
guint64 val = (guint64) v; \
|
||||
if (s390_is_imm16(val)) { \
|
||||
s390_lghi(loc, dr, val); \
|
||||
} else if (s390_is_uimm16(val)) { \
|
||||
s390_llill(loc, dr, val); \
|
||||
} else if (s390_is_imm32(val)) { \
|
||||
s390_lgfi(loc, dr, val); \
|
||||
} else if (s390_is_uimm32(val)) { \
|
||||
s390_llilf(loc, dr, val); \
|
||||
} else { \
|
||||
guint32 hi = (val) >> 32; \
|
||||
guint32 lo = (val) & 0xffffffff; \
|
||||
s390_iihf(loc, dr, hi); \
|
||||
s390_iilf(loc, dr, lo); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define S390_LONG(loc, opy, op, r, ix, br, off) \
|
||||
if (s390_is_imm20(off)) { \
|
||||
s390_##opy (loc, r, ix, br, off); \
|
||||
} else { \
|
||||
if (ix == 0) { \
|
||||
S390_SET(loc, s390_r13, off); \
|
||||
s390_la (loc, s390_r13, s390_r13, br, 0); \
|
||||
} else { \
|
||||
s390_la (loc, s390_r13, ix, br, 0); \
|
||||
S390_SET (loc, s390_r0, off); \
|
||||
s390_agr (loc, s390_r13, s390_r0); \
|
||||
} \
|
||||
s390_##op (loc, r, 0, s390_r13, 0); \
|
||||
}
|
||||
|
||||
#define S390_SET_MASK(loc, dr, v) \
|
||||
do { \
|
||||
if (s390_is_imm16 (v)) { \
|
||||
s390_lghi (loc, dr, v); \
|
||||
} else if (s390_is_imm32 (v)) { \
|
||||
s390_lgfi (loc, dr, v); \
|
||||
} else { \
|
||||
gint64 val = (gint64) v; \
|
||||
guint32 hi = (val) >> 32; \
|
||||
guint32 lo = (val) & 0xffffffff; \
|
||||
s390_iilf(loc, dr, lo); \
|
||||
s390_iihf(loc, dr, hi); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define S390_CALL_TEMPLATE(loc, r) \
|
||||
do { \
|
||||
s390_lgrl (loc, r, 0); \
|
||||
s390_basr (loc, s390_r14, r); \
|
||||
} while (0)
|
||||
|
||||
#define S390_BR_TEMPLATE(loc, r) \
|
||||
do { \
|
||||
s390_lgrl (loc, r, 0); \
|
||||
s390_br (loc, r); \
|
||||
} while (0)
|
||||
|
||||
#define S390_LOAD_TEMPLATE(loc, r) \
|
||||
do { \
|
||||
s390_iihf (loc, r, 0); \
|
||||
s390_iilf (loc, r, 0); \
|
||||
} while (0)
|
||||
|
||||
#define S390_EMIT_CALL(loc, t) \
|
||||
do { \
|
||||
uintptr_t rel; \
|
||||
uintptr_t p = (uintptr_t) loc; \
|
||||
rel = ((uintptr_t) t - (uintptr_t) loc) >> 1; \
|
||||
p += 2; \
|
||||
*(guint32 *) p = rel; \
|
||||
} while (0)
|
||||
|
||||
#define S390_EMIT_LOAD(loc, v) \
|
||||
do { \
|
||||
gint64 val = (gint64) v; \
|
||||
guint32 hi = (val) >> 32; \
|
||||
guint32 lo = (val) & 0xffffffff; \
|
||||
uintptr_t p = (uintptr_t) loc; \
|
||||
p += 2; \
|
||||
*(guint32 *) p = hi; \
|
||||
p += 6; \
|
||||
*(guint32 *) p = lo; \
|
||||
} while (0)
|
||||
|
||||
#endif /* __MONO_MINI_S390X_H__ */
|
||||
|
|
|
@ -1,101 +0,0 @@
|
|||
/**
|
||||
* \file
|
||||
*/
|
||||
|
||||
#ifndef __MONO_SUPPORT_S390X_H__
|
||||
#define __MONO_SUPPORT_S390X_H__
|
||||
|
||||
#define S390_SET(loc, dr, v) \
|
||||
do { \
|
||||
guint64 val = (guint64) v; \
|
||||
if (s390_is_imm16(val)) { \
|
||||
s390_lghi(loc, dr, val); \
|
||||
} else if (s390_is_uimm16(val)) { \
|
||||
s390_llill(loc, dr, val); \
|
||||
} else if (s390_is_imm32(val)) { \
|
||||
s390_lgfi(loc, dr, val); \
|
||||
} else if (s390_is_uimm32(val)) { \
|
||||
s390_llilf(loc, dr, val); \
|
||||
} else { \
|
||||
guint32 hi = (val) >> 32; \
|
||||
guint32 lo = (val) & 0xffffffff; \
|
||||
s390_iihf(loc, dr, hi); \
|
||||
s390_iilf(loc, dr, lo); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define S390_LONG(loc, opy, op, r, ix, br, off) \
|
||||
if (s390_is_imm20(off)) { \
|
||||
s390_##opy (loc, r, ix, br, off); \
|
||||
} else { \
|
||||
if (ix == 0) { \
|
||||
S390_SET(loc, s390_r13, off); \
|
||||
s390_la (loc, s390_r13, s390_r13, br, 0); \
|
||||
} else { \
|
||||
s390_la (loc, s390_r13, ix, br, 0); \
|
||||
S390_SET (loc, s390_r0, off); \
|
||||
s390_agr (loc, s390_r13, s390_r0); \
|
||||
} \
|
||||
s390_##op (loc, r, 0, s390_r13, 0); \
|
||||
}
|
||||
|
||||
#define S390_SET_MASK(loc, dr, v) \
|
||||
do { \
|
||||
if (s390_is_imm16 (v)) { \
|
||||
s390_lghi (loc, dr, v); \
|
||||
} else if (s390_is_imm32 (v)) { \
|
||||
s390_lgfi (loc, dr, v); \
|
||||
} else { \
|
||||
gint64 val = (gint64) v; \
|
||||
guint32 hi = (val) >> 32; \
|
||||
guint32 lo = (val) & 0xffffffff; \
|
||||
s390_iilf(loc, dr, lo); \
|
||||
s390_iihf(loc, dr, hi); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define S390_CALL_TEMPLATE(loc, r) \
|
||||
do { \
|
||||
s390_iihf (loc, r, 0); \
|
||||
s390_iilf (loc, r, 0); \
|
||||
s390_basr (loc, s390_r14, r); \
|
||||
} while (0)
|
||||
|
||||
#define S390_BR_TEMPLATE(loc, r) \
|
||||
do { \
|
||||
s390_iihf (loc, r, 0); \
|
||||
s390_iilf (loc, r, 0); \
|
||||
s390_br (loc, r); \
|
||||
} while (0)
|
||||
|
||||
#define S390_LOAD_TEMPLATE(loc, r) \
|
||||
do { \
|
||||
s390_iihf (loc, r, 0); \
|
||||
s390_iilf (loc, r, 0); \
|
||||
} while (0)
|
||||
|
||||
#define S390_EMIT_CALL(loc, t) \
|
||||
do { \
|
||||
gint64 val = (gint64) t; \
|
||||
guint32 hi = (val) >> 32; \
|
||||
guint32 lo = (val) & 0xffffffff; \
|
||||
uintptr_t p = (uintptr_t) loc; \
|
||||
p += 2; \
|
||||
*(guint32 *) p = hi; \
|
||||
p += 6; \
|
||||
*(guint32 *) p = lo; \
|
||||
} while (0)
|
||||
|
||||
#define S390_EMIT_LOAD(loc, v) \
|
||||
do { \
|
||||
gint64 val = (gint64) v; \
|
||||
guint32 hi = (val) >> 32; \
|
||||
guint32 lo = (val) & 0xffffffff; \
|
||||
uintptr_t p = (uintptr_t) loc; \
|
||||
p += 2; \
|
||||
*(guint32 *) p = hi; \
|
||||
p += 6; \
|
||||
*(guint32 *) p = lo; \
|
||||
} while (0)
|
||||
|
||||
#endif /* __MONO_SUPPORT_S390X_H__ */
|
|
@ -50,7 +50,6 @@
|
|||
#include "mini.h"
|
||||
#include "mini-s390x.h"
|
||||
#include "mini-runtime.h"
|
||||
#include "support-s390x.h"
|
||||
#include "jit-icalls.h"
|
||||
#include "debugger-agent.h"
|
||||
#include "mono/utils/mono-tls-inline.h"
|
||||
|
@ -245,43 +244,75 @@ mono_arch_create_sdb_trampoline (gboolean single_step, MonoTrampInfo **info, gbo
|
|||
return buf;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* */
|
||||
/* Name - mono_arch_patch_callsite */
|
||||
/* */
|
||||
/* Function - Patch a non-virtual callsite so it calls @addr. */
|
||||
/* */
|
||||
/*------------------------------------------------------------------*/
|
||||
/**
|
||||
*
|
||||
* @brief Locate the address of the thunk target
|
||||
*
|
||||
* @param[in] @code - Instruction following the branch and save
|
||||
* @returns Address of the thunk code
|
||||
*
|
||||
* A thunk call is a sequence of:
|
||||
* lgrl rx,tgt Load address of target (.-6)
|
||||
* basr rx,rx Branch and save to that address (.), or,
|
||||
* br r1 Jump to target (.)
|
||||
*
|
||||
* The target of that code is a thunk which:
|
||||
* tgt: .quad target Destination
|
||||
*/
|
||||
|
||||
void
|
||||
mono_arch_patch_callsite (guint8 *method_start, guint8 *orig_code, guint8 *addr)
|
||||
guint8 *
|
||||
mono_arch_get_call_target (guint8 *code)
|
||||
{
|
||||
gint32 displace;
|
||||
unsigned short opcode;
|
||||
guint8 *thunk;
|
||||
guint32 rel;
|
||||
|
||||
opcode = *((unsigned short *) (orig_code - 2));
|
||||
if (opcode == 0x0dee) {
|
||||
/* This should be a 'iihf/iilf' sequence */
|
||||
S390_EMIT_CALL((orig_code - 14), addr);
|
||||
mono_arch_flush_icache (orig_code - 14, 12);
|
||||
} else {
|
||||
/* This is the 'brasl' instruction */
|
||||
orig_code -= 4;
|
||||
displace = ((gssize) addr - (gssize) (orig_code - 2)) / 2;
|
||||
s390_patch_rel (orig_code, displace);
|
||||
mono_arch_flush_icache (orig_code, 4);
|
||||
}
|
||||
/*
|
||||
* Determine thunk address by adding the relative offset
|
||||
* in the lgrl to its location
|
||||
*/
|
||||
rel = *(guint32 *) ((uintptr_t) code - 4);
|
||||
thunk = (guint8 *) ((uintptr_t) code - 6) + (rel * 2);
|
||||
|
||||
return(thunk);
|
||||
}
|
||||
|
||||
/*========================= End of Function ========================*/
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* */
|
||||
/* Name - mono_arch_patch_plt_entry. */
|
||||
/* */
|
||||
/* Function - Patch a PLT entry - unused as yet. */
|
||||
/* */
|
||||
/*------------------------------------------------------------------*/
|
||||
/**
|
||||
*
|
||||
* @brief Patch the callsite
|
||||
*
|
||||
* @param[in] @method_start - first instruction of method
|
||||
* @param[in] @orig_code - Instruction following the branch and save
|
||||
* @param[in] @addr - New value for target of call
|
||||
*
|
||||
* Patch a call. The call is either a 'thunked' call identified by the BASR R14,R14
|
||||
* instruction or a direct call
|
||||
*/
|
||||
|
||||
void
|
||||
mono_arch_patch_callsite (guint8 *method_start, guint8 *orig_code, guint8 *addr)
|
||||
{
|
||||
guint64 *thunk;
|
||||
|
||||
thunk = (guint64 *) mono_arch_get_call_target(orig_code - 2);
|
||||
*thunk = (guint64) addr;
|
||||
}
|
||||
|
||||
/*========================= End of Function ========================*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Patch PLT entry (AOT only)
|
||||
*
|
||||
* @param[in] @code - Location of PLT
|
||||
* @param[in] @got - Global Offset Table
|
||||
* @param[in] @regs - Registers at the time
|
||||
* @param[in] @addr - Target address
|
||||
*
|
||||
* Not reached on s390x until we have AOT support
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
mono_arch_patch_plt_entry (guint8 *code, gpointer *got, host_mgreg_t *regs, guint8 *addr)
|
||||
|
@ -291,14 +322,17 @@ mono_arch_patch_plt_entry (guint8 *code, gpointer *got, host_mgreg_t *regs, guin
|
|||
|
||||
/*========================= End of Function ========================*/
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* */
|
||||
/* Name - mono_arch_create_trampoline_code */
|
||||
/* */
|
||||
/* Function - Create the designated type of trampoline according*/
|
||||
/* to the 'tramp_type' parameter. */
|
||||
/* */
|
||||
/*------------------------------------------------------------------*/
|
||||
/**
|
||||
*
|
||||
* @brief Architecture-specific trampoline creation
|
||||
*
|
||||
* @param[in] @tramp_type - Type of trampoline
|
||||
* @param[out] @info - Pointer to trampoline information
|
||||
* @param[in] @aot - AOT indicator
|
||||
*
|
||||
* Create a generic trampoline
|
||||
*
|
||||
*/
|
||||
|
||||
guchar*
|
||||
mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInfo **info, gboolean aot)
|
||||
|
@ -520,13 +554,16 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
|
|||
|
||||
/*========================= End of Function ========================*/
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* */
|
||||
/* Name - mono_arch_invalidate_method */
|
||||
/* */
|
||||
/* Function - */
|
||||
/* */
|
||||
/*------------------------------------------------------------------*/
|
||||
/**
|
||||
*
|
||||
* @brief Architecture-specific method invalidation
|
||||
*
|
||||
* @param[in] @func - Function to call
|
||||
* @param[in] @func_arg - Argument to invalidation function
|
||||
*
|
||||
* Call an error routine so peple can fix their code
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
mono_arch_invalidate_method (MonoJitInfo *ji, void *func, gpointer func_arg)
|
||||
|
@ -542,13 +579,18 @@ mono_arch_invalidate_method (MonoJitInfo *ji, void *func, gpointer func_arg)
|
|||
|
||||
/*========================= End of Function ========================*/
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* */
|
||||
/* Name - mono_arch_create_specific_trampoline */
|
||||
/* */
|
||||
/* Function - Creates the given kind of specific trampoline */
|
||||
/* */
|
||||
/*------------------------------------------------------------------*/
|
||||
/**
|
||||
*
|
||||
* @brief Architecture-specific specific trampoline creation
|
||||
*
|
||||
* @param[in] @arg1 - Argument to trampoline being created
|
||||
* @param[in] @tramp_type - Trampoline type
|
||||
* @param[in] @domain - Mono Domain
|
||||
* @param[out] @code_len - Length of trampoline created
|
||||
*
|
||||
* Create the specified kind of trampoline
|
||||
*
|
||||
*/
|
||||
|
||||
gpointer
|
||||
mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_type, MonoMemoryManager *mem_manager, guint32 *code_len)
|
||||
|
@ -591,13 +633,17 @@ mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_ty
|
|||
|
||||
/*========================= End of Function ========================*/
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* */
|
||||
/* Name - mono_arch_create_rgctx_lazy_fetch_trampoline */
|
||||
/* */
|
||||
/* Function - */
|
||||
/* */
|
||||
/*------------------------------------------------------------------*/
|
||||
/**
|
||||
*
|
||||
* @brief Architecture-specific RGCTX lazy fetch trampoline
|
||||
*
|
||||
* @param[in] @slot - Instance
|
||||
* @param[out] @info - Mono Trampoline Information
|
||||
* @param[in] @aot - AOT indicator
|
||||
*
|
||||
* Create the specified kind of trampoline
|
||||
*
|
||||
*/
|
||||
|
||||
gpointer
|
||||
mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot, MonoTrampInfo **info, gboolean aot)
|
||||
|
@ -714,14 +760,16 @@ mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot, MonoTrampInfo **info
|
|||
|
||||
/*========================= End of Function ========================*/
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* */
|
||||
/* Name - mono_arch_get_static_rgctx_trampoline */
|
||||
/* */
|
||||
/* Function - Create a trampoline which sets RGCTX_REG to ARG */
|
||||
/* then jumps to ADDR. */
|
||||
/* */
|
||||
/*------------------------------------------------------------------*/
|
||||
/**
|
||||
*
|
||||
* @brief Architecture-specific static RGCTX lazy fetch trampoline
|
||||
*
|
||||
* @param[in] @arg - Argument to trampoline being created
|
||||
* @param[out] @addr - Target
|
||||
*
|
||||
* Create a trampoline which sets RGCTX_REG to ARG
|
||||
* then jumps to ADDR.
|
||||
*/
|
||||
|
||||
gpointer
|
||||
mono_arch_get_static_rgctx_trampoline (MonoMemoryManager *mem_manager, gpointer arg, gpointer addr)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue