home *** CD-ROM | disk | FTP | other *** search
- /* OBJSCN.C - jk - 12/01/86 (rev 01/05/86)
- *
- * This program scans Microsoft MSDOS .OBJ files and reports the
- * various types of records contained within them. With simple
- * changes, it will report all content of each file.
- *
- * Added 04-Jan-87 07:22 CST by Daniel Cerutti [76267,426]:
- * Additional code to handle comment records class used by the linker.
- * I have included support for the dynamic link records used by
- * the DOS 4 / Windows linker (was documented in the material from
- * the Microsoft Windows developer's conference).
- */
- #include "stdio.h"
-
- FILE * fopen (), * Inf;
-
- int Chr, Siz, Ni = 1, Ti = 1, Gi = 1, Si = 1, Pi = 1, Ei = 1;
-
- char * donam (), * Name [ 100 ], * Type [ 10 ], * Grp [ 10 ],
- * Seg [ 50 ], * Pub [ 100 ], * Ext [ 100 ];
-
- main ( argc, argv ) int argc ; char * argv [];
- { fprintf ( stderr, "\nOBJSCN Version 1.01 - 01-05-87\n" );
- Name [ 0 ] = Type [ 0 ] = Grp [ 0 ] = Seg [ 0 ] =
- Pub [ 0 ] = Ext [ 0 ] = "none";
- if ( ! -- argc )
- { fprintf ( stderr, "\t USAGE: OBJSCN file1 file2 ...\n" );
- fprintf ( stderr, "\t\toutput, to stdout, may be redirected.\n" );
- }
- else
- while ( argc -- )
- { if ( Inf = fopen ( * ++ argv, "rb" ))
- { printf ( "\nFILE: %s\n", * argv );
- dofile ();
- printf ( "\n EOF: %s\n", * argv );
- fclose ( Inf );
- }
- else
- fprintf ( stderr, "FILE <%s> could not be opened\n", * argv );
- }
- exit ( 0 );
- }
-
- dofile ()
- { int n, gi, si;
- while (( Chr = getch ()) != EOF )
- { if ( Chr && ( Siz = getwd ()) > 0 ) /* skip over null fill */
- { switch ( Chr )
- {
- case 0x80 : /* THEADR */
- Ni = Ti = Gi = Si = Pi = Ei = 1;
- printf ( "\nHEADER\t\"" );
- n = getch ();
- while ( n -- )
- printf ( "%c", getch ());
- printf ( "\"\n\t" );
- docks ();
- continue;
-
- /*----- Modification in function dofile () by DC */
-
- case 0x88 : /* COMENT */
- docoment ();
- continue;
-
- case 0xf0 : /* MS-Library header */
- domslibhd ();
- continue;
-
- /*----- End DC modification */
-
- case 0x8A : /* ENDMOD */
- printf ( "MODEND\t" );
- break;
-
- case 0x8C : /* EXTDEF */
- doext ();
- continue;
-
- case 0x8E : /* TYPDEF */
- printf ( "TYPDEF\t" );
- break;
-
- case 0x90 : /* PUBDEF */
- printf ( "PUBDEF\t" );
- gi = getch ();
- si = getch ();
- if ( gi | si )
- printf ( "Group %d; Segment %s\n ", gi, Seg[si]);
- else
- printf ( "Frm %d\n ", getwd());
- while ( Siz > 1 )
- { printf ( "Pub %d\t", Pi );
- Pub [ Pi ] = donam ();
- n = getwd ();
- printf ( "\"%s\" at offset %04x, ", Pub [ Pi ++ ], n);
- printf ( "Type=%s\n\t", Type [ getch ()]);
- }
- docks ();
- continue;
-
- case 0x94 : /* LINNUM */
- printf ( "LINNUM\t" );
- break;
-
- case 0x96 : /* LNAMES */
- printf ( "LNAMES\t" );
- while ( Siz > 1 )
- { printf ( "Name %d\t\"", Ni );
- Name [ Ni ] = donam ();
- printf ( "%s\"\n\t", Name [ Ni ++ ]);
- }
- docks ();
- continue;
-
- case 0x98 : /* SEGDEF */
- printf ( "SEGDEF\t" );
- while ( Siz > 1 )
- segdef ();
- docks ();
- continue;
-
- case 0x9A : /* GRPDEF */
- printf ( "GRPDEF\t" );
- break;
-
- case 0x9C : /* FIXUPP */
- printf ( "FIXUPP\t" );
- while ( Siz > 1 )
- fixupp ();
- docks ();
- continue;
-
- case 0xA0 : /* LEDATA */
- dodat ( "LEDATA" );
- continue;
-
- case 0xA2 : /* LIDATA */
- dodat ( "LIDATA" );
- continue;
-
- default :
- printf ( "%02x\t%3d: ", Chr, Siz );
- break;
- }
- while ( Siz )
- printf ( "%02x ", getch ());
- printf ( "\n" );
- }
- }
- }
-
- doext ()
- { printf ( "EXTDEF\t" );
- while ( Siz > 1 )
- { printf ( "Ext %2d\t", Ei );
- Ext [ Ei ] = donam ();
- printf ( "%-16sType=%s\n\t", Ext [ Ei ++ ], Type [ getch ()]);
- }
- docks ();
- }
-
- fixupp ()
- { int ofs, ft, f1, t1, t2;
- char * x, * y;
- ofs = getch () << 8;
- ft = f1 = t1 = t2 = 0;
- switch ( ofs & 0xe000 )
- {
- case 0x0000 : /* 0 0 0 - target thread, D=0 */
- x = "TgtTHD";
- break;
-
- case 0x4000 : /* 0 1 0 - frame thread, D=1 */
- x = "FrmTHD";
- break;
-
- case 0x8000 : /* 1 0 0 - explicit, mode=0 */
- x = "SEGX";
- break;
-
- case 0xc000 : /* 1 1 0 - explicit, mode=1 */
- x = "SELFX";
- break;
-
- default : /* x x 1 - undefined */
- x = " ";
- sprintf ( x, "X=%02x", ( ofs >> 13 ) & 7 );
- break;
- }
- if ( ofs & 0x8000 ) /* explicit, decode LOC and OFS */
- { ofs += getch (); /* offset completion */
- ft = getch (); /* frame-tgt coding byte */
- switch ( ofs & 0x1c00 ) /* decode LOC */
- {
- case 0x0000 :
- y = "LOW ";
- break;
-
- case 0x0400 :
- y = "OFS ";
- break;
-
- case 0x0800 :
- y = "BASE";
- break;
-
- case 0x0c00 :
- y = "PTR ";
- break;
-
- case 0x1000 :
- y = "HIGH";
- break;
-
- default :
- y = " ";
- sprintf ( y, "Y=%02x", ( ofs >> 10 ) & 7 );
- break;
- }
- if ( ! ( ft & 0x80 )
- && ( ft & 0xF0 ) < 0x30 ) /* F=0, explicit, F1/2/3 */
- f1 = getch (); /* frame index */
- else
- f1 = 7 & ( ft >> 4 );
- if ( ! ( ft & 0x08 )) /* T=0, explicit */
- t1 = getch (); /* target index */
- else
- t1 = ft & 7;
- printf ( "%s %s ofs=%04x F%x fi=%02x T%x ti=%02x", x, y, ofs & 0x3ff, ft >> 4, f1, ft & 15, t1 );
- if ( ! ( ft & 4 )) /* P=0, primary (offset) */
- { t2 = getwd (); /* target offset */
- printf ( " tos=%04x", t2 );
- }
- printf ( "\n\t" );
- }
- else /* thread, decode METHOD, THRED, INDEX */
- {
- switch ( ofs & 0x5c00 ) /* decode METHOD */
- {
- case 0x0000 : /* t0 seg+offset */
-
- case 0x4000 : /* f0 seg */
-
- case 0x1000 : /* t4 seg */
- y = "SEG ";
- t1 = getch (); /* target index */
- break;
-
- case 0x0400 : /* t1 grp+offset */
-
- case 0x4400 : /* f1 grp */
-
- case 0x1400 : /* t5 grp */
- y = "GRP ";
- t1 = getch (); /* target index */
- break;
-
- case 0x0800 : /* t2 ext+offset */
-
- case 0x4800 : /* f2 ext */
-
- case 0x1800 : /* t6 ext */
- y = "EXT ";
- t1 = getch (); /* target index */
- break;
-
- case 0x0c00 : /* t3 frm+offset */
-
- case 0x4c00 : /* f3 frm (no ndx) */
-
- case 0x1c00 : /* t7 frm (no ndx) */
- y = "FRM ";
- break;
-
- case 0x5000 : /* f4 calc (no ndx) */
- y = "CALC";
- break;
-
- case 0x5400 : /* f5 same (no ndx) */
- y = "SAME";
- break;
-
- case 0x5800 : /* f n/a */
-
- case 0x5c00 : /* f n/a */
- y = "BAD ";
- break;
- }
- printf ( "%s Nbr %d, %sIndex=%02x\tMethod %02x\n\t",
- x, ( ofs >> 8 ) & 3, y, t1, ( ofs >> 10 ));
- }
- }
-
- docks () /* output checksum byte */
- { printf ( "Checksum=%02x\n", getch ());
- }
-
- dodat ( t ) char * t; /* dump a data record */
- { int n ,
- adr;
- n = getch (); /* segment index */
- adr = getwd (); /* starting address */
- printf ( "%s\tLen=%04x at %s:%04x\n\t", t, Siz - 1, Seg [ n ], adr );
- spcovr ( adr & 15 );
- while ( Siz > 1 )
- { if ( ! ( adr ++ & 15 ))
- printf ( "\n %04x: ", adr - 1 );
- printf ( adr & 7 ? "%02x " : "%02x ", getch ());
- }
- printf ( "\n\t" );
- docks ();
- }
-
- spcovr ( n ) int n; /* space over to data loc */
- { while ( n )
- { if ( n -- == 8 )
- printf ( " " );
- printf ( " " );
- }
- printf ( " " );
- }
-
- char * donam () /* copy name from record */
- { int n ;
- char * t, * t1;
- n = getch (); /* number of chars in name */
- t1 = t = alloc ( n + 1 ); /* get space for it */
- while ( n -- )
- * t ++ = getch (); /* save the name for use */
- * t = 0;
- return ( t1 );
- }
-
- segdef ()
- { int code ,
- len,
- ni,
- ci,
- oi;
- char * aline,
- * seg;
- code = getch (); /* read stuff from record */
- len = getwd ();
- ni = getch ();
- ci = getch ();
- oi = getch ();
- printf ( "Seg %d\t", Si );
- printf ( "%-16s", Seg [ Si ++ ] = Name [ ni ]);
- switch ( code & 0xe0 ) /* alignment */
- {
- case 0x00 : /* absolute */
- aline = "ABS ";
- break;
-
- case 0x20 : /* byte */
- aline = "BYTE";
- break;
-
- case 0x40 : /* word */
- aline = "WORD";
- break;
-
- case 0x60 : /* para */
- aline = "PARA";
- break;
-
- case 0x80 : /* page */
- aline = "PAGE";
- break;
-
- default : /* unknown */
- aline = "UNK ";
- break;
- }
- switch ( code & 0x1c ) /* segment class */
- {
- case 0x00 : /* private */
- seg = "PRIVAT";
- break;
-
- case 0x08 : /* public */
- seg = "PUBLIC";
- break;
-
- case 0x14 : /* stack */
- seg = "STACK ";
- break;
-
- case 0x18 : /* common */
- seg = "COMMON";
- break;
-
- default : /* other */
- seg = "UNKNWN";
- break;
- }
- printf ( "Sz=%04x %s %s ", len, seg, aline );
- printf ( "\'%s\'\tOvly: \"%s\"\n\t", Name [ ci ], Name [ oi ]);
- }
-
- domslibhd () /* added per DC 01/04/86 */
- {
- unsigned long idxpos;
- int idxsize;
-
- idxpos = (unsigned) getwd (); /* cast to prevent sign extension */
- idxpos |= (unsigned long) ((unsigned) getwd ()) << 16;
- idxsize = getwd ();
- printf ("MS-Library file - Index is at %lXh, %d block(s) of 512 bytes\n",
- idxpos, idxsize);
- while ( Siz )
- getch ();
- }
-
-
- docoment () /* added per DC 01/04/86 */
- { int class;
- int i;
-
- printf ( "COMENT\t" );
- getch (); /* comment type */
- switch ( class = getch () ) /* comment class */
- {
- case 0: /* Language translator comment */
- printf ("Compiler \"");
- while ( Siz > 1 )
- printf ( "%c", getch ());
- printf ("\"\n\t");
- docks ();
- break;
-
- case 159: /* default library search specification */
- printf ("DefLib\t\"");
- while ( Siz > 1 )
- printf ( "%c", getch ());
- printf ("\"\n\t");
- docks ();
- break;
-
- case 160: /* Dynamic link records (Import def)*/
- printf ("ImpDef\t"); /* for Windows/DOS 4 linker */
- getch ();
- i = getch ();
- printf ("\"%s\"\t", donam ()); /* Exported function name */
- printf ("\"%s\"", donam ()); /* Module name */
- if (i)
- printf (".%d", getwd ()); /* Function ordinal value */
- else
- getch (); /* skip a null */
- printf ("\n\t");
- docks ();
- break;
-
- default:
- printf ("Class=%d\n\t", class);
- while ( Siz )
- printf ( "%02x ", getch ());
- printf ("\n");
- break;
- }
- }
-
- getch () /* get byte from Inf, polling */
- { poll ();
- -- Siz;
- return ( getc ( Inf ));
- }
-
- getwd () /* get word from Inf, polling */
- { poll ();
- Siz -= 2;
- return ( getw ( Inf ));
- }
-
- poll ()
- { if ( bdos ( 6, 255 ) == 3 )
- exit ( 7 );
- }
-
- /*---if your library doesn't have this, remove the comment-out frame
- getw (f) FILE *f;
- { int x;
- x = EOF;
- fread(&x,2,f);
- return(x);
- }
- ---*/
-
- /* end of objscn.c */
-