Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

srt_x86.cc

Go to the documentation of this file.
00001 /*
00002  *      HT Editor
00003  *      srt_x86.cc
00004  *
00005  *      Copyright (C) 2001, 2002 Stefan Weyergraf (stefan@weyergraf.de)
00006  *
00007  *      This program is free software; you can redistribute it and/or modify
00008  *      it under the terms of the GNU General Public License version 2 as
00009  *      published by the Free Software Foundation.
00010  *
00011  *      This program is distributed in the hope that it will be useful,
00012  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *      GNU General Public License for more details.
00015  *
00016  *      You should have received a copy of the GNU General Public License
00017  *      along with this program; if not, write to the Free Software
00018  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  */
00020 
00021 #include <string.h>
00022 
00023 #include "htctrl.h"             // FIXME: remove this
00024 #include "htexcept.h"
00025 #include "htiobox.h"
00026 #include "srt_x86.h"
00027 #include "x86dis.h"
00028 
00029 #define X86_FLAG_CARRY          0
00030 #define X86_FLAG_PARITY         1
00031 #define X86_FLAG_AUX            2
00032 #define X86_FLAG_ZERO           3
00033 #define X86_FLAG_SIGNED         4
00034 #define X86_FLAG_OVERFLOW       5
00035 
00036 #define X86_FLAGS                       6
00037 
00038 char *srt_x86_flags[X86_FLAGS] = {
00039         "carry", "parity", "aux",
00040         "zero", "signed", "overflow"
00041 };
00042 
00043 struct CPU {
00044         sym_int *regs[8];
00045         sym_bool *flags[X86_FLAGS];
00046 };
00047 
00048 char *srt_x86_idx2reg(UINT idx)
00049 {
00050         if (idx >= 8) {
00051                 return srt_x86_flags[(idx-8) % X86_FLAGS];
00052         }
00053         return x86_regs[2][idx & 7];
00054 }
00055 
00056 void srt_x86_setreg(CPU *cpu, UINT idx, Object *o)
00057 {
00058         if (idx >= 8) {
00059                 sym_bool **k;
00060                 k = &cpu->flags[(idx-8) % X86_FLAGS];
00061                 (*k)->done();
00062                 delete *k;
00063                 *k = (sym_bool *)o;
00064         } else {
00065                 sym_int **k;
00066                 k = &cpu->regs[idx & 7];
00067                 (*k)->done();
00068                 delete *k;
00069                 *k = (sym_int *)o;
00070         }
00071 }
00072 
00073 /*
00074  *      CLASS sym_int_reg_x86
00075  */
00076 
00077 class sym_int_reg_x86: public sym_int_reg {
00078 public:
00079         sym_int_reg_x86::sym_int_reg_x86(UINT r): sym_int_reg(r)
00080         {
00081         }
00082 
00083         Object *duplicate()
00084         {
00085                 return new sym_int_reg_x86(regidx);
00086         }
00087 
00088         virtual int nstrfy(char *buf, int n)
00089         {
00090                 return sprintf(buf,"%s", srt_x86_idx2reg(regidx));
00091         }
00092 }; 
00093 
00094 /*
00095  *      srt_x86
00096  */
00097 
00098 state_mod *srt_x86_flag(UINT flagidx, sym_bool_token *value)
00099 {
00100         state_mod *f = new state_mod();
00101         f->ismem = false;
00102         f->dest.regidx = 8 + flagidx;
00103         f->isbool = true;
00104         f->value.boolean = value;
00105         return f;
00106 }
00107 
00108 state_mod *srt_x86_reg(UINT regidx, sym_int_token *value)
00109 {
00110         state_mod *r = new state_mod();
00111         r->ismem = false;
00112         r->dest.regidx = regidx;
00113         r->isbool = false;
00114         r->value.integer = value;
00115         return r;
00116 }
00117 
00118 void srt_x86_flags_std(ht_list *rm, x86dis_insn *insn, sym_int *cond)
00119 {
00120         state_mod *zf = new state_mod();
00121         zf->ismem = false;
00122         zf->dest.regidx = 8 + X86_FLAG_ZERO;
00123         zf->isbool = true;
00124 
00125         state_mod *sf = new state_mod();
00126         sf->ismem = false;
00127         sf->dest.regidx = 8 + X86_FLAG_SIGNED;
00128         sf->isbool = true;
00129 
00130         sym_int *i;
00131         sym_bool *b;
00132 
00133         switch (insn->op[0].size) {
00134                 case 1:
00135                         i = (sym_int*)cond->duplicate();
00136                         i->b_operate(b_and, new sym_int_const(0xff));
00137                         b = new sym_bool();
00138                         b->set(new sym_bool_intcmp(i, c_eq, new sym_int_const(0)));
00139                         zf->value.boolean = b;
00140 
00141                         i = (sym_int*)cond->duplicate();
00142                         i->b_operate(b_and, new sym_int_const(0x80));
00143                         b = new sym_bool();
00144                         b->set(new sym_bool_intcmp(i, c_ne, new sym_int_const(0)));
00145                         sf->value.boolean = b;
00146                         break;
00147                 case 2:
00148                         i = (sym_int*)cond->duplicate();
00149                         i->b_operate(b_and, new sym_int_const(0xffff));
00150                         b = new sym_bool();
00151                         b->set(new sym_bool_intcmp(i, c_eq, new sym_int_const(0)));
00152                         zf->value.boolean = b;
00153 
00154                         i = (sym_int*)cond->duplicate();
00155                         i->b_operate(b_and, new sym_int_const(0x8000));
00156                         b = new sym_bool();
00157                         b->set(new sym_bool_intcmp(i, c_ne, new sym_int_const(0)));
00158                         sf->value.boolean = b;
00159                         break;
00160                 case 4:
00161                         i = (sym_int*)cond->duplicate();
00162                         b = new sym_bool();
00163                         b->set(new sym_bool_intcmp(i, c_eq, new sym_int_const(0)));
00164                         zf->value.boolean = b;
00165 
00166                         i = (sym_int*)cond->duplicate();
00167                         i->b_operate(b_and, new sym_int_const(0x80000000));
00168                         b = new sym_bool();
00169                         b->set(new sym_bool_intcmp(i, c_ne, new sym_int_const(0)));
00170                         sf->value.boolean = b;
00171                         break;
00172         }
00173         rm->insert(zf);
00174         rm->insert(sf);
00175 }
00176 
00177 void srt_x86_flags_carry(ht_list *rm, x86dis_insn *insn, sym_int *cond, sym_bool *carry)
00178 {
00179         state_mod *cf = new state_mod();
00180         cf->ismem = false;
00181         cf->dest.regidx = 8 + X86_FLAG_CARRY;
00182         cf->isbool = true;
00183 
00184         sym_int *i;
00185         sym_bool *b;
00186 
00187         switch (insn->op[0].size) {
00188                 case 1:
00189                         i = (sym_int*)cond->duplicate();
00190                         i->b_operate(b_and, new sym_int_const(0x100));
00191                         b = new sym_bool();
00192                         b->set(new sym_bool_intcmp(i, c_ne, new sym_int_const(0)));
00193                         cf->value.boolean = b;
00194                         break;
00195                 case 2:
00196                         i = (sym_int*)cond->duplicate();
00197                         i->b_operate(b_and, new sym_int_const(0x10000));
00198                         b = new sym_bool();
00199                         b->set(new sym_bool_intcmp(i, c_ne, new sym_int_const(0)));
00200                         cf->value.boolean = b;
00201                         break;
00202                 case 4:
00203                         cf->value.boolean = (sym_bool_token*)carry->duplicate();
00204                         break;
00205         }
00206         rm->insert(cf);
00207 }
00208 
00209 /*void srt_x86_flags_overflow(cpu *CPU, x86dis_insn *insn, dword a, dword b, dword c)
00210 {
00211         bool overflow_on = false;
00212         switch (insn->op[0].size) {
00213                 case 1:
00214                         if (((a & 0x80) == (b & 0x80)) && ((a & 0x80) != (c & 0x80))) {
00215                                 overflow_on = true;
00216                                 CPU->context.d.eflags |= FLAGS_OVERFLOW;
00217                         } else {
00218                                 CPU->context.d.eflags &= ~FLAGS_OVERFLOW;
00219                         }
00220                         break;
00221                 case 2:
00222                         if (((a & 0x8000) == (b & 0x8000)) && ((a & 0x8000) != (c & 0x8000))) {
00223                                 CPU->context.d.eflags |= FLAGS_OVERFLOW;
00224                         } else {
00225                                 CPU->context.d.eflags &= ~FLAGS_OVERFLOW;
00226                         }
00227                         break;
00228                 case 4:
00229                         if (((a & 0x80000000) == (b & 0x80000000)) && ((a & 0x80000000) != (c & 0x80000000))) {
00230                                 CPU->context.d.eflags |= FLAGS_OVERFLOW;
00231                         } else {
00232                                 CPU->context.d.eflags &= ~FLAGS_OVERFLOW;
00233                         }
00234                         break;
00235         }
00236 }*/
00237 
00238 sym_int *srt_x86_mkreg(CPU *cpu, UINT regidx)
00239 {
00240         return (sym_int*)cpu->regs[regidx]->duplicate();
00241 }
00242 
00243 sym_int_token *srt_x86_mkaddr(CPU *cpu, x86_insn_op *o)
00244 {
00245         sym_int *a = new sym_int();
00246         bool first = true;
00247         if (o->mem.index != X86_REG_NO) {
00248                 a->b_operate(b_invalid, srt_x86_mkreg(cpu, o->mem.index));
00249                 if (o->mem.scale > 1)
00250                         a->b_operate(b_mul, new sym_int_const(o->mem.scale));
00251                 first = false;
00252         }
00253         if (o->mem.base != X86_REG_NO) {
00254                 a->b_operate(first ? b_invalid : b_add, srt_x86_mkreg(cpu, o->mem.base));
00255                 first = false;
00256         }
00257         if (o->mem.hasdisp && o->mem.disp) {
00258                 dword D = o->mem.disp;
00259                 b_op op = first ? b_invalid : ((D&0x80000000) ? b_sub : b_add);
00260                 if (D&0x80000000) D = -D;
00261                 a->b_operate(op, new sym_int_const(D));
00262                 first = false;
00263         }
00264         return a;
00265 }
00266 
00267 void srt_x86_mkdest(CPU *cpu, state_mod *m, x86_insn_op *d)
00268 {
00269         switch (d->type) {
00270                 case X86_OPTYPE_REG:
00271                         m->ismem = false;
00272                         m->dest.regidx = d->reg;
00273                         break;
00274                 case X86_OPTYPE_MEM:
00275                         m->ismem = true;
00276                         m->dest.mem.addr = srt_x86_mkaddr(cpu, d);
00277                         m->dest.mem.size = d->size;
00278                         m->dest.mem.endian = srte_le;
00279                         break;
00280                 default:
00281                         throw new ht_io_exception("unknown dest type: %d", d->type);
00282         }
00283 }
00284 
00285 sym_int *srt_x86_mkvalue(CPU *cpu, x86_insn_op *o)
00286 {
00287         sym_int *r = new sym_int();
00288         switch (o->type) {
00289                 case X86_OPTYPE_IMM: {
00290                         r->set(new sym_int_const(o->imm));
00291                         break;
00292                 }
00293                 case X86_OPTYPE_REG: {
00294                         r->set(srt_x86_mkreg(cpu, o->reg));
00295                         break;
00296                 }
00297                 case X86_OPTYPE_MEM:
00298                         r->set(new sym_int_mem(srt_x86_mkaddr(cpu, o), o->size, srte_le));
00299                         break;
00300                 default:
00301                         throw new ht_io_exception("unknown op type: %d", o->type);
00302         }
00303         return r;
00304 }
00305 
00306 void srt_x86_destmod(CPU *cpu, ht_list *rm, x86_insn_op *op, sym_int_token *value)
00307 {
00308         state_mod *m = new state_mod();
00309         srt_x86_mkdest(cpu, m, op);
00310         m->isbool = false;
00311         m->value.integer = value;
00312         rm->insert(m);
00313 }
00314 
00315 /*
00316  *      COMMANDS
00317  */
00318 
00319 void srt_x86_add(CPU *cpu, ht_list *rm, x86dis_insn *insn)
00320 {
00321         sym_int *v = srt_x86_mkvalue(cpu, &insn->op[0]);
00322         v->b_operate(b_add, srt_x86_mkvalue(cpu, &insn->op[1]));
00323 
00324         srt_x86_destmod(cpu, rm, &insn->op[0], v);
00325 
00326         srt_x86_flags_std(rm, insn, v);
00327         sym_bool *carry = new sym_bool();
00328         carry->set(new sym_bool_intcmp(
00329                 (sym_int*)v->duplicate(), c_lt,
00330                 srt_x86_mkvalue(cpu, &insn->op[1])));
00331         srt_x86_flags_carry(rm, insn, v, carry);
00332         delete carry;
00333 // FIXME: overflow flag
00334 }
00335 
00336 void srt_x86_and(CPU *cpu, ht_list *rm, x86dis_insn *insn)
00337 {
00338         sym_int *v = srt_x86_mkvalue(cpu, &insn->op[0]);
00339         v->b_operate(b_and, srt_x86_mkvalue(cpu, &insn->op[1]));
00340 
00341         srt_x86_destmod(cpu, rm, &insn->op[0], v);
00342 
00343         srt_x86_flags_std(rm, insn, v);
00344 }
00345 
00346 void srt_x86_cmp(CPU *cpu, ht_list *rm, x86dis_insn *insn)
00347 {
00348         sym_int *v = srt_x86_mkvalue(cpu, &insn->op[0]);
00349         v->b_operate(b_sub, srt_x86_mkvalue(cpu, &insn->op[1]));
00350 
00351         srt_x86_flags_std(rm, insn, v);
00352         sym_bool *carry = new sym_bool();
00353         carry->set(new sym_bool_intcmp(
00354                 srt_x86_mkvalue(cpu, &insn->op[0]), c_lt,
00355                 srt_x86_mkvalue(cpu, &insn->op[1])));
00356         srt_x86_flags_carry(rm, insn, v, carry);
00357         delete carry;
00358 // FIXME: overflow flag
00359 }
00360 
00361 void srt_x86_dec(CPU *cpu, ht_list *rm, x86dis_insn *insn)
00362 {
00363         sym_int *v = srt_x86_mkvalue(cpu, &insn->op[0]);
00364         v->b_operate(b_sub, new sym_int_const(1));
00365 
00366         srt_x86_destmod(cpu, rm, &insn->op[0], v);
00367 
00368         srt_x86_flags_std(rm, insn, v);
00369 }
00370 
00371 void srt_x86_div(CPU *cpu, ht_list *rm, x86dis_insn *insn)
00372 {
00373 // FIXME: DX:AX / op -> EAX, DX:AX % op -> EDX
00374         sym_int *q = srt_x86_mkvalue(cpu, &insn->op[0]);
00375         q->b_operate(b_div, srt_x86_mkvalue(cpu, &insn->op[1]));
00376 
00377         sym_int *r = srt_x86_mkvalue(cpu, &insn->op[0]);
00378         r->b_operate(b_mod, srt_x86_mkvalue(cpu, &insn->op[1]));
00379 
00380         srt_x86_destmod(cpu, rm, &insn->op[0], q);
00381 
00382         state_mod *m = new state_mod();
00383         m->ismem = false;
00384         m->dest.regidx = X86_REG_DX;
00385         m->isbool = false;
00386         m->value.integer = r;
00387         rm->insert(m);
00388 
00389         srt_x86_flags_std(rm, insn, q);
00390 // FIXME: flags
00391 /*      sym_bool *carry = new sym_bool();
00392         carry->set(new sym_bool_intcmp(
00393                 (sym_int*)v->duplicate(), c_lt,
00394                 srt_x86_mkvalue(cpu, &insn->op[1])));
00395         srt_x86_flags_carry(rm, insn, v, carry);
00396         delete carry;*/
00397 }
00398 
00399 void srt_x86_inc(CPU *cpu, ht_list *rm, x86dis_insn *insn)
00400 {
00401         sym_int *v = srt_x86_mkvalue(cpu, &insn->op[0]);
00402         v->b_operate(b_add, new sym_int_const(1));
00403 
00404         srt_x86_destmod(cpu, rm, &insn->op[0], v);
00405 
00406         srt_x86_flags_std(rm, insn, v);
00407 }
00408 
00409 void srt_x86_lea(CPU *cpu, ht_list *rm, x86dis_insn *insn)
00410 {
00411         state_mod *m = new state_mod();
00412         srt_x86_mkdest(cpu, m, &insn->op[0]);
00413         if (insn->op[1].type != X86_OPTYPE_MEM) throw new ht_io_exception("internal error in %s at %d", __FILE__, __LINE__);
00414         m->isbool = false;
00415         m->value.integer = srt_x86_mkaddr(cpu, &insn->op[1]);
00416         rm->insert(m);
00417 }
00418 
00419 void srt_x86_mov(CPU *cpu, ht_list *rm, x86dis_insn *insn)
00420 {
00421         state_mod *m = new state_mod();
00422         srt_x86_mkdest(cpu, m, &insn->op[0]);
00423         m->isbool = false;
00424         m->value.integer = srt_x86_mkvalue(cpu, &insn->op[1]);
00425         rm->insert(m);
00426 }
00427 
00428 void srt_x86_mul(CPU *cpu, ht_list *rm, x86dis_insn *insn)
00429 {
00430 // FIXME: op * AX = DX:AX
00431         sym_int *v = srt_x86_mkvalue(cpu, &insn->op[0]);
00432         v->b_operate(b_mul, srt_x86_mkvalue(cpu, &insn->op[1]));
00433 
00434         srt_x86_destmod(cpu, rm, &insn->op[0], v);
00435 
00436 /*      state_mod *m = new state_mod();
00437         m->ismem = false;
00438         m->dest.regidx = ;
00439         m->isbool = false;
00440         m->value.integer = v;
00441         rm->insert(m);*/
00442 
00443         srt_x86_flags_std(rm, insn, v);
00444 // FIXME: flags
00445 /*      sym_bool *carry = new sym_bool();
00446         carry->set(new sym_bool_intcmp(
00447                 (sym_int*)v->duplicate(), c_lt,
00448                 srt_x86_mkvalue(cpu, &insn->op[1])));
00449         srt_x86_flags_carry(rm, insn, v, carry);
00450         delete carry;*/
00451 }
00452 
00453 void srt_x86_or(CPU *cpu, ht_list *rm, x86dis_insn *insn)
00454 {
00455         sym_int *v = srt_x86_mkvalue(cpu, &insn->op[0]);
00456         v->b_operate(b_or, srt_x86_mkvalue(cpu, &insn->op[1]));
00457 
00458         srt_x86_destmod(cpu, rm, &insn->op[0], v);
00459 
00460         srt_x86_flags_std(rm, insn, v);
00461 }
00462 
00463 void srt_x86_pop(CPU *cpu, ht_list *rm, x86dis_insn *insn)
00464 {
00465 /*      dword a;
00466         read(context.w.ss, context.d.esp, &a, 4);
00467         context.d.esp += 4;
00468         return a;*/
00469         state_mod *m;
00470         int size = 4;
00471 
00472         m = new state_mod();
00473         srt_x86_mkdest(cpu, m, &insn->op[0]);
00474         m->isbool = false;
00475         m->value.integer = new sym_int_mem(srt_x86_mkreg(cpu, X86_REG_SP), size, srte_le);
00476         rm->insert(m);
00477 
00478         sym_int *sp = srt_x86_mkreg(cpu, X86_REG_SP);
00479         sp->b_operate(b_add, new sym_int_const(size));
00480 
00481         m = new state_mod();
00482         m->ismem = false;
00483         m->dest.regidx = X86_REG_SP;
00484         m->isbool = false;
00485         m->value.integer = sp;
00486         rm->insert(m);
00487 }
00488 
00489 void srt_x86_push(CPU *cpu, ht_list *rm, x86dis_insn *insn)
00490 {
00491 /*      context.d.esp -= 4;
00492         write(context.w.ss, context.d.esp, &a, 4);*/
00493         state_mod *m;
00494         int size = 4;
00495 
00496         sym_int *sp = srt_x86_mkreg(cpu, X86_REG_SP);
00497         sp->b_operate(b_sub, new sym_int_const(size));
00498 
00499         m = new state_mod();
00500         m->ismem = false;
00501         m->dest.regidx = X86_REG_SP;
00502         m->isbool = false;
00503         m->value.integer = sp;
00504         rm->insert(m);
00505         
00506         m = new state_mod();
00507         m->ismem = true;
00508         m->dest.mem.addr = (sym_int*)sp->duplicate();
00509         m->dest.mem.size = size;
00510         m->dest.mem.endian = srte_le;
00511         m->isbool = false;
00512         m->value.integer = srt_x86_mkvalue(cpu, &insn->op[0]);
00513         rm->insert(m);
00514 }
00515 
00516 void srt_x86_sub(CPU *cpu, ht_list *rm, x86dis_insn *insn)
00517 {
00518         sym_int *v = srt_x86_mkvalue(cpu, &insn->op[0]);
00519         v->b_operate(b_sub, srt_x86_mkvalue(cpu, &insn->op[1]));
00520 
00521         srt_x86_destmod(cpu, rm, &insn->op[0], v);
00522 
00523         srt_x86_flags_std(rm, insn, v);
00524         sym_bool *carry = new sym_bool();
00525         carry->set(new sym_bool_intcmp(
00526                 srt_x86_mkvalue(cpu, &insn->op[0]), c_lt,
00527                 srt_x86_mkvalue(cpu, &insn->op[1])));
00528         srt_x86_flags_carry(rm, insn, v, carry);
00529         delete carry;
00530 // FIXME: overflow flag
00531 }
00532 
00533 void srt_x86_shl(CPU *cpu, ht_list *rm, x86dis_insn *insn)
00534 {
00535         sym_int *v = srt_x86_mkvalue(cpu, &insn->op[0]);
00536         sym_int *s = srt_x86_mkvalue(cpu, &insn->op[1]);
00537         UINT S;
00538         if (!s->evaluate(&S)) throw new ht_io_exception("shl/shr with non-constant operand not supported");
00539         delete s;
00540         v->b_operate(b_mul, new sym_int_const(1 << S));
00541 
00542         srt_x86_destmod(cpu, rm, &insn->op[0], v);
00543 
00544         srt_x86_flags_std(rm, insn, v);
00545 // FIXME: flags
00546 }
00547 
00548 void srt_x86_shr(CPU *cpu, ht_list *rm, x86dis_insn *insn)
00549 {
00550         sym_int *v = srt_x86_mkvalue(cpu, &insn->op[0]);
00551         sym_int *s = srt_x86_mkvalue(cpu, &insn->op[1]);
00552         UINT S;
00553         if (!s->evaluate(&S)) throw new ht_io_exception("shl/shr with non-constant operand not supported");
00554         delete s;
00555         v->b_operate(b_div, new sym_int_const(1 << S));
00556 
00557         srt_x86_destmod(cpu, rm, &insn->op[0], v);
00558 
00559         srt_x86_flags_std(rm, insn, v);
00560 // FIXME: flags
00561 }
00562 
00563 void srt_x86_test(CPU *cpu, ht_list *rm, x86dis_insn *insn)
00564 {
00565         sym_int *v = srt_x86_mkvalue(cpu, &insn->op[0]);
00566         v->b_operate(b_and, srt_x86_mkvalue(cpu, &insn->op[1]));
00567         srt_x86_flags_std(rm, insn, v);
00568 }
00569 
00570 void srt_x86_xor(CPU *cpu, ht_list *rm, x86dis_insn *insn)
00571 {
00572         sym_int *v = srt_x86_mkvalue(cpu, &insn->op[0]);
00573         v->b_operate(b_xor, srt_x86_mkvalue(cpu, &insn->op[1]));
00574 
00575         srt_x86_destmod(cpu, rm, &insn->op[0], v);
00576 
00577         srt_x86_flags_std(rm, insn, v);
00578         rm->insert(srt_x86_flag(X86_FLAG_CARRY, new sym_bool_const(false)));
00579         rm->insert(srt_x86_flag(X86_FLAG_OVERFLOW, new sym_bool_const(false)));
00580 }
00581 
00582 typedef void (*ecmd_handler)(CPU *cpu, ht_list *rm, x86dis_insn *insn);
00583 
00584 struct ecmd {
00585         char *name;
00586         ecmd_handler h;
00587 };
00588 
00589 ecmd ecmds[] = {
00590         {"add",  srt_x86_add},
00591         {"and",  srt_x86_and},
00592         {"cmp",  srt_x86_cmp},
00593         {"dec",  srt_x86_dec},
00594         {"div",  srt_x86_div},
00595         {"inc",  srt_x86_inc},
00596         {"lea",  srt_x86_lea},
00597         {"mov",  srt_x86_mov},
00598         {"mul",  srt_x86_mul},
00599         {"or",   srt_x86_or},
00600         {"push", srt_x86_push},
00601         {"pop",  srt_x86_pop},
00602         {"sub",  srt_x86_sub},
00603         {"shl",  srt_x86_shl},
00604         {"shr",  srt_x86_shr},
00605         {"test", srt_x86_test},
00606         {"xor",  srt_x86_xor},
00607         {NULL, NULL}
00608 };
00609 
00610 ht_list *srt_x86_single(CPU *cpu, x86dis_insn *i)
00611 {
00612         ht_clist *rm = new ht_clist();
00613         rm->init();
00614 
00615         ecmd *e = ecmds;
00616         while (e->name) {
00617                 if (strcmp(i->name, e->name) == 0) {
00618                         e->h(cpu, rm, i);
00619                         return rm;
00620                 }
00621                 e++;
00622         }
00623         throw new ht_io_exception("unsupported cmd: %s", i->name);
00624 }
00625 
00626 void create_cpu(CPU *cpu)
00627 {
00628         for (UINT g = 0; g<8; g++) {
00629                 char s[32];
00630                 sprintf(s, "i%s", srt_x86_idx2reg(g));
00631                 cpu->regs[g] = new sym_int();
00632                 cpu->regs[g]->init();
00633                 cpu->regs[g]->set(new sym_int_symbol(s));
00634         }
00635 
00636         for (UINT g = 0; g<X86_FLAGS; g++) {
00637                 char s[32];
00638                 sprintf(s, "i%s", srt_x86_idx2reg(8+g));
00639                 cpu->flags[g] = new sym_bool();
00640                 cpu->flags[g]->init();
00641                 cpu->flags[g]->set(new sym_bool_symbol(s));
00642         }
00643 }
00644 
00645 void destroy_cpu(CPU *cpu)
00646 {
00647         for (UINT g = 0; g<8; g++) {
00648                 cpu->regs[g]->done();
00649                 delete cpu->regs[g];
00650         }
00651 
00652         for (UINT g = 0; g<X86_FLAGS; g++) {
00653                 cpu->flags[g]->done();
00654                 delete cpu->flags[g];
00655         }
00656 }
00657 
00658 void srt_x86(Analyser *analy, Address *addr)
00659 {
00660         x86dis *x = (x86dis*)analy->disasm;
00661         CPU_ADDR a;
00662         byte buf[15];
00663 
00664         addr->putIntoCPUAddress(&a);
00665         CPU cpu;
00666 
00667         create_cpu(&cpu);
00668 
00669 
00670         char str[256];
00671         sprintf(str, "symbolic register trace (x86)");
00672         bounds b, c, d;
00673         app->getbounds(&c);
00674         b.w = 3*c.w/4;
00675         b.h = 3*c.h/4;
00676         b.x = (c.w-b.w)/2;
00677         b.y = (c.h-b.h)/2;
00678         ht_dialog *dialog = new ht_dialog();
00679         dialog->init(&b, str, FS_KILLER | FS_TITLE | FS_MOVE);
00680         d.x = 0;
00681         d.y = 0;
00682         d.w = b.w-2;
00683         d.h = 1;
00684         ht_listbox_title *text = new ht_listbox_title();
00685         text->init(&d);
00686         text->setText(3, "insn", "register", "new value");
00687         dialog->insert(text);
00688         d.y = 1;
00689         d.h = b.h-3;
00690         ht_text_listbox *list;
00691         NEW_OBJECT(list, ht_text_listbox, &d, 3, 2);
00692         list->attachTitle(text);
00693 //      char str2[1024];
00694 
00695 #define MAX_INSNS       20
00696         for (int i=0; i<MAX_INSNS; i++) {
00697                 if (!analy->validAddress(addr, scinitialized)) break;
00698                 UINT bz = analy->bufPtr(addr, buf, sizeof buf);
00699                 dis_insn *i = (x86dis_insn*)x->decode(buf, bz, a);
00700                 if (!x->validInsn(i)) break;
00701                 x86dis_insn *xi = (x86dis_insn*)i;
00702                 char *dname = x->str(i, DIS_STYLE_HEX_NOZEROPAD + DIS_STYLE_HEX_ASMSTYLE);
00703                 ht_list *rm = NULL;
00704 
00705                 try{
00706                         rm = srt_x86_single(&cpu, xi);
00707                 } catch (ht_exception *x) {
00708                         errorbox("error: %s", x->what());
00709                         break;
00710                 }
00711 
00712                 UINT c = rm->count();
00713                 for (UINT i = 0; i<c; i++) {
00714                         state_mod *r = (state_mod*)rm->get(i);
00715                         char en[256];
00716                         if (r->isbool) {
00717                                 r->value.boolean->simplify();
00718                                 r->value.boolean->nstrfy(en, sizeof en);
00719                         } else {
00720                                 r->value.integer->simplify();
00721                                 r->value.integer->nstrfy(en, sizeof en);
00722                         }
00723                         if (r->ismem) {
00724                                 char c[256];
00725                                 char c2[256];
00726                                 r->dest.mem.addr->nstrfy(c, sizeof c);
00727 //                              infobox("%s causes memmod:\n%s%d[%s] := '%s'", dname, srt_endian_to_str(r->dest.mem.endian), r->dest.mem.size, c, en);
00728                                 sprintf(c2, "%s%d[%s]", srt_endian_to_str(r->dest.mem.endian), r->dest.mem.size, c);
00729                                 list->insert_str(0, dname, c2, en);
00730                         } else {
00731 //                              infobox("%s causes regmod:\n%s := '%s'", dname, x86_idx2reg(r->dest.regidx), en);
00732                                 list->insert_str(0, dname, srt_x86_idx2reg(r->dest.regidx), en);
00733                         }
00734                         dname = "";
00735                 }
00736                 for (UINT i = 0; i<c; i++) {
00737                         state_mod *r = (state_mod*)rm->get(i);
00738                         if (r->isbool) {
00739                                 srt_x86_setreg(&cpu, r->dest.regidx, r->value.boolean);
00740                         } else {
00741                                 srt_x86_setreg(&cpu, r->dest.regidx, r->value.integer);
00742                         }
00743                 }
00744                 addr->add(x->getSize(xi));
00745         }
00746         destroy_cpu(&cpu);
00747 
00748         list->update();
00749         dialog->insert(list);
00750         int r = dialog->run(0);
00751         if (r == button_ok) {
00752 //              ht_listbox_data data;
00753 /*              list->databuf_get(&data);
00754                 goto_address(data.cursor_id, this);*/
00755         }
00756         dialog->done();
00757         delete dialog;
00758 }
00759 

Generated on Fri May 7 21:15:43 2004 by doxygen 1.3.5