00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <string.h>
00004 #include "uctools.h"
00005
00006
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
00050
00051
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
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
00065 pdesc = NULL;
00066 }
00067
00068 nbytes = pdesc ? ( pdesc->nbytes + 1 ) : 1;
00069
00070 printf("%04X: ", coffset);
00071
00072 for( i = 0; i < nbytes; i++ )
00073 printf("%02X ", ptrc[i]);
00074
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
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
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
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
00127 printf("...");
00128 printf("\n");
00129 }
00130 break;
00131 case RELATIVE_JUMP:
00132
00133
00134 printf("\t%04X\n", *(short*)( ptrc + nbytes - 2) +
00135 coffset + nbytes);
00136
00137 break;
00138 case RELATIVE_JUMP32:
00139 printf("\t%04X\n", *(int*)( ptrc + nbytes - 4) +
00140 coffset + nbytes);
00141 break;
00142 case SLOOP:
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:
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:
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
00169 unsigned short func = *(unsigned short*)( ptrc + 1 );
00170 if( ( func < funsize ) &&
00171 func_table[func] )
00172
00173 printf("\t_%s@%d (%04X)\n", func_table[func], ptrc[3], func);
00174 else
00175
00176 printf("\t%04X, %d\n", func, ptrc[3]);
00177 }
00178 break;
00179 case EXTCALL:
00180 {
00181
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
00191 printf("\t[%04X]\n", *(unsigned short*)( ptrc + 1 ));
00192 break;
00193 case FLGREF:
00194
00195 printf("\tflag:[%04X]\n", *(unsigned short*)( ptrc + 1 ));
00196 break;
00197 default:
00198
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
00232 if( size < 3 * sizeof(unsigned short) )
00233 {
00234 printf("Code segment bad!\n");
00235 free(p);
00236 free(pdata);
00237 return;
00238 }
00239
00240 printf("\t\t.argc %04XH\n", *(unsigned short*)pp);
00241 pp += sizeof(unsigned short);
00242
00243 printf("\t\t.localc %04XH\n", *(unsigned short*)pp);
00244 pp += sizeof(unsigned short);
00245
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
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
00278
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
00288 off = ftell(f);
00289
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
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
00316 printdataseg(f, ds);
00317 printcodeseg(f, ds, s, func_table, funsize, extended);
00318 }
00319
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;
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
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;
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 }