home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 September / Simtel20_Sept92.cdr / msdos / pgmutl / objsc101.arc / OBJSCN.C next >
C/C++ Source or Header  |  1987-01-05  |  12KB  |  491 lines

  1. /* OBJSCN.C - jk - 12/01/86 (rev 01/05/86)
  2.  *
  3.  *    This program scans Microsoft MSDOS .OBJ files and reports the
  4.  *    various types of records contained within them. With simple
  5.  *    changes, it will report all content of each file.
  6.  *
  7.  *    Added 04-Jan-87 07:22 CST by Daniel Cerutti [76267,426]:
  8.  *    Additional code to handle comment records class used by the linker.
  9.  *    I have included support for the dynamic link records used by
  10.  *    the DOS 4 / Windows linker (was documented in the material from
  11.  *    the Microsoft Windows developer's conference).
  12.  */
  13. #include "stdio.h"
  14.  
  15. FILE * fopen (), * Inf;
  16.  
  17. int Chr, Siz, Ni = 1, Ti = 1, Gi = 1, Si = 1, Pi = 1, Ei = 1;
  18.  
  19. char * donam (), * Name [ 100 ], * Type [ 10 ], * Grp [ 10 ],
  20.      * Seg [ 50 ], * Pub [ 100 ], * Ext [ 100 ];
  21.  
  22. main ( argc, argv ) int argc ; char * argv [];
  23. { fprintf ( stderr, "\nOBJSCN Version 1.01 - 01-05-87\n" );
  24.   Name [ 0 ] = Type [ 0 ] = Grp [ 0 ] = Seg [ 0 ] =
  25.      Pub [ 0 ] = Ext [ 0 ] = "none";
  26.   if ( ! -- argc )
  27.     { fprintf ( stderr, "\t USAGE: OBJSCN file1 file2 ...\n" );
  28.       fprintf ( stderr, "\t\toutput, to stdout, may be redirected.\n" );
  29.     }
  30.   else
  31.     while ( argc -- )
  32.       {    if ( Inf = fopen ( * ++ argv, "rb" ))
  33.       { printf ( "\nFILE: %s\n", * argv );
  34.          dofile ();
  35.          printf ( "\n EOF: %s\n", * argv );
  36.          fclose ( Inf );
  37.       }
  38.      else
  39.        fprintf ( stderr, "FILE <%s> could not be opened\n", * argv );
  40.       }
  41.   exit ( 0 );
  42. }
  43.  
  44. dofile ()
  45. { int n, gi, si;
  46.   while (( Chr = getch ()) != EOF )
  47.     { if ( Chr && ( Siz = getwd ()) > 0 )    /* skip over null fill */
  48.     { switch ( Chr )
  49.         {
  50.         case 0x80 :            /* THEADR    */
  51.           Ni = Ti = Gi = Si = Pi = Ei = 1;
  52.            printf ( "\nHEADER\t\"" );
  53.            n = getch ();
  54.            while ( n -- )
  55.          printf ( "%c", getch ());
  56.            printf ( "\"\n\t" );
  57.            docks ();
  58.            continue;
  59.  
  60. /*----- Modification in function dofile () by DC */
  61.  
  62.         case 0x88 :         /* COMENT   */
  63.           docoment ();
  64.           continue;
  65.  
  66.         case 0xf0 :         /* MS-Library header */
  67.           domslibhd ();
  68.           continue;
  69.  
  70. /*----- End DC modification    */
  71.  
  72.          case 0x8A :            /* ENDMOD    */
  73.            printf ( "MODEND\t" );
  74.            break;
  75.  
  76.          case 0x8C :            /* EXTDEF    */
  77.            doext ();
  78.            continue;
  79.  
  80.          case 0x8E :            /* TYPDEF    */
  81.            printf ( "TYPDEF\t" );
  82.            break;
  83.  
  84.          case 0x90 :            /* PUBDEF    */
  85.            printf ( "PUBDEF\t" );
  86.           gi = getch ();
  87.           si = getch ();
  88.           if ( gi | si )
  89.          printf ( "Group %d; Segment %s\n   ", gi, Seg[si]);
  90.           else
  91.         printf ( "Frm %d\n   ", getwd());
  92.            while ( Siz > 1 )
  93.         { printf ( "Pub %d\t", Pi );
  94.            Pub [ Pi ] = donam ();
  95.           n = getwd ();
  96.            printf ( "\"%s\" at offset %04x, ", Pub [ Pi ++ ], n);
  97.            printf ( "Type=%s\n\t", Type [ getch ()]);
  98.         }
  99.            docks ();
  100.            continue;
  101.  
  102.          case 0x94 :            /* LINNUM    */
  103.            printf ( "LINNUM\t" );
  104.            break;
  105.  
  106.          case 0x96 :            /* LNAMES    */
  107.            printf ( "LNAMES\t" );
  108.            while ( Siz > 1 )
  109.         { printf ( "Name %d\t\"", Ni );
  110.            Name [ Ni ] = donam ();
  111.            printf ( "%s\"\n\t", Name [ Ni ++ ]);
  112.         }
  113.            docks ();
  114.            continue;
  115.  
  116.          case 0x98 :            /* SEGDEF    */
  117.            printf ( "SEGDEF\t" );
  118.            while ( Siz > 1 )
  119.          segdef ();
  120.            docks ();
  121.            continue;
  122.  
  123.          case 0x9A :            /* GRPDEF    */
  124.            printf ( "GRPDEF\t" );
  125.            break;
  126.  
  127.          case 0x9C :            /* FIXUPP    */
  128.            printf ( "FIXUPP\t" );
  129.            while ( Siz > 1 )
  130.          fixupp ();
  131.            docks ();
  132.            continue;
  133.  
  134.          case 0xA0 :            /* LEDATA    */
  135.            dodat ( "LEDATA" );
  136.            continue;
  137.  
  138.          case 0xA2 :            /* LIDATA    */
  139.            dodat ( "LIDATA" );
  140.            continue;
  141.  
  142.          default :
  143.            printf ( "%02x\t%3d: ", Chr, Siz );
  144.            break;
  145.         }
  146.        while ( Siz )
  147.          printf ( "%02x  ", getch ());
  148.        printf ( "\n" );
  149.     }
  150.     }
  151. }
  152.  
  153. doext ()
  154. { printf ( "EXTDEF\t" );
  155.   while ( Siz > 1 )
  156.     { printf ( "Ext %2d\t", Ei );
  157.       Ext [ Ei ] = donam ();
  158.       printf ( "%-16sType=%s\n\t", Ext [ Ei ++ ], Type [ getch ()]);
  159.     }
  160.   docks ();
  161. }
  162.  
  163. fixupp ()
  164. { int ofs, ft, f1, t1, t2;
  165.   char * x, * y;
  166.   ofs = getch () << 8;
  167.   ft = f1 = t1 = t2 = 0;
  168.   switch ( ofs & 0xe000 )
  169.     {
  170.     case 0x0000 :            /* 0 0 0 - target thread, D=0    */
  171.       x = "TgtTHD";
  172.       break;
  173.  
  174.     case 0x4000 :            /* 0 1 0 - frame thread, D=1    */
  175.       x = "FrmTHD";
  176.       break;
  177.  
  178.     case 0x8000 :            /* 1 0 0 - explicit, mode=0    */
  179.       x = "SEGX";
  180.       break;
  181.  
  182.     case 0xc000 :            /* 1 1 0 - explicit, mode=1    */
  183.       x = "SELFX";
  184.       break;
  185.  
  186.     default :                /* x x 1 - undefined    */
  187.       x = "    ";
  188.       sprintf ( x, "X=%02x", ( ofs >> 13 ) & 7 );
  189.       break;
  190.     }
  191.   if ( ofs & 0x8000 )            /* explicit, decode LOC and OFS    */
  192.     { ofs += getch ();            /*    offset completion    */
  193.       ft = getch ();            /*    frame-tgt coding byte    */
  194.       switch ( ofs & 0x1c00 )        /*    decode LOC        */
  195.     {
  196.     case 0x0000 :
  197.        y = "LOW ";
  198.        break;
  199.  
  200.      case 0x0400 :
  201.        y = "OFS ";
  202.        break;
  203.  
  204.      case 0x0800 :
  205.        y = "BASE";
  206.        break;
  207.  
  208.      case 0x0c00 :
  209.        y = "PTR ";
  210.        break;
  211.  
  212.      case 0x1000 :
  213.        y = "HIGH";
  214.        break;
  215.  
  216.      default :
  217.        y = "     ";
  218.        sprintf ( y, "Y=%02x", ( ofs >> 10 ) & 7 );
  219.        break;
  220.     }
  221.       if ( ! ( ft & 0x80 )
  222.         && ( ft & 0xF0 ) < 0x30 )    /* F=0, explicit, F1/2/3    */
  223.      f1 = getch ();            /* frame index */
  224.       else
  225.      f1 = 7 & ( ft >> 4 );
  226.       if ( ! ( ft & 0x08 ))        /* T=0, explicit        */
  227.      t1 = getch ();            /* target index */
  228.       else
  229.      t1 = ft & 7;
  230.       printf ( "%s %s ofs=%04x F%x fi=%02x T%x ti=%02x", x, y, ofs & 0x3ff, ft >> 4, f1, ft & 15, t1 );
  231.       if ( ! ( ft & 4 ))        /* P=0, primary (offset) */
  232.     { t2 = getwd ();        /* target offset */
  233.        printf ( " tos=%04x", t2 );
  234.     }
  235.       printf ( "\n\t" );
  236.     }
  237.   else                    /* thread, decode METHOD, THRED, INDEX    */
  238.     {
  239.       switch ( ofs & 0x5c00 )        /*    decode METHOD        */
  240.     {
  241.     case 0x0000 :            /* t0 seg+offset        */
  242.  
  243.      case 0x4000 :            /* f0 seg            */
  244.  
  245.      case 0x1000 :            /* t4 seg            */
  246.        y = "SEG ";
  247.        t1 = getch ();        /* target index */
  248.        break;
  249.  
  250.      case 0x0400 :            /* t1 grp+offset        */
  251.  
  252.      case 0x4400 :            /* f1 grp            */
  253.  
  254.      case 0x1400 :            /* t5 grp            */
  255.        y = "GRP ";
  256.        t1 = getch ();        /* target index */
  257.        break;
  258.  
  259.      case 0x0800 :            /* t2 ext+offset        */
  260.  
  261.      case 0x4800 :            /* f2 ext            */
  262.  
  263.      case 0x1800 :            /* t6 ext            */
  264.        y = "EXT ";
  265.        t1 = getch ();        /* target index */
  266.        break;
  267.  
  268.      case 0x0c00 :            /* t3 frm+offset        */
  269.  
  270.      case 0x4c00 :            /* f3 frm (no ndx)        */
  271.  
  272.      case 0x1c00 :            /* t7 frm (no ndx)        */
  273.        y = "FRM ";
  274.        break;
  275.  
  276.      case 0x5000 :            /* f4 calc (no ndx)        */
  277.        y = "CALC";
  278.        break;
  279.  
  280.      case 0x5400 :            /* f5 same (no ndx)        */
  281.        y = "SAME";
  282.        break;
  283.  
  284.      case 0x5800 :            /* f n/a            */
  285.  
  286.      case 0x5c00 :            /* f n/a            */
  287.        y = "BAD ";
  288.        break;
  289.     }
  290.       printf ( "%s Nbr %d, %sIndex=%02x\tMethod %02x\n\t",
  291.         x, ( ofs >> 8 ) & 3, y, t1, ( ofs >> 10 ));
  292.     }
  293. }
  294.  
  295. docks ()                /* output checksum byte        */
  296. { printf ( "Checksum=%02x\n", getch ());
  297. }
  298.  
  299. dodat ( t ) char * t;            /* dump a data record        */
  300. { int n ,
  301.      adr;
  302.   n = getch ();                /* segment index        */
  303.   adr = getwd ();            /* starting address        */
  304.   printf ( "%s\tLen=%04x at %s:%04x\n\t", t, Siz - 1, Seg [ n ], adr );
  305.   spcovr ( adr & 15 );
  306.   while ( Siz > 1 )
  307.     { if ( ! ( adr ++ & 15 ))
  308.      printf ( "\n    %04x:  ", adr - 1 );
  309.       printf ( adr & 7 ? "%02x " : "%02x   ", getch ());
  310.     }
  311.   printf ( "\n\t" );
  312.   docks ();
  313. }
  314.  
  315. spcovr ( n ) int n;            /* space over to data loc    */
  316. { while ( n )
  317.     { if ( n -- == 8 )
  318.     printf ( "  " );
  319.       printf ( "   " );
  320.     }
  321.   printf ( "   " );
  322. }
  323.  
  324. char * donam ()                /* copy name from record    */
  325. { int n ;
  326.   char * t, * t1;
  327.   n = getch ();                /* number of chars in name    */
  328.   t1 = t = alloc ( n + 1 );        /* get space for it        */
  329.   while ( n -- )
  330.     * t ++ = getch ();        /* save the name for use    */
  331.   * t = 0;
  332.   return ( t1 );
  333. }
  334.  
  335. segdef ()
  336. { int code ,
  337.      len,
  338.      ni,
  339.      ci,
  340.      oi;
  341.   char * aline,
  342.      * seg;
  343.   code = getch ();            /* read stuff from record    */
  344.   len = getwd ();
  345.   ni = getch ();
  346.   ci = getch ();
  347.   oi = getch ();
  348.   printf ( "Seg %d\t", Si );
  349.   printf ( "%-16s", Seg [ Si ++ ] = Name [ ni ]);
  350.   switch ( code & 0xe0 )        /* alignment    */
  351.     {
  352.     case 0x00 :                /* absolute    */
  353.       aline = "ABS ";
  354.       break;
  355.  
  356.     case 0x20 :                /* byte        */
  357.       aline = "BYTE";
  358.       break;
  359.  
  360.     case 0x40 :                /* word        */
  361.       aline = "WORD";
  362.       break;
  363.  
  364.     case 0x60 :                /* para        */
  365.       aline = "PARA";
  366.       break;
  367.  
  368.     case 0x80 :                /* page        */
  369.       aline = "PAGE";
  370.       break;
  371.  
  372.     default :                /* unknown     */
  373.       aline = "UNK ";
  374.       break;
  375.     }
  376.   switch ( code & 0x1c )        /* segment class     */
  377.     {
  378.     case 0x00 :                /* private     */
  379.       seg = "PRIVAT";
  380.       break;
  381.  
  382.     case 0x08 :                /* public     */
  383.       seg = "PUBLIC";
  384.       break;
  385.  
  386.     case 0x14 :                /* stack     */
  387.       seg = "STACK ";
  388.       break;
  389.  
  390.     case 0x18 :                /* common     */
  391.       seg = "COMMON";
  392.       break;
  393.  
  394.     default :                /* other     */
  395.       seg = "UNKNWN";
  396.       break;
  397.     }
  398.   printf ( "Sz=%04x  %s %s ", len, seg, aline );
  399.   printf ( "\'%s\'\tOvly: \"%s\"\n\t", Name [ ci ], Name [ oi ]);
  400. }
  401.  
  402. domslibhd ()            /* added per DC 01/04/86 */
  403. {
  404.     unsigned long idxpos;
  405.     int     idxsize;
  406.  
  407.     idxpos = (unsigned) getwd ();       /* cast to prevent sign extension */
  408.     idxpos |= (unsigned long) ((unsigned) getwd ()) << 16;
  409.     idxsize = getwd ();
  410.     printf ("MS-Library file - Index is at %lXh, %d block(s) of 512 bytes\n",
  411.         idxpos, idxsize);
  412.     while ( Siz )
  413.         getch ();
  414. }
  415.  
  416.  
  417. docoment ()            /* added per DC 01/04/86    */
  418. {   int class;
  419.     int i;
  420.  
  421.     printf ( "COMENT\t" );
  422.     getch ();                       /* comment type */
  423.     switch ( class = getch () )     /* comment class */
  424.         {
  425.         case 0:                     /* Language translator comment */
  426.             printf ("Compiler \"");
  427.             while ( Siz > 1 )
  428.                 printf ( "%c", getch ());
  429.             printf ("\"\n\t");
  430.             docks ();
  431.             break;
  432.  
  433.         case 159:                   /* default library search specification */
  434.             printf ("DefLib\t\"");
  435.             while ( Siz > 1 )
  436.                 printf ( "%c", getch ());
  437.             printf ("\"\n\t");
  438.             docks ();
  439.             break;
  440.  
  441.         case 160:                       /* Dynamic link records (Import def)*/
  442.             printf ("ImpDef\t");        /* for Windows/DOS 4 linker */
  443.             getch ();
  444.             i = getch ();
  445.             printf ("\"%s\"\t", donam ());  /* Exported function name */
  446.             printf ("\"%s\"", donam ());    /* Module name */
  447.             if (i)
  448.                 printf (".%d", getwd ());   /* Function ordinal value */
  449.             else
  450.                 getch ();                   /* skip a null */
  451.             printf ("\n\t");
  452.             docks ();
  453.             break;
  454.  
  455.         default:
  456.             printf ("Class=%d\n\t", class);
  457.             while ( Siz )
  458.                 printf ( "%02x  ", getch ());
  459.             printf ("\n");
  460.             break;
  461.         }
  462. }
  463.  
  464. getch ()                /* get byte from Inf, polling    */
  465. { poll ();
  466.   -- Siz;
  467.   return ( getc ( Inf ));
  468. }
  469.  
  470. getwd ()                /* get word from Inf, polling    */
  471. { poll ();
  472.   Siz -= 2;
  473.   return ( getw ( Inf ));
  474. }
  475.  
  476. poll ()
  477. { if ( bdos ( 6, 255 ) == 3 )
  478.     exit ( 7 );
  479. }
  480.  
  481. /*---if your library doesn't have this, remove the comment-out frame
  482. getw (f) FILE *f;
  483. { int x;
  484.   x = EOF;
  485.   fread(&x,2,f);
  486.   return(x);
  487. }
  488. ---*/
  489.  
  490. /* end of objscn.c */
  491.