From 4c25ed5b47ef710f34e75d12998b1d17803137e6 Mon Sep 17 00:00:00 2001 From: Matthew Francis-Landau Date: Fri, 5 Aug 2016 22:06:26 -0700 Subject: [PATCH] using a map to track the merge rip instead of embedding it in the assembly --- src/asm_interface.S | 9 --------- src/config.h | 2 +- src/jit_internal.h | 10 ++++++++++ src/simple_compiler.cc | 11 ----------- src/tracer.cc | 20 +++++++++----------- src/tracer.h | 3 --- 6 files changed, 20 insertions(+), 35 deletions(-) diff --git a/src/asm_interface.S b/src/asm_interface.S index d608049..e694ad3 100644 --- a/src/asm_interface.S +++ b/src/asm_interface.S @@ -67,24 +67,15 @@ red_asm_restart_trace: movq %r9, %rsi movq %rsp, %rdx movq %r8, %rcx -#ifdef CONF_CHECK_MERGE_RIP - movq %r11, %r8 -#endif // restore the origional values of r10,9,8 movq 216(%rsp), %r10 movq 224(%rsp), %r9 // vvv moving the r8 register movq 232(%rsp), %rax -#ifdef CONF_CHECK_MERGE_RIP - movq 240(%rsp), %r11 -#endif movq %r10, 56(%rsp) movq %r9, 64(%rsp) movq %rax, 72(%rsp) -#ifdef CONF_CHECK_MERGE_RIP - movq %r11, 48(%rsp) -#endif call red_resume_trace@plt m_pop_all_regs diff --git a/src/config.h b/src/config.h index b4534e3..a8381df 100644 --- a/src/config.h +++ b/src/config.h @@ -54,7 +54,7 @@ // instead of taking a trace all the way to the bottom of the loop, attempt to merge back at the ret inside of a method // the idea being that most of the branches that we can end up helping will be inside the main interpreter loop -//#define CONF_MERGE_BACK_ON_RET +#define CONF_MERGE_BACK_ON_RET //#define CONF_CHECK_RET_ADDRESS diff --git a/src/jit_internal.h b/src/jit_internal.h index 039e462..7fcc035 100644 --- a/src/jit_internal.h +++ b/src/jit_internal.h @@ -127,6 +127,16 @@ namespace redmagic { std::equal_to, RealMallocAllocator> > branches; + +#ifdef CONF_CHECK_MERGE_RIP + std::unordered_map< + mem_loc_t, + mem_loc_t, + std::hash, + std::equal_to, + RealMallocAllocator> + > merge_rip; +#endif private: std::unordered_set< void*, diff --git a/src/simple_compiler.cc b/src/simple_compiler.cc index f5d7ad9..efc53b0 100644 --- a/src/simple_compiler.cc +++ b/src/simple_compiler.cc @@ -344,11 +344,6 @@ void SimpleCompiler::do_merge_addr(CodeBuffer &buff, tracer_merge_block_stack_s // make a linked list out of address where we are going to write this merge address *ma = merge_block->merge_head; merge_block->merge_head = (mem_loc_t)ma; -#ifdef CONF_CHECK_MERGE_RIP - ma = buff.find_stump(0xfcfcfcfcfcfcfcfc); - *ma = merge_block->merge_rip_head; - merge_block->merge_rip_head = (mem_loc_t)ma; -#endif } void SimpleCompiler::ResumeBlockJump(mem_loc_t resume_pc) { @@ -361,9 +356,6 @@ void SimpleCompiler::ResumeBlockJump(mem_loc_t resume_pc) { mov(x86::ptr(x86::rsp, -TRACE_STACK_OFFSET + 216), x86::r10); mov(x86::ptr(x86::rsp, -TRACE_STACK_OFFSET + 224), x86::r9); mov(x86::ptr(x86::rsp, -TRACE_STACK_OFFSET + 232), x86::r8); -#ifdef CONF_CHECK_MERGE_RIP - mov(x86::ptr(x86::rsp, -TRACE_STACK_OFFSET + 240), x86::r11); -#endif mov(x86::r10, imm_u(resume_pc)); // TODO: have this load the address of the instruction that jumped here instead of just this block // this will allow for it to easily write in a direct jump, as being designed now, we will have to redirect the jump through this indirection @@ -371,9 +363,6 @@ void SimpleCompiler::ResumeBlockJump(mem_loc_t resume_pc) { // also, this will not work with concurrent threads lea(x86::r9, x86::ptr(label)); mov(x86::r8, imm_u(0xfbfbfbfbfbfbfbfb)); -#ifdef CONF_CHECK_MERGE_RIP - mov(x86::r11, imm_u(0xfcfcfcfcfcfcfcfc)); -#endif jmp(imm_ptr(&red_asm_restart_trace)); diff --git a/src/tracer.cc b/src/tracer.cc index 74b2ba6..6e912d2 100644 --- a/src/tracer.cc +++ b/src/tracer.cc @@ -103,17 +103,12 @@ void red_begin_tracing(struct user_regs_struct *other_stack, void* __, Tracer* t __builtin_unreachable(); } -extern "C" void red_resume_trace(mem_loc_t target_rip, mem_loc_t write_jump_address, struct user_regs_struct *regs_struct, mem_loc_t merge_addr -#ifdef CONF_CHECK_MERGE_RIP - , mem_loc_t merge_rip_check -#endif - ) { +extern "C" void red_resume_trace(mem_loc_t target_rip, mem_loc_t write_jump_address, struct user_regs_struct *regs_struct, mem_loc_t merge_addr) { using redmagic::register_t; // the dummy values assert(write_jump_address != 0xfafafafafafafafa); assert(merge_addr != 0xfbfbfbfbfbfbfbfb); - assert(merge_rip_check != 0xfcfcfcfcfcfcfcfc); // that this is a jump with a rel32 term to the next line and is aligned properly assert(*(uint8_t*)write_jump_address == 0xE9); @@ -365,7 +360,7 @@ void Tracer::Run(struct user_regs_struct *other_stack) { assert(method_stack.back().return_stack_pointer >= regs_struct->rsp + move_stack_by); #ifdef CONF_MERGE_BACK_ON_RET - assert(merge_block_stack.size() > method_stack.size()); + assert(merge_block_stack.size() >= method_stack.size()); #endif // if we somehow have less then 1kb free then we might have overwritten something @@ -821,6 +816,10 @@ mem_loc_t Tracer::merge_close_core() { *(mem_loc_t*)write_addr = resume_a; write_addr = next_addr; } +#ifdef CONF_CHECK_MERGE_RIP + mem_loc_t merge_rip = manager->merge_rip[resume_a]; + assert(merge_rip == udis_loc); +#endif // the ending of this tracer instructions finish_patch(); @@ -871,15 +870,14 @@ mem_loc_t Tracer::merge_close_core() { *(mem_loc_t*)write_addr = merge_addr; write_addr = next_addr; } +#ifdef CONF_CHECK_MERGE_RIP + manager->merge_rip[merge_addr] = udis_loc; +#endif return 0; } assert(0); } -void Tracer::patch_merge_block(tracer_merge_block_stack_s *merge_block) { - -} - void* Tracer::DeleteLastCall() { assert(icount - last_call_instruction < 2); diff --git a/src/tracer.h b/src/tracer.h index ac18487..ae4d15a 100644 --- a/src/tracer.h +++ b/src/tracer.h @@ -113,9 +113,6 @@ namespace redmagic { mem_loc_t merge_close_core(); - // patch in the correct address for a given merge block stack - void patch_merge_block(tracer_merge_block_stack_s*); - inline register_t pop_stack() { register_t r = *((register_t*)((mem_loc_t)regs_struct->rsp + move_stack_by)); move_stack_by += sizeof(register_t);