Skip to content

Commit

Permalink
Merge branch 'merge-ret-issue'
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewfl committed Aug 31, 2016
2 parents a62fcc0 + f912efd commit d08d6fa
Show file tree
Hide file tree
Showing 12 changed files with 190 additions and 72 deletions.
13 changes: 8 additions & 5 deletions make
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ from fabricate import *

TARGET = 'jit-test'

VERSION = '1.0.0'

UNIT_TARGET = 'build/unit_tests'

GIT_VERSION = Shell('git describe --always --long --dirty --abbrev=12', silent=True).strip()
Expand Down Expand Up @@ -59,9 +61,9 @@ def release():
clean()
build()
Run('mkdir -p release')
Run('cp build/libredmagic.so.1.0.0 release/')
Run('cp build/libredmagic.so.{} release/'.format(VERSION))
Run('cp src/redmagic.h release/')
Run('strip --strip-unneeded -w -K redmagic_* release/libredmagic.so.1.0.0')
Run('strip --strip-unneeded -w -K redmagic_* release/libredmagic.so.{}'.format(VERSION))


def clean():
Expand All @@ -87,11 +89,11 @@ def link():
udis_libs = ' '.join(glob.glob('deps/udis86/libudis86/.libs/*.o'))
# we are not using the compiler interface, just the assembler
asmjit_libs = ' '.join(filter(lambda x: 'compiler' not in x, glob.glob('build/asmjit/CMakeFiles/asmjit.dir/src/asmjit/*/*.o')))
Run('{LD} {LD_FLAGS} -shared -fPIC -Wl,-Bsymbolic -Wl,-soname,libredmagic.so.1.0.0 -o build/libredmagic.so.1.0.0 {objs} {udis_libs} {asmjit_libs} {LIBS}'.format(
Run('{LD} {LD_FLAGS} -shared -fPIC -Wl,-Bsymbolic -Wl,-soname,libredmagic.so.{VERSION} -o build/libredmagic.so.{VERSION} {objs} {udis_libs} {asmjit_libs} {LIBS}'.format(
**dict(globals(), **locals())
))
after()
Run('{LD} -o {TARGET} build/main.o build/libredmagic.so.1.0.0 -Wl,-rpath=$ORIGIN/build/'.format(
Run('{LD} -o {TARGET} build/main.o build/libredmagic.so.{VERSION} -Wl,-rpath=$ORIGIN/build/'.format(
**dict(globals(), **locals())
))
after()
Expand All @@ -101,8 +103,9 @@ def compile():
f.write('''
#ifndef RED_BUILD_VERSION
#define RED_BUILD_VERSION "{}"
#define RED_OBJ_VERSION "{}"
#endif
'''.format(GIT_VERSION))
'''.format(GIT_VERSION, VERSION))

for f in glob.glob('src/*.cc'):
Run('{CXX} {} -c {} -o {}'.format(
Expand Down
17 changes: 13 additions & 4 deletions src/asm_interface.S
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ red_asm_resume_tracer_block_end:

.global red_asm_resume_eval_block
red_asm_resume_eval_block:
// check if there is somewhere we are going to stash these values
test %rdi, %rdi
jz 1f

movq %rsp, 56(%rdi)

movq %r12, 0(%rdi)
Expand All @@ -32,6 +36,7 @@ red_asm_resume_eval_block:
movq %rbx, 32(%rdi)
movq %rbp, 40(%rdi)

1:
movq %rsi, %rsp
m_pop_all_regs
jmpq *-TRACE_RESUME_ADDRESS_OFFSET(%rsp)
Expand Down Expand Up @@ -66,16 +71,16 @@ red_asm_restart_trace:
movq %r10, %rdi
movq %r9, %rsi
movq %rsp, %rdx
movq %r8, %rcx
//movq %r8, %rcx

// restore the origional values of r10,9,8
// restore the origional values of r10,9,rcx
movq 216(%rsp), %r10
movq 224(%rsp), %r9
// vvv moving the r8 register
// vvv moving the rcx register
movq 232(%rsp), %rax
movq %r10, 56(%rsp)
movq %r9, 64(%rsp)
movq %rax, 72(%rsp)
movq %rax, 88(%rsp)

call red_resume_trace@plt
m_pop_all_regs
Expand All @@ -86,14 +91,18 @@ red_asm_restart_trace:
// might end up returning to a another trace block
.global red_asm_end_trace
red_asm_end_trace:
movq %rsp, %rsi
pushq $0
pushq %rdi
call red_end_trace@plt
popq %rsi
popq %rdi
jmp *%rax


.global red_asm_start_nested_trace
red_asm_start_nested_trace:
movq %rsp, %rcx
call red_branch_to_sub_trace@plt
jmp *%rax

Expand Down
1 change: 0 additions & 1 deletion src/asm_macros.S
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
* preserve registers: rbx, rsp, rbp, r12, r13, r14, r15
* scratch registers: rax, rdi, rsi, rdx, rcx, r8, r9, r10, r11
*
* N.L represents a new line in the macro expansion
*/

#include "constants.h"
Expand Down
13 changes: 10 additions & 3 deletions src/asm_snippets.S
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,16 @@ red_asm_pop_all_regs_start:
m_pop_all_regs
red_asm_pop_all_regs_end:

.global red_asm_jump_rsi
red_asm_jump_rsi:
.global red_asm_jump_rsi_temp_enable
red_asm_jump_rsi_temp_enable:
jmp *%rsi

// we don't need executable stack
.global red_asm_jump_rsi_resume_trace
red_asm_jump_rsi_resume_trace:
// this is only used to resume a tracer at a different address
// the address where we are expecting to resume will be loaded into rsi, so if the check fails then we will jump to that address
jmp *%rsi


// we don't need executable stack
.section .note.GNU-stack,"",%progbits
2 changes: 1 addition & 1 deletion src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

// makes it print all the instructions processed and extra info
#ifdef CONF_DEBUG_BUILD
# define CONF_VERBOSE
//# define CONF_VERBOSE
#endif

// support aborting the system after some fixed number of instruction have been processed, see tools/bisect for debugging with this
Expand Down
6 changes: 4 additions & 2 deletions src/jit_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ namespace redmagic {
void* end_trace(void *id, void *ret_addr);
void* jump_to_trace(void *id);

void* backwards_branch(void *id, void *ret_addr);
void* fellthrough_branch(void *id, void *ret_addr);
void* backwards_branch(void *id, void *ret_addr, void **stack_ptr);
void* fellthrough_branch(void *id, void *ret_addr, void **stack_ptr);

// void ensure_not_traced();

Expand Down Expand Up @@ -187,6 +187,8 @@ namespace redmagic {

int32_t frame_id = -1;

mem_loc_t frame_stack_ptr = -1;


#ifdef CONF_ESTIMATE_INSTRUCTIONS
int num_backwards_loops = 0;
Expand Down
60 changes: 34 additions & 26 deletions src/manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -61,60 +61,59 @@ class UnprotectMalloc {
};


extern "C" void* red_user_force_begin_trace(void *id, void *ret_addr) {
extern "C" void* red_user_force_begin_trace(void *id, void *ret_addr, void **stack_ptr) {
UnprotectMalloc upm;
return manager->begin_trace(id, ret_addr);
}

extern "C" void* red_user_force_end_trace(void *id, void *ret_addr) {
extern "C" void* red_user_force_end_trace(void *id, void *ret_addr, void **stack_ptr) {
UnprotectMalloc upm;
return manager->end_trace(id, ret_addr);
}

extern "C" void* red_user_force_jump_to_trace(void *id, void *ret_addr) {
extern "C" void* red_user_force_jump_to_trace(void *id, void *ret_addr, void **stack_ptr) {
UnprotectMalloc upm;
return manager->jump_to_trace(id);
}

extern "C" void* red_user_backwards_branch(void *id, void *ret_addr) {
extern "C" void* red_user_backwards_branch(void *id, void *ret_addr, void **stack_ptr) {
UnprotectMalloc upm;
return manager->backwards_branch(id, ret_addr);
return manager->backwards_branch(id, ret_addr, stack_ptr);
}

extern "C" void* red_user_fellthrough_branch(void *id, void *ret_addr) {
extern "C" void* red_user_fellthrough_branch(void *id, void *ret_addr, void **stack_ptr) {
UnprotectMalloc upm;
return manager->fellthrough_branch(id, ret_addr);
return manager->fellthrough_branch(id, ret_addr, stack_ptr);
}

extern "C" void* red_user_ensure_not_traced(void *_, void *ret_addr) {
// TODO:
extern "C" void* red_user_ensure_not_traced(void *_, void *ret_addr, void **stack_ptr) {
return manager->ensure_not_traced();
}

extern "C" void* red_user_temp_disable(void *_, void *ret_addr) {
extern "C" void* red_user_temp_disable(void *_, void *ret_addr, void **stack_ptr) {
UnprotectMalloc upm;
return manager->temp_disable(ret_addr);
//return NULL;
}

extern "C" void* red_user_is_traced(void *_, void *ret_addr) {
extern "C" void* red_user_is_traced(void *_, void *ret_addr, void **stack_ptr) {
UnprotectMalloc upm;
return manager->is_traced_call();
}

extern "C" void* red_user_temp_enable(void *_, void *ret_addr) {
extern "C" void* red_user_temp_enable(void *_, void *ret_addr, void **stack_ptr) {
UnprotectMalloc upm;
return manager->temp_enable(ret_addr);
//assert(0);
//return NULL;
}

extern "C" void* red_user_begin_merge_block(void *_, void *ret_addr) {
extern "C" void* red_user_begin_merge_block(void *_, void *ret_addr, void **stack_ptr) {
UnprotectMalloc upm;
return manager->begin_merge_block();
}

extern "C" void* red_user_end_merge_block(void *_, void *ret_addr) {
extern "C" void* red_user_end_merge_block(void *_, void *ret_addr, void **stack_ptr) {
UnprotectMalloc upm;
return manager->end_merge_block();
}
Expand Down Expand Up @@ -505,7 +504,7 @@ void* Manager::jump_to_trace(void *id) {
return NULL;
}

void* Manager::backwards_branch(void *id, void *ret_addr) {
void* Manager::backwards_branch(void *id, void *ret_addr, void **stack_ptr) {
// ignore
if(id == nullptr)
return NULL;
Expand Down Expand Up @@ -567,6 +566,7 @@ void* Manager::backwards_branch(void *id, void *ret_addr) {
head->tracer->JumpToNestedLoop(id);
}
new_head = push_tracer_stack();
new_head->frame_stack_ptr = (mem_loc_t)stack_ptr;
head = &threadl_tracer_stack[threadl_tracer_stack.size() - 2];
if(head->tracer) {
new_head->return_to_trace_when_done = true;
Expand Down Expand Up @@ -668,7 +668,7 @@ void* Manager::backwards_branch(void *id, void *ret_addr) {

}

void* Manager::fellthrough_branch(void *id, void *ret_addr) {
void* Manager::fellthrough_branch(void *id, void *ret_addr, void **stack_ptr) {
// ignore
if(id == nullptr)
return NULL;
Expand All @@ -686,13 +686,15 @@ void* Manager::fellthrough_branch(void *id, void *ret_addr) {
l = head->tracer;
// this will pop the head of the stack internally
ret = l->EndTraceFallthrough();
// the tracer ^^^ will delete itself

info->tracer = head->tracer = nullptr;

Tracer *expected = nullptr;
if(!free_tracer_list.compare_exchange_strong(expected, l)) {
// failled to save the tracer to the free list head
delete l;
}
// Tracer *expected = nullptr;
// if(!free_tracer_list.compare_exchange_strong(expected, l)) {
// // failled to save the tracer to the free list head
// delete l;
// }

return ret;
} else {
Expand All @@ -702,6 +704,7 @@ void* Manager::fellthrough_branch(void *id, void *ret_addr) {
// we have to pop this frame since we weren't being traced and there is nothing that will do it for us
auto old_head = pop_tracer_stack();
auto new_head = get_tracer_head();
((mem_loc_t*)stack_ptr)[-1] = old_head.frame_stack_ptr - (mem_loc_t)stack_ptr;
if(new_head->resume_addr) {
assert(old_head.return_to_trace_when_done);
if(new_head->tracer) {
Expand Down Expand Up @@ -734,22 +737,25 @@ void* Manager::fellthrough_branch(void *id, void *ret_addr) {
assert(!head->is_compiled || head->frame_id != branchable_frame_id);

return NULL;

}

void* Manager::temp_disable(void *ret_addr) {
temp_disable_last_addr = ret_addr;
auto head = get_tracer_head();
assert(!head->is_temp_disabled);
head->is_temp_disabled = true;

//head->d_ret = ret_addr;
void *ret = NULL;
assert(!head->is_traced || head->tracer);

//assert(!head->is_traced || head->tracer);
// ^^^ due to the tracer sometimes

if(head->tracer && !head->tracer->did_abort) {
// this will push the stack
ret = head->tracer->TempDisableTrace();
} else {
assert(!head->resume_addr);
head->is_temp_disabled = true;
push_tracer_stack();
}
return ret;
Expand All @@ -766,7 +772,7 @@ void* Manager::temp_enable(void *ret_addr) {
//head->is_temp_disabled = false;
void *ret = NULL;
//head->d_ret = nullptr;
if(head->tracer && !head->tracer->did_abort) {
if(old_head.return_to_trace_when_done && head->tracer && !head->tracer->did_abort) {
head->tracer->TempEnableTrace(ret_addr);
}
if(head->resume_addr != nullptr) {
Expand Down Expand Up @@ -918,8 +924,10 @@ void* Manager::end_branchable_frame(void *ret_addr, void **stack_ptr) {
}
}
#endif
auto head = get_tracer_head();
assert(head->frame_stack_ptr > (mem_loc_t)stack_ptr);
branchable_frame_id--;
assert(get_tracer_head()->frame_id <= branchable_frame_id);
assert(head->frame_id <= branchable_frame_id);
return NULL;
}

Expand Down
4 changes: 2 additions & 2 deletions src/simple_compiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -355,14 +355,14 @@ void SimpleCompiler::ResumeBlockJump(mem_loc_t resume_pc) {
bind(label_top);
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);
mov(x86::ptr(x86::rsp, -TRACE_STACK_OFFSET + 232), x86::rcx);
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)); // patch address
mov(x86::r8, imm_u(0xfbfbfbfbfbfbfbfb)); // merge point
mov(x86::rcx, imm_u(0xfbfbfbfbfbfbfbfb)); // merge point


jmp(imm_ptr(&red_asm_restart_trace));
Expand Down
Loading

0 comments on commit d08d6fa

Please sign in to comment.