On Mon, 2009-07-06 at 01:16 +0200, Tomek Grabiec wrote:
> We cannot overwrite a register which is not saved (ESI) because this
> will lead to a corruption in JIT code. The proper solution is
> to copy the call arguments.
> 
> Signed-off-by: Tomek Grabiec <tgrab...@gmail.com>

I'm confused. What exactly is the problem here and why do we need to
copy arguments?

> ---
>  arch/x86/emit-code.c    |   37 +++++++++++++++++++++++++++++++------
>  include/jit/compiler.h  |    3 ++-
>  include/jit/emit-code.h |    3 ++-
>  jit/trampoline.c        |    7 ++++---
>  4 files changed, 39 insertions(+), 11 deletions(-)
> 
> diff --git a/arch/x86/emit-code.c b/arch/x86/emit-code.c
> index 236ba0e..c4ba179 100644
> --- a/arch/x86/emit-code.c
> +++ b/arch/x86/emit-code.c
> @@ -1389,21 +1389,46 @@ void emit_trampoline(struct compilation_unit *cu,
>  }
>  
>  void emit_jni_trampoline(struct buffer *buf, struct vm_jni_env *jni_env,
> -                      void *target)
> +                      void *target, struct vm_method *method)
>  {
> +     unsigned long args_size;
> +
>       jit_text_lock();
>  
>       buf->buf = jit_text_ptr();
>  
> -     /* save return address into caller-saved register */
> -     __emit_pop_reg(buf, REG_ESI);
> +     __emit_push_reg(buf, REG_ESI);
> +     __emit_push_reg(buf, REG_EDI);
> +     __emit_push_reg(buf, REG_ECX);
> +
> +     /*
> +      * Make a copy of call arguments
> +      */
> +     __emit_mov_reg_reg(buf, REG_ESP, REG_ESI);
> +     __emit_add_imm_reg(buf, (3 + 1) * sizeof(unsigned long), REG_ESI);
> +
> +     args_size = sizeof(unsigned long) + (method->args_count + 1);
> +
> +     __emit_add_imm_reg(buf, -args_size, REG_ESP);
> +     __emit_mov_reg_reg(buf, REG_ESP, REG_EDI);
> +
> +     __emit_mov_imm_reg(buf, method->args_count + 1, REG_ECX);
> +
> +     /* CLD */
> +     emit(buf, 0xfc);
> +
> +     /* REP MOVSD */
> +     emit(buf, 0xf3);
> +     emit(buf, 0xa5);
>  
>       __emit_push_imm(buf, (unsigned long) jni_env);
>       __emit_call(buf, target);
> -     __emit_add_imm_reg(buf, 4, REG_ESP);
> +     __emit_add_imm_reg(buf, args_size + sizeof(unsigned long), REG_ESP);
> +
> +     __emit_pop_reg(buf, REG_ECX);
> +     __emit_pop_reg(buf, REG_EDI);
> +     __emit_pop_reg(buf, REG_ESI);
>  
> -     /* return to caller*/
> -     __emit_push_reg(buf, REG_ESI);
>       emit_ret(buf);
>  
>       jit_text_reserve(buffer_offset(buf));
> diff --git a/include/jit/compiler.h b/include/jit/compiler.h
> index 8584954..e2609ef 100644
> --- a/include/jit/compiler.h
> +++ b/include/jit/compiler.h
> @@ -14,6 +14,7 @@ struct compilation_unit;
>  struct expression;
>  struct statement;
>  struct buffer;
> +struct vm_method;
>  
>  struct fixup_site {
>       /* Compilation unit to which relcall_insn belongs */
> @@ -62,7 +63,7 @@ void *jit_magic_trampoline(struct compilation_unit *);
>  struct jit_trampoline *alloc_jit_trampoline(void);
>  struct jni_trampoline *alloc_jni_trampoline(void);
>  struct jit_trampoline *build_jit_trampoline(struct compilation_unit *);
> -struct jni_trampoline *build_jni_trampoline(void *);
> +struct jni_trampoline *build_jni_trampoline(struct vm_method *, void *);
>  void free_jit_trampoline(struct jit_trampoline *);
>  void free_jni_trampoline(struct jni_trampoline *);
>  
> diff --git a/include/jit/emit-code.h b/include/jit/emit-code.h
> index 07c41bf..291955f 100644
> --- a/include/jit/emit-code.h
> +++ b/include/jit/emit-code.h
> @@ -8,6 +8,7 @@ struct buffer;
>  struct insn;
>  struct vm_object;
>  struct vm_jni_env;
> +struct vm_method;
>  
>  enum emitter_type {
>       NO_OPERANDS = 1,
> @@ -39,6 +40,6 @@ extern void emit_body(struct basic_block *, struct buffer 
> *);
>  extern void backpatch_branch_target(struct buffer *buf, struct insn *insn,
>                                   unsigned long target_offset);
>  extern void emit_jni_trampoline(struct buffer *buf, struct vm_jni_env 
> *jni_env,
> -                             void *target);
> +                             void *target, struct vm_method *method);
>  
>  #endif /* JATO_EMIT_CODE_H */
> diff --git a/jit/trampoline.c b/jit/trampoline.c
> index 0de2db5..42f3afa 100644
> --- a/jit/trampoline.c
> +++ b/jit/trampoline.c
> @@ -65,7 +65,8 @@ static void *jit_native_trampoline(struct compilation_unit 
> *cu)
>               add_cu_mapping((unsigned long)ret, cu);
>  
>               if (!method->jni_trampoline)
> -                     method->jni_trampoline = build_jni_trampoline(ret);
> +                     method->jni_trampoline =
> +                             build_jni_trampoline(method, ret);
>  
>               return buffer_ptr(method->jni_trampoline->objcode);
>       }
> @@ -151,13 +152,13 @@ struct jit_trampoline *build_jit_trampoline(struct 
> compilation_unit *cu)
>       return trampoline;
>  }
>  
> -struct jni_trampoline *build_jni_trampoline(void *target)
> +struct jni_trampoline *build_jni_trampoline(struct vm_method *vmm, void 
> *target)
>  {
>       struct jni_trampoline *trampoline;
>  
>       trampoline = alloc_jni_trampoline();
>       if (trampoline)
>               emit_jni_trampoline(trampoline->objcode, vm_jni_get_jni_env(),
> -                                 target);
> +                                 target, vmm);
>       return trampoline;
>  }


------------------------------------------------------------------------------
_______________________________________________
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel

Reply via email to