home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sd386v50.zip / sd386src.zip / DISASM.C < prev    next >
Text File  |  1996-03-08  |  38KB  |  582 lines

  1. /*****************************************************************************/
  2. /* File:                                             IBM INTERNAL USE ONLY   */
  3. /*   disasm.c                                                                */
  4. /*                                                                           */
  5. /* Description:                                                              */
  6. /*   Contains functions that deal with disassembly for SD/86.                */
  7. /*                                                                           */
  8. /* History:                                                                  */
  9. /*                                                                           */
  10. /*...16->32 port.                                                            */
  11. /*...                                                                        */
  12. /*... 02/08/91  100   Philip    port to 32 bit.                              */
  13. /*... 02/08/91  101   Joe       port to 32 bit.                              */
  14. /*... 02/08/91  102   Pratima   port to 32 bit.                              */
  15. /*... 02/08/91  103   Dave      port to 32 bit.                              */
  16. /*... 02/08/91  104                                                          */
  17. /*... 02/08/91  105   Christina port to 32 bit.                              */
  18. /*... 02/08/91  106   Srinivas  port to 32 bit.                              */
  19. /*... 02/08/91  107   Dave      port to 32 bit.                              */
  20. /*... 02/08/91  108   Dave      port to 32 bit.                              */
  21. /*... 02/08/91  109                                                          */
  22. /*... 02/08/91  110   Srinivas  port to 32 bit.                              */
  23. /*... 02/08/91  111   Christina port to 32 bit.                              */
  24. /*... 02/08/91  112   Joe       port to 32 bit.                              */
  25. /*... 02/08/91  113                                                          */
  26. /*... 02/08/91  114                                                          */
  27. /*... 02/08/91  115   Srinivas  port to 32 bit.                              */
  28. /*... 02/08/91  116   Joe       port to 32 bit.                              */
  29. /*                                                                           */
  30. /*...Release 1.00 (Pre-release 1)                                            */
  31. /*...                                                                        */
  32. /*... 07/09/91  201   srinivas  single line disassembly when stepping into   */
  33. /*                              a system dll.                                */
  34. /*... 08/30/91  235   Joe       Cleanup/rewrite ascroll() to fix several bugs*/
  35. /*                              a system dll.                                */
  36. /*...                                                                        */
  37. /*...Release 1.00 (Pre-release 108 12/05/91)                                 */
  38. /*...                                                                        */
  39. /*... 02/18/92  534   Srinivas  Double execution lines in disassembly view   */
  40. /*                              when we have REP instruction.                */
  41. /*...                                                                        */
  42. /*...Release 1.00 (03/03/92)                                                 */
  43. /*...                                                                        */
  44. /*... 03/18/92  606   Srinivas  Handle multiple segment numbers in lno table */
  45. /*...                           due to alloc_text pragma.                    */
  46. /*... 12/14/93  911   Joe       Hang showing PL/X disassembly of select stmt.*/
  47. /** Includes *****************************************************************/
  48.                                         /*                                   */
  49. #include "all.h"                        /* SD86 include files                */
  50.                                         /*                                   */
  51. /** Macros *******************************************************************/
  52.                                         /*                                   */
  53. #define VBAR         179                /* vertical bar character            */
  54. #define ROLLBACK     300                /* bytes to start back scrolling.    */
  55. #define CHUNKOFBYTES 300                /* number of bytes to read at a   235*/
  56.                                         /* time while forming instr cache.235*/
  57. #define MAXINSTLENGTH 25                /*                                235*/
  58.                                         /*                                   */
  59. /** Externs ******************************************************************/
  60.                                         /*                                   */
  61. extern PtraceBuffer AppPTB;             /*                                   */
  62. extern uint         AL86orMASM;         /* AL86 or MASM mnemonics flag.      */
  63. extern int          CacheAnchorIndex;   /*                                235*/
  64. extern int          InstrCacheSize;     /*                                235*/
  65. extern INSTR       *icache;             /* instruction cache.             235*/
  66. extern uint         MneChange;          /* flag to tell DBDisa about a       */
  67. extern uchar        AllocTextFlag;      /* flag to know of alloc_text     606*/
  68.                                         /*                                   */
  69. static UINT MidLastOff;                 /* last offset of mod in segment.    */
  70. static UINT MidFirstOff;                /* first offset of module in segment.*/
  71.  
  72. UINT   CurrentMid;                      /* current disasm mid.               */
  73. /*****************************************************************************/
  74. /* DBDisa                                                complete rewrite 235*/
  75. /*                                                                           */
  76. /* Description:                                                              */
  77. /*   returns an index in the instruction cache of addr and ensures           */
  78. /*   that there will be rows instructions after addr. The delta              */
  79. /*   is a bias that is used for backing up in the instruction stream.        */
  80. /*   It is the number of instructions "before" the addr.                     */
  81. /*                                                                           */
  82. /* Parameters:                                                               */
  83. /*   mid        input - module id.                                           */
  84. /*   addr       input - instruction address in cache.                        */
  85. /*   rows       input - number of instructions to disassemble.               */
  86. /*   delta      input - number of rows to adjust before addr.                */
  87. /*                                                                           */
  88. /* Return:                                                                   */
  89. /*   index      the index of addr in the cache.                              */
  90. /*                                                                           */
  91. /* Assumptions:                                                              */
  92. /*                                                                           */
  93. /*  -addr is valid and its pdf can be found.                                 */
  94. /*  -addr will always be in the current cache-if this were not true, the     */
  95. /*   last disassembly would not exist.                                       */
  96. /*                                                                           */
  97. /*****************************************************************************/
  98.   int
  99. DBDisa( uint mid, uint addr, uint rows, int delta )
  100. {
  101.  uint     midoff;                       /* base addr of module.              */
  102.  uint     modlen;                       /* length of module.                 */
  103.  uint     instaddr;                     /* just an instruction address.      */
  104.  int      index;                        /* just a counter.                   */
  105.  DEBFILE *pdf;                          /* ->pdf containing the mid.         */
  106.  int      found;                        /* flag for find of addr in cache.   */
  107.  uint     FirstAddrInCache;             /*                                   */
  108.  int      RowsLeftInCache;              /*                                   */
  109.  
  110. /*****************************************************************************/
  111. /* Handle special case to rebuild cache. This is currently only called       */
  112. /* for a change in mnemonics. The AL86orMASM global determines which         */
  113. /* set of mnemonics we use.                                                  */
  114. /*****************************************************************************/
  115.  if( addr == 0 && rows == 0)
  116.  {
  117.   cache( icache[0].instaddr, MidLastOff );
  118.   return(0);
  119.  }
  120.  
  121. /*****************************************************************************/
  122. /* setup new static values if the module changed sinve we were here last.    */
  123. /* - get base address and length of the module.                              */
  124. /* - setup some static values.                                               */
  125. /* - do the initial cache.                                                   */
  126. /*****************************************************************************/
  127.  pdf         = FindExeOrDllWithAddr( addr );
  128.  midoff      = DBLsegInfo( addr, &modlen, pdf );
  129.  MidFirstOff = midoff;
  130.  MidLastOff  = midoff + modlen - 1;
  131.  if( (mid != CurrentMid) || (mid == FAKEMID) )
  132.  /****************************************************************************/
  133.  /* If the mid is a FAKEMID then rebuild the tables, since the FAKEMID       */
  134.  /* corresponds to all the unknown address space.                            */
  135.  /****************************************************************************/
  136.  {
  137.   CurrentMid = mid;
  138.   cache(addr,MidLastOff);
  139.  }
  140.  
  141. FINDADDRINCACHE:
  142.   /***************************************************************************/
  143.   /* find add in cache.                                                      */
  144.   /***************************************************************************/
  145.   found = TRUE;
  146.   index = FindAddrInCache( addr );
  147.   if( index == ADDRNOTFOUND )
  148.     found = FALSE;
  149.  
  150.   /***************************************************************************/
  151.   /* - If delta = 0 and we found the addr in the cache, then test to         */
  152.   /*   see if there are enough instructions left in the cache to quench      */
  153.   /*   rows. If so, return the index. If the rows can't be quenched, then    */
  154.   /*   move the cache down in the instruction stream. If addr is not         */
  155.   /*   currently in the cache, then build a new cache.                       */
  156.   /*                                                                         */
  157.   /* - after go back and you will be successful this time.                   */
  158.   /*                                                                         */
  159.   /***************************************************************************/
  160.   if( delta == 0 )
  161.   {
  162.    RowsLeftInCache = InstrCacheSize - index;
  163.    if( found == TRUE )
  164.    {
  165.     if( rows <= (uint)RowsLeftInCache )
  166.      return(index);
  167.     /*************************************************************************/
  168.     /* - It's possible that there may not be enough lines in the cache    911*/
  169.     /*   to quench the request for rows. If that's the case,then          911*/
  170.     /*   cache the addr so that it will be at the 0 index in the cache.   911*/
  171.     /*   This is only likely to happen in PL/X.                           911*/
  172.     /*************************************************************************/
  173.     if( index != 0 )                                                    /*911*/
  174.      cache(addr,MidLastOff);                                            /*911*/
  175.     return(0); /* return index = 0 */                                   /*911*/
  176.    }
  177.    if( found == TRUE )
  178.     cache( icache[CacheAnchorIndex].instaddr , MidLastOff );
  179.    else
  180.    {
  181.     FirstAddrInCache = rollback ( addr, -CacheAnchorIndex, MidFirstOff);
  182.     cache(FirstAddrInCache,MidLastOff);
  183.    }
  184.    goto FINDADDRINCACHE;
  185.   }
  186.  
  187.   /*****************************************************************************/
  188.   /* Handle delta < 0. Here we test to see if there are delta instructions     */
  189.   /* available in the cache before the addr. If so, we simply return an index. */
  190.   /* Other wise we backup in the instruction stream and re-cache.              */
  191.   /*                                                                           */
  192.   /*****************************************************************************/
  193.   if( delta < 0 )
  194.   {
  195.    if( index < -delta )
  196.    {
  197.     instaddr = rollback ( addr, -CacheAnchorIndex, MidFirstOff);
  198.     cache(instaddr,MidLastOff);
  199.     index =  FindAddrInCache( addr );
  200.     for( ; delta < 0 && index > 0 ; index--,delta++){;}
  201.    }
  202.    else
  203.     index += delta;
  204.    return( index );
  205.   }
  206.  return(0);
  207. }
  208.  
  209. /*****************************************************************************/
  210. /* FindAddrInCache()                                  ( function added )  235*/
  211. /*                                                                           */
  212. /* Description:                                                              */
  213. /*   Finds the index of an address in the instruction cache.                 */
  214. /*                                                                           */
  215. /* Parameters:                                                               */
  216. /*   addr       input - address to be found.                                 */
  217. /*                                                                           */
  218. /* Return:                                                                   */
  219. /*   index      index of the addr.                                           */
  220. /*                                                                           */
  221. /* Assumptions:                                                              */
  222. /*                                                                           */
  223. /*                                                                           */
  224. /*****************************************************************************/
  225.  int
  226. FindAddrInCache( uint addr )
  227. {
  228.  int index;
  229.  for (index = 0; icache[index].instaddr != ENDOFCACHE &&
  230.                  index < InstrCacheSize; index++)
  231.  {
  232.   if( icache[index].instaddr==addr )
  233.    return( index );
  234.  }
  235.  return( ADDRNOTFOUND );
  236. }
  237.  
  238. /*****************************************************************************/
  239. /* rollback                                                                  */
  240. /*                                                                           */
  241. /* Description:                                                              */
  242. /*   adjusts an address backwards in the instruction stream.                 */
  243. /*                                                                           */
  244. /* Parameters:                                                               */
  245. /*   iap        ->current instruction (where we are sitting in showA window).*/
  246. /*   deltai     number of instructions to adjust iap by.                     */
  247. /*   fbyte      offset of first byte in current module.                      */
  248. /*   lbyte      offset of last byte in current module.                       */
  249. /*                                                                           */
  250. /* Return:                                                                   */
  251. /*   p          iap modified by deltai worth of instructions (when possible).*/
  252. /*                                                                           */
  253. /* Assumptions:                                                              */
  254. /*                                                                           */
  255. /*   deltai is negative.                                                     */
  256. /*                                                                           */
  257. /*****************************************************************************/
  258.   uint
  259. rollback(uint iap,int deltai,uint fbyte )
  260.                                         /* ->current instruction             */
  261.                                         /* # of instsrs to adj for disasm    */
  262.                                         /* offset of first byte in curr mid  */
  263. {                                       /* begin instdelta                   */
  264.   int   lentab[ROLLBACK];               /* retained instruction lengths      */
  265.   int   i;                              /* index into lentab                 */
  266.   uint  trialiap;                       /* experimental ptr to scroll     107*/
  267.   uchar *streamptr;                     /* ->read in instruction stream   107*/
  268.   uchar type;                           /* indicates 16- or 32-bit code   107*/
  269.   uint  read;                           /* number of bytes read in by DBGetCS*/
  270.   UCHAR bitness;
  271.  
  272. /*****************************************************************************/
  273. /*                                                                           */
  274. /* Scrolling assembly instructions backward is tricky.    The idea is to     */
  275. /* start disassembling (for instruction length only) at a point well behind  */
  276. /* where you currently are and keep track of these lengths.  At some point,  */
  277. /* this stream of disassembly will (about 99.999% of the time!) meet back at */
  278. /* the current instruction.  You can then back track thru an array of lengths*/
  279. /* to figure out the proper address to scroll back to.                       */
  280. /*                                                                           */
  281. /*****************************************************************************/
  282.   if ( deltai < 0 &&                    /* want to delta backward and        */
  283.        iap != fbyte )                   /*   we can ?                     107*/
  284.   {                                     /* begin delta backward              */
  285.     bitness = GetBitness( iap );           /* set type for InstLengthGlob    107*/
  286.     type = (bitness==BIT16)?USE16:USE32;
  287.     trialiap = fbyte;                   /* assume scroll back to mid start107*/
  288.     if ( fbyte + ROLLBACK <  iap )      /* just need rollback amount ?    107*/
  289.       trialiap = iap - ROLLBACK;        /* scroll back shorter amt        107*/
  290.  
  291.     streamptr=GetCodeBytes(trialiap,    /* read in all bytes up thru addr 827*/
  292.                     iap-trialiap,
  293.                     &read);
  294.  
  295.     i = 0;                              /* initialize index into lentab      */
  296.     while( trialiap < iap )             /* still need disasm lengths ?    107*/
  297.     {                                   /* disasm forward till we converge   */
  298.       lentab[i] = InstLengthGlob( streamptr, type ); /* gimme inst len !  107*/
  299.       trialiap += lentab[i];            /* bump to next instr address     107*/
  300.       streamptr += lentab[i++];         /* bump to next instr & next entry107*/
  301.     }                                   /* end disasm frwd till we converge  */
  302.  
  303.     if ( trialiap == iap )              /* did we converge ?              107*/
  304.       for(
  305.            i--;                         /* back up to last instr entry       */
  306.            i >= 0;                      /* make sure we still have entries   */
  307.            i--                          /* back up another entry             */
  308.          )
  309.       {                                 /* add up all instr lengths for delta*/
  310.         iap -= lentab[i];               /* back up by this entry's length 107*/
  311.         if ( !( ++deltai ) )            /* done scrolling back ?             */
  312.           break;                        /* finished adjusting iap            */
  313.       }                                 /* end add up all instr lens for delt*/
  314.   }                                     /* end delta backward                */
  315.  
  316.   return( iap );                        /* give back new deltad address      */
  317. }                                       /* end instdelta                     */
  318. /*****************************************************************************/
  319. /* cache()                                                                   */
  320. /*                                                                           */
  321. /* Description:                                                              */
  322. /*   cache assembler instructions beginning at some address.                 */
  323. /*                                                                           */
  324. /* Parameters:                                                               */
  325. /*   addr       address where to begin disassembly.                          */
  326. /*   lastoff    offset of last byte in current module.                       */
  327. /*                                                                           */
  328. /* Return:                                                                   */
  329. /*   index      number of instructions cached. Could be less than cache size */
  330. /*              when we hit the end of the module.                           */
  331. /*                                                                           */
  332. /* Assumptions:                                                              */
  333. /*                                                                           */
  334. /*   addr is a valid instruction.                                            */
  335. /*                                                                           */
  336. /*****************************************************************************/
  337.  int
  338. cache(uint addr ,uint lastoff)
  339. {
  340.   UCHAR    bitness;
  341.   uchar   *tempptr;                     /* ->DBGet allocated memory space    */
  342.   int     index;                        /*                                   */
  343.   uint    instaddr;                     /*                                   */
  344.   uint    read;                         /* number of bytes read in by DBGet  */
  345.   uint    instlen;
  346.   uchar   hexbuffer[HEXBUFFSIZE];       /* where disassembler puts hex.   108*/
  347.   char    mnebuffer[MNEMBUFFSIZE];      /* where disassembler puts mne.   108*/
  348.   uchar   textbuffer[TEXTBUFFSIZE];     /* where disassembler puts text.  108*/
  349.   uchar   type;                         /* type of module 16 or 32 bit    106*/
  350.   uint    Bytes_Consumed = 0;           /* counter to keep track of no    235*/
  351.   DTIF    packet;                       /* disassembler comm packet          */
  352.                                         /* bytes consumed in instr stream 235*/
  353.    tempptr =  GetCodeBytes(             /* ->instruction stream which is  827*/
  354.                      addr,              /* read in starting at current addr  */
  355.                      CHUNKOFBYTES,      /* for a max of CHUNKOFBYTES bytes   */
  356.                      &read );           /*   (but maybe less available)   106*/
  357.    memset(&packet,0,sizeof(DTIF));      /* clear the comm packet.         101*/
  358.    packet.InstPtr = tempptr;            /* ->read in hex from user app       */
  359.    packet.InstEIP  = 0xffffffff;        /* EIP value for this instr.         */
  360.    packet.Flags.MASMbit=AL86orMASM;     /* use AL/86 or MASM (user decides)  */
  361.    packet.Flags.N387bit  = 1;           /* not a 80x87 processor instr       */
  362.    bitness = GetBitness(addr);
  363.    type = (bitness==BIT16)?USE16:USE32;
  364.    packet.Flags.Use32bit = (ushort) type;
  365.    packet.Flags.Unused1 = 0;            /* make zero due to possible future  */
  366.    instaddr = addr;
  367.    for (index = 0; index < InstrCacheSize; index++)
  368.    {                                    /* disassemble one line at a pop     */
  369.  
  370.  
  371. /*****************************************************************************/
  372. /*                                                                           */
  373. /* Use Dave Toll's disassembler to disassemble the instruction.              */
  374. /*                                                                           */
  375. /*****************************************************************************/
  376.  
  377.     memset(hexbuffer, 0, sizeof(hexbuffer));
  378.     memset(mnebuffer, 0, sizeof(mnebuffer));
  379.     memset(textbuffer, 0, sizeof(textbuffer));
  380.  
  381.  
  382.     packet.HexBuffer = hexbuffer;       /* hexbuffer will have instr stream h*/
  383.     packet.MneBuffer = mnebuffer;       /* -> disassembled mnemonic.         */
  384.     packet.TextBuffer = textbuffer;     /* for disasembly text               */
  385.     DisAsm( ( DTIF * ) &packet );       /* disassemble current instruction   */
  386.  
  387.     icache[index].instaddr = instaddr;
  388.     strcpy(icache[index].mne,mnebuffer);
  389.     strcpy(icache[index].text,textbuffer);
  390.     strcpy(icache[index].hex,hexbuffer);
  391.     instlen = packet.retInstLen;          /* instruction length         */
  392.     icache[index].type     = packet.retType;   /* type of operand info       */
  393.     if(packet.retType == REPETC )         /* instr is of repeat form ?    108*/
  394.     {
  395.      packet.HexBuffer = hexbuffer;
  396.      packet.MneBuffer = mnebuffer;
  397.      packet.TextBuffer = textbuffer;
  398.      DisAsm( ( DTIF * ) &packet );
  399.      strcpy(icache[index].text,mnebuffer);
  400.      strcat(icache[index].hex,hexbuffer);
  401.      instlen  += packet.retInstLen;            /* instruction length         */
  402.     }
  403.     icache[index].len      = instlen;          /* instruction length         */
  404.     icache[index].reg      = packet.retReg;    /* register field             */
  405.     icache[index].offset   = packet.retOffset; /* instrn's offset/displacemnt*/
  406.     icache[index].seg      = packet.retSeg;    /* instrn's selector field    */
  407.     icache[index].base     = packet.retBase;   /* base register field        */
  408.     icache[index].index    = packet.retIndex;  /* index register field       */
  409.     icache[index].scale    = packet.retScale;  /* index register scale    108*/
  410.     icache[index].mod_type = type;             /* module type             106*/
  411.     icache[index].OpSize   = 0;                /* assume 16-bit op size   108*/
  412.     if (packet.retbits.retOpSize)              /* 32-bit op size ?        108*/
  413.       icache[index].OpSize   = 1;
  414.  
  415.     instaddr += instlen;
  416.     Bytes_Consumed += instlen;          /* update the bytes consumed cntr 235*/
  417.  
  418.     if ( instaddr  > lastoff )          /* disassembling past end of mod ?   */
  419.     {
  420.      index++;
  421.      break;                             /* terminate cache with null selector*/
  422.     }
  423.  
  424.     if ( Bytes_Consumed > (CHUNKOFBYTES - MAXINSTLENGTH) )              /*235*/
  425.     {                                                                   /*235*/
  426.       tempptr =  GetCodeBytes(          /* ->instruction stream which is  827*/
  427.                        instaddr,        /* read starting at current addr  235*/
  428.                      CHUNKOFBYTES,      /* for a max of CHUNKOFBYTES bytes235*/
  429.                      &read );           /*   (but maybe less available)   235*/
  430.       Bytes_Consumed = 0;               /* reset the bytes consumed cntr  235*/
  431.       packet.InstPtr = tempptr;         /* ->read in hex from user app    235*/
  432.     }                                                                   /*235*/
  433. /* DumpINSTRStructure( (void*)(&icache[index]) ); */
  434.    }                                    /* end for{} to disassemble.         */
  435.    icache[index].instaddr = NULL;       /* terminate the cache.              */
  436. /* DumpCache( icache); */
  437.  return( index );
  438. }
  439. /*****************************************************************************/
  440. /* GetInstrPacket                                                            */
  441. /*                                                                           */
  442. /* Description:                                                              */
  443. /*   Get the disassembler packet for an instruction.                         */
  444. /*                                                                           */
  445. /* Parameters:                                                               */
  446. /*   addr        input - address of instruction.                             */
  447. /*   packet      input - -> to instruction packet.                           */
  448. /*                       gets filled in by this function.                    */
  449. /*                                                                           */
  450. /* Return:                                                                   */
  451. /*                                                                           */
  452. /* Assumptions:                                                              */
  453. /*                                                                           */
  454. /*  addr is valid.                                                           */
  455. /*                                                                           */
  456. /*****************************************************************************/
  457. #define BLEN 15                         /* bytes of debuggee code to read 107*/
  458.                                         /* for call instruction disassembl   */
  459.  void                                   /*                                   */
  460. GetInstrPacket( uint addr, DTIF *InstrPacket ) /*                         101*/
  461. {                                       /*                                   */
  462.  uchar    hexbuffer[HEXBUFFSIZE];       /* where disassembler puts hex.   108*/
  463.  char     mnebuffer[MNEMBUFFSIZE];      /* where disassembler puts mne.   108*/
  464.  uchar    textbuffer[TEXTBUFFSIZE];     /* where disassembler puts text.  108*/
  465.  uchar   *tempptr;                      /* ->DBGet allocated memory.         */
  466.  uint     read;                         /* bytes read in by DBGet.           */
  467.                                         /*                                   */
  468.  /****************************************************************************/
  469.  /* tempptr allocate and free is managed by DBGet which allocates the        */
  470.  /* buffer and just holds on to it until the next call by any caller.        */
  471.  /****************************************************************************/
  472.  tempptr =  GetCodeBytes(addr,BLEN,&read); /* read BLEN bytes from debugge827*/
  473.  InstrPacket->InstPtr = tempptr;        /* ->read in hex from user app       */
  474.  InstrPacket->InstEIP  = 0xffffffff;    /* EIP value for this instr->        */
  475.  InstrPacket->Flags.MASMbit=1;          /* 1 for masm disassembly.           */
  476.  InstrPacket->Flags.N387bit  = 1;       /* not a 80x87 processor instr       */
  477.  InstrPacket->Flags.Unused1 = 0;        /* make zero due to possible futur   */
  478.  /****************************************************************************/
  479.  /* We don't really care about these buffers at this time. We put them       */
  480.  /* in to satisfy the disassembler.                                          */
  481.  /****************************************************************************/
  482.  memset(hexbuffer, 0, sizeof(hexbuffer));
  483.  memset(mnebuffer, 0, sizeof(mnebuffer));
  484.  memset(textbuffer, 0, sizeof(textbuffer));
  485.  InstrPacket->HexBuffer = hexbuffer;    /* hexbuffer will have instr strea   */
  486.  InstrPacket->MneBuffer = mnebuffer;    /* -> disassembled mnemonic.         */
  487.  InstrPacket->TextBuffer = textbuffer;  /* for disasembly text               */
  488.  DisAsm( InstrPacket );                 /* disassemble current instruction   */
  489. }                                       /* end GetInstrPacket.               */
  490. /*************************************************************************101*/
  491. /* InstLength()                                                           101*/
  492. /*                                                                        101*/
  493. /* Description:                                                           101*/
  494. /*   Gets the length of an assembler instruction.                         101*/
  495. /*                                                                        101*/
  496. /* Parameters:                                                            101*/
  497. /*   addr        input - address of instruction.                          101*/
  498. /*                                                                        101*/
  499. /* Return:                                                                101*/
  500. /*               length of instruction.                                   101*/
  501. /*                                                                        101*/
  502. /* Assumptions:                                                           101*/
  503. /*                                                                        101*/
  504. /*   addr is flat.                                                        101*/
  505. /*                                                                        101*/
  506. /*************************************************************************101*/
  507.  uchar                                                                  /*101*/
  508. InstLength( uint addr )                                                 /*101*/
  509. {                                                                       /*101*/
  510.  DTIF    InstrPacket;                                                   /*101*/
  511.  int     PacketSize;                                                    /*101*/
  512.  UCHAR   bitness;                                                       /*101*/
  513.  UCHAR   type;                                                          /*101*/
  514.  
  515.                                                                         /*101*/
  516.  PacketSize = sizeof(InstrPacket);                                      /*101*/
  517.  memset(&InstrPacket,0,PacketSize );                                    /*101*/
  518.  bitness = GetBitness( addr );
  519.  type = (bitness==BIT16)?USE16:USE32;
  520.  InstrPacket.Flags.Use32bit = type;                                     /*101*/
  521.  GetInstrPacket( addr, (DTIF*)&InstrPacket );                           /*101*/
  522.  return(InstrPacket.retInstLen);                                        /*101*/
  523. }                                                                       /*101*/
  524. /*************************************************************************107*/
  525. /* InstLengthGlob()                                                       107*/
  526. /*                                                                        107*/
  527. /* Description:                                                           107*/
  528. /*   Gets the length of an assembler instruction where the instruction    107*/
  529. /*   stream is already in our memory (no more DBGets!).                   107*/
  530. /*                                                                        107*/
  531. /* Parameters:                                                            107*/
  532. /*   inststreamptr  input - points to instruction stream.                 107*/
  533. /*   type           input - 0=>USE16, 1=>USE32.                           107*/
  534. /*                                                                        107*/
  535. /* Return:                                                                107*/
  536. /*                  length of instruction.                                107*/
  537. /*                                                                        107*/
  538. /* Assumptions:                                                           107*/
  539. /*                                                                        107*/
  540. /*    instruction stream already read in via DBGet!                       107*/
  541. /*************************************************************************107*/
  542.  uchar
  543. InstLengthGlob( uchar* inststreamptr, uchar type )
  544. {
  545.  DTIF     InstrPacket;
  546.  int      PacketSize;
  547.  uchar    InstrLen;                     /* instruction length             534*/
  548.  uchar    hexbuffer[HEXBUFFSIZE];       /* where disassembler puts hex.   108*/
  549.  char     mnebuffer[MNEMBUFFSIZE];      /* where disassembler puts mne.   108*/
  550.  uchar    textbuffer[TEXTBUFFSIZE];     /* where disassembler puts text.  108*/
  551.  
  552.  PacketSize = sizeof(InstrPacket);
  553.  memset(&InstrPacket,0,PacketSize );
  554.  InstrPacket.InstPtr=inststreamptr;     /* ->read in hex from user app       */
  555.  InstrPacket.InstEIP=0xffffffff;        /* EIP value for this instr->        */
  556.  InstrPacket.Flags.Use32bit=type;       /* based upon address type           */
  557.  InstrPacket.Flags.MASMbit=1;           /* 1 for masm disassembly.           */
  558.  InstrPacket.Flags.N387bit=1;           /* not a 80x87 processor instr       */
  559.  InstrPacket.Flags.Unused1=0;           /* make zero due to possible futur   */
  560.  /****************************************************************************/
  561.  /* We don't really care about these buffers at this time. We put them       */
  562.  /* in to satisfy the disassembler.                                          */
  563.  /****************************************************************************/
  564.  memset(hexbuffer, 0, sizeof(hexbuffer));
  565.  memset(mnebuffer, 0, sizeof(mnebuffer));
  566.  memset(textbuffer, 0, sizeof(textbuffer));
  567.  InstrPacket.HexBuffer=hexbuffer;       /* hexbuffer will have instr strea   */
  568.  InstrPacket.MneBuffer=mnebuffer;       /* -> disassembled mnemonic.         */
  569.  InstrPacket.TextBuffer=textbuffer;     /* for disasembly text               */
  570.  DisAsm( &InstrPacket );                /* disassemble current instruction   */
  571.  InstrLen = InstrPacket.retInstLen;     /*                                534*/
  572.  if(InstrPacket.retType == REPETC )     /* instr is of repeat form ?      534*/
  573.  {                                      /*                                534*/
  574.    InstrPacket.HexBuffer=hexbuffer;     /* hexbuffer will have instr strea534*/
  575.    InstrPacket.MneBuffer=mnebuffer;     /* -> disassembled mnemonic.      534*/
  576.    InstrPacket.TextBuffer=textbuffer;   /* for disasembly text            534*/
  577.    DisAsm( &InstrPacket );              /* disassemble current instruction534*/
  578.    InstrLen += InstrPacket.retInstLen;  /*                                534*/
  579.  }                                      /*                                534*/
  580.  return(InstrLen);                      /* caller gets instruction length 534*/
  581. }                                       /* end GetInstrPacket.               */
  582.