Merge pull request #424 from Daniel-Cortez/pawndisasm-fixes

pawndisasm: Minor fixes, code cleanup
This commit is contained in:
Zeex 2019-06-15 22:11:05 +06:00 committed by GitHub
commit 382b30e00b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -47,183 +47,178 @@ cell do_proc(FILE *ftxt,const cell *params,cell opcode,cell cip);
cell do_call(FILE *ftxt,const cell *params,cell opcode,cell cip); cell do_call(FILE *ftxt,const cell *params,cell opcode,cell cip);
cell do_jump(FILE *ftxt,const cell *params,cell opcode,cell cip); cell do_jump(FILE *ftxt,const cell *params,cell opcode,cell cip);
cell do_sysreq(FILE *ftxt,const cell *params,cell opcode,cell cip); cell do_sysreq(FILE *ftxt,const cell *params,cell opcode,cell cip);
cell do_switch(FILE *ftxt,const cell *params,cell opcode,cell cip); cell do_casetbl(FILE *ftxt,const cell *params,cell opcode,cell cip);
cell casetbl(FILE *ftxt,const cell *params,cell opcode,cell cip);
cell do_file(FILE *ftxt,const cell *params,cell opcode,cell cip);
cell do_symbol(FILE *ftxt,const cell *params,cell opcode,cell cip);
typedef struct { typedef struct {
cell opcode;
char *name; char *name;
OPCODE_PROC func; OPCODE_PROC func;
} OPCODE; } OPCODE;
static OPCODE opcodelist[] = { static OPCODE opcodelist[] = {
{ 0, "???", parm0 }, { /* 0*/ NULL, NULL },
{ 1, "load.pri", parm1 }, { /* 1*/ "load.pri", parm1 },
{ 2, "load.alt", parm1 }, { /* 2*/ "load.alt", parm1 },
{ 3, "load.s.pri", parm1 }, { /* 3*/ "load.s.pri", parm1 },
{ 4, "load.s.alt", parm1 }, { /* 4*/ "load.s.alt", parm1 },
{ 5, "lref.pri", parm1 }, { /* 5*/ "lref.pri", parm1 },
{ 6, "lref.alt", parm1 }, { /* 6*/ "lref.alt", parm1 },
{ 7, "lref.s.pri", parm1 }, { /* 7*/ "lref.s.pri", parm1 },
{ 8, "lref.s.alt", parm1 }, { /* 8*/ "lref.s.alt", parm1 },
{ 9, "load.i", parm0 }, { /* 9*/ "load.i", parm0 },
{ 10, "lodb.i", parm1 }, { /* 10*/ "lodb.i", parm1 },
{ 11, "const.pri", parm1 }, { /* 11*/ "const.pri", parm1 },
{ 12, "const.alt", parm1 }, { /* 12*/ "const.alt", parm1 },
{ 13, "addr.pri", parm1 }, { /* 13*/ "addr.pri", parm1 },
{ 14, "addr.alt", parm1 }, { /* 14*/ "addr.alt", parm1 },
{ 15, "stor.pri", parm1 }, { /* 15*/ "stor.pri", parm1 },
{ 16, "stor.alt", parm1 }, { /* 16*/ "stor.alt", parm1 },
{ 17, "stor.s.pri", parm1 }, { /* 17*/ "stor.s.pri", parm1 },
{ 18, "stor.s.alt", parm1 }, { /* 18*/ "stor.s.alt", parm1 },
{ 19, "sref.pri", parm1 }, { /* 19*/ "sref.pri", parm1 },
{ 20, "sref.alt", parm1 }, { /* 20*/ "sref.alt", parm1 },
{ 21, "sref.s.pri", parm1 }, { /* 21*/ "sref.s.pri", parm1 },
{ 22, "sref.s.alt", parm1 }, { /* 22*/ "sref.s.alt", parm1 },
{ 23, "stor.i", parm0 }, { /* 23*/ "stor.i", parm0 },
{ 24, "strb.i", parm1 }, { /* 24*/ "strb.i", parm1 },
{ 25, "lidx", parm0 }, { /* 25*/ "lidx", parm0 },
{ 26, "lidx.b", parm1 }, { /* 26*/ "lidx.b", parm1 },
{ 27, "idxaddr", parm0 }, { /* 27*/ "idxaddr", parm0 },
{ 28, "idxaddr.b", parm1 }, { /* 28*/ "idxaddr.b", parm1 },
{ 29, "align.pri", parm1 }, { /* 29*/ "align.pri", parm1 },
{ 30, "align.alt", parm1 }, { /* 30*/ "align.alt", parm1 },
{ 31, "lctrl", parm1 }, { /* 31*/ "lctrl", parm1 },
{ 32, "sctrl", parm1 }, { /* 32*/ "sctrl", parm1 },
{ 33, "move.pri", parm0 }, { /* 33*/ "move.pri", parm0 },
{ 34, "move.alt", parm0 }, { /* 34*/ "move.alt", parm0 },
{ 35, "xchg", parm0 }, { /* 35*/ "xchg", parm0 },
{ 36, "push.pri", parm0 }, { /* 36*/ "push.pri", parm0 },
{ 37, "push.alt", parm0 }, { /* 37*/ "push.alt", parm0 },
{ 38, "push.r", parm1 }, /* obsolete (never generated) */ { /* 38*/ "push.r", parm1 }, /* obsolete (never generated) */
{ 39, "push.c", parm1 }, { /* 39*/ "push.c", parm1 },
{ 40, "push", parm1 }, { /* 40*/ "push", parm1 },
{ 41, "push.s", parm1 }, { /* 41*/ "push.s", parm1 },
{ 42, "pop.pri", parm0 }, { /* 42*/ "pop.pri", parm0 },
{ 43, "pop.alt", parm0 }, { /* 43*/ "pop.alt", parm0 },
{ 44, "stack", parm1 }, { /* 44*/ "stack", parm1 },
{ 45, "heap", parm1 }, { /* 45*/ "heap", parm1 },
{ 46, "proc", do_proc }, { /* 46*/ "proc", do_proc },
{ 47, "ret", parm0 }, { /* 47*/ "ret", parm0 },
{ 48, "retn", parm0 }, { /* 48*/ "retn", parm0 },
{ 49, "call", do_call }, { /* 49*/ "call", do_call },
{ 50, "call.pri", parm0 }, { /* 50*/ "call.pri", parm0 },
{ 51, "jump", do_jump }, { /* 51*/ "jump", do_jump },
{ 52, "jrel", parm1 }, /* same as jump, since version 10 */ { /* 52*/ "jrel", parm1 }, /* same as jump, since version 10 */
{ 53, "jzer", do_jump }, { /* 53*/ "jzer", do_jump },
{ 54, "jnz", do_jump }, { /* 54*/ "jnz", do_jump },
{ 55, "jeq", do_jump }, { /* 55*/ "jeq", do_jump },
{ 56, "jneq", do_jump }, { /* 56*/ "jneq", do_jump },
{ 57, "jless", do_jump }, { /* 57*/ "jless", do_jump },
{ 58, "jleq", do_jump }, { /* 58*/ "jleq", do_jump },
{ 59, "jgrtr", do_jump }, { /* 59*/ "jgrtr", do_jump },
{ 60, "jgeq", do_jump }, { /* 60*/ "jgeq", do_jump },
{ 61, "jsless", do_jump }, { /* 61*/ "jsless", do_jump },
{ 62, "jsleq", do_jump }, { /* 62*/ "jsleq", do_jump },
{ 63, "jsgrtr", do_jump }, { /* 63*/ "jsgrtr", do_jump },
{ 64, "jsgeq", do_jump }, { /* 64*/ "jsgeq", do_jump },
{ 65, "shl", parm0 }, { /* 65*/ "shl", parm0 },
{ 66, "shr", parm0 }, { /* 66*/ "shr", parm0 },
{ 67, "sshr", parm0 }, { /* 67*/ "sshr", parm0 },
{ 68, "shl.c.pri", parm1 }, { /* 68*/ "shl.c.pri", parm1 },
{ 69, "shl.c.alt", parm1 }, { /* 69*/ "shl.c.alt", parm1 },
{ 70, "shr.c.pri", parm1 }, { /* 70*/ "shr.c.pri", parm1 },
{ 71, "shr.c.alt", parm1 }, { /* 71*/ "shr.c.alt", parm1 },
{ 72, "smul", parm0 }, { /* 72*/ "smul", parm0 },
{ 73, "sdiv", parm0 }, { /* 73*/ "sdiv", parm0 },
{ 74, "sdiv.alt", parm0 }, { /* 74*/ "sdiv.alt", parm0 },
{ 75, "umul", parm0 }, { /* 75*/ "umul", parm0 },
{ 76, "udiv", parm0 }, { /* 76*/ "udiv", parm0 },
{ 77, "udiv.alt", parm0 }, { /* 77*/ "udiv.alt", parm0 },
{ 78, "add", parm0 }, { /* 78*/ "add", parm0 },
{ 79, "sub", parm0 }, { /* 79*/ "sub", parm0 },
{ 80, "sub.alt", parm0 }, { /* 80*/ "sub.alt", parm0 },
{ 81, "and", parm0 }, { /* 81*/ "and", parm0 },
{ 82, "or", parm0 }, { /* 82*/ "or", parm0 },
{ 83, "xor", parm0 }, { /* 83*/ "xor", parm0 },
{ 84, "not", parm0 }, { /* 84*/ "not", parm0 },
{ 85, "neg", parm0 }, { /* 85*/ "neg", parm0 },
{ 86, "invert", parm0 }, { /* 86*/ "invert", parm0 },
{ 87, "add.c", parm1 }, { /* 87*/ "add.c", parm1 },
{ 88, "smul.c", parm1 }, { /* 88*/ "smul.c", parm1 },
{ 89, "zero.pri", parm0 }, { /* 89*/ "zero.pri", parm0 },
{ 90, "zero.alt", parm0 }, { /* 90*/ "zero.alt", parm0 },
{ 91, "zero", parm1 }, { /* 91*/ "zero", parm1 },
{ 92, "zero.s", parm1 }, { /* 92*/ "zero.s", parm1 },
{ 93, "sign.pri", parm0 }, { /* 93*/ "sign.pri", parm0 },
{ 94, "sign.alt", parm0 }, { /* 94*/ "sign.alt", parm0 },
{ 95, "eq", parm0 }, { /* 95*/ "eq", parm0 },
{ 96, "neq", parm0 }, { /* 96*/ "neq", parm0 },
{ 97, "less", parm0 }, { /* 97*/ "less", parm0 },
{ 98, "leq", parm0 }, { /* 98*/ "leq", parm0 },
{ 99, "grtr", parm0 }, { /* 99*/ "grtr", parm0 },
{100, "geq", parm0 }, { /*100*/ "geq", parm0 },
{101, "sless", parm0 }, { /*101*/ "sless", parm0 },
{102, "sleq", parm0 }, { /*102*/ "sleq", parm0 },
{103, "sgrtr", parm0 }, { /*103*/ "sgrtr", parm0 },
{104, "sgeq", parm0 }, { /*104*/ "sgeq", parm0 },
{105, "eq.c.pri", parm1 }, { /*105*/ "eq.c.pri", parm1 },
{106, "eq.c.alt", parm1 }, { /*106*/ "eq.c.alt", parm1 },
{107, "inc.pri", parm0 }, { /*107*/ "inc.pri", parm0 },
{108, "inc.alt", parm0 }, { /*108*/ "inc.alt", parm0 },
{109, "inc", parm1 }, { /*109*/ "inc", parm1 },
{110, "inc.s", parm1 }, { /*110*/ "inc.s", parm1 },
{111, "inc.i", parm0 }, { /*111*/ "inc.i", parm0 },
{112, "dec.pri", parm0 }, { /*112*/ "dec.pri", parm0 },
{113, "dec.alt", parm0 }, { /*113*/ "dec.alt", parm0 },
{114, "dec", parm1 }, { /*114*/ "dec", parm1 },
{115, "dec.s", parm1 }, { /*115*/ "dec.s", parm1 },
{116, "dec.i", parm0 }, { /*116*/ "dec.i", parm0 },
{117, "movs", parm1 }, { /*117*/ "movs", parm1 },
{118, "cmps", parm1 }, { /*118*/ "cmps", parm1 },
{119, "fill", parm1 }, { /*119*/ "fill", parm1 },
{120, "halt", parm1 }, { /*120*/ "halt", parm1 },
{121, "bounds", parm1 }, { /*121*/ "bounds", parm1 },
{122, "sysreq.pri", parm0 }, { /*122*/ "sysreq.pri", parm0 },
{123, "sysreq.c", do_sysreq }, { /*123*/ "sysreq.c", do_sysreq },
{124, "file", do_file }, { /*124*/ NULL, NULL }, /* file */
{125, "line", parm2 }, { /*125*/ NULL, NULL }, /* line */
{126, "symbol", do_symbol }, { /*126*/ NULL, NULL }, /* symbol */
{127, "srange", parm2 }, /* version 1 */ { /*127*/ NULL, NULL }, /* srange, version 1 */
{128, "jump.pri", parm0 }, /* version 1 */ { /*128*/ "jump.pri", parm0 }, /* version 1 */
{129, "switch", do_switch }, /* version 1 */ { /*129*/ "switch", do_jump }, /* version 1 */
{130, "casetbl", casetbl }, /* version 1 */ { /*130*/ "casetbl", do_casetbl }, /* version 1 */
{131, "swap.pri", parm0 }, /* version 4 */ { /*131*/ "swap.pri", parm0 }, /* version 4 */
{132, "swap.alt", parm0 }, /* version 4 */ { /*132*/ "swap.alt", parm0 }, /* version 4 */
{133, "push.adr", parm1 }, /* version 4 */ { /*133*/ "push.adr", parm1 }, /* version 4 */
{134, "nop", parm0 }, /* version 6 */ { /*134*/ "nop", parm0 }, /* version 6 */
{135, "sysreq.n", parm2 }, /* version 9 (replaces SYSREQ.d from earlier version) */ { /*135*/ "sysreq.n", parm2 }, /* version 9 (replaces SYSREQ.d from earlier version) */
{136, "symtag", parm1 }, /* version 7 */ { /*136*/ NULL, NULL }, /* symtag, version 7 */
{137, "break", parm0 }, /* version 8 */ { /*137*/ "break", parm0 }, /* version 8 */
{138, "push2.c", parm2 }, /* version 9 */ { /*138*/ "push2.c", parm2 }, /* version 9 */
{139, "push2", parm2 }, /* version 9 */ { /*139*/ "push2", parm2 }, /* version 9 */
{140, "push2.s", parm2 }, /* version 9 */ { /*140*/ "push2.s", parm2 }, /* version 9 */
{141, "push2.adr", parm2 }, /* version 9 */ { /*141*/ "push2.adr", parm2 }, /* version 9 */
{142, "push3.c", parm3 }, /* version 9 */ { /*142*/ "push3.c", parm3 }, /* version 9 */
{143, "push3", parm3 }, /* version 9 */ { /*143*/ "push3", parm3 }, /* version 9 */
{144, "push3.s", parm3 }, /* version 9 */ { /*144*/ "push3.s", parm3 }, /* version 9 */
{145, "push3.adr", parm3 }, /* version 9 */ { /*145*/ "push3.adr", parm3 }, /* version 9 */
{146, "push4.c", parm4 }, /* version 9 */ { /*146*/ "push4.c", parm4 }, /* version 9 */
{147, "push4", parm4 }, /* version 9 */ { /*147*/ "push4", parm4 }, /* version 9 */
{148, "push4.s", parm4 }, /* version 9 */ { /*148*/ "push4.s", parm4 }, /* version 9 */
{149, "push4.adr", parm4 }, /* version 9 */ { /*149*/ "push4.adr", parm4 }, /* version 9 */
{150, "push5.c", parm5 }, /* version 9 */ { /*150*/ "push5.c", parm5 }, /* version 9 */
{151, "push5", parm5 }, /* version 9 */ { /*151*/ "push5", parm5 }, /* version 9 */
{152, "push5.s", parm5 }, /* version 9 */ { /*152*/ "push5.s", parm5 }, /* version 9 */
{153, "push5.adr", parm5 }, /* version 9 */ { /*153*/ "push5.adr", parm5 }, /* version 9 */
{154, "load.both", parm2 }, /* version 9 */ { /*154*/ "load.both", parm2 }, /* version 9 */
{155, "load.s.both",parm2 }, /* version 9 */ { /*155*/ "load.s.both",parm2 }, /* version 9 */
{156, "const", parm2 }, /* version 9 */ { /*156*/ "const", parm2 }, /* version 9 */
{157, "const.s", parm2 }, /* version 9 */ { /*157*/ "const.s", parm2 }, /* version 9 */
}; };
void print_opcode(FILE *ftxt,cell opcode,cell cip) void print_opcode(FILE *ftxt,cell opcode,cell cip)
{ {
fprintf(ftxt,"%08"PRIxC" %s", fprintf(ftxt,"%08"PRIxC" %s",cip,opcodelist[opcode].name);
cip,opcodelist[(int)(opcode &0x0000ffff)].name);
} }
void print_funcname(FILE *ftxt,cell address) void print_funcname(FILE *ftxt,cell address)
@ -354,14 +349,7 @@ cell do_sysreq(FILE *ftxt,const cell *params,cell opcode,cell cip)
return 2; return 2;
} }
cell do_switch(FILE *ftxt,const cell *params,cell opcode,cell cip) cell do_casetbl(FILE *ftxt,const cell *params,cell opcode,cell cip)
{
print_opcode(ftxt,opcode,cip);
fprintf(ftxt," %08"PRIxC"\n",*params);
return 2;
}
cell casetbl(FILE *ftxt,const cell *params,cell opcode,cell cip)
{ {
cell num; cell num;
int idx; int idx;
@ -375,18 +363,6 @@ cell casetbl(FILE *ftxt,const cell *params,cell opcode,cell cip)
return 2*num+1; return 2*num+1;
} }
cell do_file(FILE *ftxt,const cell *params,cell opcode,cell cip)
{
assert(0);
return 0;
}
cell do_symbol(FILE *ftxt,const cell *params,cell opcode,cell cip)
{
assert(0);
return 0;
}
static void expand(unsigned char *code,long codesize,long memsize) static void expand(unsigned char *code,long codesize,long memsize)
{ {
ucell c; ucell c;
@ -457,19 +433,21 @@ static void addchars(char *str,cell value,int pos)
int main(int argc,char *argv[]) int main(int argc,char *argv[])
{ {
char name[FILENAME_MAX]; char name[FILENAME_MAX];
FILE *fplist; FILE *fplist=NULL;
int codesize,count; int codesize,count;
cell *code,*cip; cell *code=NULL,*cip;
OPCODE_PROC func; OPCODE_PROC func;
const char *filename; const char *filename;
long nline,nprevline; long nline,nprevline;
FILE *fpsrc; FILE *fpsrc;
int i,j; int i,j;
char line[sLINEMAX]; char line[sLINEMAX];
int retval=1;
fpamx=NULL;
if (argc<2 || argc>3) { if (argc<2 || argc>3) {
printf("Usage: pawndisasm <input> [output]\n"); printf("Usage: pawndisasm <input> [output]\n");
return 1; goto ret;
} /* if */ } /* if */
if (argc==2) { if (argc==2) {
char *ptr; char *ptr;
@ -482,11 +460,11 @@ int main(int argc,char *argv[])
} /* if */ } /* if */
if ((fpamx=fopen(argv[1],"rb"))==NULL) { if ((fpamx=fopen(argv[1],"rb"))==NULL) {
printf("Unable to open input file \"%s\"\n",argv[1]); printf("Unable to open input file \"%s\"\n",argv[1]);
return 1; goto ret;
} /* if */ } /* if */
if ((fplist=fopen(name,"wt"))==NULL) { if ((fplist=fopen(name,"wt"))==NULL) {
printf("Unable to create output file \"%s\"\n",name); printf("Unable to create output file \"%s\"\n",name);
return 1; goto ret;
} /* if */ } /* if */
/* load debug info */ /* load debug info */
@ -497,28 +475,28 @@ int main(int argc,char *argv[])
if (fread(&amxhdr,sizeof amxhdr,1,fpamx)==0) { if (fread(&amxhdr,sizeof amxhdr,1,fpamx)==0) {
printf("Unable to read AMX header: %s\n", printf("Unable to read AMX header: %s\n",
feof(fpamx) ? "End of file reached" : strerror(errno)); feof(fpamx) ? "End of file reached" : strerror(errno));
return 1; goto ret;
} /* if */ } /* if */
if (amxhdr.magic!=AMX_MAGIC) { if (amxhdr.magic!=AMX_MAGIC) {
printf("Not a valid AMX file\n"); printf("Not a valid AMX file\n");
return 1; goto ret;
} /* if */ } /* if */
codesize=amxhdr.hea-amxhdr.cod; /* size for both code and data */ codesize=amxhdr.hea-amxhdr.cod; /* size for both code and data */
fprintf(fplist,";File version: %d\n",amxhdr.file_version); fprintf(fplist,";File version: %d\n",amxhdr.file_version);
fprintf(fplist,";Flags: "); fprintf(fplist,";Flags: ");
if ((amxhdr.flags & AMX_FLAG_COMPACT)!=0) if ((amxhdr.flags & AMX_FLAG_COMPACT)!=0)
fprintf(fplist,"compact-encoding "); fprintf(fplist," compact-encoding");
if ((amxhdr.flags & AMX_FLAG_DEBUG)!=0) if ((amxhdr.flags & AMX_FLAG_DEBUG)!=0)
fprintf(fplist,"debug-info "); fprintf(fplist," debug-info");
if ((amxhdr.flags & AMX_FLAG_NOCHECKS)!=0) if ((amxhdr.flags & AMX_FLAG_NOCHECKS)!=0)
fprintf(fplist,"no-checks "); fprintf(fplist," no-checks");
if ((amxhdr.flags & AMX_FLAG_SLEEP)!=0) if ((amxhdr.flags & AMX_FLAG_SLEEP)!=0)
fprintf(fplist,"sleep "); fprintf(fplist," sleep");
fprintf(fplist,"\n\n"); fprintf(fplist,"\n\n");
/* load the code block */ /* load the code block */
if ((code=malloc(codesize))==NULL) { if ((code=malloc(codesize))==NULL) {
printf("Insufficient memory: need %d bytes\n",codesize); printf("Insufficient memory: need %d bytes\n",codesize);
return 1; goto ret;
} /* if */ } /* if */
/* read and expand the file */ /* read and expand the file */
@ -526,7 +504,7 @@ int main(int argc,char *argv[])
if ((int32_t)fread(code,1,codesize,fpamx)<amxhdr.size-amxhdr.cod) { if ((int32_t)fread(code,1,codesize,fpamx)<amxhdr.size-amxhdr.cod) {
printf("Unable to read code: %s\n", printf("Unable to read code: %s\n",
feof(fpamx) ? "End of file reached" : strerror(errno)); feof(fpamx) ? "End of file reached" : strerror(errno));
return 1; goto ret;
} /* if */ } /* if */
if ((amxhdr.flags & AMX_FLAG_COMPACT)!=0) if ((amxhdr.flags & AMX_FLAG_COMPACT)!=0)
expand((unsigned char *)code,amxhdr.size-amxhdr.cod,amxhdr.hea-amxhdr.cod); expand((unsigned char *)code,amxhdr.size-amxhdr.cod,amxhdr.hea-amxhdr.cod);
@ -565,8 +543,13 @@ int main(int argc,char *argv[])
nprevline=nline; nprevline=nline;
} /* if */ } /* if */
} /* if */ } /* if */
func=opcodelist[(int)(*cip&0x0000ffff)].func; if (*(ucell *)cip>=(ucell)(sizeof opcodelist/sizeof opcodelist[0])
cip+=func(fplist,cip+1,*cip,(cell)(cip-code)*sizeof(cell)); || (func=opcodelist[*cip].func)==NULL) {
printf("Invalid opcode %08"PRIxC" at address %08"PRIxC"\n",
*cip, (cell)((unsigned char *)cip-(unsigned char *)code));
goto ret;
} /* if */
cip+=func(fplist,cip+1,*cip,(cell)((unsigned char *)cip-(unsigned char *)code));
} /* while */ } /* while */
/* dump the data section too */ /* dump the data section too */
@ -597,8 +580,12 @@ int main(int argc,char *argv[])
dbg_FreeInfo(&amxdbg); dbg_FreeInfo(&amxdbg);
} /* if */ } /* if */
retval=0;
ret:
free(code); free(code);
fclose(fpamx); if (fpamx!=NULL)
fclose(fplist); fclose(fpamx);
return 0; if (fplist!=NULL)
fclose(fplist);
return retval;
} }