00001 static char *sccsid = "@(#) dismain.c, Ver. 2.1 created 00:00:00 87/09/01";
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "dis.h"
00033
00034 extern char *release;
00035 static char *IFILE = NULL;
00036 static char *OFILE = NULL;
00037 static char *PRG;
00038 static unsigned long zcount;
00039 int objflg = 0;
00040
00041 #define unix 1
00042 #define i8086 1
00043 #define ibmpc 1
00044
00045 #if unix && i8086 && ibmpc
00046 static int cpuid = 1;
00047 #else
00048 static int cpuid = 0;
00049 #endif
00050
00051 _PROTOTYPE(static void usage, (char *s ));
00052 _PROTOTYPE(static void fatal, (char *s, char *t ));
00053 _PROTOTYPE(static void zdump, (unsigned long beg ));
00054 _PROTOTYPE(static void prolog, (void));
00055 _PROTOTYPE(static void distext, (void));
00056 _PROTOTYPE(static void disdata, (void));
00057 _PROTOTYPE(static void disbss, (void));
00058
00059 _PROTOTYPE(static char *invoker, (char *s));
00060 _PROTOTYPE(static int objdump, (char *c));
00061 _PROTOTYPE(static char *getlab, (int type));
00062 _PROTOTYPE(static void prolog, (void));
00063
00064
00065
00066 static void
00067 usage(s)
00068 register char *s;
00069 {
00070 fprintf(stderr,"Usage: %s [-o] ifile [ofile]\n",s);
00071 exit(-1);
00072 }
00073
00074 static void
00075 fatal(s,t)
00076 register char *s, *t;
00077 {
00078 fprintf(stderr,"\07%s: %s\n",s,t);
00079 exit(-1);
00080 }
00081
00082 static void
00083 zdump(beg)
00084 unsigned long beg;
00085 {
00086 beg = PC - beg;
00087 if (beg > 1L)
00088 printf("\t.zerow\t%ld\n",(beg >> 1));
00089 if (beg & 1L)
00090 printf("\t.byte\t0\n");
00091 }
00092
00093 static char *
00094 invoker(s)
00095 register char *s;
00096 {
00097 register int k;
00098
00099 k = strlen(s);
00100
00101 while (k--)
00102 if (s[k] == '/')
00103 {
00104 s += k;
00105 ++s;
00106 break;
00107 }
00108
00109 return (s);
00110 }
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 static int
00131 objdump(c)
00132
00133 register char *c;
00134
00135 {
00136
00137 register int k;
00138 int retval = 0;
00139
00140 if (objptr == OBJMAX)
00141 {
00142 for (k = 0; k < OBJMAX; ++k)
00143 if (objbuf[k])
00144 break;
00145 if (k == OBJMAX)
00146 {
00147 zcount += k;
00148 objptr = 0;
00149 if (c == NULL)
00150 return (retval);
00151 }
00152 }
00153
00154 if (zcount)
00155 {
00156 printf("\t.zerow\t%ld\n",(zcount >> 1));
00157 ++retval;
00158 zcount = 0L;
00159 }
00160
00161 if (objptr)
00162 {
00163 printf("\t.byte\t");
00164 ++retval;
00165 }
00166 else
00167 return (retval);
00168
00169 for (k = 0; k < objptr; ++k)
00170 {
00171 printf("0x%02.2x",objbuf[k]);
00172 if (k < (objptr - 1))
00173 putchar(',');
00174 else
00175 putchar('\n');
00176 }
00177
00178 objptr = 0;
00179
00180 return (retval);
00181
00182 }
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 static char *
00198 getlab(type)
00199 register int type;
00200 {
00201
00202 register int k;
00203 static char b[32], c[10];
00204
00205 if (symptr < 0)
00206 if ((type == N_TEXT)
00207 || ((type == N_DATA) && ( ! objptr ) && ( ! zcount )))
00208 {
00209 if (type == N_TEXT)
00210 sprintf(b,"T%05.5lx:",PC);
00211 else
00212 sprintf(b,"D%05.5lx:",PC);
00213 return (b);
00214 }
00215 else
00216 return (NULL);
00217
00218 for (k = 0; k <= symptr; ++k)
00219 if ((symtab[k].n_value == PC)
00220 && ((symtab[k].n_sclass & N_SECT) == type))
00221 {
00222 sprintf(b,"%s:\n",getnam(k));
00223 if (objflg && (type != N_TEXT))
00224 sprintf(c,"| %05.5lx\n",PC);
00225 strcat(b,c);
00226 return (b);
00227 }
00228
00229 return (NULL);
00230
00231 }
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241 static void
00242 prolog()
00243
00244 {
00245
00246 register int j, flag;
00247
00248 if (symptr < 0)
00249 return;
00250
00251 for (j = flag = 0; j <= symptr; ++j)
00252 if ((symtab[j].n_sclass & N_CLASS) == C_EXT)
00253 if (((symtab[j].n_sclass & N_SECT) > N_UNDF)
00254 && ((symtab[j].n_sclass & N_SECT) < N_COMM))
00255 {
00256 char *c = getnam(j);
00257 printf("\t.globl\t%s",c);
00258 if (++flag == 1)
00259 {
00260 putchar('\t');
00261 if (strlen(c) < 8)
00262 putchar('\t');
00263 printf("| Internal global\n");
00264 }
00265 else
00266 putchar('\n');
00267 }
00268 else
00269 if (symtab[j].n_value)
00270 {
00271 char *c = getnam(j);
00272 printf("\t.comm\t%s,0x%08.8lx",c,
00273 symtab[j].n_value);
00274 if (++flag == 1)
00275 printf("\t| Internal global\n");
00276 else
00277 putchar('\n');
00278 }
00279
00280 if (flag)
00281 putchar('\n');
00282
00283 for (j = flag = 0; j <= relptr; ++j)
00284 if (relo[j].r_symndx < S_BSS)
00285 {
00286 char *c = getnam(relo[j].r_symndx);
00287 ++flag;
00288 printf("\t.globl\t%s",c);
00289 putchar('\t');
00290 if (strlen(c) < 8)
00291 putchar('\t');
00292 printf("| Undef: %05.5lx\n",relo[j].r_vaddr);
00293 }
00294
00295 if (flag)
00296 putchar('\n');
00297
00298 for (j = flag = 0; j <= symptr; ++j)
00299 if ((symtab[j].n_sclass & N_SECT) == N_ABS)
00300 {
00301 char *c = getnam(j);
00302 printf("%s=0x%08.8lx",c,symtab[j].n_value);
00303 if (++flag == 1)
00304 {
00305 printf("\t\t");
00306 if (strlen(c) < 5)
00307 putchar('\t');
00308 printf("| Literal\n");
00309 }
00310 else
00311 putchar('\n');
00312 }
00313
00314 if (flag)
00315 putchar('\n');
00316
00317 }
00318
00319
00320
00321
00322
00323
00324
00325
00326 static void
00327 distext()
00328
00329 {
00330
00331 char *c;
00332 register int j;
00333 register void (*f)();
00334
00335 for (j = 0; j < (int)(HDR.a_hdrlen); ++j)
00336 getchar();
00337
00338 printf("| %s, %s\n\n",PRG,release);
00339
00340 printf("| @(");
00341
00342 printf("#)\tDisassembly of %s",IFILE);
00343
00344 if (symptr < 0)
00345 printf(" (no symbols)\n\n");
00346 else
00347 printf("\n\n");
00348
00349 if (HDR.a_flags & A_EXEC)
00350 printf("| File is executable\n\n");
00351
00352 if (HDR.a_flags & A_SEP)
00353 {
00354 printf("| File has split I/D space, and may have\n");
00355 printf("| extraneous instructions in text segment\n\n");
00356 }
00357
00358 prolog();
00359
00360 printf("\t.text\t\t\t| loc = %05.5lx, size = %05.5lx\n\n",
00361 PC,HDR.a_text);
00362
00363 segflg = 0;
00364
00365 for (PC = 0L; PC < HDR.a_text; ++PC)
00366 {
00367 j = getchar() & 0xff;
00368 if ((j == 0) && ((PC + 1L) == HDR.a_text))
00369 {
00370 ++PC;
00371 break;
00372 }
00373 if ((c = getlab(N_TEXT)) != NULL)
00374 printf("%s",c);
00375 f = optab[j].func;
00376 (*f)(j);
00377 }
00378
00379 }
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400 static void
00401 disdata()
00402
00403 {
00404
00405 register char *c;
00406 register int j;
00407 unsigned long end;
00408
00409 putchar('\n');
00410
00411 if (HDR.a_flags & A_SEP)
00412 {
00413 PC = 0L;
00414 end = HDR.a_data;
00415 }
00416 else
00417 end = HDR.a_text + HDR.a_data;
00418
00419 printf("\t.data\t\t\t| loc = %05.5lx, size = %05.5lx\n\n",
00420 PC,HDR.a_data);
00421
00422 segflg = 0;
00423
00424 for (objptr = 0, zcount = 0L; PC < end; ++PC)
00425 {
00426 if ((c = getlab(N_DATA)) != NULL)
00427 {
00428 objdump(c);
00429 printf("%s",c);
00430 }
00431 if (objptr >= OBJMAX)
00432 if (objdump(NULL) && (symptr < 0))
00433 printf("D%05.5lx:",PC);
00434 j = getchar() & 0xff;
00435 objbuf[objptr++] = j;
00436 }
00437
00438 objdump("");
00439
00440 }
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450 static void disbss()
00451
00452 {
00453
00454 register int j;
00455 register char *c;
00456 unsigned long beg, end;
00457
00458 putchar('\n');
00459
00460 if (HDR.a_flags & A_SEP)
00461 end = HDR.a_data + HDR.a_bss;
00462 else
00463 end = HDR.a_text + HDR.a_data + HDR.a_bss;
00464
00465 printf("\t.bss\t\t\t| loc = %05.5lx, size = %05.5lx\n\n",
00466 PC,HDR.a_bss);
00467
00468 segflg = 0;
00469
00470 for (beg = PC; PC < end; ++PC)
00471 if ((c = getlab(N_BSS)) != NULL)
00472 {
00473 if (PC > beg)
00474 {
00475 zdump(beg);
00476 beg = PC;
00477 }
00478 printf("%s",c);
00479 }
00480
00481 if (PC > beg)
00482 zdump(beg);
00483
00484 }
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498 void
00499 main(argc,argv)
00500
00501 int argc;
00502 register char **argv;
00503
00504 {
00505
00506 char a[1024];
00507 register int fd;
00508 long taboff, tabnum;
00509 long reloff, relnum;
00510
00511 PRG = invoker(*argv);
00512
00513 while (*++argv != NULL)
00514 if (**argv == '-')
00515 switch (*++*argv)
00516 {
00517 case 'o' :
00518 if (*++*argv)
00519 usage(PRG);
00520 else
00521 ++objflg;
00522 break;
00523 default :
00524 usage(PRG);
00525 }
00526 else
00527 if (IFILE == NULL)
00528 IFILE = *argv;
00529 else if (OFILE == NULL)
00530 OFILE = *argv;
00531 else
00532 usage(PRG);
00533
00534 if (IFILE == NULL)
00535 usage(PRG);
00536 else
00537 if ((fd = open(IFILE,0)) < 0)
00538 {
00539 sprintf(a,"can't access input file %s",IFILE);
00540 fatal(PRG,a);
00541 }
00542
00543 if (OFILE != NULL)
00544 if (freopen(OFILE,"w",stdout) == NULL)
00545 {
00546 sprintf(a,"can't open output file %s",OFILE);
00547 fatal(PRG,a);
00548 }
00549
00550 if ( ! cpuid )
00551 fprintf(stderr,"\07%s: warning: host/cpu clash\n",PRG);
00552
00553 read(fd, (char *) &HDR,sizeof(struct exec));
00554
00555 if (BADMAG(HDR))
00556 {
00557 sprintf(a,"input file %s not in object format",IFILE);
00558 fatal(PRG,a);
00559 }
00560
00561 if (HDR.a_cpu != A_I8086)
00562 {
00563 sprintf(a,"%s is not an 8086/8088 object file",IFILE);
00564 fatal(PRG,a);
00565 }
00566
00567 if (HDR.a_hdrlen <= A_MINHDR)
00568 HDR.a_trsize = HDR.a_drsize = 0L;
00569 HDR.a_tbase = HDR.a_dbase = 0L;
00570
00571
00572
00573
00574 reloff = HDR.a_text
00575 + HDR.a_data
00576 + (long)(HDR.a_hdrlen);
00577
00578 relnum =
00579 (HDR.a_trsize + HDR.a_drsize) / sizeof(struct reloc);
00580
00581 taboff = reloff
00582 + HDR.a_trsize
00583 + HDR.a_drsize;
00584
00585 tabnum = HDR.a_syms / sizeof(struct nlist);
00586
00587 if (relnum > MAXSYM)
00588 fatal(PRG,"reloc table overflow");
00589
00590 if (tabnum > MAXSYM)
00591 fatal(PRG,"symbol table overflow");
00592
00593 if (relnum)
00594 if (lseek(fd,reloff,0) != reloff)
00595 fatal(PRG,"lseek error");
00596 else
00597 {
00598 for (relptr = 0; relptr < relnum; ++relptr)
00599 read(fd, (char *) &relo[relptr],sizeof(struct reloc));
00600 relptr--;
00601 }
00602
00603 if (tabnum)
00604 if (lseek(fd,taboff,0) != taboff)
00605 fatal(PRG,"lseek error");
00606 else
00607 {
00608 for (symptr = 0; symptr < tabnum; ++symptr)
00609 read(fd, (char *) &symtab[symptr],sizeof(struct nlist));
00610 symptr--;
00611 }
00612 else
00613 fprintf(stderr,"\07%s: warning: no symbols\n",PRG);
00614
00615 close(fd);
00616
00617 if (freopen(IFILE,"r",stdin) == NULL)
00618 {
00619 sprintf(a,"can't reopen input file %s",IFILE);
00620 fatal(PRG,a);
00621 }
00622
00623 distext();
00624
00625 disdata();
00626
00627 disbss();
00628
00629 exit(0);
00630
00631 }