/* * push_shack() * Push next guest eip into shadow stack. */ void push_shack(CPUState *env, TCGv_ptr cpu_env, target_ulong next_eip) { TCGv_ptr temp_shack_top = tcg_temp_new_ptr(); TCGv_ptr temp_shack_end = tcg_temp_new_ptr(); TCGv_ptr temp_entry_ptr = tcg_temp_new_ptr(); TCGv temp_next_eip = tcg_temp_local_new_i32(); // int flush_label = gen_new_label(); shack_hash_entry *entry; //Load the entry. Entry is the constant for each next_eip int table_index = next_eip & (SHACK_SIZE-1); entry = &shadow_hash_list[table_index]; // load to temp tcg_gen_ld_ptr(temp_shack_top, cpu_env, offsetof(CPUState, shack_top)); tcg_gen_ld_ptr(temp_shack_end, cpu_env, offsetof(CPUState, shack_end)); tcg_gen_movi_i32(temp_next_eip, next_eip); tcg_gen_movi_i32(temp_entry_ptr ,entry); //- branch to flush // tcg_gen_brcond_ptr(TCG_COND_EQ, temp_shack_top, temp_shack_end, flush_label); // push to stack tcg_gen_st_ptr(temp_entry_ptr, temp_shack_top, 0); tcg_gen_addi_ptr(temp_shack_top, temp_shack_top, sizeof(uint64_t)); tcg_gen_st_ptr(temp_shack_top, cpu_env, offsetof(CPUState, shack_top)); // gen_set_label(flush_label); // printf("");//do nothing // // flush stack // helper_shack_flush(env); // tcg_gen_mov_tl(temp_shack_top, tcg_const_tl((int32_t)(env->shack + 1))); }
// #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *) 0)->MEMBER) void pop_shack(TCGv_ptr cpu_env, TCGv next_eip){ //----------------------TCG operations TCGv_ptr temp_shack_top = tcg_temp_new_ptr(); TCGv_ptr temp_shack_empty = tcg_temp_new_ptr(); TCGv_ptr temp_shack_top_next = tcg_temp_new_ptr(); TCGv_ptr temp_entry_ptr = tcg_temp_new_ptr(); TCGv_ptr temp_host_eip = tcg_temp_new_ptr(); TCGv temp_guest_eip = tcg_temp_local_new_i32(); TCGv temp_next_eip = tcg_temp_local_new_i32(); int eip_match_label = gen_new_label(); // create label int empty_label = gen_new_label(); // create label //load next_eip into temp_next_eip tcg_gen_mov_i32(temp_next_eip, next_eip); // load shack_top ptr into temp_shack_top tcg_gen_ld_ptr(temp_shack_top, cpu_env, offsetof(CPUState, shack_top)); tcg_gen_ld_ptr(temp_shack_empty, cpu_env, offsetof(CPUState, shack)); //check if stack is empty tcg_gen_brcond_ptr(TCG_COND_EQ, temp_shack_top, temp_shack_empty, empty_label); // get (shack_top - 8) tcg_gen_ld_ptr(temp_shack_top, cpu_env, offsetof(CPUState, shack_top)); tcg_gen_subi_tl(temp_shack_top_next, temp_shack_top, sizeof(uint64_t)); // get entry tcg_gen_ld_ptr(temp_entry_ptr, temp_shack_top_next, 0); // load entry.guest_eip tcg_gen_ld_ptr(temp_guest_eip, temp_entry_ptr, offsetof(shack_hash_entry, guest_eip)); // branch to label tcg_gen_brcond_ptr(TCG_COND_NE, temp_next_eip, temp_guest_eip, eip_match_label); //reload all temps. tcg_gen_ld_ptr(temp_shack_top, cpu_env, offsetof(CPUState, shack_top)); tcg_gen_subi_tl(temp_shack_top_next, temp_shack_top, sizeof(uint64_t)); tcg_gen_ld_ptr(temp_entry_ptr, temp_shack_top_next, 0); // load entry.host_eip into temp_host_eip tcg_gen_ld_ptr(temp_host_eip, temp_entry_ptr, offsetof(shack_hash_entry, host_eip)); // update shack_top tcg_gen_st_ptr(temp_shack_top_next, cpu_env, offsetof(CPUState, shack_top)); // jump *gen_opc_ptr++ = INDEX_op_jmp; *gen_opparam_ptr++ = temp_host_eip; // set label here gen_set_label(eip_match_label); // empty stack do nothing gen_set_label(empty_label); }
/* * push_shack() * Push next guest eip into shadow stack. */ void push_shack(CPUState *env, TCGv_ptr cpu_env, target_ulong next_eip) { // label int label_do_push = gen_new_label(); // prepare registers TCGv_ptr temp_shack_end = tcg_temp_local_new_ptr(); // store shack end TCGv_ptr temp_shack_top = tcg_temp_local_new_ptr(); // store shack top TCGv temp_next_eip = tcg_temp_local_new(); // store eip // load common values tcg_gen_ld_ptr(temp_shack_end, cpu_env, offsetof(CPUState, shack_end)); tcg_gen_ld_ptr(temp_shack_top, cpu_env, offsetof(CPUState, shack_top)); tcg_gen_mov_tl(temp_next_eip, tcg_const_tl(next_eip)); // check shack full? tcg_gen_brcond_ptr(TCG_COND_NE,temp_shack_top,temp_shack_end,label_do_push); // if not full // flush here TCGv_ptr temp_shack_start = tcg_temp_new_ptr(); // store shack start //tcg_en_st_tl(tcg_const_tl(0), cpu_env, offsetof(CPUState, shadow_ret_count)); // reset ret count tcg_gen_ld_ptr(temp_shack_start, cpu_env, offsetof(CPUState, shack)); tcg_gen_mov_tl(temp_shack_top, temp_shack_start); tcg_temp_free_ptr(temp_shack_start); // call helper: flush the hash gen_helper_shack_flush(cpu_env); // end of flush gen_set_label(label_do_push); // do push here // push guest eip tcg_gen_st_ptr(temp_next_eip, temp_shack_top, 0); // store guest eip tcg_gen_addi_ptr(temp_shack_top, temp_shack_top, sizeof(uint64_t)); // increase top // call helper: check if we can fill the ret directly, or need to add hash-pair gen_helper_shack_push(cpu_env, temp_next_eip); // store back top tcg_gen_st_ptr(temp_shack_top, cpu_env, offsetof(CPUState, shack_top)); // clean up tcg_temp_free(temp_next_eip); tcg_temp_free_ptr(temp_shack_top); tcg_temp_free_ptr(temp_shack_end); }
/* * pop_shack() * Pop next host eip from shadow stack. */ void pop_shack(TCGv_ptr cpu_env, TCGv next_eip) { // labels int label_end = gen_new_label(); // prepare registers TCGv_ptr temp_shack_start = tcg_temp_local_new_ptr(); // store shack start TCGv_ptr temp_shack_top = tcg_temp_local_new_ptr(); // store shack top TCGv eip_on_shack = tcg_temp_local_new(); TCGv_ptr host_slot_addr = tcg_temp_local_new(); TCGv_ptr host_addr = tcg_temp_new(); // load common values tcg_gen_ld_ptr(temp_shack_start, cpu_env, offsetof(CPUState, shack)); tcg_gen_ld_ptr(temp_shack_top, cpu_env, offsetof(CPUState, shack_top)); // check if stack empty? tcg_gen_brcond_ptr(TCG_COND_EQ,temp_shack_top,temp_shack_start,label_end); // stack not empty, pop one tcg_gen_subi_ptr(temp_shack_top, temp_shack_top, sizeof(uint64_t)); // decrease top tcg_gen_st_ptr(temp_shack_top, cpu_env, offsetof(CPUState, shack_top)); // store back top tcg_gen_ld_tl(eip_on_shack, temp_shack_top, 0); // get eip // check if the same? tcg_gen_brcond_ptr(TCG_COND_NE,tcg_const_tl(next_eip),eip_on_shack,label_end); // go to "end" if not the same tcg_gen_ld_tl(host_slot_addr, temp_shack_top, sizeof(unsigned long)); // get slot addr tcg_gen_ld_ptr(host_addr, host_slot_addr, 0) ; // get host addr tcg_gen_brcond_ptr(TCG_COND_EQ,tcg_const_tl(0),host_addr,label_end); // go to "end" if addr is zero // jump! *gen_opc_ptr++ = INDEX_op_jmp; *gen_opparam_ptr++ = GET_TCGV_I32(host_addr); // label: end gen_set_label(label_end); tcg_temp_free(eip_on_shack); tcg_temp_free_ptr(host_slot_addr); tcg_temp_free_ptr(host_addr); tcg_temp_free_ptr(temp_shack_top); tcg_temp_free_ptr(temp_shack_start); }