home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / os2 / rob / rob.c next >
Encoding:
C/C++ Source or Header  |  1988-01-04  |  23.4 KB  |  1,045 lines

  1. /****************************************************************
  2. * name         readobj -- read and format obj files             *
  3. *                         into a printable output               *
  4. *                                                               *
  5. * Original by Kip Davidson (73247,620)                          *
  6. * Upgraded to handle OS/2 object & libs by Dave Cortesi (72155,450) *
  7. *                                                               *
  8. * usage        readobj filename                                 *
  9. *                                                               *
  10. *              where "filename" is the name of an object code   *
  11. *              file, e.g. ROB.OBJ, or else the name of an       *
  12. *              object library, e.g. DOSCALLS.LIB.               *
  13. *                                                               *
  14. ****************************************************************/
  15.  
  16. /****************
  17. * Include files *
  18. *****************/
  19. #define LINT_ARGS
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <ctype.h>
  23. #include <string.h>
  24.  
  25. /********************************
  26. * Microsoft Object Record Types *
  27. ********************************/
  28. #define BLKDEF  0x7A
  29. #define BLKEND  0x7C
  30. #define THEADR  0x80
  31. #define COMENT  0x88
  32. #define MODEND  0x8A
  33. #define EXTDEF  0x8C
  34. #define TYPDEF  0x8E
  35. #define PUBDEF  0x90
  36. #define LINNUM  0x94
  37. #define LNAMES  0x96
  38. #define SEGDEF  0x98
  39. #define GRPDEF  0x9A
  40. #define FIXUPP  0x9C
  41. #define LEDATA  0xA0
  42. #define LIDATA  0xA2
  43. #define COMDEF  0xB0    /* communal-names definition */
  44.  
  45. /********************************
  46. * Intel Object Record Types     *
  47. ********************************/
  48. #define RHEADR  0x6E
  49. #define REGINT  0x70
  50. #define REDATA  0x72
  51. #define RIDATA  0x74
  52. #define OVLDEF  0x76
  53. #define ENDREC  0x78
  54. #define DEBSYM  0x7E
  55. #define LHEADR  0x82
  56. #define PEDATA  0x84
  57. #define PIDATA  0x86
  58. #define LOCSYM  0x92
  59. #define LIBHED  0xA4
  60. #define LIBNAM  0xA6
  61. #define LIBLOC  0xA8
  62. #define LIBDIC  0xAA
  63.  
  64. /************************
  65. * Miscellaneous defines *
  66. ************************/
  67. #define NUM_ARGS  2
  68. #define MAX_LNAME_ENTRIES  100
  69. #define MAX_NAME_LEN        64
  70. #define MAX_SNAME_ENTRIES  100
  71. #define SNAME_SEG   0
  72. #define SNAME_CLASS 1
  73. #define SNAME_OVL   2
  74. #define GRPDEF_SI   0xff
  75. #define CV_ARRAY  0x6281   /* Codeview array indicator? */
  76. #define BLANK   ' '
  77. #define ZERO    0x00
  78. #define NOSWAP  00
  79. #define SWAP    01
  80. #define BIT7    0x80
  81. #define BIT6    0x40
  82. #define BIT5    0x20
  83. #define BIT4    0x10
  84. #define BIT3    0x08
  85. #define BIT2    0x04
  86. #define BIT1    0x02
  87. #define BIT0    0x01
  88.  
  89. /*********************
  90. * Error code defines *
  91. *********************/
  92. #define USAGE_ERR  1
  93. #define OPEN_ERR   2
  94.  
  95. /*********
  96. * Macros *
  97. **********/
  98. #define MALLOC(x)      ((x *) malloc(sizeof(x)))
  99. #define CALLOC(n, x)    ((x *) calloc(n, sizeof(x)))
  100.  
  101. /***********
  102. * Typedefs *
  103. ************/
  104. typedef unsigned char byte;
  105. typedef unsigned char *p_byte;    /* pointer to a byte */
  106. typedef unsigned short word;
  107. typedef unsigned short *p_word;    /* pointer to a word */
  108.  
  109. /****************
  110. * File pointers *
  111. ****************/
  112. FILE *fp1;                /* object code file pointer */
  113.  
  114. /*******************
  115. * Global variables *
  116. *******************/
  117. word stoppit;            /* flag for end of file */
  118. word i = 0, j = 0, k = 0;    /* misc index counters */
  119. byte c = 0, c1 = 0, c2 = 0;    /* misc unsigned char variables */
  120. word reclen = 0;        /* length of record */
  121. byte num_bytes = 0;        /* length of string passed */
  122. word chksum_count = 0;    /* total bytes read for a record */
  123. byte chksum = 0;        /* the checksum from the obj file */
  124. byte Lnames_index = 1;    /* number of LNAMES entries */
  125. byte Lnames_total = 0;    /* number of LNAMES entries */
  126.                        /* storage for LNAMES data */
  127. byte Lnames[MAX_LNAME_ENTRIES][MAX_NAME_LEN + 1] = 
  128.     {'*', 'N', 'U', 'L', 'L', '*', '\0'};
  129. byte Snames_index = 1;    /* number of SNAMES entries */
  130. byte Snames_total = 0;    /* number of SNAMES entries */
  131.                        /* storage for SNAMES data */
  132. word Snames[MAX_SNAME_ENTRIES][SNAME_OVL + 1] = 
  133.     {{0, 0, 0}};
  134. byte *align_msg[] = /* SEGDEF align messages */
  135.     {
  136.     "0 Absolute segment", 
  137.     "1 Relocatable and byte-aligned segment", 
  138.     "2 Relocatable and word-aligned segment", 
  139.     "3 Relocatable and paragraph-aligned segment", 
  140.     "4 Relocatable and page-aligned segment", 
  141.     };
  142. byte *combine_msg[] = /* SEGDEF combine messages */
  143.     {
  144.     "0 Private segment", 
  145.     "1 ?", 
  146.     "2 Public segment", 
  147.     "3 ?", 
  148.     "4 ?", 
  149.     "5 Stack segment", 
  150.     "6 Common segment", 
  151.     };
  152.  
  153. byte chr_buff[256];        /* string buffer */
  154.  
  155. /**************************************************************
  156. * This program uses the Object Record Types as described in   *
  157. * the following documents :                                   *
  158. *                                                             *
  159. * Intel :     8086 Relocatable Object Module Formats          *
  160. *             Version 4.0, Order # 121748-001                 *
  161. * Microsoft : MS-DOS Programmers Reference                    *
  162. *             Document # 8411-310-02                          *
  163. *             Part # 036-014-012                              *
  164. ***************************************************************/
  165.  
  166. word main(argc, argv)
  167. word argc;
  168. byte *argv[];
  169.     {
  170.     void do_blkdef(void);
  171.     void do_blkend(void);
  172.     void do_comdef(void);
  173.     void do_coment(void);
  174.     void do_extdef(void);
  175.     void do_fixupp(void);
  176.     void do_grpdef(void);
  177.     void do_ledata(void);
  178.     void do_lidata(void);
  179.     void do_linnum(void);
  180.     void do_lnames(void);
  181.     void do_modend(void);
  182.     void do_pubdef(void);
  183.     void do_locsym(void);
  184.     void do_segdef(void);
  185.     void do_theadr(void);
  186.     void do_typdef(void);
  187.     void do_unimplt(void);
  188.     void exit(int);
  189.     byte get_obj_byte(void);
  190.  
  191.     if (argc != NUM_ARGS) {
  192.         fputs("Usage: readobj filename \n", stderr);
  193.         exit(USAGE_ERR);
  194.         }
  195.  
  196.     if ((fp1 = fopen(argv[1], "rb")) == NULL) {
  197.         fprintf(stderr, "Can't open %s\n", argv[1]);
  198.         exit(OPEN_ERR);
  199.         }
  200.  
  201.     printf("READOBJ by Kip Davidson (73247,620)\n");
  202.     printf("\tOS/2 version Dave Cortesi (72155,450)\n\n");
  203.  
  204.     c = get_obj_byte();
  205.     while (stoppit == 0) {
  206.         switch (c) {
  207.         case BLKDEF:
  208.             do_blkdef();
  209.             break;
  210.         case BLKEND:
  211.             do_blkend();
  212.             break;
  213.         case THEADR:
  214.             do_theadr();
  215.             break;
  216.         case COMENT:
  217.             do_coment();
  218.             break;
  219.         case MODEND:
  220.             do_modend();
  221.             break;
  222.         case EXTDEF:
  223.             do_extdef();
  224.             break;
  225.         case TYPDEF:
  226.             do_typdef();
  227.             break;
  228.         case PUBDEF:
  229.             do_pubdef();
  230.             break;
  231.         case LOCSYM:
  232.             do_locsym();
  233.             break;
  234.         case LINNUM:
  235.             do_linnum();
  236.             break;
  237.         case LNAMES:
  238.             do_lnames();
  239.             break;
  240.         case SEGDEF:
  241.             do_segdef();
  242.             break;
  243.         case GRPDEF:
  244.             do_grpdef();
  245.             break;
  246.         case FIXUPP:
  247.             do_fixupp();
  248.             break;
  249.         case LEDATA:
  250.             do_ledata();
  251.             break;
  252.         case LIDATA:
  253.             do_lidata();
  254.             break;
  255.         case COMDEF:
  256.             do_comdef();
  257.             break;
  258.         case 0x00:        /* null bytes used in LIB files for padding */
  259.             break;        /* skip 'em, a THEADR will show up soon */
  260.         default:
  261.             do_unimplt();
  262.             break;
  263.             }
  264.         c = get_obj_byte();
  265.         }
  266.     return (0);
  267.     }
  268.  
  269. /************************************************
  270. * get a byte from the object code file pointer  *
  271. ************************************************/
  272.  
  273. byte get_obj_byte()
  274.     {
  275.     word w;
  276.     c = (byte) (w = getc(fp1));
  277.     stoppit = (w == EOF);
  278.     chksum_count = chksum_count + c;
  279.     return (c);
  280.     }
  281.  
  282. /************************************************
  283. * get a word from the object code file pointer  *
  284. ************************************************/
  285.  
  286. word get_obj_word(swap)
  287. byte swap;
  288.     {                    /* input -  Hi Lo */
  289.     if (swap) {
  290.         c1 = get_obj_byte();
  291.         c2 = get_obj_byte();
  292.         return ((c2 << 8) + c1);    /* swap - Lo Hi */
  293.         }
  294.     else  {
  295.         c1 = get_obj_byte();
  296.         c2 = get_obj_byte();
  297.         return ((c1 << 8) + c2);    /* noswap - Hi Lo */
  298.         }
  299.     }
  300.  
  301. /****************************************************
  302. * return the length of the contents field in bytes  *
  303. ****************************************************/
  304.  
  305. word get_reclen()
  306.     {
  307.     word get_obj_word(byte);
  308.  
  309.     reclen = get_obj_word(SWAP);
  310.     printf(" (reclen %04x)\n", reclen);
  311.     return (reclen);
  312.     }
  313.  
  314. /*********************
  315. * check the checksum; print only if wrong *
  316. *********************/
  317.  
  318. void do_checksum()
  319.     {
  320.     byte get_obj_byte(void);
  321.  
  322.     chksum = get_obj_byte();
  323.  /* printf(" checksum = %02x\n",chksum); */
  324.     chksum_count = (chksum_count - chksum);
  325.     c1 = (chksum_count % 256);
  326.     c2 = -c1;
  327.     if (c2 != chksum) {
  328.         printf(" Checksum %02x unequal to computed checksum %02x\n",
  329.             chksum, c2);
  330.         }
  331.     chksum_count = 0;
  332.     return;
  333.     }
  334.  
  335. /******************************
  336. * gather up an unsized string into chr_buff *
  337. ******************************/
  338.  
  339. void get_u_string(num_chars)
  340. byte num_chars;
  341.     {
  342.     byte get_obj_byte(void);
  343.  
  344.     for (i = 0;  i < num_chars;  i++) {
  345.         c = get_obj_byte();
  346.         if (isprint(c))
  347.             chr_buff[i] = c;
  348.         else 
  349.             chr_buff[i] = BLANK;
  350.         }
  351.     chr_buff[i] = '\0';
  352.     return;
  353.     }
  354.  
  355. /***************************
  356. * gather up a sized string into chr_buff *
  357. ***************************/
  358.  
  359. byte get_s_string()
  360.     {
  361.     void get_u_string(byte);
  362.     byte get_obj_byte(void);
  363.  
  364.     num_bytes = get_obj_byte();
  365.     get_u_string(num_bytes);
  366.     return (num_bytes);
  367.     }
  368.  
  369. /******************************
  370. * get index value (1 or 2 bytes) *
  371. ******************************/
  372.  
  373. byte get_index(index)
  374. word *index;
  375.     {
  376.     byte get_obj_byte(void);
  377.  
  378.     c = get_obj_byte();
  379.     if (c & BIT7) {
  380.         c1 = (c & ~BIT7);
  381.         c2 = get_obj_byte();
  382.         *index = (c1 << 8) + c2;
  383.         return (sizeof(word));
  384.         }
  385.     else  {
  386.         *index = c;
  387.         return (sizeof(byte));
  388.         }
  389.     return 0;
  390.     }
  391.  
  392. /***************************************************
  393. * Get a COMDEF length, 1 2 3 4 or 5 bytes.         *
  394. ***************************************************/
  395.  
  396. byte get_varlength(tolong)
  397. long *tolong;
  398.     {
  399.     byte numform, used, toget, tozero;
  400.     byte *zapper;
  401.  
  402.     zapper = (char *) tolong;
  403.     numform = get_obj_byte();
  404.     used = 1;
  405.     if (numform < 128) {
  406.         *zapper++ = numform;
  407.         toget = 0;
  408.         tozero = 3;
  409.         }
  410.     else if (numform == 129) {
  411.         toget = 2;
  412.         tozero = 2;
  413.         }
  414.     else if (numform == 132) {
  415.         toget = 3;
  416.         tozero = 1;
  417.         }
  418.     else                 /* four-byte number */
  419.         {
  420.         toget = 4;
  421.         tozero = 0;
  422.         }
  423.     for (;  toget;  --toget,  ++used)
  424.         *zapper++ = get_obj_byte();
  425.     for (;  tozero;  --tozero)
  426.         *zapper++ = 0;
  427.     return (used);
  428.     }
  429.  
  430. /*********************************************************
  431. * print out an Lname if there is one of the given index  *
  432. **********************************************************/
  433.  
  434. void put_name(inx)
  435. word inx;
  436.     {
  437.     if (inx)
  438.         if (inx < Lnames_index)
  439.             printf("%s\n", Lnames[inx]);
  440.         else 
  441.             printf("???\n");
  442.     else 
  443.         printf("{nul}\n");
  444.     }
  445.  
  446. /***********************************************
  447. * dump a given number of record bytes in hex   *
  448. ***********************************************/
  449.  
  450. void dumpn(cnt)
  451. word cnt;
  452.     {
  453.     byte b[16];
  454.     word adr, p, q;
  455.     adr = 0;
  456.     while ((adr < cnt) && (stoppit == 0)) {
  457.         q = cnt - adr;
  458.         if (q > 16)
  459.             q = 16;
  460.         for (p = 0;  p < q;  p++)
  461.             b[p] = get_obj_byte();
  462.         printf("%04x  ", adr);
  463.         for (p = 0;  p < q;  p++)
  464.             printf("%02x ", b[p]);
  465.         for (;  p < 16;  p++)
  466.             printf("   ");
  467.         for (p = 0;  p < q;  p++)
  468.             printf("%c", ((31 < b[p]) && (b[p] < 127)) ? b[p] : '.');
  469.         printf("\n");
  470.         adr += q;
  471.         }
  472.     }
  473.  
  474. /**************************
  475. * print out THEADR record *
  476. **************************/
  477.  
  478. void do_theadr()
  479.     {
  480.     void do_checksum(void);
  481.     byte get_s_string(void);
  482.     word get_reclen(void);
  483.  
  484.     printf("\n80h: THEADR");
  485.     reclen = get_reclen();
  486.     get_s_string();
  487.     printf("\tmodule = %s\n", chr_buff);
  488.     do_checksum();
  489.     return;
  490.     }
  491.  
  492. /**************************
  493. * print out COMENT record *
  494. * -including support for OS/2 dynalink record class A0h *
  495. **************************/
  496.  
  497. void do_coment()
  498.     {
  499.     void do_checksum(void);
  500.     byte get_obj_byte(void);
  501.     word get_reclen(void);
  502.     word get_obj_word(byte);
  503.     void get_u_string(byte);
  504.     byte get_s_string(void);
  505.     byte purge, list, class;
  506.     word ordinal;
  507.  
  508.     printf("88h: COMENT");
  509.     reclen = get_reclen() - 1;
  510.     c1 = get_obj_byte();
  511.     purge = (c1 & BIT7) >> 7;
  512.     list = (c1 & BIT6) >> 6;
  513.     class = get_obj_byte();
  514.     printf("\tclass = %01x, purge = %01x, list = %01x\n",
  515.         class, purge, list);
  516.     if (class != 0xA0) {
  517.         num_bytes = reclen - 2;    /* adust for flag, class */
  518.         get_u_string(num_bytes);
  519.         printf("\tComment = \"%s\"\n", chr_buff);
  520.         switch (class) {
  521.         case 0x00:
  522.             printf("\t\tcompiler name, /dsalloc\n");
  523.             break;
  524.         case 0x9c:
  525.             printf("\t\tDOS version\n");
  526.             break;
  527.         case 0x9d:
  528.             printf("\t\tmemory model\n");
  529.             break;
  530.         case 0x9e:
  531.             printf("\t\tforce /dosseg order\n");
  532.             break;
  533.         case 0x9f:
  534.             printf("\t\tlibrary specifier\n");
  535.             break;
  536.         case 0x81:
  537.             printf("\t\tlibrary specifier (obs.)\n");
  538.             break;
  539.         case 0xa1:
  540.             printf("\t\tMSoft extension marker\n");
  541.             break;
  542.             }
  543.         }
  544.     else                 /* dynamic link import record */
  545.         {
  546.         list = get_obj_byte();
  547.         class = get_obj_byte();
  548.         printf("\tdynalink import, flag1 %02x, flag2 %02x\n", list, class);
  549.         num_bytes = get_obj_byte();
  550.         get_u_string(num_bytes);
  551.         printf("\tName = %s", chr_buff);
  552.         num_bytes = get_obj_byte();
  553.         get_u_string(num_bytes);
  554.         printf(", Module = %s", chr_buff);
  555.         if (class) {
  556.             ordinal = get_obj_word(SWAP);
  557.             printf(", Ordinal %d\n", ordinal);
  558.             }
  559.         else  {
  560.             num_bytes = get_obj_byte();
  561.             get_u_string(num_bytes);
  562.             printf(", Entry = %s\n", chr_buff);
  563.             }
  564.         }
  565.     do_checksum();
  566.     return;
  567.     }
  568.  
  569. /**************************
  570. * print out LNAMES record *
  571. **************************/
  572.  
  573. void do_lnames()
  574.     {
  575.     void do_checksum(void);
  576.     byte get_obj_byte(void);
  577.     word get_reclen(void);
  578.     word sum, name_index;
  579.  
  580.     printf("96h: LNAMES");
  581.     reclen = get_reclen();
  582.     reclen = reclen - 1;    /* adjust for checksum byte */
  583.     sum = 0;
  584.     while (sum < reclen) {
  585.         num_bytes = get_obj_byte();    /* get length of string */
  586.         sum = sum + (num_bytes + 1);    /* account for length */
  587.         name_index = Lnames_index;    /* next free entry */
  588.         if (name_index > MAX_LNAME_ENTRIES)    /* no more free */
  589.             name_index = 0;    /* 0th entry always free */
  590.         if (num_bytes != 0)    /* check for a null name */
  591.             {
  592.             for (i = 0;  i < num_bytes;  i++)
  593.                 Lnames[name_index][i] = get_obj_byte();
  594.             }
  595.         else  {
  596.             Lnames[name_index][0] = '{';
  597.             Lnames[name_index][1] = '}';
  598.             i = 2;
  599.             }
  600.         Lnames[name_index][i] = '\0';
  601.         printf("\t%02x  %s", name_index, Lnames[name_index]);
  602.         if (name_index != 0) {
  603.             Lnames_index++;
  604.             printf("\n");
  605.             }
  606.         else 
  607.             printf(" (no room for this name)\n");
  608.         }
  609.     Lnames_total = Lnames_index - 1;
  610.     do_checksum();
  611.     return;
  612.     }
  613.  
  614. /**************************
  615. * print out SEGDEF record *
  616. **************************/
  617.  
  618. void do_segdef()
  619.     {
  620.     void do_checksum(void);
  621.     byte get_index(word *);
  622.     byte get_obj_byte(void);
  623.     word get_obj_word(byte);
  624.     word get_reclen(void);
  625.     byte align, combine, big;
  626.     word abs_fn, abs_off;
  627.     word seg_len;
  628.     word seg_index, class_index, ovl_index;
  629.  
  630.     printf("98h: SEGDEF");
  631.     reclen = get_reclen();
  632.     c = get_obj_byte();
  633.     align = (c & (BIT7 + BIT6 + BIT5)) >> 5;
  634.     combine = (c & (BIT4 + BIT3 + BIT2)) >> 2;
  635.     big = (c & BIT1) >> 1;
  636.     printf("\tAlignment = %s\n", align_msg[align]);
  637.     if (align == 0) {
  638.         abs_fn = get_obj_word(SWAP);
  639.         abs_off = get_obj_word(SWAP);
  640.         printf("\t\tFrame = %04x : Offset = %04x\n",
  641.             abs_fn, abs_off);
  642.         }
  643.     printf("\tCombine = %s\n", combine_msg[combine]);
  644.     seg_len = get_obj_word(SWAP);
  645.  
  646.     printf("\tSegment length =");
  647.     if (big == 1)
  648.         printf(" 64K\n");
  649.     else 
  650.         printf(" %04x\n", seg_len);
  651.  
  652.     get_index(&seg_index);
  653.     printf("\tSegment name = ");
  654.     put_name(seg_index);
  655.  
  656.     get_index(&class_index);
  657.     printf("\tSegment class = ");
  658.     put_name(class_index);
  659.  
  660.     get_index(&ovl_index);
  661.     printf("\tSegment overlay = ");
  662.     put_name(ovl_index);
  663.  
  664.     if (Snames_index > MAX_SNAME_ENTRIES) {
  665.         printf(" No room to store SNAME\n");
  666.         Snames_index = MAX_SNAME_ENTRIES + 1;
  667.         Snames_total = MAX_SNAME_ENTRIES;
  668.         }
  669.     else  {
  670.         Snames[Snames_index][SNAME_SEG] = seg_index;
  671.         Snames[Snames_index][SNAME_CLASS] = class_index;
  672.         Snames[Snames_index][SNAME_OVL] = ovl_index;
  673.         Snames_index++;
  674.         Snames_total = (Snames_index - 1);
  675.         }
  676.     do_checksum();
  677.     return;
  678.     }
  679.  
  680. /**************************
  681. * print out GRPDEF record *
  682. **************************/
  683.  
  684. void do_grpdef()
  685.     {
  686.     void do_checksum(void);
  687.     byte get_index(word *);
  688.     byte get_obj_byte(void);
  689.     word get_reclen(void);
  690.     word index;
  691.     word sum;
  692.  
  693.     printf("9Ah: GRPDEF");
  694.     reclen = get_reclen();
  695.  /* adjust reclen for checksum */
  696.     reclen = reclen - 1;
  697.     sum = get_index(&index);
  698.     printf("\tGroup = ");
  699.     put_name(index);
  700.     while (sum < reclen) {
  701.         c = get_obj_byte();    /* read the FFh */
  702.         sum++;
  703.         sum += get_index(&index);
  704.         printf("\t\tsegment = ");
  705.         put_name(Snames[index][SNAME_SEG]);
  706.         }
  707.     do_checksum();
  708.     return;
  709.     }
  710.  
  711. /**************************
  712. * print out EXTDEF record *
  713. **************************/
  714.  
  715. void do_extdef()
  716.     {
  717.     void do_checksum(void);
  718.     byte get_obj_byte(void);
  719.     word get_reclen(void);
  720.     void get_u_string(byte);
  721.     word sum;
  722.     word type_index;
  723.  
  724.     printf("8Ch: EXTDEF");
  725.     reclen = get_reclen();
  726.     reclen = reclen - 1;    /* adjust reclen for checksum byte */
  727.     sum = 0;
  728.     while (sum < reclen) {
  729.         num_bytes = get_obj_byte();
  730.         sum = sum + (num_bytes + 1);
  731.         get_u_string(num_bytes);
  732.         sum += get_index(&type_index);
  733.         printf("\ttype %04x, name = %s\n",
  734.             type_index, chr_buff);
  735.         }
  736.     do_checksum();
  737.     return;
  738.     }
  739.  
  740. /**************************
  741. * print out COMDEF record *
  742. * defines communal (FORTRAN COMMON, any C public array) variable *
  743. **************************/
  744.  
  745. void do_comdef()
  746.     {
  747.  
  748.     void do_checksum(void);
  749.     byte get_obj_byte(void);
  750.     word get_obj_word(byte);
  751.     word get_reclen(void);
  752.     byte get_index(word *);
  753.     byte get_varlength(long *);
  754.     byte get_s_string(void);
  755.  
  756.     byte seg_type;
  757.     word sum, type_index;
  758.     long num_elem, size_elem;
  759.  
  760.     printf("B0h: COMDEF");
  761.     reclen = get_reclen() - 1;
  762.     sum = 0;
  763.     while (sum < reclen) {
  764.         sum += get_s_string() + 1;
  765.         sum += get_index(&type_index);
  766.         seg_type = get_obj_byte();
  767.         sum++;
  768.         if (seg_type == 0x61)    /* FAR */
  769.             sum += get_varlength(&num_elem);
  770.         sum += get_varlength(&size_elem);
  771.         printf("\ttype = %04x, segtype = %02x, name = %s\n",
  772.             type_index, seg_type, chr_buff);
  773.         if (seg_type == 0x61)
  774.             printf("\t\t %l items of length %l\n",
  775.                 num_elem, size_elem);
  776.         else 
  777.             printf("\t\titem size %l\n", size_elem);
  778.         }
  779.     do_checksum();
  780.     return;
  781.     }
  782.  
  783. /**************************
  784. * print out LEDATA record *
  785. **************************/
  786.  
  787. void do_ledata()
  788.     {
  789.     void do_checksum(void);
  790.     byte get_obj_byte(void);
  791.     byte get_index(word *);
  792.     word get_reclen(void);
  793.     word sum, index;
  794.  
  795.     printf("A0h: LEDATA");
  796.     reclen = get_reclen() - 1;
  797.     sum = get_index(&index);
  798.     printf("\tSegment = ");
  799.     put_name(Snames[index][SNAME_SEG]);
  800.     i = get_obj_word(SWAP);
  801.     sum += 2;
  802.     printf("\tEnumerated data offset = %04x\n", i);
  803.     dumpn(reclen - sum);
  804.     do_checksum();
  805.     return;
  806.     }
  807.  
  808. /**************************
  809. * print out BLKDEF record *
  810. **************************/
  811.  
  812. void do_blkdef()
  813.     {
  814.     void do_checksum(void);
  815.     byte get_obj_byte(void);
  816.     word get_reclen(void);
  817.  
  818.     printf("7Ah: BLKDEF");
  819.     reclen = get_reclen();
  820.     dumpn(reclen - 1);
  821.     do_checksum();
  822.     return;
  823.     }
  824.  
  825. /**************************
  826. * print out BLKEND record *
  827. **************************/
  828.  
  829. void do_blkend()
  830.     {
  831.     void do_checksum(void);
  832.     byte get_obj_byte(void);
  833.     word get_reclen(void);
  834.  
  835.     printf("7Ch: BLKEND");
  836.     reclen = get_reclen();
  837.     dumpn(reclen - 1);
  838.     do_checksum();
  839.     return;
  840.     }
  841.  
  842. /**************************
  843. * print out MODEND record *
  844. **************************/
  845.  
  846. void do_modend()
  847.     {
  848.     void do_checksum(void);
  849.     byte get_obj_byte(void);
  850.     word get_reclen(void);
  851.     byte flags, ismain, hasadr;
  852.  
  853.     printf("8Ah: MODEND");
  854.     reclen = get_reclen();
  855.     flags = get_obj_byte();
  856.     ismain = (flags >> 7) & 0x1;
  857.     hasadr = (flags >> 6) & 0x1;
  858.     printf("\tModType = %02x, main: %c, start address: %c\n",
  859.         flags,
  860.         ismain ? '1' : '0',
  861.         hasadr ? '1' : '0');
  862.     dumpn(reclen - 2);
  863.     do_checksum();
  864.     return;
  865.     }
  866.  
  867. /**************************
  868. * print out TYPDEF record *
  869. **************************/
  870.  
  871. void do_typdef()
  872.     {
  873.     void do_checksum(void);
  874.     byte get_obj_byte(void);
  875.     word get_reclen(void);
  876.  
  877.     printf("8Eh: TYPDEF");
  878.     reclen = get_reclen();
  879.     dumpn(reclen - 1);
  880.     do_checksum();
  881.     return;
  882.     }
  883.  
  884. /**************************
  885. * print out PUBDEF record *
  886. **************************/
  887.  
  888. void do_pubdef()
  889.     {
  890.     void do_checksum(void);
  891.     byte get_obj_byte(void);
  892.     word get_reclen(void);
  893.     word grp, seg, frame, type, sum;
  894.  
  895.     printf("90h: PUBDEF");
  896.     reclen = get_reclen();
  897.     reclen -= 1;        /* adjust for checksum */
  898.     sum = get_index(&grp);
  899.     printf("\tGroup =");
  900.     put_name(grp);
  901.     sum += get_index(&seg);
  902.     if (seg) {
  903.         printf("\tSegment = ");
  904.         put_name(Snames[seg][SNAME_SEG]);
  905.         }
  906.     else  {
  907.         i = get_obj_word(SWAP);
  908.         sum += 2;
  909.         printf("\tSegment = 0, Frame = %04x\n", i);
  910.         }
  911.     while (sum < reclen) {
  912.         sum += get_s_string() + 1;
  913.         i = get_obj_word(SWAP);
  914.         sum += 2;
  915.         sum += get_index(&type);
  916.         printf("\t\ttype %04x, offset %04x, name = %s\n",
  917.             type, i, chr_buff);
  918.         }
  919.     do_checksum();
  920.     return;
  921.     }
  922.  
  923. /**************************
  924. * print out LOCSYM record (identical to PUBDEF) *
  925. **************************/
  926.  
  927. void do_locsym()
  928.     {
  929.     void do_checksum(void);
  930.     byte get_obj_byte(void);
  931.     word get_reclen(void);
  932.     word grp, seg, frame, type, sum;
  933.  
  934.     printf("92h: LOCSYM");
  935.     reclen = get_reclen();
  936.     reclen -= 1;        /* adjust for checksum */
  937.     sum = get_index(&grp);
  938.     printf("\tGroup =");
  939.     put_name(grp);
  940.     sum += get_index(&seg);
  941.     if (seg) {
  942.         printf("\tSegment = ");
  943.         put_name(Snames[seg][SNAME_SEG]);
  944.         }
  945.     else  {
  946.         i = get_obj_word(SWAP);
  947.         sum += 2;
  948.         printf("\tSegment = 0, Frame = %04x\n", i);
  949.         }
  950.     while (sum < reclen) {
  951.         sum += get_s_string() + 1;
  952.         i = get_obj_word(SWAP);
  953.         sum += 2;
  954.         sum += get_index(&type);
  955.         printf("\t\ttype %04x, offset %04x, name = %s\n",
  956.             type, i, chr_buff);
  957.         }
  958.     do_checksum();
  959.     return;
  960.     }
  961.  
  962. /**************************
  963. * print out LINNUM record *
  964. **************************/
  965.  
  966. void do_linnum()
  967.     {
  968.     void do_checksum(void);
  969.     byte get_obj_byte(void);
  970.     word get_reclen(void);
  971.     word grp, seg, number, offset, sum;
  972.  
  973.     printf("94h: LINNUM");
  974.     reclen = get_reclen() - 1;
  975.     sum = get_index(&grp);
  976.     printf("\tGroup = ");
  977.     put_name(grp);
  978.     sum += get_index(&seg);
  979.     if (seg) {
  980.         printf("\tSegment = ");
  981.         put_name(Snames[seg][SNAME_SEG]);
  982.         }
  983.     else printf("\tSegment = 0\n");
  984.     while (sum < reclen) {
  985.         number = get_obj_word(SWAP);
  986.         offset = get_obj_word(SWAP);
  987.         sum += 4;
  988.         printf("\t\tNumber = %04x, offset = %04x\n", number, offset);
  989.         }
  990.     do_checksum();
  991.     return;
  992.     }
  993.  
  994. /**************************
  995. * print out FIXUPP record *
  996. **************************/
  997.  
  998. void do_fixupp()
  999.     {
  1000.     void do_checksum(void);
  1001.     byte get_obj_byte(void);
  1002.     word get_reclen(void);
  1003.  
  1004.     printf("9Ch: FIXUPP");
  1005.     reclen = get_reclen();
  1006.     dumpn(reclen - 1);
  1007.     do_checksum();
  1008.     return;
  1009.     }
  1010.  
  1011. /**************************
  1012. * print out LIDATA record *
  1013. **************************/
  1014.  
  1015. void do_lidata()
  1016.     {
  1017.     void do_checksum(void);
  1018.     byte get_obj_byte(void);
  1019.     word get_reclen(void);
  1020.  
  1021.     printf("A2h: LIDATA");
  1022.     reclen = get_reclen();
  1023.     dumpn(reclen - 1);
  1024.     do_checksum();
  1025.     return;
  1026.     }
  1027.  
  1028. /*********************************
  1029. * unimplemented record type trap *
  1030. *********************************/
  1031.  
  1032. void do_unimplt()
  1033.     {
  1034.     void do_checksum(void);
  1035.     byte get_obj_byte(void);
  1036.     word get_reclen(void);
  1037.     word dumplen;
  1038.  
  1039.     printf("%02xh: unknown record type", c);
  1040.     dumplen = (reclen = get_reclen()) - 1;
  1041.     dumpn(dumplen);
  1042.     do_checksum();
  1043.     return;
  1044.     }
  1045.