This instruction saves the address of itself to a memory location with GS segment override prefix. It will be needed for storing the approximate call site address into JNI call stack entry.
Signed-off-by: Tomek Grabiec <tgrab...@gmail.com> --- arch/x86/emit-code.c | 35 ++++++++++++++++++++++++++++++--- arch/x86/include/arch/instruction.h | 1 + arch/x86/lir-printer.c | 36 ++++++++++++++++++++++++++-------- arch/x86/use-def.c | 1 + 4 files changed, 60 insertions(+), 13 deletions(-) diff --git a/arch/x86/emit-code.c b/arch/x86/emit-code.c index f3a0485..53ef166 100644 --- a/arch/x86/emit-code.c +++ b/arch/x86/emit-code.c @@ -477,6 +477,8 @@ static void emit_mov_reg_membase(struct buffer *buf, struct operand *src, struct operand *dest); static void emit_mov_imm_membase(struct buffer *buf, struct operand *src, struct operand *dest); +static void __emit_mov_imm_membase(struct buffer *buf, long imm, + enum machine_reg base, long disp); /* * __encode_reg: Encode register to be used in IA-32 instruction. @@ -753,6 +755,16 @@ static void emit_mov_imm_thread_local_membase(struct buffer *buf, emit_mov_imm_membase(buf, src, dest); } +static void emit_mov_ip_thread_local_membase(struct buffer *buf, + struct operand *dest) +{ + unsigned long addr + = (unsigned long)buffer_current(buf); + + emit(buf, 0x65); /* GS segment override prefix */ + __emit_mov_imm_membase(buf, addr, mach_reg(&dest->base_reg), dest->disp); +} + static void emit_mov_memdisp_reg(struct buffer *buf, struct operand *src, struct operand *dest) @@ -787,18 +799,32 @@ static void emit_mov_imm_reg(struct buffer *buf, struct operand *src, __emit_mov_imm_reg(buf, src->imm, mach_reg(&dest->reg)); } +static void __emit_mov_imm_membase(struct buffer *buf, long imm, + enum machine_reg base, long disp) +{ + __emit_membase(buf, 0xc7, base, disp, 0); + emit_imm32(buf, imm); +} + static void emit_mov_imm_membase(struct buffer *buf, struct operand *src, struct operand *dest) { - __emit_membase(buf, 0xc7, mach_reg(&dest->base_reg), dest->disp, 0); + __emit_mov_imm_membase(buf, src->imm, mach_reg(&dest->base_reg), + dest->disp); +} - emit_imm32(buf, src->imm); +static void __emit_mov_reg_membase(struct buffer *buf, enum machine_reg src, + enum machine_reg base, unsigned long disp) +{ + __emit_membase(buf, 0x89, base, disp, __encode_reg(src)); } static void -emit_mov_reg_membase(struct buffer *buf, struct operand *src, struct operand *dest) +emit_mov_reg_membase(struct buffer *buf, struct operand *src, + struct operand *dest) { - __emit_membase(buf, 0x89, mach_reg(&dest->base_reg), dest->disp, encode_reg(&src->reg)); + __emit_mov_reg_membase(buf, mach_reg(&src->reg), + mach_reg(&dest->base_reg), dest->disp); } static void emit_mov_reg_memlocal(struct buffer *buf, struct operand *src, @@ -1344,6 +1370,7 @@ struct emitter emitters[] = { DECL_EMITTER(INSN_MOV_IMM_MEMBASE, emit_mov_imm_membase, TWO_OPERANDS), DECL_EMITTER(INSN_MOV_IMM_REG, emit_mov_imm_reg, TWO_OPERANDS), DECL_EMITTER(INSN_MOV_IMM_THREAD_LOCAL_MEMBASE, emit_mov_imm_thread_local_membase, TWO_OPERANDS), + DECL_EMITTER(INSN_MOV_IP_THREAD_LOCAL_MEMBASE, emit_mov_ip_thread_local_membase, SINGLE_OPERAND), DECL_EMITTER(INSN_MOV_MEMLOCAL_REG, emit_mov_memlocal_reg, TWO_OPERANDS), DECL_EMITTER(INSN_MOV_MEMLOCAL_FREG, emit_mov_memlocal_freg, TWO_OPERANDS), DECL_EMITTER(INSN_MOV_MEMBASE_REG, emit_mov_membase_reg, TWO_OPERANDS), diff --git a/arch/x86/include/arch/instruction.h b/arch/x86/include/arch/instruction.h index a5bd8da..a0657e9 100644 --- a/arch/x86/include/arch/instruction.h +++ b/arch/x86/include/arch/instruction.h @@ -88,6 +88,7 @@ enum insn_type { INSN_MOV_IMM_MEMBASE, INSN_MOV_IMM_REG, INSN_MOV_IMM_THREAD_LOCAL_MEMBASE, + INSN_MOV_IP_THREAD_LOCAL_MEMBASE, INSN_MOV_MEMLOCAL_REG, INSN_MOV_MEMLOCAL_FREG, INSN_MOV_MEMBASE_REG, diff --git a/arch/x86/lir-printer.c b/arch/x86/lir-printer.c index 208fd28..7d7d7ad 100644 --- a/arch/x86/lir-printer.c +++ b/arch/x86/lir-printer.c @@ -133,28 +133,39 @@ static int print_tlmemdisp_reg(struct string *str, struct insn *insn) return print_reg(str, &insn->dest); } +static int print_tlmembase(struct string *str, struct operand *op) +{ + str_append(str, "gs:("); + print_membase(str, op); + return str_append(str, ")"); +} + +static int print_tlmemdisp(struct string *str, struct operand *op) +{ + str_append(str, "gs:("); + print_imm(str, op); + return str_append(str, ")"); +} + static int print_reg_tlmemdisp(struct string *str, struct insn *insn) { print_reg(str, &insn->src); - str_append(str, ", gs:("); - print_imm(str, &insn->dest); - return str_append(str, ")"); + str_append(str, ", "); + return print_tlmemdisp(str, &insn->dest); } static int print_imm_tlmembase(struct string *str, struct insn *insn) { print_imm(str, &insn->src); - str_append(str, ", gs:("); - print_membase(str, &insn->dest); - return str_append(str, ")"); + str_append(str, ", "); + return print_tlmembase(str, &insn->dest); } static int print_reg_tlmembase(struct string *str, struct insn *insn) { print_reg(str, &insn->src); - str_append(str, ", gs:("); - print_membase(str, &insn->dest); - return str_append(str, ")"); + str_append(str, ", "); + return print_tlmembase(str, &insn->dest); } static int print_reg_membase(struct string *str, struct insn *insn) @@ -461,6 +472,12 @@ static int print_mov_imm_tlmembase(struct string *str, struct insn *insn) return print_imm_tlmembase(str, insn); } +static int print_mov_ip_tlmembase(struct string *str, struct insn *insn) +{ + print_func_name(str); + return print_tlmembase(str, &insn->operands[0]); +} + static int print_mov_reg_tlmembase(struct string *str, struct insn *insn) { print_func_name(str); @@ -711,6 +728,7 @@ static print_insn_fn insn_printers[] = { [INSN_MOV_IMM_MEMBASE] = print_mov_imm_membase, [INSN_MOV_IMM_REG] = print_mov_imm_reg, [INSN_MOV_IMM_THREAD_LOCAL_MEMBASE] = print_mov_imm_tlmembase, + [INSN_MOV_IP_THREAD_LOCAL_MEMBASE] = print_mov_ip_tlmembase, [INSN_MOV_MEMLOCAL_REG] = print_mov_memlocal_reg, [INSN_MOV_MEMLOCAL_FREG] = print_mov_memlocal_freg, [INSN_MOV_MEMBASE_REG] = print_mov_membase_reg, diff --git a/arch/x86/use-def.c b/arch/x86/use-def.c index 3a140d0..652314d 100644 --- a/arch/x86/use-def.c +++ b/arch/x86/use-def.c @@ -75,6 +75,7 @@ static struct insn_info insn_infos[] = { DECLARE_INFO(INSN_MOV_IMM_MEMBASE, USE_DST), DECLARE_INFO(INSN_MOV_IMM_REG, DEF_DST), DECLARE_INFO(INSN_MOV_IMM_THREAD_LOCAL_MEMBASE, USE_NONE | DEF_NONE), + DECLARE_INFO(INSN_MOV_IP_THREAD_LOCAL_MEMBASE, USE_NONE | DEF_NONE), DECLARE_INFO(INSN_MOV_MEMLOCAL_REG, USE_FP | DEF_DST), DECLARE_INFO(INSN_MOV_MEMLOCAL_FREG, USE_FP | DEF_DST), DECLARE_INFO(INSN_MOV_MEMBASE_REG, USE_SRC | DEF_DST), -- 1.6.0.6 ------------------------------------------------------------------------------ _______________________________________________ Jatovm-devel mailing list Jatovm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jatovm-devel