Skip to content

Commit

Permalink
going to start checking the rip on merge blocks, thinking that this s…
Browse files Browse the repository at this point in the history
…hould be traced in an external strcture instead of through embedding the address in assembly code
  • Loading branch information
matthewfl committed Aug 5, 2016
1 parent 6baafda commit 87dc9cb
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 82 deletions.
16 changes: 13 additions & 3 deletions src/asm_interface.S
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "asm_macros.S"


#include "config.h"

.global red_asm_resume_tracer_block_start
.global red_asm_resume_tracer_block_end
Expand Down Expand Up @@ -67,14 +67,24 @@ 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
movq 232(%rsp), %r8
// 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 %r8, 72(%rsp)
movq %rax, 72(%rsp)
#ifdef CONF_CHECK_MERGE_RIP
movq %r11, 48(%rsp)
#endif

call red_resume_trace@plt
m_pop_all_regs
Expand Down
3 changes: 2 additions & 1 deletion src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,11 @@

// 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

// check the instruction pointer when performing a merge close block
#define CONF_CHECK_MERGE_RIP

#endif // REDMAGIC_CONFIG_H_
20 changes: 19 additions & 1 deletion src/jit_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,6 @@ namespace redmagic {

// if we have nested tracers eg an outer loop calls an inner loop
// or if we have an outter tracer disabled and an inner tracer running still
//
struct tracer_stack_state {
Tracer *tracer = nullptr;
void *resume_addr = nullptr;
Expand All @@ -166,6 +165,25 @@ namespace redmagic {
//bool did_abort = false;
};

struct tracer_method_stack_s {
mem_loc_t method_address;
mem_loc_t return_stack_pointer;

tracer_method_stack_s(mem_loc_t a=0, mem_loc_t b=0):
method_address(a), return_stack_pointer(b) {}
};

struct tracer_merge_block_stack_s {
mem_loc_t merge_head = 0; // head of linked list for this merge point

#ifdef CONF_CHECK_MERGE_RIP
mem_loc_t merge_rip_head = 0;
#endif


tracer_merge_block_stack_s() {}
};

//extern thread_local std::vector<tracer_stack_state> trace_return_addr;
//extern thread_local Tracer *tracer; // current running tracer
//extern thread_local void *trace_id; // id of current executing trace
Expand Down
28 changes: 20 additions & 8 deletions src/simple_compiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ void SimpleCompiler::SetRegister(int reg, register_t val) {
mov(get_register(reg), imm_u(val));
}

CodeBuffer SimpleCompiler::TestRegister(mem_loc_t resume_pc, int reg, register_t val, mem_loc_t *merge_addr, uint32_t _comp_op) {
CodeBuffer SimpleCompiler::TestRegister(mem_loc_t resume_pc, int reg, register_t val, tracer_merge_block_stack_s *merge_addr, uint32_t _comp_op) {
auto r = get_register(reg);
asmjit::X86GpReg scr;
if(val > 0x7fffffff)
Expand Down Expand Up @@ -190,7 +190,7 @@ CodeBuffer SimpleCompiler::TestRegister(mem_loc_t resume_pc, int reg, register_t
return resume_cb;
}

CodeBuffer SimpleCompiler::TestMemoryLocation(mem_loc_t resume_pc, mem_loc_t where, register_t val, mem_loc_t *merge_addr) {
CodeBuffer SimpleCompiler::TestMemoryLocation(mem_loc_t resume_pc, mem_loc_t where, register_t val, tracer_merge_block_stack_s *merge_addr) {
//Label success = newLabel();

Label failure = newLabel();
Expand Down Expand Up @@ -225,7 +225,7 @@ CodeBuffer SimpleCompiler::TestMemoryLocation(mem_loc_t resume_pc, mem_loc_t whe
return resume_cb;
}

CodeBuffer SimpleCompiler::TestOperand(mem_loc_t resume_pc, const asmjit::Operand& opr, register_t val, mem_loc_t *merge_addr) {
CodeBuffer SimpleCompiler::TestOperand(mem_loc_t resume_pc, const asmjit::Operand& opr, register_t val, tracer_merge_block_stack_s *merge_addr) {
Label failure = newLabel();
asmjit::X86GpReg scr, scr2;
scr = get_scratch_register();
Expand Down Expand Up @@ -319,7 +319,7 @@ void SimpleCompiler::Push64bitValue(uint64_t value) {

}

CodeBuffer SimpleCompiler::ConditionalJump(mem_loc_t resume_pc, enum asmjit::X86InstId mnem, mem_loc_t *merge_addr) {
CodeBuffer SimpleCompiler::ConditionalJump(mem_loc_t resume_pc, enum asmjit::X86InstId mnem, tracer_merge_block_stack_s *merge_addr) {
CodeBuffer rb = MakeResumeTraceBlock(resume_pc, merge_addr);
auto label = newLabel();
set_label_address(label, rb.getRawBuffer());
Expand All @@ -330,7 +330,7 @@ CodeBuffer SimpleCompiler::ConditionalJump(mem_loc_t resume_pc, enum asmjit::X86

extern "C" void red_asm_restart_trace();

CodeBuffer SimpleCompiler::MakeResumeTraceBlock(mem_loc_t resume_pc, mem_loc_t *merge_addr) {
CodeBuffer SimpleCompiler::MakeResumeTraceBlock(mem_loc_t resume_pc, tracer_merge_block_stack_s *merge_addr) {
SimpleCompiler resume_block(buffer);
//resume_block.clobbered_registers |= clobbered_registers;
resume_block.ResumeBlockJump(resume_pc);
Expand All @@ -339,11 +339,16 @@ CodeBuffer SimpleCompiler::MakeResumeTraceBlock(mem_loc_t resume_pc, mem_loc_t *
return ret;
}

void SimpleCompiler::do_merge_addr(CodeBuffer &buff, mem_loc_t *merge_addr) {
void SimpleCompiler::do_merge_addr(CodeBuffer &buff, tracer_merge_block_stack_s *merge_block) {
mem_loc_t* ma = buff.find_stump<mem_loc_t>(0xfbfbfbfbfbfbfbfb);
// make a linked list out of address where we are going to write this merge address
*ma = *merge_addr;
*merge_addr = (mem_loc_t)ma;
*ma = merge_block->merge_head;
merge_block->merge_head = (mem_loc_t)ma;
#ifdef CONF_CHECK_MERGE_RIP
ma = buff.find_stump<mem_loc_t>(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) {
Expand All @@ -356,13 +361,20 @@ 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
// so first conditional jump followed by direct jump
// 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));

// for identifying which instruction it jumped from
Expand Down
12 changes: 6 additions & 6 deletions src/simple_compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,17 @@ namespace redmagic {
void PushMemoryLocationValue(mem_loc_t where);
void Push64bitValue(uint64_t value);

CodeBuffer TestRegister(mem_loc_t resume_pc, int reg, register_t val, mem_loc_t *merge_addr, uint32_t _comp_op=asmjit::kX86InstIdJne);
CodeBuffer TestMemoryLocation(mem_loc_t resume_pc, mem_loc_t where, register_t val, mem_loc_t *merge_addr);
CodeBuffer TestRegister(mem_loc_t resume_pc, int reg, register_t val, tracer_merge_block_stack_s *merge_addr, uint32_t _comp_op=asmjit::kX86InstIdJne);
CodeBuffer TestMemoryLocation(mem_loc_t resume_pc, mem_loc_t where, register_t val, tracer_merge_block_stack_s *merge_addr);

CodeBuffer TestOperand(mem_loc_t resume_pc, const asmjit::Operand& opr, register_t val, mem_loc_t *merge_addr);
CodeBuffer TestOperand(mem_loc_t resume_pc, const asmjit::Operand& opr, register_t val, tracer_merge_block_stack_s *merge_addr);

CodeBuffer MakeResumeTraceBlock(mem_loc_t resume_pc, mem_loc_t *merge_addr);
CodeBuffer MakeResumeTraceBlock(mem_loc_t resume_pc, tracer_merge_block_stack_s *merge_addr);

uint64_t* MakeCounter();

// return the CodeBuffer of the destination jump block instead of self
CodeBuffer ConditionalJump(mem_loc_t resume_pc, enum asmjit::X86InstId mnem, mem_loc_t *merge_addr);
CodeBuffer ConditionalJump(mem_loc_t resume_pc, enum asmjit::X86InstId mnem, tracer_merge_block_stack_s *merge_addr);

private:
void ResumeBlockJump(mem_loc_t resume_pc);
Expand All @@ -79,7 +79,7 @@ namespace redmagic {

void set_label_address(const asmjit::Label &label, mem_loc_t addr);

void do_merge_addr(CodeBuffer &buff, mem_loc_t *merge_addr);
void do_merge_addr(CodeBuffer &buff, tracer_merge_block_stack_s *merge_addr);

public:
virtual size_t _relocCode(void *_dst, asmjit::Ptr baseAddress) const noexcept override;
Expand Down
Loading

0 comments on commit 87dc9cb

Please sign in to comment.