home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume22 / omfdump / part01 / omfdump.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-31  |  19.8 KB  |  1,104 lines

  1. /*
  2.  * (C) Copyright 1991 Stephen A. Bleazard <Steve@RoboBar.Co.Uk>
  3.  * 
  4.  * Permission is granted to redistribute this program and any derivatives
  5.  * thereof in source or binary form, for any purpose, including commercial
  6.  * use, provided that this copyright message is retained in the source code
  7.  * and is reproduced in full in any documentation that accompanies such
  8.  * redistribution.  Source code redistribution is encouraged, but is not
  9.  * mandatory.  The rcsid string above must be retained unmodified in any 
  10.  * redistributed binary.
  11.  *
  12.  * NO WARRANTY:  This software is licensed free of charge without any claim
  13.  * regarding its fitness for any purpose.  The Licensor cannot accept
  14.  * responsibility for any damage arising from the use or inability to use
  15.  * this software for any purpose.
  16.  */
  17.  
  18. char rcsid[] = "@(#) $Id: omfdump.c,v 1.1 1991/08/29 15:17:56 root Exp $";
  19.  
  20. #ifdef __TSC__
  21. #  include <io.h>
  22. #  include <stdlib.h>
  23. #  include <alloc.h>
  24. #  include <stdarg.h>
  25. #else
  26. #  include <varargs.h>
  27. extern char *sys_errlist[];
  28. extern int errno;
  29. #endif /* __TSC __ */
  30.  
  31. #ifdef i386
  32. #  undef i386
  33. #endif /* because I have variables called i386 */
  34.  
  35. #include <ctype.h>
  36. #include <stdio.h>
  37. #include <string.h>
  38. #include <fcntl.h>
  39. #include <ar.h>
  40. #include "xenixomf.h"
  41.  
  42. #define  HDRSIZE    3
  43. #define  TRUE        1
  44. #define  FALSE        0
  45.  
  46. #define  NOERROR    0
  47. #define  NODATA        1
  48. #define  ILLSTRLEN    2
  49.  
  50. #define  EXT_EXTERN    0
  51. #define  EXT_LOC_EXT    1
  52. #define  EXT_FLOC_EXT    2
  53.  
  54. #define  PUB_16        0
  55. #define  PUB_32        1
  56. #define  PUB_LOC_32    2
  57. #define  PUB_LOC_16    3
  58.  
  59. typedef struct sName {
  60.     char *name;
  61.     struct sName *next;
  62. } Name;
  63.  
  64. FILE *infile;
  65. FILE *outfile;
  66. int prevrdoff = 0, lastrdoff = 0;
  67. int lnamecnt = 1, extdefcnt = 1, segdefcnt = 1, grpdefcnt = 1;
  68. Name *lnamelst = NULL, *lastlname = NULL;
  69. int error = NOERROR;
  70. int rawdump = FALSE;
  71.  
  72.  
  73. void dump();
  74.  
  75. main(argc, argv)
  76. char **argv;
  77. int argc;
  78. {
  79.     int opt;
  80.     extern optind;
  81.  
  82.     infile = stdin;  outfile = stdout;
  83. #ifdef __TSC__
  84.     setmode(fileno(infile), O_BINARY);
  85. #endif /* __TSC __ */
  86.     
  87.     while ((opt = getopt(argc, argv, "rv")) != EOF)
  88.     {
  89.         switch (opt)
  90.         {
  91.         case 'v':
  92.             fprintf(stderr, "omfdump version %s\n", rcsid + 5);
  93.             fprintf(stderr, "report bugs to steve@robobar.co.uk\n");
  94.             break;
  95.         case 'r':
  96.             rawdump = TRUE;
  97.             break;
  98.         case '?':
  99.             fprintf(stderr, "usage: omfdump [-r] file1...\n");
  100.             exit(1);
  101.             break;
  102.         }
  103.     }
  104.  
  105.     if (optind >= argc)
  106.         dump();
  107.     else
  108.     {
  109.         for ( ; optind < argc; optind++ )
  110.         {
  111.             if ((infile = fopen(argv[optind], "rb")) == NULL)
  112.             {
  113.                 fprintf(stderr, "omfdump: cannot open %s (%s)\n",
  114.                     argv[optind], sys_errlist[errno]);
  115.             }
  116.             else
  117.                 dump();
  118.             fclose(infile);
  119.         }
  120.     }
  121. }
  122.  
  123. void abend(s)
  124. char *s;
  125. {
  126.     fprintf(stderr, "Fatal Error: %s\n", s);
  127.     exit(1);
  128. }
  129.  
  130. #ifdef __TSC__
  131. void output(char *fmt, ...)
  132. {
  133.     va_list args;
  134.  
  135.     va_start(args, fmt);
  136.     if (error == NOERROR)
  137.          vfprintf(outfile, fmt, args);
  138.     va_end(args);
  139. }
  140. #else /* __TSC__ */
  141. void output(va_alist)
  142. va_dcl
  143. {
  144.     char *fmt;
  145.     va_list args;
  146.  
  147.     va_start(args);
  148.     fmt = va_arg(args, char *);
  149.     if (error == NOERROR)
  150.          vfprintf(outfile, fmt, args);
  151.     va_end(args);
  152. }
  153. #endif /* __TSC__ */
  154.  
  155. void setinfilepos(pos)
  156. long pos;
  157. {
  158.     fseek(infile, pos, 0);
  159.     prevrdoff = lastrdoff = pos;
  160. }
  161.  
  162. int rdbytes(buff, count)
  163. char *buff;
  164. int count;
  165. {
  166.     prevrdoff = lastrdoff;
  167.     lastrdoff += count;
  168.     return (fread(buff, 1, count, infile) == count);
  169. }
  170.  
  171. void skiprecord(reclen)
  172. int *reclen;
  173. {
  174.     while (*reclen > 1)
  175.     {
  176.         unsigned char junk;
  177.  
  178.         if (!rdbytes(&junk, 1))
  179.             *reclen = 0;
  180.         (*reclen)--;
  181.     }
  182. }
  183.  
  184. int checkcnt(from, count)
  185. int *from, count;
  186. {
  187.     if ((*from - 1) < count)
  188.     {
  189.         output("\nWarning: Not enough data in record\n");
  190.         error = NODATA;
  191.         skiprecord(from);
  192.         return FALSE;
  193.     }
  194.     *from -= count;
  195.     return TRUE;
  196. }
  197.  
  198. void rddata(buff, count)
  199. char *buff;
  200. int count;
  201. {
  202.     if (!rdbytes(buff, count))
  203.         abend("unexpected end of file");
  204. }
  205.  
  206. unsigned short rdmagic()
  207. {
  208.     unsigned short magic;
  209.  
  210.     rddata(&magic, sizeof magic);
  211.     return magic;
  212. }
  213.  
  214. int rdarhdr(name, size)
  215. char *name;
  216. long *size;
  217. {
  218.     char cjunk;
  219.     short sjunk;
  220.     long ljunk;
  221.  
  222.     if (!rdbytes(name, 14))
  223.         return FALSE;
  224.     rddata(&ljunk, sizeof(long));
  225.     rddata(&cjunk, sizeof(char));
  226.     rddata(&cjunk, sizeof(char));
  227.     rddata(&sjunk, sizeof(short));
  228.     rddata(size, sizeof(long));
  229.     return TRUE;
  230. }
  231.  
  232. long rdvint(count, reclen)
  233. int count;
  234. int *reclen;
  235. {
  236.     long val = 0;
  237.     unsigned char b;
  238.     int i = 0;
  239.  
  240.     if (!checkcnt(reclen, count))
  241.         return -1;
  242.     while (i < count)
  243.     {
  244.         rddata(&b, 1);
  245.         val = val | ((long)b << ( 8 * i));
  246.         i++;
  247.     }
  248.     return val;
  249. }
  250.  
  251. long rdoffset(i386, reclen)
  252. int i386;
  253. int *reclen;
  254. {
  255.     return rdvint(i386 ? 4 : 2, reclen);
  256. }
  257.  
  258. unsigned int rdword(reclen)
  259. int *reclen;
  260. {
  261.     return (unsigned int)rdvint(2, reclen);
  262. }
  263.  
  264. unsigned char rdbyte(reclen)
  265. int *reclen;
  266. {
  267.     unsigned char b;
  268.  
  269.     if (!checkcnt(reclen, 1))
  270.         return 0;
  271.     rddata(&b, 1);
  272.     return b;
  273. }
  274.  
  275. unsigned int rdindex(reclen)
  276. int *reclen;
  277. {
  278.     unsigned char b, b1;
  279.  
  280.     b = rdbyte(reclen);
  281.     if (b < 128)
  282.         return b;
  283.     b1 = rdbyte(reclen);
  284.     return (((unsigned int)b & 0x7f) << 8) + b1;
  285. }
  286.  
  287. void rdomfstr(name, reclen)
  288. char *name;
  289. int *reclen;
  290. {
  291.     unsigned char l;
  292.  
  293.     l = rdbyte(reclen);
  294.     if (l > OMFNAMELENGTH)
  295.     {
  296.         output("\nWarning: illegal string length - skipping record\n");
  297.         name[0] = '\0';
  298.         error = ILLSTRLEN;
  299.         skiprecord(reclen);
  300.         return;
  301.     }
  302.     if (!checkcnt(reclen, l))
  303.     {
  304.         name[0] = '\0';
  305.         return;
  306.     }
  307.     rddata(name, l);  name[l] = '\0';
  308. }
  309.  
  310. void addtolnamelst(s)
  311. char *s;
  312. {
  313.     Name *node;
  314.     int count;
  315.  
  316.     count = strlen(s);
  317.     node = (Name *)malloc(sizeof(Name));
  318.     node->next = NULL;
  319.     if (lastlname == NULL)
  320.         lnamelst = node;
  321.     else
  322.         lastlname->next = node;
  323.     lastlname = node;
  324.     node->name = (char *)malloc(count + 1);
  325.     strncpy(node->name, s, count);
  326.     node->name[count] = '\0';
  327. }
  328.  
  329. displaylname(fp, index)
  330. FILE *fp;
  331. unsigned int index;
  332. {
  333.     int i;
  334.     Name *node = lnamelst;
  335.  
  336.  
  337.     for (i = 1; i < index; i++)
  338.     {
  339.         if (node->next == NULL)
  340.             break;
  341.         else
  342.             node = node->next;
  343.     }
  344.     output("\"%s\"", (node == NULL) ? "NoName" : node->name);
  345.     
  346. }
  347.  
  348. void dumpbytes(data, count)
  349. unsigned char *data;
  350. {
  351.     int i;
  352.  
  353.     output("%6s", "");
  354.     for (i = 0; i < count; i++)
  355.     {
  356.         output("%02x ", data[i]);
  357.         if (i == 7) output(" ");
  358.     }
  359.     for (i = 16 - count; i > 0; i--)
  360.         output("   ");
  361.     output("  ");
  362.     
  363.     for (i = 0; i < count; i++)
  364.     {
  365.         char c = ((data[i] > 32) && (data[i] < 127)) ? data[i] : '.';
  366.         output("%c", c);
  367.     }
  368.     output("\n");
  369. }
  370.  
  371. void dumpdata(count)
  372. int count;
  373. {
  374.     unsigned char buff[16];
  375.  
  376.     while (count != 0)
  377.     {
  378.         int size = count > 16 ? 16 : count;
  379.  
  380.         rddata(buff, size);
  381.         dumpbytes(buff, size);
  382.         count -= size;
  383.     }
  384. }
  385.  
  386. void outomfstr(p)
  387. unsigned char *p;
  388. {
  389.     output("%c", '\"');
  390.     while (*p != '\0')
  391.     {
  392.         unsigned char c = *p++;
  393.  
  394.         output((c > 31) && (c <= 128) ? "%c" : "\\%03o", c);
  395.     }
  396.     output("%c", '\"');
  397. }
  398.  
  399. void skipchksum(reclen)
  400. int reclen;
  401. {
  402.     unsigned char b;
  403.  
  404.     if (reclen > 1)
  405.     {
  406.         output("%d bytes of trailing garbage:\n", reclen - 1);
  407.         dumpdata(reclen - 1);
  408.     }
  409.     else if (reclen < 1)
  410.         output("No checksum");
  411.     else
  412.         rddata(&b, 1);
  413. }
  414.  
  415. void theadr(reclen)
  416. int reclen;
  417. {
  418.     unsigned char buff[OMFNAMELENGTH+2];
  419.  
  420.     output("THEADR  ");
  421.     rdomfstr(buff, &reclen);
  422.     outomfstr(buff);
  423.     output("\n");
  424.     skipchksum(reclen);
  425. }
  426.  
  427. void coment(reclen)
  428. int reclen;
  429. {
  430.     unsigned char class, bits;
  431.  
  432.     output("COMENT  ");
  433.     bits = rdbyte(&reclen);
  434.     class = rdbyte(&reclen);
  435.     output("%s, ", (bits & CMT_PURGE) ? "NOPURGE" : "PURGE");
  436.     output("%s, ", (bits & CMT_LIST) ? "NOLIST" : "LIST");
  437.     output("CLASS = %d\n", class);
  438.     dumpdata(reclen - 1);
  439.     skipchksum(1);
  440. }
  441.  
  442. void lnames(reclen)
  443. int reclen;
  444. {
  445.     unsigned char buff[OMFNAMELENGTH+2]; /* include space for length byte */
  446.     int i = 1;
  447.  
  448.     output("LNAMES  ");
  449.     while (reclen > 1)
  450.     {
  451.         rdomfstr(buff, &reclen);
  452.         addtolnamelst(buff);
  453.         output(i > 1 ? "%17d " : "%3d ", lnamecnt);
  454.         outomfstr(buff);
  455.         output("\n");
  456.         i++;  lnamecnt++;
  457.     }
  458.     skipchksum(1);
  459. }
  460.  
  461. void segdef(reclen, i386)
  462. int reclen, i386;
  463. {
  464.     unsigned int segname, classname, overlayname;
  465.     long seglen;
  466.     unsigned char attr;
  467.     unsigned int frame, offset;
  468.  
  469.     attr = rdbyte(&reclen);
  470.     if ((attr & SD_ALIGN) == 0)
  471.     {
  472.         frame = rdword(&reclen);
  473.         offset = rdword(&reclen);
  474.     }
  475.     seglen = rdoffset(i386, &reclen);
  476.     segname = rdindex(&reclen);
  477.     classname = rdindex(&reclen);
  478.     overlayname = rdindex(&reclen);
  479.  
  480.     if (i386)
  481.         output("SEG386 %4d:  ", segdefcnt++);
  482.     else
  483.         output("SEGDEF %4d:  ", segdefcnt++);
  484.  
  485.     displaylname(outfile, segname);
  486.     output(", Class = ");
  487.     displaylname(outfile, classname);
  488.     output(", ");
  489.  
  490.     switch (attr & SD_COMBO)
  491.     {
  492.         case SD_PRIV: output("NO COMBINE, "); break;
  493.         case SD_HCOMM: output("HIGH_MEM COMM, "); break;
  494.         case SD_PUBLIC: output("PUBLIC, "); break;
  495.         case SD_BAD: output("UNDEFINED, "); break;
  496.         case SD_C4: output("NOT-KNOWN, "); break;
  497.         case SD_STACK: output("STACK, "); break;
  498.         case SD_COMM: output("COMMON, "); break;
  499.         case SD_RCOMM: output("REV-COMM, "); break;
  500.     }
  501.  
  502.     switch (attr & SD_ALIGN)
  503.     {
  504.         case SD_ABS:output("ABSOLUTE (%d:%d),",frame,offset);break;
  505.         case SD_BYTE: output("BYTE, "); break;
  506.         case SD_WORD: output("WORD, "); break;
  507.         case SD_PARA: output("PARA, "); break;
  508.         case SD_PAGE: output("PAGE, "); break;
  509.         case SD_DWORD: output("DWORD, "); break;
  510.         case SD_LTL: output("LOAD-TIME, "); break;
  511.         case 7: output("UKNOWN(7), "); break;
  512.     }
  513.  
  514.     if (attr & SD_PGRES)
  515.         output("PAGE-RES, ");
  516.     if (i386)
  517.     {
  518.         if (attr & SD_64K)
  519.             output("Len = %ld(B)", seglen);
  520.         else
  521.             output("Len = %ld", seglen);
  522.     }
  523.     else
  524.     {
  525.         if (attr & SD_64K)
  526.         {
  527.             output("Len = 65536");
  528.             if (seglen != 0)
  529.                 output("(B, length != 0(%ld))",seglen);
  530.             else
  531.                 output("(B)");
  532.         }
  533.         else
  534.             output("Len = %ld", seglen);
  535.     }
  536.     output("\n");
  537.     skipchksum(reclen);
  538. }
  539.  
  540. void grpdef(reclen)
  541. int reclen;
  542. {
  543.     unsigned int grpname;
  544.  
  545.     grpname = rdindex(&reclen);
  546.     output("GRPDEF %4d:  ", grpdefcnt++);
  547.     displaylname(outfile, grpname);
  548.     output("\n");
  549.  
  550.     while (reclen > 1)
  551.     {
  552.         unsigned char junk;
  553.         int segindex;
  554.  
  555.         junk = rdbyte(&reclen);
  556.         segindex = rdindex(&reclen);
  557.         output("%6sSI = %d\n", "", segindex);
  558.     }
  559.     skipchksum(1);
  560. }
  561.  
  562. void extdef(reclen, type)
  563. int reclen;
  564. int type;
  565. {
  566.     int i = 1;
  567.  
  568.     switch (type)
  569.     {
  570.         case EXT_EXTERN:   output("EXTDEF  ");  break;
  571.         case EXT_LOC_EXT:  output("LOCEXD  ");  break;
  572.         case EXT_FLOC_EXT: output("FLCEXD  ");  break;
  573.     }
  574.     while (reclen > 1)
  575.     {
  576.         int type;
  577.         unsigned char buff[OMFNAMELENGTH+2];
  578.         
  579.         rdomfstr(buff, &reclen);
  580.         type = rdindex(&reclen);
  581.         output(i > 1 ? "%17d " : "%3d ", extdefcnt);
  582.         outomfstr(buff);
  583.         output("\n");
  584.         extdefcnt++; i++;
  585.     }
  586.     skipchksum(reclen);
  587.  
  588. }
  589.  
  590. void pubdef(reclen, rtype)
  591. int reclen;
  592. int rtype;
  593. {
  594.     unsigned int grpindex, segindex, framenum;
  595.  
  596.     grpindex = rdindex(&reclen);
  597.     segindex = rdindex(&reclen);
  598.     if (grpindex == 0 && segindex == 0)
  599.         framenum = rdword(&reclen);
  600.  
  601.     switch (rtype)
  602.     {
  603.         case PUB_32:     output("PUB386  ");  break;
  604.         case PUB_16:     output("PUBDEF  ");  break;
  605.         case PUB_LOC_32: output("LPB386  ");  break;
  606.         case PUB_LOC_16: output("LOCPUB  ");  break;
  607.     }
  608.  
  609.     output("GI = %d,  SI = %d", grpindex, segindex);
  610.     if (grpindex == 0 && segindex == 0)
  611.         output(", Frame no. = 0x%x\n", framenum);
  612.     else
  613.         output("\n");
  614.  
  615.     while (reclen > 1)
  616.     {
  617.         unsigned char buff[OMFNAMELENGTH+2];
  618.         unsigned long offset; 
  619.         int type;
  620.         int i386 = (rtype == PUB_32) || (rtype == PUB_LOC_32);
  621.  
  622.         rdomfstr(buff, &reclen);
  623.         offset = rdoffset(i386, &reclen);
  624.         type = rdindex(&reclen);
  625.  
  626.         output("%18s", "");
  627.         outomfstr(buff);
  628.         output("  Offset = 0x%lx\n", offset);
  629.     }
  630.     skipchksum(reclen);
  631. }
  632.  
  633. void frametype(method, index)
  634. unsigned int method;
  635. unsigned int index;
  636. {
  637.     switch (method)
  638.     {
  639.         case FRM_SI: output("SI(%d)", index); break;
  640.         case FRM_GI: output("GI(%d)", index); break;
  641.         case FRM_EI: output("EI(%d)", index); break;
  642.         case FRM_ABS: output("ABS(0x%x)", index); break;
  643.         case FRM_LOC: output("LOCATION"); break;
  644.         case FRM_TRGT: output("TARGET"); break;
  645.     }
  646. }
  647.  
  648. void targettype(method, index)
  649. unsigned int method;
  650. unsigned int index;
  651. {
  652.     switch (method)
  653.     {
  654.         case TGT_SI: output("SI(%d)", index); break;
  655.         case TGT_GI: output("GI(%d)", index); break;
  656.         case TGT_EI: output("EI(%d)", index); break;
  657.         case TGT_ABS: output("ABS(0x%x)", index); break;
  658.         case TGT_SI_0: output("SI(%d)", index); break;
  659.         case TGT_GI_0: output("GI(%d)", index); break;
  660.         case TGT_EI_0: output("EI(%d)", index); break;
  661.         case TGT_ABS_0: output("ABS(0x%x)", index); break;
  662.     }
  663. }
  664.  
  665. void threadfixup(i386, reclen, trd)
  666. int i386;
  667. int *reclen;
  668. unsigned char trd;
  669. {
  670.     unsigned int index;
  671.     int method;
  672.  
  673.     output("THREAD:  ");
  674.     method = (trd & TRD_MTHDMSK) >> TRD_MTHDSHFT;
  675.     if (trd & TRD_FRAME)
  676.     {
  677.         if (method < 4)
  678.             index = rdindex(reclen);
  679.         output("FRAME=");
  680.         frametype(method, index);
  681.     }
  682.     else
  683.     {
  684.         index = rdindex(reclen);
  685.         output("TARGET=");
  686.         targettype(method, index);
  687.     }
  688.     output(", THREAD=%d\n", trd & TRD_THRED);
  689. }
  690.  
  691. void displayfixdat(i386, dat, reclen)
  692. int i386;
  693. int dat;
  694. int *reclen;
  695. {
  696.     unsigned int  frame, index, target;
  697.  
  698.     frame = (dat & FIXDAT_FRAME) >> FIXDAT_FRSHFT;
  699.     if (dat & FIXDAT_FTHRD)
  700.         output("Thread %d", frame);
  701.     else
  702.     {
  703.         if (frame < 4)
  704.             index = rdindex(reclen);
  705.         frametype(frame, index);
  706.     }
  707.  
  708.     output("  TARGET=");
  709.     target = dat & FIXDAT_TRGT;
  710.     if (dat & FIXDAT_TTHRD)
  711.         output("Thread %d", target);
  712.     else
  713.     {
  714.         index = rdindex(reclen);
  715.         targettype(target, index);
  716.     }
  717.  
  718.     if ((dat & FIXDAT_TSCND) == 0)
  719.         output("+0x%lx", rdoffset(i386, reclen));
  720. }
  721.  
  722. void fixupfixup(i386, reclen, locat)
  723. int i386;
  724. int *reclen;
  725. unsigned int locat;
  726. {
  727.     unsigned int off, loc, fixdat;
  728.  
  729.     output("FIX @");
  730.     off = locat & FIX_DATAOFF;
  731.     loc = (locat & FIX_LOCMSK) >> FIX_LOCSHFT;
  732.     output("0x%x  Mode=%s", off, locat & FIX_SEG ? "Seg":"Self");
  733.     output(", LOC=");
  734.     switch (loc)
  735.     {
  736.         case LOC_LOBYTE:    output("LoByte");  break;
  737.         case LOC_OFFSET:    output("Offset");  break;
  738.         case LOC_BASE:    output("Base");  break;
  739.         case LOC_POINTER:    output("Pointer");  break;
  740.         case LOC_HIBTE:    output("HiByte");  break;
  741.         case LOC_OFFSETL:    output("offset (link res)");  break;
  742.         case LOC_OFFSET32:    output("32 bit offset");  break;
  743.         case LOC_POINTER48:    output("48 bit pointer");  break;
  744.         case LOC_OFFSETL32:    output("32 bit offset (link res)");  break;
  745.         default:        output("Unknown");  break;
  746.     }
  747.  
  748.     output(" => FRAME=");
  749.     fixdat = rdbyte(reclen);
  750.     displayfixdat(i386, fixdat, reclen);
  751.     output("\n");
  752. }
  753.  
  754. void fixup(i386, reclen)
  755. int i386;
  756. int reclen;
  757. {
  758.     unsigned char b;
  759.  
  760.     if (i386)
  761.         output("FIX386\n");
  762.     else
  763.         output("FIXUPP\n");
  764.  
  765.     while (reclen > 1)
  766.     {
  767.         output("%6s", "");
  768.         b = rdbyte(&reclen);
  769.         if (b & FIX_FIXUP)
  770.         {
  771.             unsigned int locat;
  772.  
  773.             locat = (b << 8) | rdbyte(&reclen);
  774.             fixupfixup(i386, &reclen, locat);
  775.         }
  776.         else
  777.             threadfixup(i386, &reclen, b);
  778.     }
  779.     skipchksum(1);
  780. }
  781.  
  782. void comdef(reclen)
  783. int reclen;
  784. {
  785.     int i = 1;
  786.  
  787.     output("COMDEF  ");
  788.  
  789.     while (reclen > 1)
  790.     {
  791.         int type, flag;
  792.         long size, width;
  793.         unsigned char buff[OMFNAMELENGTH+2];
  794.         
  795.         output(i > 1 ? "%17d " : "%3d ", extdefcnt);
  796.         rdomfstr(buff, &reclen);
  797.         outomfstr(buff);
  798.         output(", ");
  799.         flag = rdbyte(&reclen);
  800.         if (flag != 0)
  801.         {
  802.             output("Debug = 0x%02x", flag);
  803.             flag = rdbyte(&reclen);
  804.             output(" 0x%02x, ", flag);
  805.         }
  806.         type = rdbyte(&reclen);
  807.         if (type == TD_CNEAR) output("NEAR, ");
  808.         else if (type == TD_CFAR) output("FAR, ");
  809.         else output("unknown, ");
  810.         
  811.         size = rdbyte(&reclen);
  812.         if (size > 128)
  813.         {
  814.             switch (size)
  815.             {
  816.                 case 129: size = rdvint(2, &reclen);  break;
  817.                 case 132: size = rdvint(3, &reclen);  break;
  818.                 case 136: size = rdvint(4, &reclen);  break;
  819.             }
  820.         }
  821.             
  822.         if (type == 0x61)
  823.         {
  824.             width = rdbyte(&reclen);
  825.             if (width > 128)
  826.             {
  827.                 switch (width)
  828.                 {
  829.                     case 129: width = rdvint(2, &reclen);  break;
  830.                     case 132: width = rdvint(3, &reclen);  break;
  831.                     case 136: width = rdvint(4, &reclen);  break;
  832.                 }
  833.             }
  834.             
  835.             output("element width=%ld bytes, ", width);
  836.             output("size=%ld elements\n", size);
  837.         }
  838.         else
  839.             output("Size=%ld bytes\n", size);
  840.         extdefcnt++; i++;
  841.     }
  842.     skipchksum(1);
  843. }
  844.  
  845. void modend(i386, reclen)
  846. int i386;
  847. int reclen;
  848. {
  849.     int type, saddr, enddat;
  850.  
  851.     if (i386)
  852.         output("386END  ");
  853.     else
  854.         output("MODEND  ");
  855.  
  856.     type = rdbyte(&reclen);
  857.  
  858.     saddr = 0;
  859.     switch ((type >> 6) & 3)
  860.     {
  861.         case 1:
  862.         output("NON-MAIN Start address = ");
  863.         saddr = 1;
  864.         break;
  865.         case 3:
  866.         output("MAIN Start address = ");
  867.         saddr = 1;
  868.         break;
  869.     }
  870.     if (saddr)
  871.     {
  872.         enddat = rdbyte(&reclen);
  873.         displayfixdat(i386, enddat, &reclen);
  874.     }
  875.     output("\n");
  876.     skipchksum(reclen);
  877. }
  878.  
  879. void ledata(i386, reclen)
  880. int i386;
  881. int reclen;
  882. {
  883.     int segindex;
  884.     long offset;
  885.  
  886.     if (i386)
  887.         output("LED386  ");
  888.     else
  889.         output("LEDATA  ");
  890.  
  891.     segindex = rdindex(&reclen);
  892.     offset = rdoffset(i386, &reclen);
  893.     output("SI = %d,  Offset = 0x%lx\n", segindex, offset);
  894.     dumpdata(reclen - 1);
  895.     skipchksum(1);
  896. }
  897.  
  898. void linnum(i386, reclen)
  899. int i386;
  900. int reclen;
  901. {
  902.     int segindex, grpindex;
  903.  
  904.     if (i386)
  905.         output("LIN386  ");
  906.     else
  907.         output("LINNUM  ");
  908.  
  909.     grpindex = rdindex(&reclen);
  910.     segindex = rdindex(&reclen);
  911.     output("SI = %d\n", segindex);
  912.     while (reclen > 1)
  913.     {
  914.         int line;
  915.         long offset;
  916.  
  917.         line = rdword(&reclen);
  918.         offset = rdoffset(i386, &reclen);
  919.         output("%6sLine = %d,  ", "", line);
  920.         output("Offset = 0x%lx\n", offset);
  921.     }
  922.     skipchksum(1);
  923. }
  924.  
  925. void dumprec(rectype, reclen)
  926. int rectype, reclen;
  927. {
  928.     error = NOERROR;
  929.     output("%5x ", prevrdoff);
  930.     
  931.     if (rawdump)
  932.     {
  933.         output("Record type = 0x%02x  ", rectype);
  934.         output("length = %d\n", reclen);
  935.         dumpdata(reclen);
  936.     }
  937.     else
  938.     {
  939.         switch (rectype) {
  940.             case MLNAMES:
  941.             lnames(reclen);
  942.             break;
  943.             case MTHEADR:
  944.             theadr(reclen);
  945.             break;
  946.             case MCOMENT:
  947.             coment(reclen);
  948.             break;
  949.             case MSEGDEF:
  950.             segdef(reclen, FALSE);
  951.             break;
  952.             case MSEG386:
  953.             segdef(reclen, TRUE);
  954.             break;
  955.             case MGRPDEF:
  956.             grpdef(reclen);
  957.             break;
  958.             case MPUBDEF:
  959.             pubdef(reclen, PUB_16);
  960.             break;
  961.             case MPUB386:
  962.             pubdef(reclen, PUB_32);
  963.             break;
  964.             case MLOCPUB:
  965.             pubdef(reclen, PUB_LOC_16);
  966.             break;
  967.             case MLPB386:
  968.             pubdef(reclen, PUB_LOC_32);
  969.             break;
  970.             case MEXTDEF:
  971.             extdef(reclen, EXT_EXTERN);
  972.             break;
  973.             case MLOCEXD:
  974.             extdef(reclen, EXT_LOC_EXT);
  975.             break;
  976.             case MFLCEXD:
  977.             extdef(reclen, EXT_FLOC_EXT);
  978.             break;
  979.             case MFIXUPP:
  980.             fixup(FALSE, reclen);
  981.             break;
  982.             case MFIX386:
  983.             fixup(TRUE, reclen);
  984.             break;
  985.             case MCOMDEF:
  986.             comdef(reclen);
  987.             break;
  988.             case M386END:
  989.             modend(TRUE, reclen);
  990.             break;
  991.             case MLEDATA:
  992.             ledata(FALSE, reclen);
  993.             break;
  994.             case MLED386:
  995.             ledata(TRUE, reclen);
  996.             break;
  997.             case MMODEND:
  998.             modend(FALSE, reclen);
  999.             break;
  1000.             case MLINNUM:
  1001.             linnum(FALSE, reclen);
  1002.             break;
  1003.             case MLIN386:
  1004.             linnum(TRUE, reclen);
  1005.             break;
  1006.             default:
  1007.             output("Record type = 0x%02x  ", rectype);
  1008.             output("length = %d\n", reclen);
  1009.             dumpdata(reclen);
  1010.             break;
  1011.         }
  1012.     }
  1013. }
  1014.  
  1015. void dumpobj()
  1016. {
  1017.     unsigned char buff[HDRSIZE+2];
  1018.  
  1019.     while (rdbytes(buff, HDRSIZE))
  1020.     {
  1021.         int rectype, reclen;
  1022.  
  1023.         rectype = buff[0];
  1024.         reclen = buff[1] | ((int)buff[2] << 8);
  1025.         dumprec(rectype, reclen);
  1026.     }
  1027. }
  1028.  
  1029. void dumparsymdef(size)
  1030. {
  1031.     char len;
  1032.     char name[256];
  1033.     long addr;
  1034.     unsigned short scount;
  1035.  
  1036.     for (rddata(&scount, sizeof(unsigned short)); scount > 0; scount--)
  1037.     {
  1038.         rddata(&len, 1);
  1039.         rddata(name, len);
  1040.         name[len] = 0;
  1041.         rddata(&addr, sizeof(long));
  1042.         size -= len + 1 + sizeof(long);
  1043.         output("0x%08x  %s\n", addr, name);
  1044.     }
  1045. }
  1046.  
  1047. void dumparobj(size)
  1048. long size;
  1049. {
  1050.     long ftell();
  1051.     long startpos;
  1052.     unsigned char buff[HDRSIZE+2];
  1053.  
  1054.     startpos = ftell(infile);
  1055.     while (((ftell(infile) - startpos) < size) && rdbytes(buff, HDRSIZE))
  1056.     {
  1057.         int rectype, reclen;
  1058.  
  1059.         rectype = buff[0];
  1060.         reclen = buff[1] | ((int)buff[2] << 8);
  1061.         dumprec(rectype, reclen);
  1062.     }
  1063. }
  1064.  
  1065. void dumpar()
  1066. {
  1067.     long ftell();
  1068.     char name[15];
  1069.     long size, memcount = 0, memoffset;
  1070.  
  1071.     rdmagic();
  1072.     
  1073.     name[14] = '\0';  memoffset = ftell(infile);
  1074.     while (rdarhdr(name, &size))
  1075.     {
  1076.         output("\n%s:\n", name);
  1077.         if (!memcount && (strcmp(name, "__.SYMDEF") == 0))
  1078.             dumparsymdef(size);
  1079.         else
  1080.             dumparobj(size);
  1081.         memcount++;
  1082.         memoffset += 26 + size;
  1083.         if (memoffset & 1) memoffset++;
  1084.         setinfilepos(memoffset);
  1085.     }
  1086. }
  1087.  
  1088. void dump()
  1089. {
  1090.     unsigned short magic;
  1091.  
  1092.     prevrdoff = 0; lastrdoff = 0;
  1093.     lnamecnt = 1; extdefcnt = 1; segdefcnt = 1; grpdefcnt = 1;
  1094.     lnamelst = NULL; lastlname = NULL;
  1095.     error = NOERROR;
  1096.  
  1097.     magic = rdmagic();
  1098.     setinfilepos(0L);
  1099.     if (magic == XARMAG)
  1100.         dumpar();
  1101.     else
  1102.         dumpobj();
  1103. }
  1104.