home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / READOBJ.ZIP / READOBJ.C next >
Text File  |  1980-01-01  |  25KB  |  1,028 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. word main(argc,argv)
  166. word argc;
  167. byte *argv[];
  168. {
  169. void do_blkdef(void);
  170. void do_blkend(void);
  171. void do_comdef(void);
  172. void do_coment(void);
  173. void do_extdef(void);
  174. void do_fixupp(void);
  175. void do_grpdef(void);
  176. void do_ledata(void);
  177. void do_lidata(void);
  178. void do_linnum(void);
  179. void do_lnames(void);
  180. void do_modend(void);
  181. void do_pubdef(void);
  182. void do_locsym(void);
  183. void do_segdef(void);
  184. void do_theadr(void);
  185. void do_typdef(void);
  186. void do_unimplt(void);
  187. void exit(int);
  188. byte get_obj_byte(void);
  189.  
  190. if (argc != NUM_ARGS)
  191.    {
  192.     fputs("Usage: readobj filename \n", stderr);
  193.     exit(USAGE_ERR);
  194.    }
  195.  
  196. if ((fp1 = fopen(argv[1], "rb")) == NULL)
  197.    {
  198.     fprintf(stderr,"Can't open %s\n",argv[1]);
  199.     exit(OPEN_ERR);
  200.    }
  201.  
  202. printf("READOBJ by Kip Davidson (73247,620)\n");
  203. printf("\tOS/2 version Dave Cortesi (72155,450)\n\n");
  204.  
  205. c = get_obj_byte();
  206. while (stoppit == 0)
  207.    {
  208.     switch (c)
  209.      {
  210.       case BLKDEF :
  211.             do_blkdef();
  212.             break;
  213.       case BLKEND :
  214.             do_blkend();
  215.             break;
  216.       case THEADR :
  217.             do_theadr();
  218.             break;
  219.       case COMENT :
  220.             do_coment();
  221.             break;
  222.       case MODEND :
  223.             do_modend();
  224.             break;
  225.       case EXTDEF :
  226.             do_extdef();
  227.             break;
  228.       case TYPDEF :
  229.             do_typdef();
  230.             break;
  231.       case PUBDEF :
  232.             do_pubdef();
  233.             break;
  234.       case LOCSYM :
  235.             do_locsym();
  236.             break;
  237.       case LINNUM :
  238.             do_linnum();
  239.             break;
  240.       case LNAMES :
  241.             do_lnames();
  242.             break;
  243.       case SEGDEF :
  244.             do_segdef();
  245.             break;
  246.       case GRPDEF:
  247.             do_grpdef();
  248.             break;
  249.       case FIXUPP :
  250.             do_fixupp();
  251.             break;
  252.       case LEDATA :
  253.             do_ledata();
  254.             break;
  255.       case LIDATA :
  256.             do_lidata();
  257.             break;
  258.       case COMDEF :
  259.             do_comdef();
  260.             break;
  261.       case 0x00 : /* null bytes used in LIB files for padding */
  262.             break; /* skip 'em, a THEADR will show up soon */
  263.       default :
  264.             do_unimplt();
  265.             break;
  266.      }
  267.      c = get_obj_byte();
  268.    }
  269. return(0);
  270. }
  271.  
  272. /************************************************
  273. * get a byte from the object code file pointer  *
  274. ************************************************/
  275. byte get_obj_byte()
  276. {
  277. word w;
  278.  c = (byte)(w =  getc(fp1));
  279.  stoppit = (w == EOF);
  280.  chksum_count = chksum_count + c;
  281.  return(c);
  282. }
  283.  
  284. /************************************************
  285. * get a word from the object code file pointer  *
  286. ************************************************/
  287. word get_obj_word(swap)
  288. byte swap;
  289. {                                /* input -  Hi Lo */
  290.  if (swap)
  291.   {
  292.    c1 = get_obj_byte();
  293.    c2 = get_obj_byte();
  294.    return( (c2 << 8) + c1);       /* swap - Lo Hi */
  295.   }
  296.  else
  297.   {
  298.    c1 = get_obj_byte();
  299.    c2 = get_obj_byte();
  300.    return( (c1 << 8) + c2);       /* noswap - Hi Lo */
  301.   }
  302. }
  303.  
  304. /****************************************************
  305. * return the length of the contents field in bytes  *
  306. ****************************************************/
  307. word get_reclen()
  308. {
  309. word get_obj_word(byte);
  310.  
  311.  reclen = get_obj_word(SWAP);
  312.  printf(" (reclen %04x)\n",reclen);
  313.  return(reclen);
  314. }
  315.  
  316. /*********************
  317. * check the checksum; print only if wrong *
  318. *********************/
  319. void do_checksum()
  320. {
  321. byte get_obj_byte(void);
  322.  
  323.  chksum = get_obj_byte();
  324.  /* printf(" checksum = %02x\n",chksum); */
  325.  chksum_count = (chksum_count - chksum);
  326.  c1 = (chksum_count % 256);
  327.  c2 = -c1;
  328.  if (c2 != chksum)
  329.    {
  330.     printf(" Checksum %02x unequal to computed checksum %02x\n",
  331.            chksum, c2);
  332.    }
  333.  chksum_count = 0;
  334.  return;
  335. }
  336.  
  337. /******************************
  338. * gather up an unsized string into chr_buff *
  339. ******************************/
  340. void get_u_string(num_chars)
  341. byte num_chars;
  342. {
  343. byte get_obj_byte(void);
  344.  
  345.  for(i=0; i < num_chars; i++)
  346.   {
  347.    c = get_obj_byte();
  348.    if ( isprint(c) )
  349.     chr_buff[i] = c;
  350.    else
  351.     chr_buff[i] = BLANK;
  352.   }
  353.  chr_buff[i] = '\0';
  354.  return;
  355. }
  356.  
  357. /***************************
  358. * gather up a sized string into chr_buff *
  359. ***************************/
  360. byte get_s_string()
  361. {
  362. void get_u_string(byte);
  363. byte get_obj_byte(void);
  364.  
  365.  num_bytes = get_obj_byte();
  366.  get_u_string(num_bytes);
  367.  return(num_bytes);
  368. }
  369.  
  370. /******************************
  371. * get index value (1 or 2 bytes) *
  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.   {
  381.    c1 = (c & ~BIT7);
  382.    c2 = get_obj_byte();
  383.    *index = (c1 << 8) + c2;
  384.    return(sizeof(word));
  385.   }
  386.  else
  387.   {
  388.    *index = c;
  389.    return(sizeof(byte));
  390.   }
  391.  return;
  392. }
  393.  
  394. /***************************************************
  395. * Get a COMDEF length, 1 2 3 4 or 5 bytes.         *
  396. ***************************************************/
  397. byte get_varlength(tolong)
  398. long *tolong;
  399. {
  400. byte numform, used, toget, tozero;
  401. byte *zapper;
  402.  
  403.         zapper = (char *)tolong;
  404.         numform = get_obj_byte();
  405.         used = 1;
  406.         if (numform < 128)
  407.         {
  408.                 *zapper++ = numform;
  409.                 toget = 0;
  410.                 tozero = 3;
  411.         }
  412.         else if (numform == 129)
  413.         {
  414.                 toget = 2;
  415.                 tozero = 2;
  416.         }
  417.         else if (numform == 132)
  418.         {
  419.                 toget = 3;
  420.                 tozero = 1;
  421.         }
  422.         else /* four-byte number */
  423.         {
  424.                 toget = 4;
  425.                 tozero = 0;
  426.         }
  427.         for (; toget; --toget, ++used)
  428.                 *zapper++ = get_obj_byte();
  429.         for (; tozero; --tozero)
  430.                 *zapper++ = 0;
  431.         return(used);
  432. }
  433.  
  434. /*********************************************************
  435. * print out an Lname if there is one of the given index  *
  436. **********************************************************/
  437. void put_name(inx)
  438. word inx;
  439. {
  440.     if (inx)
  441.         if (inx < Lnames_index)
  442.             printf("%s\n",Lnames[inx]);
  443.         else
  444.             printf("???\n");
  445.     else
  446.         printf("{nul}\n");
  447. }
  448.  
  449. /***********************************************
  450. * dump a given number of record bytes in hex   *
  451. ***********************************************/
  452. void dumpn(cnt)
  453. word cnt;
  454. {
  455. byte b[16];
  456. word adr, p, q;
  457.     adr = 0;
  458.     while ( (adr < cnt) && (stoppit == 0) )
  459.     {
  460.         q = cnt-adr; if (q > 16) q = 16;
  461.         for (p=0; p<q; p++)
  462.             b[p] = get_obj_byte();
  463.         printf("%04x  ",adr);
  464.         for (p=0; p<q; p++)
  465.             printf("%02x ",b[p]);
  466.         for (; p<16; p++)
  467.             printf("   ");
  468.         for (p=0; p<q; p++)
  469.             printf("%c", ((31<b[p])&&(b[p]<127))?b[p]:'.');
  470.         printf("\n");
  471.         adr += q;
  472.     }
  473. }
  474. /**************************
  475. * print out THEADR record *
  476. **************************/
  477. void do_theadr()
  478. {
  479. void do_checksum(void);
  480. byte get_s_string(void);
  481. word get_reclen(void);
  482.  
  483.  printf("\n80h: THEADR");
  484.  reclen = get_reclen();
  485.  get_s_string();
  486.  printf("\tmodule = %s\n",chr_buff);
  487.  do_checksum();
  488.  return;
  489. }
  490.  
  491. /**************************
  492. * print out COMENT record *
  493. * -including support for OS/2 dynalink record class A0h *
  494. **************************/
  495. void do_coment()
  496. {
  497. void do_checksum(void);
  498. byte get_obj_byte(void);
  499. word get_reclen(void);
  500. word get_obj_word(byte);
  501. void get_u_string(byte);
  502. byte get_s_string(void);
  503. byte purge,list,class;
  504. word ordinal;
  505.  
  506.  printf("88h: COMENT");
  507.  reclen = get_reclen() - 1;
  508.  c1 = get_obj_byte();
  509.  purge = (c1 & BIT7) >> 7;
  510.  list = (c1 & BIT6) >> 6;
  511.  class = get_obj_byte();
  512.  printf("\tclass = %01x, purge = %01x, list = %01x\n",
  513.                   class,        purge,         list);
  514.  if (class != 0xa0)
  515.  {
  516.      num_bytes = reclen - 2; /* adust for flag, class */
  517.      get_u_string(num_bytes);
  518.      printf("\tComment = \"%s\"\n",chr_buff);
  519.      switch (class)
  520.      {
  521.          case 0x00: printf("\t\tcompiler name, /dsalloc\n"); break;
  522.          case 0x9c: printf("\t\tDOS version\n"); break;
  523.          case 0x9d: printf("\t\tmemory model\n"); break;
  524.          case 0x9e: printf("\t\tforce /dosseg order\n"); break;
  525.          case 0x9f: printf("\t\tlibrary specifier\n"); break;
  526.          case 0x81: printf("\t\tlibrary specifier (obs.)\n"); break;
  527.          case 0xa1: printf("\t\tMSoft extension marker\n"); break;
  528.      }
  529.  }
  530.  else /* dynamic link import record */
  531.  {
  532.         list = get_obj_byte();
  533.         class = get_obj_byte();
  534.         printf("\tdynalink import, flag1 %02x, flag2 %02x\n",list,class);
  535.         num_bytes = get_obj_byte();
  536.         get_u_string(num_bytes);
  537.         printf("\tName = %s",chr_buff);
  538.         num_bytes = get_obj_byte();
  539.         get_u_string(num_bytes);
  540.         printf(", Module = %s",chr_buff);
  541.         if (class)
  542.         {
  543.             ordinal = get_obj_word(SWAP);
  544.             printf(", Ordinal %d\n",ordinal);
  545.         }
  546.         else
  547.         {
  548.             num_bytes = get_obj_byte();
  549.             get_u_string(num_bytes);
  550.             printf(", Entry = %s\n",chr_buff);
  551.         }
  552.  }
  553.  do_checksum();
  554.  return;
  555. }
  556.  
  557. /**************************
  558. * print out LNAMES record *
  559. **************************/
  560. void do_lnames()
  561. {
  562. void do_checksum(void);
  563. byte get_obj_byte(void);
  564. word get_reclen(void);
  565. word sum,name_index;
  566.  
  567.     printf("96h: LNAMES");
  568.     reclen = get_reclen();
  569.     reclen = reclen - 1;  /* adjust for checksum byte */
  570.     sum = 0;
  571.     while (sum < reclen)
  572.     {
  573.         num_bytes = get_obj_byte();  /* get length of string */
  574.         sum = sum + (num_bytes + 1); /* account for length */
  575.         name_index = Lnames_index;  /* next free entry */
  576.         if (name_index > MAX_LNAME_ENTRIES) /* no more free */
  577.             name_index = 0; /* 0th entry always free */
  578.         if (num_bytes != 0)   /* check for a null name */
  579.         {
  580.             for(i=0; i < num_bytes; i++)
  581.                 Lnames[name_index][i] = get_obj_byte();
  582.         }
  583.         else
  584.         {
  585.             Lnames[name_index][0] = '{';
  586.             Lnames[name_index][1] = '}';
  587.             i=2;
  588.         }
  589.         Lnames[name_index][i] = '\0';
  590.         printf("\t%02x  %s", name_index, Lnames[name_index]);
  591.         if (name_index != 0)
  592.         {
  593.             Lnames_index++;
  594.             printf("\n");
  595.         }
  596.         else
  597.             printf(" (no room for this name)\n");
  598.     }
  599.     Lnames_total = Lnames_index - 1;
  600.     do_checksum();
  601. return;
  602. }
  603.  
  604. /**************************
  605. * print out SEGDEF record *
  606. **************************/
  607. void do_segdef()
  608. {
  609. void do_checksum(void);
  610. byte get_index(word *);
  611. byte get_obj_byte(void);
  612. word get_obj_word(byte);
  613. word get_reclen(void);
  614. byte align,combine,big;
  615. word abs_fn,abs_off;
  616. word seg_len;
  617. word seg_index,class_index,ovl_index;
  618.  
  619.  printf("98h: SEGDEF");
  620.  reclen = get_reclen();
  621.  c = get_obj_byte();
  622.  align = (c & (BIT7+BIT6+BIT5)) >> 5;
  623.  combine = (c & (BIT4+BIT3+BIT2)) >> 2;
  624.  big = (c & BIT1) >> 1;
  625.  printf("\tAlignment = %s\n",align_msg[align]);
  626.  if (align == 0)
  627.   {
  628.    abs_fn = get_obj_word(SWAP);
  629.    abs_off = get_obj_word(SWAP);
  630.    printf("\t\tFrame = %04x : Offset = %04x\n",
  631.           abs_fn,abs_off);
  632.   }
  633.  printf("\tCombine = %s\n",combine_msg[combine]);
  634.  seg_len = get_obj_word(SWAP);
  635.  
  636.  printf("\tSegment length =");
  637.  if (big == 1)
  638.    printf(" 64K\n");
  639.  else
  640.    printf(" %04x\n",seg_len);
  641.  
  642.  get_index(&seg_index);
  643.  printf("\tSegment name = ");
  644.  put_name(seg_index);
  645.  
  646.  get_index(&class_index);
  647.  printf("\tSegment class = ");
  648.  put_name(class_index);
  649.  
  650.  get_index(&ovl_index);
  651.  printf("\tSegment overlay = ");
  652.  put_name(ovl_index);
  653.  
  654.  if (Snames_index > MAX_SNAME_ENTRIES)
  655.   {
  656.    printf(" No room to store SNAME\n");
  657.    Snames_index = MAX_SNAME_ENTRIES+1;
  658.    Snames_total = MAX_SNAME_ENTRIES;
  659.   }
  660.  else
  661.   {
  662.    Snames[Snames_index][SNAME_SEG] = seg_index;
  663.    Snames[Snames_index][SNAME_CLASS] = class_index;
  664.    Snames[Snames_index][SNAME_OVL] = ovl_index;
  665.    Snames_index++;
  666.    Snames_total = (Snames_index - 1);
  667.   }
  668.  do_checksum();
  669.  return;
  670. }
  671.  
  672. /**************************
  673. * print out GRPDEF record *
  674. **************************/
  675. void do_grpdef()
  676. {
  677. void do_checksum(void);
  678. byte get_index(word *);
  679. byte get_obj_byte(void);
  680. word get_reclen(void);
  681. word index;
  682. word sum;
  683.  
  684.  printf("9Ah: GRPDEF");
  685.  reclen = get_reclen();
  686.  /* adjust reclen for checksum */
  687.  reclen = reclen - 1;
  688.  sum = get_index(&index);
  689.  printf("\tGroup = "); put_name(index);
  690.  while (sum < reclen)
  691.  {
  692.      c = get_obj_byte(); /* read the FFh */
  693.      sum++;
  694.      sum += get_index(&index);
  695.      printf("\t\tsegment = ");
  696.      put_name(Snames[index][SNAME_SEG]);
  697.  }
  698.  do_checksum();
  699.  return;
  700. }
  701.  
  702. /**************************
  703. * print out EXTDEF record *
  704. **************************/
  705. void do_extdef()
  706. {
  707. void do_checksum(void);
  708. byte get_obj_byte(void);
  709. word get_reclen(void);
  710. void get_u_string(byte);
  711. word sum;
  712. word type_index;
  713.  
  714.  printf("8Ch: EXTDEF");
  715.  reclen = get_reclen();
  716.  reclen = reclen - 1;   /* adjust reclen for checksum byte */
  717.  sum = 0;
  718.  while (sum < reclen)
  719.   {
  720.    num_bytes = get_obj_byte();
  721.    sum = sum + (num_bytes + 1);
  722.    get_u_string(num_bytes);
  723.    sum += get_index(&type_index);
  724.    printf("\ttype %04x, name = %s\n",
  725.           type_index,chr_buff);
  726.   }
  727.  do_checksum();
  728.  return;
  729. }
  730.  
  731. /**************************
  732. * print out COMDEF record *
  733. * defines communal (FORTRAN COMMON, any C public array) variable *
  734. **************************/
  735. void do_comdef()
  736. {
  737.  
  738. void do_checksum(void);
  739. byte get_obj_byte(void);
  740. word get_obj_word(byte);
  741. word get_reclen(void);
  742. byte get_index(word *);
  743. byte get_varlength(long *);
  744. byte get_s_string(void);
  745.  
  746. byte seg_type;
  747. word sum, type_index;
  748. long num_elem, size_elem;
  749.  
  750.  printf("B0h: COMDEF");
  751.  reclen = get_reclen() - 1;
  752.  sum = 0;
  753.  while (sum < reclen)
  754.  {
  755.         sum += get_s_string() + 1;
  756.         sum += get_index(&type_index);
  757.         seg_type = get_obj_byte(); sum++;
  758.         if (seg_type == 0x61) /* FAR */
  759.                 sum += get_varlength(&num_elem);
  760.         sum += get_varlength(&size_elem);
  761.         printf("\ttype = %04x, segtype = %02x, name = %s\n",
  762.                     type_index,       seg_type,     chr_buff);
  763.         if (seg_type == 0x61)
  764.                 printf("\t\t %l items of length %l\n",
  765.                           num_elem,        size_elem);
  766.         else
  767.                 printf("\t\titem size %l\n",size_elem);
  768.  }
  769.  do_checksum();
  770.  return;
  771. }
  772.  
  773. /**************************
  774. * print out LEDATA record *
  775. **************************/
  776. void do_ledata()
  777. {
  778. void do_checksum(void);
  779. byte get_obj_byte(void);
  780. byte get_index(word *);
  781. word get_reclen(void);
  782. word sum, index;
  783.  
  784.  printf("A0h: LEDATA");
  785.  reclen = get_reclen() - 1;
  786.  sum = get_index(&index);
  787.  printf("\tSegment = "); put_name(Snames[index][SNAME_SEG]);
  788.  i = get_obj_word(SWAP);
  789.  sum += 2;
  790.  printf("\tEnumerated data offset = %04x\n",i);
  791.  dumpn(reclen - sum);
  792.  do_checksum();
  793.  return;
  794. }
  795.  
  796. /**************************
  797. * print out BLKDEF record *
  798. **************************/
  799. void do_blkdef()
  800. {
  801. void do_checksum(void);
  802. byte get_obj_byte(void);
  803. word get_reclen(void);
  804.  
  805.  printf("7Ah: BLKDEF");
  806.  reclen = get_reclen();
  807.  dumpn(reclen-1);
  808.  do_checksum();
  809.  return;
  810. }
  811.  
  812. /**************************
  813. * print out BLKEND record *
  814. **************************/
  815. void do_blkend()
  816. {
  817. void do_checksum(void);
  818. byte get_obj_byte(void);
  819. word get_reclen(void);
  820.  
  821.  printf("7Ch: BLKEND");
  822.  reclen = get_reclen();
  823.  dumpn(reclen-1);
  824.  do_checksum();
  825.  return;
  826. }
  827.  
  828. /**************************
  829. * print out MODEND record *
  830. **************************/
  831. void do_modend()
  832. {
  833. void do_checksum(void);
  834. byte get_obj_byte(void);
  835. word get_reclen(void);
  836. byte flags, ismain, hasadr;
  837.  
  838.  printf("8Ah: MODEND");
  839.  reclen = get_reclen();
  840.  flags = get_obj_byte();
  841.  ismain = (flags >> 7)&0x01;
  842.  hasadr = (flags >> 6)&0x01;
  843.  printf("\tModType = %02x, main: %c, start address: %c\n",
  844.                 flags,
  845.                 ismain ? '1' : '0',
  846.                 hasadr ? '1' : '0');
  847.  dumpn(reclen-2);
  848.  do_checksum();
  849.  return;
  850. }
  851.  
  852. /**************************
  853. * print out TYPDEF record *
  854. **************************/
  855. void do_typdef()
  856. {
  857. void do_checksum(void);
  858. byte get_obj_byte(void);
  859. word get_reclen(void);
  860.  
  861.  printf("8Eh: TYPDEF");
  862.  reclen = get_reclen();
  863.  dumpn(reclen-1);
  864.  do_checksum();
  865.  return;
  866. }
  867.  
  868. /**************************
  869. * print out PUBDEF record *
  870. **************************/
  871. void do_pubdef()
  872. {
  873. void do_checksum(void);
  874. byte get_obj_byte(void);
  875. word get_reclen(void);
  876. word grp, seg, frame, type, sum;
  877.  
  878.  printf("90h: PUBDEF");
  879.  reclen = get_reclen();
  880.  reclen -= 1; /* adjust for checksum */
  881.  sum = get_index(&grp);
  882.  printf("\tGroup ="); put_name(grp);
  883.  sum += get_index(&seg);
  884.  if (seg)
  885.  {
  886.      printf("\tSegment = ");
  887.      put_name(Snames[seg][SNAME_SEG]);
  888.  }
  889.  else
  890.  {
  891.      i = get_obj_word(SWAP);
  892.      sum += 2;
  893.      printf("\tSegment = 0, Frame = %04x\n",i);
  894.  }
  895.  while (sum < reclen)
  896.  {
  897.      sum += get_s_string() + 1;
  898.      i = get_obj_word(SWAP);
  899.      sum += 2;
  900.      sum += get_index(&type);
  901.      printf("\t\ttype %04x, offset %04x, name = %s\n",
  902.                         type,         i,        chr_buff);
  903.  }
  904.  do_checksum();
  905.  return;
  906. }
  907.  
  908. /**************************
  909. * print out LOCSYM record (identical to PUBDEF) *
  910. **************************/
  911. void do_locsym()
  912. {
  913. void do_checksum(void);
  914. byte get_obj_byte(void);
  915. word get_reclen(void);
  916. word grp, seg, frame, type, sum;
  917.  
  918.  printf("92h: LOCSYM");
  919.  reclen = get_reclen();
  920.  reclen -= 1; /* adjust for checksum */
  921.  sum = get_index(&grp);
  922.  printf("\tGroup ="); put_name(grp);
  923.  sum += get_index(&seg);
  924.  if (seg)
  925.  {
  926.      printf("\tSegment = ");
  927.      put_name(Snames[seg][SNAME_SEG]);
  928.  }
  929.  else
  930.  {
  931.      i = get_obj_word(SWAP);
  932.      sum += 2;
  933.      printf("\tSegment = 0, Frame = %04x\n",i);
  934.  }
  935.  while (sum < reclen)
  936.  {
  937.      sum += get_s_string() + 1;
  938.      i = get_obj_word(SWAP);
  939.      sum += 2;
  940.      sum += get_index(&type);
  941.      printf("\t\ttype %04x, offset %04x, name = %s\n",
  942.                         type,         i,        chr_buff);
  943.  }
  944.  do_checksum();
  945.  return;
  946. }
  947.  
  948. /**************************
  949. * print out LINNUM record *
  950. **************************/
  951. void do_linnum()
  952. {
  953. void do_checksum(void);
  954. byte get_obj_byte(void);
  955. word get_reclen(void);
  956. word grp, seg, number, offset, sum;
  957.  
  958.  printf("94h: LINNUM");
  959.  reclen = get_reclen() - 1;
  960.  sum = get_index(&grp);
  961.  printf("\tGroup = "); put_name(grp);
  962.  sum += get_index(&seg);
  963.  if (seg)
  964.  {
  965.      printf("\tSegment = ");
  966.      put_name(Snames[seg][SNAME_SEG]);
  967.  }
  968.  else printf("\tSegment = 0\n");
  969.  while (sum < reclen)
  970.  {
  971.      number = get_obj_word(SWAP);
  972.      offset = get_obj_word(SWAP);
  973.      sum += 4;
  974.      printf("\t\tNumber = %04x, offset = %04x\n",number,offset);
  975.  }
  976.  do_checksum();
  977.  return;
  978. }
  979.  
  980. /**************************
  981. * print out FIXUPP record *
  982. **************************/
  983. void do_fixupp()
  984. {
  985. void do_checksum(void);
  986. byte get_obj_byte(void);
  987. word get_reclen(void);
  988.  
  989.  printf("9Ch: FIXUPP");
  990.  reclen = get_reclen();
  991.  dumpn(reclen - 1);
  992.  do_checksum();
  993.  return;
  994. }
  995.  
  996. /**************************
  997. * print out LIDATA record *
  998. **************************/
  999. void do_lidata()
  1000. {
  1001. void do_checksum(void);
  1002. byte get_obj_byte(void);
  1003. word get_reclen(void);
  1004.  
  1005.  printf("A2h: LIDATA");
  1006.  reclen = get_reclen();
  1007.  dumpn(reclen - 1);
  1008.  do_checksum();
  1009.  return;
  1010. }
  1011.  
  1012. /*********************************
  1013. * unimplemented record type trap *
  1014. *********************************/
  1015. void do_unimplt()
  1016. {
  1017. void do_checksum(void);
  1018. byte get_obj_byte(void);
  1019. word get_reclen(void);
  1020. word dumplen;
  1021.  
  1022.  printf("%02xh: unknown record type",c);
  1023.  dumplen = (reclen = get_reclen()) - 1;
  1024.  dumpn(dumplen);
  1025.  do_checksum();
  1026.  return;
  1027. }
  1028.