wud.c

Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <string.h>
00004 #include "uctools.h"
00005 
00006 // Prints module's data segment
00007 void printdataseg(FILE* f, unsigned int ds)
00008 {
00009   long pos;
00010   unsigned int off = 0;
00011   unsigned char* p; unsigned char* pp;
00012   unsigned char* tempstr,*tempstr2;
00013   tempstr = malloc(60 + 1);
00014   pos = ftell(f);
00015   pp = p = malloc(ds);
00016   fread(p, 1, ds, f);
00017   fseek(f, pos, SEEK_SET);
00018   printf("\t\t.data\n");
00019   while( off < ds )
00020   {
00021     int len;
00022     unsigned int localoff = 0;
00023     while( (len = ( strlen(pp) > 60 ) ? 60 : strlen(pp)) )
00024     {
00025       memcpy(tempstr, pp, len);
00026       tempstr[len] = '\0';
00027       if (!localoff)
00028         printf("L%04X:",off);
00029         while (strchr(tempstr,13))
00030         {
00031          tempstr2=strchr(tempstr,13)+2;
00032          tempstr[strchr(tempstr,13) - (char *) tempstr]=0;
00033          printf("\tdb\t\'%s\'\n\tdb\t0d\n\tdb\t0a\n", tempstr);
00034          strcpy(tempstr,tempstr2);
00035         }
00036       if (tempstr)
00037         printf("\tdb\t\'%s\'\n", tempstr);
00038       localoff += len; 
00039       pp += len;
00040     }
00041     pp++;
00042     printf("L%04X:\tdb\t00\n", off+localoff);
00043     off += localoff + 1;
00044   }
00045   free(p);
00046   free(tempstr);
00047 }
00048 
00049 // Prints single opcode
00050 // Return number of bytes to advance the code pointer
00051 // Prints first characters of strings referenced
00052 unsigned int print_opcode(unsigned char* ptrc, unsigned int coffset,
00053   unsigned char* pdataseg,unsigned short* pextern,
00054   unsigned int externsize, const char **func_table, int funsize)
00055 {
00056   unsigned int nbytes;
00057   unsigned int i;
00058   // Find the description
00059   opcode_desc* pdesc = ( *ptrc >= ( sizeof(opcode_table) / sizeof( opcode_desc ) ) ) ?
00060               NULL : opcode_table + ( *ptrc );
00061   if( pdesc && ( pdesc->mnemonic == NULL ) )
00062   {
00063     printf("Unknown opcode: %x\n",*ptrc);
00064     // Unknown opcode
00065     pdesc = NULL;
00066   }
00067   // Number of bytes to print
00068   nbytes = pdesc ? ( pdesc->nbytes + 1 ) : 1;
00069   // Print label
00070   printf("%04X: ", coffset);
00071   // Print bytes
00072   for( i = 0; i < nbytes; i++ )
00073     printf("%02X ", ptrc[i]);
00074   // Print mnemonic
00075   if( nbytes < 4 )
00076     printf("\t");
00077         if (pdesc)
00078     printf("\t%s", pdesc->mnemonic);
00079   else
00080     printf("\tdb %x\t???",ptrc[0]);
00081   // Print operands if any
00082   if( ( nbytes == 1 ) || ( pdesc == NULL && pdesc->type == 0) )
00083   {
00084     printf("\n");
00085     return nbytes;
00086   }
00087   switch( pdesc->type )
00088   {
00089   case BYTE:
00090     printf("\t%x\n",*(unsigned char*)(ptrc+1));
00091     break;
00092   case PUSH:
00093     for ( i = 1; i < nbytes; i++)
00094       printf("\n%04X:\t\t\tdb %x",coffset+i,ptrc[i]);
00095     printf("\n");
00096     break;
00097   case IMMED:
00098     // Print immediate operand
00099     printf("\t%04XH\t\t\t; %d\n", *(unsigned short*)( ptrc + 1 ), *(short*)( ptrc + 1 ));
00100     break;
00101   case IMMED32:
00102     printf("\t%04XH\t\t\t; %d\n", *(unsigned int*)( ptrc + 1 ), *(int*)( ptrc + 1 ));
00103     break;
00104   case DATA_STRING:
00105   case DATA_STRING32:
00106     {
00107       unsigned char* pstr;
00108       int len;
00109       // Print data string operand
00110       if (pdesc->type == DATA_STRING)
00111         pstr = pdataseg + *(unsigned short*)( ptrc + 1 );
00112       else
00113         pstr = pdataseg + *(unsigned int*)( ptrc + 1 );
00114 
00115       len = strlen(pstr);
00116       if( len > 20 )
00117         len = 20 - 3;
00118 
00119       if (pdesc->type == DATA_STRING)
00120         printf("\tL%04X\t\t\t; ", *(unsigned short*)( ptrc + 1 ));
00121       else
00122         printf("\tL%04X\t\t\t; ", *(unsigned int*)( ptrc + 1 ));
00123       for( i = 0; i < len; i++ )
00124         printf("%c", pstr[i]);
00125       if( len < strlen(pstr) )
00126         // String truncated
00127         printf("...");
00128       printf("\n");
00129     }
00130     break;
00131   case RELATIVE_JUMP:
00132     // Print jump desination
00133 //    printf("\t%04X\n", *(short*)( ptrc + 1 ) + (short)coffset + 3);
00134     printf("\t%04X\n", *(short*)( ptrc + nbytes - 2) + 
00135         coffset + nbytes);
00136 // debugging printf("nbytes=%d, coffset=%d\n", nbytes, coffset);
00137     break;
00138   case RELATIVE_JUMP32:
00139     printf("\t%04X\n", *(int*)( ptrc + nbytes - 4) + 
00140           coffset + nbytes);
00141     break;
00142   case SLOOP:  /* WJP */
00143     printf("\t[%04X], [%04X], [%04X], [%04X], %04X\n", 
00144          *(unsigned short*)( ptrc + nbytes - 10 ),
00145          *(unsigned short*)( ptrc + nbytes - 8 ),
00146          *(unsigned short*)( ptrc + nbytes - 6 ),
00147          *(unsigned short*)( ptrc + nbytes - 4 ),
00148          *(short*)( ptrc + nbytes - 2) + coffset + nbytes);
00149     break;
00150   case SLOOP32:  /* WJP */
00151     printf("\t[%04X], [%04X], [%04X], [%04X], %04X\n", 
00152          *(unsigned short*)( ptrc + nbytes - 12 ),
00153          *(unsigned short*)( ptrc + nbytes - 10 ),
00154          *(unsigned short*)( ptrc + nbytes - 8 ),
00155          *(unsigned short*)( ptrc + nbytes - 6 ),
00156          *(int*)( ptrc + nbytes - 4) + coffset + nbytes);
00157     break;
00158   case IMMED_AND_RELATIVE_JUMP: /* JSF */
00159     printf("\t%04XH, %04X\n", *(unsigned short*)( ptrc + 1 ),
00160         *(short*)( ptrc + 3 ) + coffset + 5);
00161     break;
00162   case IMMED_RELJUMP32:
00163     printf("\t%04XH, %04X\n", *(unsigned short*)( ptrc + 1 ),
00164         *(int*)( ptrc + 3 ) + coffset + 5);
00165     break;
00166   case CALL:
00167     {
00168       // Print call operand
00169       unsigned short func = *(unsigned short*)( ptrc + 1 );
00170       if( ( func < funsize ) &&
00171          func_table[func] )
00172         // Known function
00173         printf("\t_%s@%d (%04X)\n", func_table[func], ptrc[3], func);
00174       else
00175         // Unknown function
00176         printf("\t%04X, %d\n", func, ptrc[3]);
00177     }
00178     break;
00179   case EXTCALL:
00180     {
00181       // Print extern call
00182       unsigned short externpos = *(unsigned short*)( ptrc + 1 );
00183       if( externpos < externsize )
00184         printf("\t[%04X]\t\t\t; %04XH\n", externpos, pextern[externpos]);
00185       else
00186         printf("\t[%04X]\t\t\t; ????\n", externpos);
00187     }
00188     break;
00189   case VARREF:
00190     // Print variable reference
00191     printf("\t[%04X]\n", *(unsigned short*)( ptrc + 1 ));
00192     break;
00193   case FLGREF:
00194     // Print global flag reference
00195     printf("\tflag:[%04X]\n", *(unsigned short*)( ptrc + 1 ));
00196     break;
00197   default:
00198     // Unknown type
00199     printf("\n");
00200     break;
00201   }
00202   return nbytes;
00203 }
00204 
00205 void printcodeseg(FILE* f, unsigned int ds, unsigned int s,
00206         const char **func_table, int funsize, int extended)
00207 {
00208   long pos;
00209   unsigned int size;
00210   unsigned int externsize;
00211   unsigned int i;
00212   unsigned int offset;
00213   unsigned int nbytes;
00214   unsigned char* p;
00215   unsigned char* pp;
00216   unsigned char* pdata;
00217   unsigned short* pextern;
00218   pos = ftell(f);
00219   if (extended == 0) {
00220     size = s - ds - sizeof(unsigned short);
00221   } else {
00222     size = s - ds - sizeof(unsigned int);
00223   }
00224 
00225   pp = p = malloc(size);
00226   pdata = malloc(ds);
00227   fread(pdata, 1, ds, f);
00228   printf("\t\t.code\n");
00229   fread(p, 1, size, f);
00230   fseek(f, pos, SEEK_SET);
00231   // Print code segment header
00232   if( size < 3 * sizeof(unsigned short) )
00233   {
00234     printf("Code segment bad!\n");
00235     free(p);
00236     free(pdata);
00237     return;
00238   }
00239   // Print argument counter
00240   printf("\t\t.argc %04XH\n", *(unsigned short*)pp);
00241   pp += sizeof(unsigned short);
00242   // Print locals counter
00243   printf("\t\t.localc %04XH\n", *(unsigned short*)pp);
00244   pp += sizeof(unsigned short);
00245   // Print externs section
00246   externsize = *(unsigned short*)pp;
00247   printf("\t\t.externsize %04XH\n", externsize);
00248   pp += sizeof(unsigned short);
00249   if( size < ( ( 3 + externsize ) * sizeof(unsigned short) ) )
00250   {
00251     printf("Code segment bad!\n");
00252     free(p);
00253     free(pdata);
00254     return;
00255   }
00256   size -= ( ( 3 + externsize ) * sizeof(unsigned short) );
00257   pextern = (unsigned short*)pp;
00258   for( i = 0; i < externsize; i++ )
00259   {
00260     printf("\t\t.extern %04XH\n", *(unsigned short*)pp);
00261     pp += sizeof(unsigned short);
00262   }
00263   offset = 0;
00264   // Print opcodes
00265   while( offset < size )
00266   {
00267     nbytes = print_opcode(pp, offset, pdata, pextern, externsize,
00268             func_table, funsize);
00269     pp += nbytes;
00270     offset += nbytes;
00271   }
00272   free(p);
00273   free(pdata);
00274 }
00275 
00276 /*
00277  *  Note:  func = -1 just to print header, funcnum to print it all, or
00278  *    -2 for any function.
00279  */
00280 void printfunc(FILE* f, long func, int i, const char **func_table, int funsize)
00281 {
00282   unsigned short funcnum;
00283   unsigned int s, ds; 
00284   unsigned short temp;
00285   long off, bodyoff;
00286   int extended = 0;
00287   // Save start offset
00288   off = ftell(f);
00289   // Read function header
00290   fread(&funcnum, sizeof(unsigned short), 1, f);
00291 
00292   if (funcnum == 0xFFFF) {
00293     fread(&funcnum, sizeof(unsigned short), 1, f);
00294     fread(&s, 4, 1, f);
00295     bodyoff = ftell(f);
00296     fread(&ds, 4, 1, f); 
00297     extended = 1;
00298   } else {
00299     fread(&temp, sizeof(unsigned short), 1, f);
00300     s = temp;
00301     // Save body offset
00302     bodyoff = ftell(f);
00303     fread(&temp, sizeof(unsigned short), 1, f);
00304     ds = temp;
00305   }
00306 
00307   if( func == -1 )
00308     printf("\tFunction #%d (%04XH), offset = %08lx, size = %04x, data = %04x\n", i,
00309       funcnum, off, s, ds);
00310   if( funcnum == func || func == -2)
00311   {
00312     printf("\t\t.funcnumber\t%04XH\n", funcnum);
00313     if (extended == 1)
00314       printf("\t\t.ext32\n");
00315     // Dump function contents
00316     printdataseg(f, ds);
00317     printcodeseg(f, ds, s, func_table, funsize, extended);
00318   }
00319   // Seek back, then to next function
00320   fseek(f, bodyoff, SEEK_SET);
00321   fseek(f, s, SEEK_CUR);
00322 }
00323 
00324 int main(int argc, char** argv)
00325 {
00326   unsigned long func = -1;
00327   long sz;
00328   int i = 0;
00329   FILE* f;
00330   int findex = 1;     // Argv index of file.
00331   const char **func_table = bg_intrinsic_table;
00332   int funsize = bg_intrinsic_size;
00333 
00334 
00335   if(argc<2) {
00336     fprintf(stderr, "Usage\n%s [-s] usecode_file [func_num]\n", argv[0]);
00337     return -1;
00338   }
00339           // Serpent Isle?
00340   if (strcmp(argv[1], "-s") == 0)
00341     {
00342     findex++;
00343     func_table = si_intrinsic_table;
00344     funsize = si_intrinsic_size;
00345     }
00346   f = fopen(argv[findex], "rb");
00347   if( f == NULL )
00348   {
00349     fprintf(stderr,"Failed to open %s\n\n", argv[findex]);
00350     return 0;
00351   }
00352   fseek(f, 0, SEEK_END);
00353   sz = ftell(f);
00354   fseek(f, 0, SEEK_SET);
00355   if( argc > findex + 1 )
00356   {
00357     char* stopstr;
00358     if (strcmp(argv[findex + 1], "-a") == 0)
00359       func = -2;  // Print ALL functions.
00360     else
00361       func = strtoul(argv[findex + 1], &stopstr, 16);
00362   }
00363   while( ftell(f) < sz )
00364   {   
00365     printfunc(f, func, i, func_table, funsize);
00366     i++;
00367   }
00368   if( func == -1 )
00369   {
00370     if( ftell(f) != sz )
00371       fprintf(stderr,"Problem, tell = %ld!\n", ftell(f));
00372     printf("Functions: %d\n", i);
00373   }
00374   fclose(f);
00375   return 0;
00376 }

Generated on Mon Jul 9 14:42:51 2007 for ExultEngine by  doxygen 1.5.1