home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sd386v50.zip / sd386src.zip / UNWIND.C < prev    next >
Text File  |  1996-04-17  |  22KB  |  445 lines

  1. /*****************************************************************************/
  2. /* File:                                             IBM INTERNAL USE ONLY   */
  3. /*   unwind.c                                                                */
  4. /*                                                                           */
  5. /* Description:                                                              */
  6. /*  unwind the user's call stack.                                            */
  7. /*                                                                           */
  8. /*                                                                           */
  9. /* History:                                                                  */
  10. /*                                                                           */
  11. /*****************************************************************************/
  12. #include "all.h"                        /* SD86 include files                */
  13. #include "diaclstk.h"                   /* call stack dialog data         701*/
  14.  
  15. /*
  16.  * The following vectors define active stack frames.  They do NOT include
  17.  * the stack frame for the procedure currently executing.  They are ordered
  18.  * from most recent (subscript 0) to least recent (subscript N).  The
  19.  * total number of active frames is given by NActFrames.  The accuracy
  20.  * of these tables depends on the application using the standard linkage
  21.  * convention:
  22.  *
  23.  *   push bp
  24.  *   mov  bp, sp
  25.  */
  26.  
  27. UINT           NActFrames;
  28. UCHAR          ActCSAtrs[ MAXAFRAMES ]; /* 0 => 16-bit frame 1=>32-bit       */
  29. UINT           ActFrames[ MAXAFRAMES ]; /* value of frame pointer (bp).      */
  30. ULONG          ActFaddrs[ MAXAFRAMES ]; /* value of return addr on stack.    */
  31. UINT           ActFlines[ MAXAFRAMES ] [ 2 ] ; /* mid/lno for ret addr.      */
  32. SCOPE          ActScopes[ MAXAFRAMES ]; /* (mid,ssproc) for return addr.     */
  33.  
  34. extern uchar         VideoAtr;
  35. extern PtraceBuffer  AppPTB;
  36. extern uint          VideoRows;
  37. extern uint          VideoCols;
  38. extern CmdParms      cmd;
  39.  
  40. /* The ActiveProcsMenu procedure displays a list of the active procedures.
  41.  * An item from this list may be selected for a temporary breakpoint, or
  42.  * for finding within the debugger.
  43.  */
  44.  
  45. #define NEARRET         1
  46. #define FARRET          0
  47. #define ATR32           0xD0               /* stack frame is 32-bit       107*/
  48. #define ATR16           0x00               /* stack frame 1s 16-bit       107*/
  49. #define NUM_FRAME_BYTES 12              /* bumped to 12.                  706*/
  50.  
  51. static  int  ShowAllFlag   = FALSE;
  52. static  SCOPE         ExecScope;
  53.  
  54. uint ActiveProcsMenu(AFILE **fpp)
  55. {
  56.  UINT key;
  57.  
  58.  key = Cua_ActiveProcsMenu( fpp );
  59.  return(key);
  60. }
  61.  
  62. /*****************************************************************************/
  63. /*    Same as ActiveProcsMenu function except that it builds the buffer with */
  64. /* with \0 instead of \r and calls dialog routines to process the keys.   701*/
  65. /*****************************************************************************/
  66. uint Cua_ActiveProcsMenu( AFILE **fpp )                                 /*701*/
  67. {                                                                       /*701*/
  68.   int     i, rc, MaxSymLen, SymLen, LongSymLen;                    /*811  701*/
  69.   uint    key;                                                          /*701*/
  70.   uchar   *cp, *buf, *SaveBuffer = NULL;                                /*701*/
  71.   DEBFILE *pdf;                                                         /*701*/
  72.   DIALOGCHOICE  *chptr;                                                 /*701*/
  73.   CALLSTACKPARAM ClstkParam;                                            /*701*/
  74.   int     buflen;
  75.   int     ScrollBar;                                                    /*701*/
  76.  
  77.   for( ;; )                                                             /*701*/
  78.   {                                                                     /*701*/
  79.     chptr = &Dia_Clstk_Choices;                                         /*701*/
  80.  
  81.     MaxSymLen = VideoCols - 6;                                          /*811*/
  82.     buflen = ( (NActFrames + 1)*(MaxSymLen+2) ) + 1 ;
  83.     cp = buf = Talloc( buflen);                                    /*811  701*/
  84.  
  85.     LongSymLen = 0;                                                     /*811*/
  86.     SymLen    = 0;                                                      /*811*/
  87.     for( i = (short)NActFrames; --i >= 0;  )                            /*701*/
  88.     {                                                                   /*701*/
  89.      pdf = FindExeOrDllWithAddr( ActFaddrs[i] );                        /*701*/
  90.      if(pdf != NULL )
  91.       FormatProcName( cp, ActFaddrs[i], ActScopes[i], pdf,              /*824*/
  92.                                ActCSAtrs[i], MaxSymLen);                /*824*/
  93.      else
  94.       sprintf(cp,"%08X Invalid Frame Address",ActFaddrs[i]);
  95.  
  96.      SymLen = strlen(cp);                                               /*824*/
  97.      if( SymLen > MaxSymLen )                                           /*824*/
  98.      {                                                                  /*824*/
  99.       SymLen = MaxSymLen;                                               /*824*/
  100.       cp[SymLen] = '\0';                                                /*824*/
  101.      }                                                                  /*824*/
  102.      if( SymLen > LongSymLen )                                          /*824*/
  103.       LongSymLen = SymLen;                                              /*824*/
  104.      cp += SymLen + 1;                                                  /*824*/
  105.     }                                                                   /*824*/
  106.     /* 906 if terminating check was removed */                          /*701*/
  107.     {                                                                   /*824*/
  108.  
  109.      pdf = FindExeOrDllWithAddr( GetExecAddr() );                       /*901*/
  110.      if( pdf != NULL )
  111.       FormatProcName( cp, GetExecAddr(), ExecScope, pdf,                /*901*/
  112.                            AppPTB.CSAtr, MaxSymLen);                    /*824*/
  113.      else
  114.       sprintf(cp,"%08X Invalid Frame Address",GetExecAddr() );
  115.      SymLen = strlen(cp);                                               /*824*/
  116.      if( SymLen > MaxSymLen )                                           /*824*/
  117.      {                                                                  /*824*/
  118.       SymLen = MaxSymLen;                                               /*824*/
  119.       cp[SymLen] = '\0';                                                /*824*/
  120.      }                                                                  /*824*/
  121.      if( SymLen > LongSymLen )                                          /*824*/
  122.       LongSymLen = SymLen;                                              /*824*/
  123.     }                                                                   /*824*/
  124.  
  125.     chptr->entries = NActFrames + 1;
  126.     chptr->labels  = buf;
  127.  
  128.     if( chptr->entries > 10 )
  129.     {
  130.       chptr->MaxRows = 10;
  131.       Dia_Clstk.length = chptr->MaxRows + 8;
  132.       ScrollBar = TRUE;
  133.     }
  134.     else
  135.     {
  136.       Dia_Clstk.length = chptr->entries + 8;
  137.       chptr->MaxRows = chptr->entries;
  138.       ScrollBar = FALSE;
  139.     }
  140.  
  141.     /*************************************************************************/
  142.     /* At this point, LongSymLen <= MaxSymLen.                               */
  143.     /*************************************************************************/
  144.     Dia_Clstk.width = LongSymLen + 6;
  145.     if( Dia_Clstk.width < 36 )
  146.       Dia_Clstk.width = 36;
  147.     Dia_Clstk.row = (VideoRows - Dia_Clstk.length) / 2;
  148.     Dia_Clstk.col = (VideoCols - Dia_Clstk.width) / 2;
  149.     Dia_Clstk.Buttons[0].row = Dia_Clstk.row + chptr->MaxRows + 4;
  150.     Dia_Clstk.Buttons[0].col = Dia_Clstk.col + 5;
  151.     Dia_Clstk.Buttons[1].row = Dia_Clstk.row + chptr->MaxRows + 4;
  152.     Dia_Clstk.Buttons[1].col = Dia_Clstk.col + Dia_Clstk.width - 16;
  153.     Dia_Clstk.Buttons[2].row = Dia_Clstk.row + chptr->MaxRows + 5;
  154.     Dia_Clstk.Buttons[2].col = Dia_Clstk.col + 5;
  155.     Dia_Clstk.Buttons[3].row = Dia_Clstk.row + chptr->MaxRows + 5;
  156.     Dia_Clstk.Buttons[3].col = Dia_Clstk.col + Dia_Clstk.width - 16;
  157.     Dia_Clstk.Buttons[4].row = Dia_Clstk.row + chptr->MaxRows + 6;
  158.     Dia_Clstk.Buttons[4].col = Dia_Clstk.col + 5;
  159.     Dia_Clstk.Buttons[5].row = Dia_Clstk.row + chptr->MaxRows + 6;
  160.     Dia_Clstk.Buttons[5].col = Dia_Clstk.col + Dia_Clstk.width - 16;
  161.  
  162.     if( SaveBuffer )
  163.     {
  164.       RemoveMsgBox( "Unwinding...", SaveBuffer );
  165.       SaveBuffer = NULL;
  166.     }
  167.     DisplayDialog( &Dia_Clstk, ScrollBar );
  168.     rc = 0;
  169.     ClstkParam.rc = &rc;
  170.     ClstkParam.fpp= fpp;
  171.     key = ProcessDialog( &Dia_Clstk, &Dia_Clstk_Choices, ScrollBar,
  172.                          (void *)&ClstkParam );
  173.     RemoveDialog( &Dia_Clstk );
  174.  
  175.     if( rc != RECIRCULATE )
  176.       return( key );
  177.     else
  178.     {
  179.       SaveBuffer = SayMsgBox4( "Unwinding..." );
  180.       if( key == key_a || key == key_A )
  181.       {
  182.         SetShowAll( TRUE );
  183.         SetActFrames();
  184.         SetShowAll( FALSE );
  185.       }
  186.       else
  187.       {
  188.         SetActFrames();
  189.       }
  190.     }
  191.   }
  192. }
  193.  
  194. void FormatProcName( uchar *buf, uint addr, SCOPE scope, DEBFILE *pdf,  /*824*/
  195.                        uchar FrameAtr, int MaxSymLen)                   /*824*/
  196. {                                                                       /*824*/
  197.  uchar *cp;                                                             /*824*/
  198.  ushort Sel;                                                            /*824*/
  199.  ushort Off;                                                            /*824*/
  200.                                                                         /*824*/
  201.  /****************************************************************************/
  202.  /* Stuff a z-string name in the buf.                                     824*/
  203.  /* - If there is scope, then get the name from symbols.                  824*/
  204.  /* - else get the name from publics.                                     824*/
  205.  /* - else format as 32 address if 32 bit frame.                          824*/
  206.  /* - else format as 16 address if 16 bit frame.                          824*/
  207.  /****************************************************************************/
  208.  if( scope != NULL)
  209.   CopyProcName( scope, buf, MaxSymLen );
  210.  else
  211.  {
  212.   cp = DBFindProcName(addr , pdf);
  213.   if ( cp )
  214.   {
  215.    int  NameLen;
  216.    BOOL IsMangled;
  217.    char buffer[256];
  218.  
  219.    memset(buffer, 0, sizeof(buffer));
  220.  
  221.    IsMangled = FALSE;
  222.    IsMangled = unmangle( buffer, cp + 2 );
  223.    if( IsMangled == FALSE )
  224.    {
  225.     NameLen =  *(USHORT *)cp;
  226.     if( NameLen > MaxSymLen )
  227.      NameLen = MaxSymLen;
  228.     memcpy(buf, cp+2, NameLen);
  229.     buf[NameLen] = '\0';
  230.    }
  231.    else
  232.    {
  233.     NameLen =  strlen(buffer);
  234.     if( NameLen > MaxSymLen )
  235.      NameLen = MaxSymLen;
  236.     memcpy(buf, buffer, NameLen);
  237.     buf[NameLen] = '\0';
  238.    }
  239.   }
  240.   else if ( FrameAtr == ATR32 )
  241.   {
  242.    sprintf(buf, "%08X", addr);
  243.   }
  244.   else /* FrameAtr == ATR16 */
  245.   {
  246.    Code_Flat2SelOff(addr,&Sel,&Off);
  247.    sprintf( buf, "%04X:%04X",Sel,Off);
  248.   }
  249.  }
  250. }
  251.  
  252. /*****************************************************************************/
  253. /* SetActFrames()                                                            */
  254. /*                                                                           */
  255. /* Description:                                                              */
  256. /*  1. Establishes the following arrays for the current state of the user's  */
  257. /*     stack:                                                                */
  258. /*                                                                           */
  259. /*      ActFaddrs[]   the CS:IP or EIP values for the stack frames        107*/
  260. /*      ActCSAtrs[]   0 => 16-bit stack frame  1 => 32-bit stack frame    107*/
  261. /*      ActFlines[][] the mid/lno values for the CS:IP/EIP return values  107*/
  262. /*      ActScopes[]   pointers to SSProc records for the frame CS:IP/EIP vals*/
  263. /*      ActFrames[]   offsets in the stack of the stack frames ( EBP values )*/
  264. /*                                                                           */
  265. /* Parameters:                                                               */
  266. /*   none                                                                    */
  267. /*                                                                           */
  268. /* Return:                                                                   */
  269. /*   none                                                                    */
  270. /*                                                                           */
  271. /* Assumptions:                                                              */
  272. /*                                                                           */
  273. /*    This routine has to guarantee the above arrays are valid. "Valid"      */
  274. /*    implies, for example, that ActFaddrs contains valid addresses          */
  275. /*    in the application code.                                               */
  276. /*                                                                           */
  277. /*****************************************************************************/
  278. void SetActFrames( )
  279. {
  280.  STACK_PARMS  parms;
  281.  UCHAR       *pActCSAtrs = NULL;
  282.  UINT        *pActFrames = NULL;
  283.  UINT        *pActFaddrs = NULL;
  284.  ULONG        n;
  285.  DEBFILE     *pdf;                                                      /*901*/
  286.  
  287.  parms.CS          = AppPTB.CS;
  288.  parms.SS          = AppPTB.SS;
  289.  parms.EBP         = AppPTB.EBP;
  290.  parms.ESP         = AppPTB.ESP;
  291.  parms.SSAtr       = AppPTB.SSAtr;
  292.  parms.ShowAllFlag = ShowAllFlag;
  293.  
  294.  NActFrames = xGetCallStack( &parms,&pActCSAtrs,&pActFrames,&pActFaddrs );
  295.  memcpy(ActCSAtrs,pActCSAtrs,NActFrames*sizeof(ActCSAtrs[0]));
  296.  memcpy(ActFrames,pActFrames,NActFrames*sizeof(ActFrames[0]));
  297.  memcpy(ActFaddrs,pActFaddrs,NActFrames*sizeof(ActFaddrs[0]));
  298.  if(pActCSAtrs) Tfree(pActCSAtrs);
  299.  if(pActFrames) Tfree(pActFrames);
  300.  if(pActFaddrs) Tfree(pActFaddrs);
  301.  
  302.  for( n = 0; n < NActFrames; n++ )
  303.  {
  304.   ActScopes[n] = FindScope( ActFaddrs[n] , &ActFlines[n][0] );
  305.  }
  306.  pdf = FindExeOrDllWithAddr( GetExecAddr() );                            /*901*/
  307.  ExecScope = LocateScope(GetExecAddr(),GetExecMid(),pdf);                /*901*/
  308. }
  309.  
  310.  uint
  311. StackFrameIndex(SCOPE scope)
  312. {
  313.     uint n;                             /* was register.                  112*/
  314.  
  315.     if( scope == ExecScope )        return(1);
  316.     if( NActFrames
  317.      && ((n = lindex(ActScopes, NActFrames, (ulong)scope)) < NActFrames)
  318.       ) return( n+2 );
  319.     return(0);
  320. }
  321.  
  322.  uint
  323. StackFrameAddress(uint index)
  324. {
  325.     if( index == 1 )
  326.     {
  327.      if( AppPTB.SSAtr == 0 )
  328.       return( (uint)Data_SelOff2Flat( AppPTB.SS, LoFlat(AppPTB.EBP) ) );
  329.      else
  330.       return( AppPTB.EBP );
  331.     }
  332.  
  333.     if( (index -= 2) < NActFrames )
  334.         return( ActFrames[index] );            /* return 32-bit frame     107*/
  335.     return( NULL);
  336. }
  337.  
  338.  
  339. /*****************************************************************************/
  340. /* StackFrameMemModel()                                                   112*/
  341. /*                                                                        112*/
  342. /* Description:                                                           112*/
  343. /*   Returns the memory model of the stack frame for the index.           112*/
  344. /*                                                                        112*/
  345. /* Parameters:                                                            112*/
  346. /*   index       input - the stack frame index.                           112*/
  347. /*                                                                        112*/
  348. /* Return:                                                                112*/
  349. /*   BIT16        0.                                                      112*/
  350. /*   BIT32        1.                                                      112*/
  351. /*                                                                        112*/
  352. /* Assumptions:                                                           112*/
  353. /*                                                                        112*/
  354. /*   The index has been verified by caller so no need to check for error. 112*/
  355. /*   Future callers may not do the verification so you may want to add    112*/
  356. /*   the error checking, but this is currently valid.                     112*/
  357. /*                                                                        112*/
  358. /*****************************************************************************/
  359.  uchar                                                                  /*112*/
  360. StackFrameMemModel( uint index )                                        /*112*/
  361. {                                                                       /*112*/
  362.  if( index == 1 )                                                       /*112*/
  363.  {                                                                      /*112*/
  364.   if( AppPTB.SSAtr == 0 )                                               /*112*/
  365.    return( BIT16 );                                                     /*112*/
  366.   else                                                                  /*112*/
  367.    return( BIT32 );                                                     /*112*/
  368.  }                                                                      /*112*/
  369.                                                                         /*112*/
  370.  if ( ActCSAtrs[index-2] == 0 )         /* index should be decremented    532*/
  371.    return( BIT16 );                                                     /*218*/
  372.   else                                                                  /*218*/
  373.    return( BIT32 );                                                     /*218*/
  374.  
  375. }                                       /* end StackFrameMemModel().      112*/
  376.  
  377.  
  378. /*****************************************************************************
  379. * name          bcopy -- Copy bytes
  380. *
  381. * synopsis      cp = bcopy( source, destination, Nbytes );
  382. *
  383. *               char *cp            -  pointer to 1st byte beyond dest
  384. *               char *source        -  pointer to 1st byte to be copied
  385. *               char *destination   -  pointer to 1st byte to receive copy
  386. *               uint Nbytes         -  number of bytes to copy
  387. *
  388. * description   This routine copies N bytes (does not detect overlap).
  389. *               It always copies bytes from left to right (lower to higher).
  390. *               It returns the address of the 1st byte after the destination.
  391. */
  392.  char*                                                                  /*215*/
  393. bcopy(char *source,char *destination,uint Nbytes)
  394. {
  395.  memcpy( destination, source, Nbytes );  /* copy source to dest           107*/
  396.  return(destination+Nbytes);             /* give back ptr to next slot    107*/
  397.  
  398. }
  399.  
  400. /*****************************************************************************/
  401. /* DBDLLLoadInfo()                                                           */
  402. /*                                                                           */
  403. /* Description:                                                              */
  404. /*   Returns a beginning address for a DLL code object.                      */
  405. /*   This routine might ought to go into DBIF.C.                          107*/
  406. /*                                                                           */
  407. /* Parameters:                                                               */
  408. /*   addr        input  - address within the DLL.                            */
  409. /*   pdf         input  - DLL containing the instruction.                    */
  410. /*                                                                           */
  411. /* Return:                                                                   */
  412. /*   loadaddr           - start address of the DLL object.                   */
  413. /*                                                                           */
  414. /* Assumptions:                                                              */
  415. /*                                                                           */
  416. /*   pdf is valid.                                                           */
  417. /*                                                                           */
  418. /*****************************************************************************/
  419.  uint
  420. DBDLLLoadInfo(uint addr,DEBFILE *pdf)
  421.                                         /* current instruction addr          */
  422.                                         /* EXE/DLL containing addr           */
  423. {
  424.  int           i;                       /* loop counter                      */
  425.  uint          NumCodeObjs;             /* number of table entries        521*/
  426.  uint          *p;                      /* working ptr                    521*/
  427.  OBJTABLEENTRY *te;                     /* -> to a object table entry        */
  428.  
  429.  NumCodeObjs = *(p=pdf->CodeObjs);
  430.  te = (OBJTABLEENTRY *)++p;
  431.  for(i=1; i <= NumCodeObjs; i++,te++ )
  432.  {
  433.   if( (te->ObjType == CODE)     &&                                        /*706*/
  434.       (addr >= te->ObjLoadAddr) &&
  435.       (addr <  te->ObjLoadAddr + te->ObjLoadSize) )
  436.    return( te->ObjLoadAddr );
  437.  }
  438.  return(0);
  439. }                                       /* end DBDLLLoadInfo().              */
  440.  
  441. void  SetShowAll( int FlagOption )                                      /*701*/
  442. {                                                                       /*701*/
  443.   ShowAllFlag = FlagOption;                                             /*701*/
  444. }                                                                       /*701*/
  445.