Skip to content

Commit

Permalink
Fix various blockchain bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
tbodt committed Jun 1, 2018
1 parent 470146c commit cd31019
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 27 deletions.
5 changes: 4 additions & 1 deletion emu/gen.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ void gen_start(addr_t addr, struct gen_state *state) {
state->block = malloc(sizeof(struct jit_block) + state->capacity * sizeof(unsigned long));
state->block->addr = addr;
state->ip = addr;
for (int i = 0; i <= 1; i++)
for (int i = 0; i <= 1; i++) {
state->jump_ip[i] = 0;
}
}

void gen_end(struct gen_state *state) {
Expand All @@ -39,7 +40,9 @@ void gen_end(struct gen_state *state) {
} else {
block->jump_ip[i] = NULL;
}

list_init(&block->jumps_from[i]);
list_init(&block->jumps_from_links[i]);
}
}

Expand Down
41 changes: 23 additions & 18 deletions emu/jit.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ struct jit *jit_new(struct mem *mem) {
jit->mem = mem;
for (int i = 0; i < JIT_HASH_SIZE; i++)
list_init(&jit->hash[i]);
lock_init(&jit->lock);
return jit;
}

Expand All @@ -26,23 +27,29 @@ void jit_free(struct jit *jit) {
free(jit);
}

static inline struct list *blocks_list(struct jit *jit, page_t page, int i) {
return &jit->mem->pt[page].blocks[i];
}

void jit_invalidate_page(struct jit *jit, page_t page) {
lock(&jit->lock);
struct jit_block *block, *tmp;
list_for_each_entry_safe(&jit->mem->pt[page].blocks[0], block, tmp, page[0]) {
jit_block_free(block);
}
list_for_each_entry_safe(&jit->mem->pt[page].blocks[1], block, tmp, page[1]) {
jit_block_free(block);
for (int i = 0; i <= 1; i++) {
struct list *blocks = blocks_list(jit, page, i);
if (list_null(blocks))
continue;
list_for_each_entry_safe(blocks, block, tmp, page[i]) {
jit_block_free(block);
}
}
unlock(&jit->lock);
}

static void jit_insert(struct jit *jit, struct jit_block *block) {
list_add(&jit->hash[block->addr % JIT_HASH_SIZE], &block->chain);
list_add(&jit->mem->pt[PAGE(block->addr)].blocks[0], &block->page[0]);
list_init_add(blocks_list(jit, PAGE(block->addr), 0), &block->page[0]);
if (PAGE(block->addr) != PAGE(block->end_addr))
list_add(&jit->mem->pt[PAGE(block->end_addr)].blocks[0], &block->page[1]);
list_init_add(blocks_list(jit, PAGE(block->end_addr), 1), &block->page[1]);
}

static struct jit_block *jit_lookup(struct jit *jit, addr_t addr) {
Expand Down Expand Up @@ -75,16 +82,15 @@ static struct jit_block *jit_block_compile(addr_t ip, struct tlb *tlb) {

static void jit_block_free(struct jit_block *block) {
list_remove(&block->chain);
list_remove(&block->page[0]);
if (!list_empty(&block->page[1]))
list_remove(&block->page[1]);
for (int i = 0; i <= 1; i++) {
if (!list_empty(&block->jumps_from_links[i]))
list_remove(&block->jumps_from_links[i]);
struct jit_block *last_block;
list_for_each_entry(&block->jumps_from[i], last_block, jumps_from_links[i]) {
if (block->jump_ip[i] != NULL)
*block->jump_ip[i] = block->old_jump_ip[i];
list_remove(&block->page[i]);
list_remove_safe(&block->jumps_from_links[i]);

struct jit_block *last_block, *tmp;
list_for_each_entry_safe(&block->jumps_from[i], last_block, tmp, jumps_from_links[i]) {
if (last_block->jump_ip[i] != NULL)
*last_block->jump_ip[i] = last_block->old_jump_ip[i];
list_remove(&last_block->jumps_from_links[i]);
}
}
free(block);
Expand Down Expand Up @@ -114,8 +120,7 @@ void cpu_run(struct cpu_state *cpu) {
for (int i = 0; i <= 1; i++) {
if (last_block->jump_ip[i] != NULL &&
(*last_block->jump_ip[i] & 0xffffffff) == block->addr) {
*last_block->jump_ip[i] = block->code;
last_block->jumps_to[i] = block;
*last_block->jump_ip[i] = (unsigned long) block->code;
list_add(&block->jumps_from[i], &last_block->jumps_from_links[i]);
}
}
Expand Down
2 changes: 0 additions & 2 deletions emu/jit.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ struct jit_block {
addr_t addr;
addr_t end_addr;

// blocks that this block jumps to
struct jit_block *jumps_to[2];
// pointers to the ip values in the last gadget
unsigned long *jump_ip[2];
// original values of *jump_ip[]
Expand Down
4 changes: 0 additions & 4 deletions emu/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@ struct mem *mem_new() {
mem->changes = 0;
#if JIT
mem->jit = jit_new(mem);
for (page_t page = 0; page < MEM_PAGES; page++) {
list_init(&mem->pt[page].blocks[0]);
list_init(&mem->pt[page].blocks[1]);
}
#endif
wrlock_init(&mem->lock);
return mem;
Expand Down
19 changes: 17 additions & 2 deletions util/list.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ static inline void list_init(struct list *list) {
list->prev = list;
}

static inline bool list_null(struct list *list) {
return list->next == NULL && list->prev == NULL;
}

static inline bool list_empty(struct list *list) {
return list->next == list || list_null(list);
}

static inline void _list_add_between(struct list *prev, struct list *next, struct list *item) {
prev->next = item;
item->prev = prev;
Expand All @@ -25,14 +33,21 @@ static inline void list_add(struct list *list, struct list *item) {
_list_add_between(list, list->next, item);
}

static inline void list_init_add(struct list *list, struct list *item) {
if (list_null(list))
list_init(list);
list_add(list, item);
}

static inline void list_remove(struct list *item) {
item->prev->next = item->next;
item->next->prev = item->prev;
item->next = item->prev = NULL;
}

static inline bool list_empty(struct list *list) {
return list->next == list || (list->next == NULL && list->prev == NULL);
static inline void list_remove_safe(struct list *item) {
if (!list_null(item))
list_remove(item);
}

#define list_entry(item, type, member) \
Expand Down

0 comments on commit cd31019

Please sign in to comment.