/* This software is Copyright 1989, 1990, 1992, 1993 by various individuals. Please see the accompanying file COPYRIGHT for details. */ #include "db.h" #include "inst.h" #include "config.h" #include "externs.h" #include "interface.h" void disassemble(dbref player, dbref program, int oarg[], int argc) { struct inst *curr; struct inst *codestart; struct inst *start; int i; int o1; int o2; struct stab *stab; int nstab; int stabx; char *bp; char buf[BUFFER_LEN]; codestart = DBFETCH(program)->sp.program.codevec; if (!DBFETCH(program)->sp.program.codesiz) { notify(player,"Nothing to disassemble!"); return; } if ((argc != 0) && (argc != 2)) { notify(player,"You must provide zero or two offset arguments!"); return; } if (argc) { int csz; o1 = oarg[0]; o2 = oarg[1]; if (o1 < 0) { notify(player,"Invalid argument: start offset must be >= 0"); return; } if (o2 < o1) { notify(player,"Invalid argument: end must be >= start"); return; } csz = DBFETCH(program)->sp.program.codesiz; if (o1 >= csz) { sprintf(&buf[0],"Program ends at %d",csz-1); notify(player,&buf[0]); return; } if (o2 >= csz) { o2 = csz - 1; sprintf(&buf[0],"Note: program ends at %d",o2); notify(player,&buf[0]); } } else { o1 = 0; o2 = DBFETCH(program)->sp.program.codesiz - 1; } stab = DBFETCH(program)->sp.program.stabvec; nstab = DBFETCH(program)->sp.program.stabsiz; start = DBFETCH(program)->sp.program.start; stabx = 0; curr = codestart + o1; for (i=o1;i<=o2;i++,curr++) { bp = &buf[0]; while ((stabx+1 < nstab) && (stab[stabx+1].off <= i)) stabx ++; sprintf(bp,"%3d%c %s+%d: ",i,(curr==start)?'*':':',stab[stabx].name,i-stab[stabx].off); bp += strlen(bp); switch (curr->type) { case PROG_PRIMITIVE: if ((curr->data.number >= BASE_MIN) && (curr->data.number <= BASE_MAX)) { sprintf(bp,"PRIMITIVE: %s",base_inst[curr->data.number-BASE_MIN]); } else { sprintf(bp,"PRIMITIVE: %d",curr->data.number); } break; case PROG_STRING: sprintf(bp,"STRING: \"%s\"",curr->data.string?curr->data.string:""); break; case PROG_INTEGER: sprintf(bp,"INTEGER: %d",curr->data.number); break; case PROG_ADD: { struct stab *st; sprintf(bp,"ADDRESS: %d",(int)(curr->data.call-codestart)); st = findstab(program,curr->data.call-codestart); if (st) { bp += strlen(bp); sprintf(bp," (%s+%d)",st->name,(int)(curr->data.call-codestart)-st->off); } } break; case PROG_OBJECT: sprintf(bp,"OBJECT REF: %d",curr->data.number); break; case PROG_VAR: sprintf(bp,"VARIABLE: %d",curr->data.number); break; case PROG_PTR: if (Typeof(curr->data.ptr->prog) == TYPE_PROGRAM) { if (DBFETCH(curr->data.ptr->prog)->sp.program.start == 0) { sprintf(bp,"POINTER: <#%d,uncompiled>",curr->data.ptr->prog); } else { struct stab *st; sprintf(bp,"POINTER: <#%d,%d>",curr->data.ptr->prog,(int)(curr->data.ptr->ptr-DBFETCH(curr->data.ptr->prog)->sp.program.codevec)); st = findstab(curr->data.ptr->prog,curr->data.ptr->ptr-DBFETCH(curr->data.ptr->prog)->sp.program.codevec); if (st) { bp += strlen(bp); sprintf(bp," (%s+%d)",st->name,(int)(curr->data.ptr->ptr-DBFETCH(curr->data.ptr->prog)->sp.program.codevec)-st->off); } } } else { sprintf(bp,"POINTER: <#%d,non-program>",curr->data.ptr->prog); } break; case PROG_RE: sprintf(bp,"REGEXP (?)"); break; } notify(player,&buf[0]); } }