int main() { #if __WORDSIZE==64 oassert(strtol_or_strtoll("0xAB12345678", NULL, 16)==0xAB12345678); #else oassert(strtol_or_strtoll("0x12345678", NULL, 16)==0x12345678); #endif const char* strings[]={"string1", "hello", "world", "another string"}; size_t strings_t=sizeof(strings)/sizeof(char*); printf ("%d\n", find_string_in_array_of_strings("another string", strings, strings_t, false, false)); printf ("%d\n", find_string_in_array_of_strings("world", strings, strings_t, true, false)); printf ("%d\n", find_string_in_array_of_strings("Hello", strings, strings_t, true, false)); printf ("%d\n", find_string_in_array_of_strings("world2", strings, strings_t, true, false)); printf ("%d\n", find_string_in_array_of_strings("World", strings, strings_t, false, false)); oassert (string_is_ends_with ("hello", "lo")==true); oassert (string_is_ends_with ("hello", "lo1")==false); oassert (str_common_prefix_len("asd", "das")==0); oassert (str_common_prefix_len(" & Her Lover", " Cook, the Thief, His Wife & Her Lover")==1); oassert (str_common_prefix_len("asd", "as2")==2); oassert (str_common_prefix_len("asd", "as")==2); oassert (str_common_prefix_len("asd", "asd")==3); oassert (str_common_prefix_len("asd", "abb")==1); char *buf=DSTRDUP("hello world","buf"); string_remove_part (buf, 0, 4); // "hello" string_remove_part (buf, 0, 0); // " " oassert (strcmp (buf, "world")==0); DFREE(buf); buf=DSTRDUP(" ","buf"); string_remove_part (buf, 0, 0); // " " oassert (strcmp (buf, "")==0); DFREE(buf); buf=DSTRDUP("asdfg","buf"); string_remove_part (buf, 4, 4); string_remove_part (buf, 0, 0); oassert (strcmp (buf, "sdf")==0); DFREE(buf); oassert(is_string_consists_only_of_Latin_letters("abcdef")==true); oassert(is_string_consists_only_of_Latin_letters("abcd1ef")==false); oassert(is_string_has_only_one_character_repeating("111111111", NULL)==true); oassert(is_string_has_only_one_character_repeating("1111111112", NULL)==false); char* tmp=dmalloc_and_snprintf ("%d %d", 123, 456); oassert(streq(tmp, "123 456")); DFREE(tmp); tmp=dmalloc_and_snprintf ("%" PRIx64 " %d", 0x1234567890ABCDEF, 456); oassert(streq(tmp, "1234567890abcdef 456")); DFREE(tmp); dump_unfreed_blocks(); };
void dmessage_free(dmessage_t* mp) { if (mp->release) (*mp->release)(mp); if ((mp->buffer < mp->data) || (mp->buffer > mp->data+mp->size)) DFREE(mp->buffer); DFREE(mp); }
void set_add_string_or_free (rbtree *t, char *s) { if (rbtree_is_key_present(t, (void*)s)) DFREE(s); else rbtree_insert(t, (void*)s, NULL); };
dthread_t* dthread_start(ErlDrvPort port, void* (*func)(void* arg), void* arg, int stack_size) { ErlDrvThreadOpts* opts = NULL; dthread_t* thr = NULL; if (!(thr = DALLOC(sizeof(dthread_t)))) return 0; if (dthread_init(thr, port) < 0) goto error; if (!(opts = erl_drv_thread_opts_create("dthread_opts"))) goto error; opts->suggested_stack_size = stack_size; thr->arg = arg; if (erl_drv_thread_create("dthread", &thr->tid, func, thr, opts) < 0) goto error; erl_drv_thread_opts_destroy(opts); return thr; error: dthread_finish(thr); if (opts) erl_drv_thread_opts_destroy(opts); dthread_finish(thr); DFREE(thr); return 0; }
bool strbuf_replace_if_possible (strbuf *sb, const char *s1, const char *s2) { char *t=strstr (sb->buf, s1); char *newbuf; unsigned newbuf_cursize=0, newbuf_newsize; if (t==NULL) return false; // now rebuild buf newbuf_newsize=sb->strlen-strlen(s1)+strlen(s2)+1; newbuf=DMALLOC(char, newbuf_newsize, "strbuf::buf"); // C++ style naming? haha // 1st part newbuf_cursize=t-sb->buf; memcpy (newbuf, sb->buf, newbuf_cursize); // 2nd part memcpy (newbuf+newbuf_cursize, s2, strlen(s2)); newbuf_cursize+=strlen(s2); // 3rd part memcpy (newbuf+newbuf_cursize, t+strlen(s1), newbuf_newsize-newbuf_cursize); newbuf[newbuf_newsize-1]=0; DFREE (sb->buf); sb->buf=newbuf; sb->buflen=newbuf_newsize; sb->strlen=newbuf_newsize-1; return true; };
void set_of_REG_to_string (rbtree *t, strbuf *out, unsigned limit) { unsigned cnt=rbtree_count(t); REG *keys=DMALLOC(REG, cnt, "keys"); rbtree_return_all_keys (t, (void**)keys); make_compact_list_of_REGs (keys, cnt, out, limit); DFREE (keys); };
void thread_free (thread *t) { if (thread_c_debug) L ("%s() begin\n", __func__); for (unsigned b=0; b<4; b++) { BP_thread_specific_dynamic_info *bp=&t->BP_dynamic_info[b]; DFREE (bp->BPF_args); if (bp->BPF_buffers_at_start) { for (unsigned i=0; i<bp->BPF_buffers_at_start_cnt; i++) DFREE(bp->BPF_buffers_at_start[i]); DFREE(bp->BPF_buffers_at_start); }; }; DFREE (t); };
void dterm_reset_links(dterm_t* p) { if (p->head) { dterm_link_t* lp = p->head; while(lp) { dterm_link_t* nlp = lp->next; DFREE(lp); lp = nlp; } p->head = NULL; } }
static ErlDrvData uart_drv_start(ErlDrvPort port, char* command) { (void) command; drv_ctx_t* ctx = NULL; INFOF("memory allocated: %ld", dlib_allocated()); INFOF("total memory allocated: %ld", dlib_total_allocated()); ctx = DZALLOC(sizeof(drv_ctx_t)); dthread_init(&ctx->self, port); if (strncmp(command, "uart_drv", 8) == 0) command += 8; if (*command == ' ') command++; DEBUGF("uart_drv: start (%s)", command); if (strcmp(command, "ftdi") == 0) { #ifdef HAVE_FTDI ctx->other = dthread_start(port, uart_ftdi_main, &ctx->self, 4096); DEBUGF("uart_drv: ftdi thread = %p", ctx->other); #endif } else { #ifdef __WIN32__ if ((*command == '\0') || (strcmp(command, "win32") == 0)) { ctx->other = dthread_start(port, uart_win32_main, &ctx->self, 4096); DEBUGF("uart_drv: win32 thread = %p", ctx->other); } #else if ((*command == '\0') || (strcmp(command, "unix") == 0)) { ctx->other = dthread_start(port, uart_unix_main, &ctx->self, 4096); DEBUGF("uart_drv: unix thread = %p", ctx->other); } #endif } if (ctx->other == NULL) { dthread_finish(&ctx->self); DFREE(ctx); return ERL_DRV_ERROR_BADARG; } dthread_signal_use(&ctx->self, 1); dthread_signal_select(&ctx->self, 1); set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY); return (ErlDrvData) ctx; }
bool MC_LoadPageForAddress (MemoryCache *mc, address adr) { address idx, rd_adr; SIZE_T bytes_read; MemoryCacheElement *t=NULL; #ifndef _WIN64 // as of win32 #define _ADR_SKIP 0x7FFE0000 if (mc->dont_read_from_quicksilver_places && (adr>=_ADR_SKIP && adr<(_ADR_SKIP+PAGE_SIZE))) { // нужно всегда обламывать чтение этих мест - там, например, текущее системное время, // от этого тестирование эмулятора CPU рандомно глючит, долго я искал эту багу :( // с другой стороны, эмулятор CPU вполне может нормально работать, хоть и с небольшими // отклонениями по системному времени //L (2, __FUNCTION__ "(0x" PRI_ADR_HEX "): wouldn't read process memory\n"); return false; }; #endif idx=adr>>LOG2_PAGE_SIZE; rd_adr=idx<<LOG2_PAGE_SIZE; t=DCALLOC(MemoryCacheElement, 1, "MemoryCacheElement"); #ifdef BOLT_DEBUG if (mc->testing) { if (rd_adr+PAGE_SIZE > mc->testing_memory_size) goto free_t_and_return_false; memcpy (t->block, mc->testing_memory+rd_adr, PAGE_SIZE); bytes_read=PAGE_SIZE; }; #endif #ifdef BOLT_DEBUG if (mc->testing==false) #endif if (ReadProcessMemory (mc->PHDL, (LPCVOID)rd_adr, t->block, PAGE_SIZE, &bytes_read)==false) goto free_t_and_return_false; oassert (bytes_read==PAGE_SIZE); rbtree_insert(mc->_cache, (void*)idx, t); return true; free_t_and_return_false: DFREE(t); return false; };
/** * @desc 关闭程序 * @param int signo 信号 * @return void */ void server_end(int signo) { //防止重复关闭 if(SERVER_STATUS_CLOSE == g_status) return; g_status = SERVER_STATUS_CLOSE; //关闭socket shutdown_epoll_socket(g_epoll_socket); //关闭thread shutdown_epoll_thread(g_thread); //释放内存资源 destroy_epoll_thread(g_thread); destroy_epoll_socket(g_epoll_socket); destroy_lrumc(g_lrumc); DFREE(g_lrumc_config); unlink_pid_file(); }
static void uart_drv_stop(ErlDrvData d) { drv_ctx_t* ctx = (drv_ctx_t*) d; void* value; DEBUGF("uart_drv_stop: called"); dthread_stop(ctx->other, &ctx->self, &value); DEBUGF("uart_drv_stop: signal_use=0"); dthread_signal_use(&ctx->self, 0); DEBUGF("uart_drv_stop: dthread_finish"); dthread_finish(&ctx->self); DFREE(ctx); INFOF("memory allocated: %ld", dlib_allocated()); INFOF("total memory allocated: %ld", dlib_total_allocated()); }
// replace %substring% to environment variable, if possible void env_vars_expansion(strbuf *sb, char** env) { oassert(env!=NULL); for (int i=0; env[i]; i++) { char *s=DSTRDUP (env[i], "env"); char *s1=strtok (s, "="); char *s2=strtok (NULL, "="); strbuf percented_env_var=STRBUF_INIT; strbuf_addc (&percented_env_var, '%'); strbuf_addstr (&percented_env_var, s1); strbuf_addc (&percented_env_var, '%'); strbuf_replace_if_possible (sb, percented_env_var.buf, s2); strbuf_deinit(&percented_env_var); DFREE(s); }; };
int dthread_stop(dthread_t* target, dthread_t* source, void** exit_value) { dmessage_t* mp; int r; if (!(mp = dmessage_create(DTHREAD_STOP, NULL, 0))) return -1; dthread_send(target, source, mp); DEBUGF("dthread_stop: wait to join"); r = erl_drv_thread_join(target->tid, exit_value); DEBUGF("dthread_stop: thread_join: return=%d, exit_value=%p", r, *exit_value); dthread_signal_finish(target, 1); dthread_finish(target); DFREE(target); return 0; }
void dump_buf_as_array_of_strings(MemoryCache *mc, address a, size_t size) { strbuf sb=STRBUF_INIT; BYTE *buf=DMALLOC (BYTE, size, "BYTE*"); if (MC_ReadBuffer (mc, a, size, buf)==false) goto exit; for (unsigned i=0; i<size; i+=sizeof(REG)) { address a2=*(REG*)&buf[i]; if (MC_get_any_string(mc, a2, &sb)) { L ("0x" PRI_ADR_HEX "+0x%x: ptr to %s\n", a, i, sb.buf); strbuf_reinit(&sb, 0); }; }; exit: DFREE (buf); strbuf_deinit(&sb); };
void strbuf_grow (strbuf *sb, size_t size) { char* new_buf; if (size < (sb->buflen - sb->strlen)) { //printf ("(no need to reallocate)\n"); return; // we have space already }; new_buf=DMALLOC(char, sb->strlen + size + 1, "strbuf"); // FIXME: realloc or DREALLOC should be here for clarity if (sb->buf) { memcpy (new_buf, sb->buf, sb->strlen+1); if (sb->buf!=strbuf_dummybuf) DFREE(sb->buf); }; sb->buf=new_buf; sb->buflen=sb->strlen + size + 1; };
void PE_get_imports_info_free(struct PE_get_imports_info *i) { for (int DLLs=0; DLLs < i->import_descriptors_t; DLLs++) { struct PE_get_imports_DLL_info* DLL=i->dlls + DLLs; DFREE (DLL->DLL_name); for (int s=0; s<DLL->symbols_t; s++) DFREE(DLL->symbols[s]); DFREE(DLL->symbols); DFREE(DLL->hints); }; DFREE(i->dlls); DFREE(i); };
void MC_MemoryCache_dtor(MemoryCache *mc, bool check_unflushed_elements) { struct rbtree_node_t *i; if (check_unflushed_elements) { for (i=rbtree_minimum(mc->_cache); i!=NULL; i=rbtree_succ(i)) { MemoryCacheElement *v=(MemoryCacheElement*)i->value; if (v->to_be_flushed) { printf ("%s(): there are still elements to be flushed!\n", __FUNCTION__); oassert(0); }; }; }; rbtree_foreach(mc->_cache, NULL, NULL, dfree); rbtree_deinit(mc->_cache); DFREE (mc); };
Da_emulate_result Da_emulate(Da* d, CONTEXT * ctx, MemoryCache *mem, bool emulate_FS_accesses, address FS) { #ifdef _WIN64 return DA_NOT_EMULATED; #endif //bool SF=IS_SET(ctx->EFlags, FLAG_SF); //bool OF=IS_SET(ctx->EFlags, FLAG_OF); //bool ZF=IS_SET(ctx->EFlags, FLAG_ZF); bool CF=IS_SET(ctx->EFlags, FLAG_CF); bool b; if (x86_emu_debug) { // FIXME: write to log also? L ("%s() begin: [", __func__); Da_DumpString(&cur_fds, d); L ("]\n"); }; if ((emulate_FS_accesses==false && IS_SET(d->prefix_codes, PREFIX_FS)) || (IS_SET(d->prefix_codes, PREFIX_SS) || IS_SET(d->prefix_codes, PREFIX_GS))) { if (x86_emu_debug) L ("%s() skipping (data selector prefix present) at 0x" PRI_ADR_HEX "\n", __func__, CONTEXT_get_PC(ctx)); return DA_EMULATED_CANNOT_READ_MEMORY; }; switch (d->ins_code) { case I_CDQ: { uint32_t a=CONTEXT_get_Accum (ctx)&0xFFFFFFFF; CONTEXT_set_xDX (ctx, (a&0x80000000) ? 0xFFFFFFFF : 0); goto add_to_PC_and_return_OK; }; break; case I_PUSH: { address rt_adr; obj v; b=Da_op_get_value_of_op (&d->op[0], &rt_adr, ctx, mem, __FILE__, __LINE__, &v, d->prefix_codes, FS); if (b==false) { if (x86_emu_debug) L ("%s() I_PUSH: can't read memory\n", __func__); return DA_EMULATED_CANNOT_READ_MEMORY; }; b=DO_PUSH (ctx, mem, obj_get_as_REG(&v)); if (b==false) { if (x86_emu_debug) L ("%s() I_PUSH: can't write memory\n", __func__); return DA_EMULATED_CANNOT_WRITE_MEMORY; }; goto add_to_PC_and_return_OK; }; break; case I_PUSHFD: if (DO_PUSH (ctx, mem, ctx->EFlags | FLAG_TF)==false) { if (x86_emu_debug) L ("%s() I_PUSHFD: can't write memory\n", __func__); return DA_EMULATED_CANNOT_WRITE_MEMORY; }; goto add_to_PC_and_return_OK; break; case I_POP: { REG val; if (DO_POP(ctx, mem, &val)==false) return DA_EMULATED_CANNOT_READ_MEMORY; obj v; obj_tetrabyte2 (val, &v); Da_op_set_value_of_op (&d->op[0], &v, ctx, mem, d->prefix_codes, FS); goto add_to_PC_and_return_OK; }; break; case I_POPFD: { REG val; if (DO_POP(ctx, mem, &val)==false) return DA_EMULATED_CANNOT_READ_MEMORY; ctx->EFlags=val; goto add_to_PC_and_return_OK; }; break; case I_LEAVE: { //ESP <- EBP //POP EBP REG val; CONTEXT_set_SP(ctx, CONTEXT_get_BP(ctx)); if (DO_POP(ctx, mem, &val)==false) return DA_EMULATED_CANNOT_READ_MEMORY; // FIXME: а надо еще SP назад возвращать! CONTEXT_set_BP(ctx, val); goto add_to_PC_and_return_OK; }; break; case I_REP_STOSB: case I_REP_STOSW: case I_REP_STOSD: { BYTE *buf; bool DF=IS_SET(ctx->EFlags, FLAG_DF); if (DF) return DA_NOT_EMULATED; // not supported... bug here SIZE_T BUF_SIZE; if (d->ins_code==I_REP_STOSB) BUF_SIZE=CONTEXT_get_xCX (ctx); else if (d->ins_code==I_REP_STOSW) BUF_SIZE=CONTEXT_get_xCX (ctx)*2; else if (d->ins_code==I_REP_STOSD) BUF_SIZE=CONTEXT_get_xCX (ctx)*4; buf=DMALLOC(BYTE, BUF_SIZE, "buf"); if (d->ins_code==I_REP_STOSB) { for (REG i=0; i<CONTEXT_get_xCX(ctx); i++) // FIXME: rewrite to my own bzero()! buf[i]=CONTEXT_get_Accum(ctx)&0xFF; } else if (d->ins_code==I_REP_STOSW) { for (REG i=0; i<CONTEXT_get_xCX(ctx); i++) // FIXME: rewrite to my own bzero()! ((WORD*)buf)[i]=CONTEXT_get_Accum(ctx)&0xFFFF; } else if (d->ins_code==I_REP_STOSD) { for (REG i=0; i<CONTEXT_get_xCX(ctx); i++) // FIXME: rewrite to my own bzero()! ((DWORD*)buf)[i]=(DWORD)(CONTEXT_get_Accum(ctx)&0xFFFFFFFF); } else { oassert(0); }; if (MC_WriteBuffer (mem, CONTEXT_get_xDI (ctx), BUF_SIZE, buf)==false) return DA_EMULATED_CANNOT_WRITE_MEMORY; DFREE(buf); CONTEXT_set_xDI (ctx, CONTEXT_get_xDI (ctx) + BUF_SIZE); CONTEXT_set_xCX (ctx, 0); goto add_to_PC_and_return_OK; }; break; case I_REP_MOVSB: case I_REP_MOVSW: case I_REP_MOVSD: { BYTE *buf; bool DF=IS_SET(ctx->EFlags, FLAG_DF); if (DF) return DA_NOT_EMULATED; // not supported... bug here SIZE_T BUF_SIZE; SIZE_T sizeof_element; if (d->ins_code==I_REP_MOVSB) sizeof_element=1; else if (d->ins_code==I_REP_MOVSW) sizeof_element=2; else if (d->ins_code==I_REP_MOVSD) sizeof_element=4; else { oassert(0); }; BUF_SIZE=CONTEXT_get_xCX(ctx)*sizeof_element; //printf ("%s() BUF_SIZE=0x%x\n", __func__, BUF_SIZE); //printf ("%s() (before) SI=0x" PRI_REG_HEX "\n", __func__, CONTEXT_get_xSI(ctx)); //printf ("%s() (before) DI=0x" PRI_REG_HEX "\n", __func__, CONTEXT_get_xDI(ctx)); buf=DMALLOC(BYTE, BUF_SIZE, "buf"); address blk_src=CONTEXT_get_xSI(ctx); address blk_dst=CONTEXT_get_xDI(ctx); if (DF) { blk_src-=BUF_SIZE; // +sizeof_element; blk_dst-=BUF_SIZE; // +sizeof_element; }; if (MC_ReadBuffer (mem, blk_src, BUF_SIZE, buf)==false) { DFREE(buf); return DA_EMULATED_CANNOT_READ_MEMORY; }; if (MC_WriteBuffer (mem, blk_dst, BUF_SIZE, buf)==false) { DFREE(buf); return DA_EMULATED_CANNOT_WRITE_MEMORY; }; DFREE(buf); if (DF==false) { CONTEXT_set_xSI (ctx, CONTEXT_get_xSI (ctx) + BUF_SIZE); CONTEXT_set_xDI (ctx, CONTEXT_get_xDI (ctx) + BUF_SIZE); } else { CONTEXT_set_xSI (ctx, CONTEXT_get_xSI (ctx) - BUF_SIZE); CONTEXT_set_xDI (ctx, CONTEXT_get_xDI (ctx) - BUF_SIZE); }; CONTEXT_set_xCX (ctx, 0); //printf ("%s() (after) SI=0x" PRI_REG_HEX "\n", __func__, CONTEXT_get_xSI(ctx)); //printf ("%s() (after) DI=0x" PRI_REG_HEX "\n", __func__, CONTEXT_get_xDI(ctx)); goto add_to_PC_and_return_OK; }; case I_STD: SET_BIT (ctx->EFlags, FLAG_DF); goto add_to_PC_and_return_OK; case I_CLD: REMOVE_BIT (ctx->EFlags, FLAG_DF); goto add_to_PC_and_return_OK; case I_RETN: { WORD ret_arg=0; if (d->ops_total==1) { oassert (d->op[0].type==DA_OP_TYPE_VALUE); ret_arg=obj_get_as_wyde(&d->op[0].val._v); // RETN arg is 16-bit }; address newPC; if (DO_POP(ctx, mem, &newPC)==false) return DA_EMULATED_CANNOT_READ_MEMORY; CONTEXT_set_SP(ctx, CONTEXT_get_SP(ctx)+ret_arg); CONTEXT_set_PC(ctx, newPC); return DA_EMULATED_OK; }; break; case I_ADD: case I_ADC: case I_INC: { //L (__FUNCTION__ "() I_ADD/I_INC begin: [%s]\n", ToString().c_str()); obj rt1, rt2; REG rt1_adr, rt2_adr; b=Da_op_get_value_of_op (&d->op[0], &rt1_adr, ctx, mem, __FILE__, __LINE__, &rt1, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_READ_MEMORY; if (d->ins_code==I_ADD || d->ins_code==I_ADC) { oassert (d->op[0].value_width_in_bits==d->op[1].value_width_in_bits); b=Da_op_get_value_of_op (&d->op[1], &rt2_adr, ctx, mem, __FILE__, __LINE__, &rt2, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_READ_MEMORY; } else { // INC case // make second op 1 obj_REG2_and_set_type (rt1.t, 1, 0, &rt2); }; obj res_sum; obj_add (&rt1, &rt2, &res_sum); if (d->ins_code==I_ADC && CF) obj_increment(&res_sum); set_PF (ctx, &res_sum); set_SF (ctx, &res_sum); set_ZF (ctx, &res_sum); set_AF (ctx, &rt1, &rt2, &res_sum); if (d->ins_code==I_ADD || d->ins_code==I_ADC) set_or_clear_flag (ctx, FLAG_CF, obj_compare (&res_sum, &rt1)==-1); // res_sum < rt1 octabyte tmp=((zero_extend_to_REG(&rt1) ^ zero_extend_to_REG(&rt2) ^ get_sign_bit (d->op[0].value_width_in_bits)) & (zero_extend_to_REG(&res_sum) ^ zero_extend_to_REG(&rt1))) & get_sign_bit (d->op[0].value_width_in_bits); set_or_clear_flag (ctx, FLAG_OF, tmp); b=Da_op_set_value_of_op (&d->op[0], &res_sum, ctx, mem, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_WRITE_MEMORY; goto add_to_PC_and_return_OK; }; break; case I_NOT: { obj rt1, res; REG rt1_adr; if (Da_op_get_value_of_op (&d->op[0], &rt1_adr, ctx, mem, __FILE__, __LINE__, &rt1, d->prefix_codes, FS)==false) return DA_EMULATED_CANNOT_READ_MEMORY; obj_NOT(&rt1, &res); if (Da_op_set_value_of_op (&d->op[0], &res, ctx, mem, d->prefix_codes, FS)) goto add_to_PC_and_return_OK; }; break; case I_NEG: { obj rt1, res; REG rt1_adr; if (Da_op_get_value_of_op (&d->op[0], &rt1_adr, ctx, mem, __FILE__, __LINE__, &rt1, d->prefix_codes, FS)==false) return DA_EMULATED_CANNOT_READ_MEMORY; obj_NEG(&rt1, &res); set_or_clear_flag (ctx, FLAG_CF, obj_is_zero(&rt1)==false); set_PF (ctx, &res); set_SF (ctx, &res); set_ZF (ctx, &res); set_or_clear_flag (ctx, FLAG_AF, (0 ^ obj_get_4th_bit(&rt1)) ^ obj_get_4th_bit(&res)); REMOVE_BIT (ctx->EFlags, FLAG_OF); //SET_BIT (ctx->EFlags, FLAG_AF); if (Da_op_set_value_of_op (&d->op[0], &res, ctx, mem, d->prefix_codes, FS)) goto add_to_PC_and_return_OK; }; break; case I_OR: case I_XOR: case I_AND: case I_TEST: { oassert (d->op[0].value_width_in_bits==d->op[1].value_width_in_bits); obj rt1, rt2, res; REG rt1_adr, rt2_adr; b=Da_op_get_value_of_op (&d->op[0], &rt1_adr, ctx, mem, __FILE__, __LINE__, &rt1, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_READ_MEMORY; b=Da_op_get_value_of_op (&d->op[1], &rt2_adr, ctx, mem, __FILE__, __LINE__, &rt2, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_READ_MEMORY; switch (d->ins_code) { case I_OR: obj_OR(&rt1, &rt2, &res); break; case I_XOR: obj_XOR(&rt1, &rt2, &res); break; case I_TEST: case I_AND: obj_AND(&rt1, &rt2, &res); break; default: oassert(0); break; }; set_PF (ctx, &res); set_SF (ctx, &res); set_ZF (ctx, &res); REMOVE_BIT (ctx->EFlags, FLAG_AF); REMOVE_BIT (ctx->EFlags, FLAG_CF); REMOVE_BIT (ctx->EFlags, FLAG_OF); if (d->ins_code==I_TEST) b=true; else b=Da_op_set_value_of_op (&d->op[0], &res, ctx, mem, d->prefix_codes, FS); if (b) goto add_to_PC_and_return_OK; else return DA_EMULATED_CANNOT_WRITE_MEMORY; }; break; case I_DEC: case I_SUB: case I_SBB: case I_CMP: { if (d->ins_code==I_SUB || d->ins_code==I_SBB || d->ins_code==I_CMP) { oassert (d->op[0].value_width_in_bits==d->op[1].value_width_in_bits); }; obj rt1, rt2; REG rt1_adr, rt2_adr; b=Da_op_get_value_of_op (&d->op[0], &rt1_adr, ctx, mem, __FILE__, __LINE__, &rt1, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_READ_MEMORY; if (d->ins_code==I_DEC) { // make second op 1 obj_REG2_and_set_type (rt1.t, 1, 0, &rt2); } else { b=Da_op_get_value_of_op (&d->op[1], &rt2_adr, ctx, mem, __FILE__, __LINE__, &rt2, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_READ_MEMORY; }; obj res; obj_subtract (&rt1, &rt2, &res); if (d->ins_code==I_SBB && CF) obj_decrement (&res); set_PF (ctx, &res); set_SF (ctx, &res); set_ZF (ctx, &res); set_AF (ctx, &rt1, &rt2, &res); if (d->ins_code==I_SBB) { int tmp=(obj_compare (&rt1, &res)==-1 /* rt1<res */) || (CF && obj_get_as_tetrabyte(&rt2)==0xffffffff); set_or_clear_flag (ctx, FLAG_CF, tmp); } else { if (d->ins_code!=I_DEC) // DEC leave CF flag unaffected set_or_clear_flag (ctx, FLAG_CF, obj_compare (&rt1, &rt2)==-1); /* rt1<rt2 */ }; octabyte tmp=((zero_extend_to_octabyte(&rt1) ^ zero_extend_to_octabyte(&rt2)) & (zero_extend_to_octabyte(&res) ^ zero_extend_to_octabyte(&rt1))) & get_sign_bit (d->op[0].value_width_in_bits); set_or_clear_flag (ctx, FLAG_OF, tmp); if (d->ins_code==I_CMP) b=true; else b=Da_op_set_value_of_op (&d->op[0], &res, ctx, mem, d->prefix_codes, FS); if (b) goto add_to_PC_and_return_OK; else return DA_EMULATED_CANNOT_WRITE_MEMORY; }; break; case I_XCHG: { REG op1_adr, op2_adr; obj op1; b=Da_op_get_value_of_op(&d->op[0], &op1_adr, ctx, mem, __FILE__, __LINE__, &op1, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_READ_MEMORY; obj op2; b=Da_op_get_value_of_op(&d->op[1], &op2_adr, ctx, mem, __FILE__, __LINE__, &op2, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_READ_MEMORY; if (Da_op_set_value_of_op (&d->op[0], &op2, ctx, mem, d->prefix_codes, FS)==false) return DA_EMULATED_CANNOT_WRITE_MEMORY; if (Da_op_set_value_of_op (&d->op[1], &op1, ctx, mem, d->prefix_codes, FS)==false) return DA_EMULATED_CANNOT_WRITE_MEMORY; goto add_to_PC_and_return_OK; }; break; case I_MOV: case I_MOVDQA: case I_MOVDQU: return Da_emulate_MOV_op1_op2(d, ctx, mem, d->prefix_codes, FS); case I_MOVZX: case I_MOVSX: { address rt_adr; obj op2; bool b=Da_op_get_value_of_op(&d->op[1], &rt_adr, ctx, mem, __FILE__, __LINE__, &op2, d->prefix_codes, FS); if (b==false) { /* if (L_verbose_level>=2) { printf (__FUNCTION__ "(): ["); Da_DumpString(d); printf ("]: can't read src (2nd) operand\n"); }; */ return DA_EMULATED_CANNOT_WRITE_MEMORY; }; obj to_be_stored_v; if (d->ins_code==I_MOVZX) { enum obj_type op1_type_will_be=bit_width_to_obj_type (d->op[0].value_width_in_bits); obj_zero_extend (&op2, op1_type_will_be, &to_be_stored_v); } else if (d->ins_code==I_MOVSX) { enum obj_type op1_type_will_be=bit_width_to_obj_type (d->op[0].value_width_in_bits); obj_sign_extend (&op2, op1_type_will_be, &to_be_stored_v); } else { oassert (0); }; b=Da_op_set_value_of_op (&d->op[0], &to_be_stored_v, ctx, mem, d->prefix_codes, FS); if (b==false) { /* if (L_verbose_level>=2) { printf(__FUNCTION__ "(): ["); Da_DumpString(d); printf ("]: can't write dst (1st) operand\n"); }; */ return DA_EMULATED_CANNOT_WRITE_MEMORY; }; goto add_to_PC_and_return_OK; }; case I_NOP: goto add_to_PC_and_return_OK; case I_LEA: { address a=(address)Da_op_calc_adr_of_op(&d->op[1], ctx, mem, d->prefix_codes, FS); obj val; obj_tetrabyte2(a, &val); b=Da_op_set_value_of_op (&d->op[0], &val, ctx, mem, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_WRITE_MEMORY; goto add_to_PC_and_return_OK; }; case I_SAR: case I_SHR: case I_SHL: { // http://cs.smith.edu/~thiebaut/ArtOfAssembly/CH06/CH06-3.html REG op1_adr, op2_adr; obj op1; bool b=Da_op_get_value_of_op(&d->op[0], &op1_adr, ctx, mem, __FILE__, __LINE__, &op1, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_READ_MEMORY; // should be read anyway! obj op2; b=Da_op_get_value_of_op(&d->op[1], &op2_adr, ctx, mem, __FILE__, __LINE__, &op2, d->prefix_codes, FS); if (b==false) return DA_EMULATED_CANNOT_READ_MEMORY; #ifdef _WIN64 obj_AND_with (&op2, 0x3F); #else obj_AND_with (&op2, 0x1F); #endif if (obj_is_zero(&op2)==false) { unsigned new_CF; if (d->ins_code==I_SHR || d->ins_code==I_SAR) new_CF=(zero_extend_to_octabyte(&op1) >> (obj_get_as_byte (&op2) - 1)) & 1; else // SHL new_CF=(zero_extend_to_octabyte(&op1) >> (obj_width_in_bits(&op1) - obj_get_as_byte (&op2))) & 1; obj new_op1; if (d->ins_code==I_SHR) { REG new_v=zero_extend_to_REG(&op1) >> obj_get_as_byte (&op2); obj_REG2_and_set_type(op1.t, new_v, 0, &new_op1); } else if (d->ins_code==I_SAR)
void strbuf_deinit(strbuf *sb) { if (sb->buf && sb->buf!=strbuf_dummybuf) DFREE(sb->buf); };
void BPM_free(BPM *o) { DFREE (o); };
int main() { listPtr List, Queue, Stack, Splay; char *String1, *String2, *String3, *String4, *Get; int Result; printf("Testing LINKLIST Library for ANSI C.\n\n"); String1 = malloc(20); String2 = malloc(20); String3 = malloc(20); String4 = malloc(20); strcpy(String1, "Hi"); strcpy(String2, "Low"); strcpy(String3, "Up"); strcpy(String4, "Down"); printf("Creating List.\n"); List = NewListAlloc(LIST, DMALLOC, DFREE, (NodeCompareFunc)strcmp); printf("Creating Queue.\n"); Queue = NewListAlloc(QUEUE, DMALLOC, DFREE, NULL); printf("Creating Stack.\n"); Stack = NewListAlloc(STACK, DMALLOC, DFREE, NULL); printf("Creating Splay Tree\n"); Splay = NewListAlloc(STREE, DMALLOC, DFREE, (NodeCompareFunc)StringCompare); printf("Adding Elements to List...\n"); AddNode(List, NewNode("Hi")); AddNode(List, NewNode("Low")); AddNode(List, NewNode("Up")); AddNode(List, NewNode("Down")); printf("Adding Elements to Queue...\n"); AddNode(Queue, NewNode("Hi")); AddNode(Queue, NewNode("Low")); AddNode(Queue, NewNode("Up")); AddNode(Queue, NewNode("Down")); printf("Adding Elements to Stack...\n"); AddNode(Stack, NewNode(String1)); AddNode(Stack, NewNode(String2)); AddNode(Stack, NewNode(String3)); AddNode(Stack, NewNode(String4)); printf("Adding Elements to Splay Tree...\n"); AddNode(Splay, NewNode("High")); AddNode(Splay, NewNode("Low")); AddNode(Splay, NewNode("Up")); AddNode(Splay, NewNode("Down")); printf("Attempting to add duplicate nodes to Splay Tree...\n"); Result = AddNode(Splay, NewNode("Down")); printf("Result: "); if (Result == LLIST_OK) printf("OK\n"); else if (Result == LLIST_BADVALUE) printf("Node Already Exists; not added\n"); else printf("Error\n"); printf("Calimed Memory: %d bytes\n", DCOUNT(NULL)); printf("LIST:\n"); PrintList(List, "%s"); printf("QUEUE:\n"); PrintList(Queue, "%s"); printf("STACK:\n"); PrintList(Stack, "%s"); printf("SPLAY:\n"); PrintList(Splay, "%s"); printf("\n-----------------------\n"); printf("Reading Element from LIST\n"); printf("Read Element: %s\n", GetNode(List)); PrintList(List, "%s"); printf("\n\nReading Element from QUEUE\n"); printf("Read Element: %s\n", GetNode(Queue)); PrintList(Queue, "%s"); printf("\n\nReading Element from STACK\n"); printf("Read Element: %s\n", (Get = GetNode(Stack))); DFREE(Get); PrintList(Stack, "%s"); printf("\n-----------------------\n"); printf("Reading Element #2 from LIST\n"); printf("Read Element: %s\n", IndexNode(List, 2)); PrintList(List, "%s"); printf("\nAdding One More Element to LIST\n"); AddNode(List, NewNode("And")); PrintList(List, "%s"); printf("\n-----------------------\n"); printf("\nSorting LIST\n"); SortList(List); PrintList(List, "%s"); printf("\n-----------------------\n"); printf("\nDeleting Element 2 From LIST\n"); IndexNode(List, 2); RemoveList(List); PrintList(List, "%s"); printf("\nDeleting Head From LIST\n"); DelHeadList(List); PrintList(List, "%s"); printf("\nDeleting Tail From LIST\n"); DelTailList(List); PrintList(List, "%s"); printf("\n------------------------\n"); printf("Reading Element from Splay Tree\n"); printf("Read Element: %s\n", GetNode(Splay)); printf("\nDeleting Element From Splay Tree\n"); DelNode(Splay); PrintList(Splay, "%s"); printf("\nDeleting Element \"Low\" In Splay Tree\n"); FindNode(Splay, "Low"); DelNode(Splay); PrintList(Splay, "%s"); printf("Reading Element from Splay Tree\n"); printf("Read Element: %s\n", GetNode(Splay)); printf("\n-----------------------\n"); printf("Removing List.\n"); FreeList(List, NULL); printf("Removing Queue.\n"); FreeList(Queue, NULL); printf("Removing Stack.\n"); FreeList(Stack, NULL); printf("Removing Splay Tree.\n"); FreeList(Splay, NULL); printf("\n-----------------------\n"); printf("\nUnclaimed Memory: %d bytes\n", DCOUNT(NULL)); printf("\nLinkList Test/Demo Done.\n"); return 0; } /* main */
void dterm_finish(dterm_t* p) { if (p->base != p->data) DFREE(p->base); dterm_reset_links(p); }
static void release_xptr_func(dmessage_t* mp) { DEBUGF("release_xptr_func called"); DFREE(mp->udata); }
void dterm_free(dterm_t* p) { dterm_finish(p); if (p->dyn_alloc) DFREE(p); }