home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sd386v50.zip / sd386src.zip / IDBRK.C < prev    next >
Text File  |  1996-04-24  |  48KB  |  1,028 lines

  1. /*****************************************************************************/
  2. /* File:                                             IBM INTERNAL USE ONLY   */
  3. /*   idbrk.c                                                                 */
  4. /*                                                                           */
  5. /* Description:                                                              */
  6. /*   immediate and deferred breakpoint handling.                             */
  7. /*                                                                           */
  8. /*                                                                           */
  9. /* History:                                                                  */
  10. /*                                                                           */
  11. /*   02/08/91 Creation of 32-bit SD86, from 16-bit version.                  */
  12. /*                                                                           */
  13. /*...16->32 port.                                                            */
  14. /*...                                                                        */
  15. /*... 02/08/91  115   Srinivas  port to 32 bit.                              */
  16. /*                                                                           */
  17. /*...Release 1.00 (Pre-release 1)                                            */
  18. /*...                                                                        */
  19. /*... 07/09/91  204   srinivas  Hooking up of deferred breakpoints.          */
  20. /*                                                                           */
  21. /*...Release 1.00 (Pre-release 108 12/05/91)                                 */
  22. /*...                                                                        */
  23. /*... 02/10/92  515   Srinivas  Multiple hits of a deferred break points     */
  24. /*                              (same func names).                           */
  25. /*... 02/12/92  521   Srinivas  Port to C-Set/2.                             */
  26. /*...                                                                        */
  27. /*...Release 1.00 (03/03/92)                                                 */
  28. /*...                                                                        */
  29. /*... 03/20/92  607   Srinivas  CRMA fixes.                                  */
  30. /*... 10/05/92  707   Selwyn    Function entry/address breaks not getting    */
  31. /*...                           marked.                                      */
  32. /*... 12/07/92  805   Selwyn    Function entry breakpoint not being shown.   */
  33. /**Includes*******************************************************************/
  34.  
  35. #include "all.h"                        /* SD86 include files                */
  36. #include "diabkpt.h"
  37.  
  38. /**Externs********************************************************************/
  39.  
  40. extern CmdParms      cmd;
  41. extern uchar         hilite[];
  42. extern uchar         normal[];
  43.  
  44. /*****************************************************************************/
  45. /* ParseNameAddr()                                                           */
  46. /*                                                                           */
  47. /* Description:                                                              */
  48. /*                                                                           */
  49. /*   Parse name or address.                                                  */
  50. /*                                                                           */
  51. /* Parameters:                                                               */
  52. /*                                                                           */
  53. /*   addr       output - -> location to stuff address into.                  */
  54. /*   msg        output - -> location where to stuff name or error message.   */
  55. /*                                                                           */
  56. /* Return:                                                                   */
  57. /*                                                                           */
  58. /*   rc         return code. 0 => ok. 1 => expression error.                 */
  59. /*                                                                           */
  60. /* Assumptions:                                                              */
  61. /*                                                                           */
  62. /*****************************************************************************/
  63. #define OP0  0x00                       /* initial -- no operands            */
  64. #define OP1  0x10                       /* got one operand                   */
  65. #define OP1C 0x18                       /* got one operand and colon         */
  66. #define OP2  0x20                       /* got two operands                  */
  67. #define OPE  0x30                       /* got an error.                     */
  68. #define OPN  0x40                       /* got a name.                       */
  69.                                         /*                                   */
  70.  uint                                   /*                                   */
  71. ParseNameAddr(char *expr, ULONG *addr,uchar *emsg)
  72. {                                       /*                                   */
  73.  uchar *cp;                             /* a char pointer.                   */
  74.  ulong  bigans;                         /* a holder for a long value.        */
  75.  uint   ans;                            /* a holder for an int value.        */
  76.  uint   c;                              /* the current character in the expr.*/
  77.  uint   base;                           /* hex or decimal base.              */
  78.  uchar *sym;                            /* -> to token in expr.              */
  79.  uint   symlen;                         /* length of token in expr.          */
  80.  uint   seg;                            /* selector of addr.                 */
  81.  uint   off;                            /* offset of addr.                   */
  82.  uint   state = OP0;                    /* state.                            */
  83.                                         /*                                   */
  84.  cp = expr;                             /*                                   */
  85.  base = 16;                             /*                                   */
  86.  for( ;; )                              /*  begin token parsing.             */
  87.  {                                      /*  one loop iteration per token.    */
  88.   /***************************************************************************/
  89.   /* At this point, we have an address that should be in sel:off form or a   */
  90.   /* function name. If we have an address, then the first character will     */
  91.   /* be a number and we will proceed to parse off a number. If the first     */
  92.   /* char is an alpha, then we proceed parse off a valid c/plx identifier.   */
  93.   /*                                                                         */
  94.   /* A proper address input consists of three tokens. We return here         */
  95.   /* each time we want to parse one off. A function name consists of only    */
  96.   /* one token. So, we're done when parsing when we hit the null at the      */
  97.   /* end of the string returned from the expr.                               */
  98.   /*                                                                         */
  99.   /* Initially, we're in the OP0 state at the beginning of a token. We may   */
  100.   /* return here in other states.                                            */
  101.   /*                                                                         */
  102.   /***************************************************************************/
  103.   while( (c = *(sym=cp++) ) == ' ' ){;} /*                                   */
  104.   if( c==0 )                            /*                                   */
  105.    break;                               /* DONE! we've hit the end of string.*/
  106.                                         /*                                   */
  107.  ParseNumber:                           /* handle token is a number.         */
  108.                                         /*                                   */
  109.   if( c >= '0' && c <= '9' )            /* fall in if{} if token starts as   */
  110.   {                                     /* a number.                         */
  111.    if( c == '0' && *cp == 'x' )         /* adjust if 0x form of input.       */
  112.     ++cp;                               /*                                   */
  113.                                         /*                                   */
  114.    for( bigans = c - '0' ;; ++cp )      /* begin loop to evaluate constant.  */
  115.    {                                    /*                                   */
  116.     c = *cp - '0';                      /* get value of next digit.          */
  117.     if( c > 9 )                         /* check potential a-f.              */
  118.     {                                   /*                                   */
  119.      c = *cp | 0x20;                    /* convert c to its lower case value.*/
  120.      c = c - 'a' + 10;                  /* calc "real" value of it.          */
  121.      if( c < 10 || c > 15 )             /* if not a-f then we're done with   */
  122.       break;                            /* this number.                      */
  123.     }                                   /*                                   */
  124.     bigans = bigans * base + c;         /* update the value.                 */
  125.    }                                    /*                                   */
  126.    /**************************************************************************/
  127.    /* At this point, we can be in many parsing states. If we are in the OP0  */
  128.    /* state, then we are working on a simple constant or a seg:off constant. */
  129.    /*                                                                        */
  130.    /**************************************************************************/
  131.    if( state == OP0 )                   /*                                   */
  132.     seg = ( uint )(bigans >> 16);       /* anticipate possible seg:off form. */
  133.    ans = ( uint )bigans;                /* hold 16 bit result.               */
  134.    switch( state )                      /*                                   */
  135.    {                                    /*                                   */
  136.     case OP0:                           /* initial state.                    */
  137.      off = ans;                         /*                                   */
  138.      state = OP1;                       /*                                   */
  139.      break;                             /*                                   */
  140.                                         /*                                   */
  141.     case OP1C:                          /* one operand and a ":"             */
  142.      off = ans;                         /*                                   */
  143.      state = OP2;                       /*                                   */
  144.      break;                             /*                                   */
  145.                                         /*                                   */
  146.     default:                            /* invalid states.                   */
  147.      state = OPE;                       /*                                   */
  148.      break;                             /* go process exit.                  */
  149.    }                                    /*                                   */
  150.    if(state == OPE )                    /* if we have an error then abort    */
  151.     break;                              /* the parsing loop.                 */
  152.    continue; /* with NextSymbol */      /* go to next symboland next token.  */
  153.   }                                     /*                                   */
  154.  
  155.   /***************************************************************************/
  156.   /* The following code parses a valid c or pl/x identifier.                 */
  157.   /***************************************************************************/
  158.   if( IsOKchar( ( uchar )c) )           /* If the leading character is valid,*/
  159.    while( IsOKchar(*cp) )               /* then parse to the end of the      */
  160.    {                                    /* token.                            */
  161.     if(*cp == 0x15 )                    /* maintain italian relations and    */
  162.      *cp = '@';                         /* convert  to @.                   */
  163.     ++cp;                               /*                                   */
  164.    };                                   /*                                   */
  165.  
  166.   /***************************************************************************/
  167.   /* The followinig code handles operators. In our case, a ':'.              */
  168.   /* sym points to a token that looks like ":xxxx" and cp would point to     */
  169.   /* the first x. c=':' or some invalid operator.                            */
  170.   /*                                                                         */
  171.   /***************************************************************************/
  172.   symlen=cp-sym;                        /* calc symbol length.               */
  173.   if( symlen==1 )                       /*                                   */
  174.   {                                     /*                                   */
  175.    if( c==':' )                         /*                                   */
  176.    {                                    /*                                   */
  177.     if( state == OP1 )                  /*                                   */
  178.     {                                   /*                                   */
  179.      state = OP1C;                      /* advance to OP1C state.            */
  180.      seg = off;                         /* we now have our seg part of       */
  181.      continue; /* with NextSymbol */    /* an address. We'll go on           */
  182.     }                                   /* and get the offset.               */
  183.     state = OPE;                        /* bad news.                         */
  184.     break;                              /*                                   */
  185.    }                                    /*                                   */
  186.    if( !IsOKchar( ( uchar )c) )         /* Is this is not a valid            */
  187.    {                                    /* identifier, then go to the error  */
  188.     state = OPE;                        /* state.                            */
  189.     break;                              /*                                   */
  190.    }                                    /*                                   */
  191.   }                                     /*                                   */
  192.   /***************************************************************************/
  193.   /* At this point, we may have an expression of the form ABxx:ABxx. In the  */
  194.   /* case of the first operand, if *cp = ':', then we say "oops...I need to  */
  195.   /* force this to be parsed as a number". So, we insert a leading 0 and     */
  196.   /* continue. If we get here and the second operand has been parsed off as  */
  197.   /* a symbol, then we trap this by being in the OP1C state.                 */
  198.   /*                                                                         */
  199.   /***************************************************************************/
  200.   if( (state == OP1C || *cp == ':') )   /*                                   */
  201.   {                                     /*                                   */
  202.    c = '0';                             /* force a leading zero              */
  203.    cp = sym;                            /* backup to start of symbol         */
  204.    goto ParseNumber;                    /*                                   */
  205.   }                                     /* parse as a number                 */
  206.  
  207.   /***************************************************************************/
  208.   /* We have a token that should be a function name.  If we find the name, we*/
  209.   /* will proceed to the OP2 state. If we don't we will break out of the     */
  210.   /* parsing loop and return with . If we don't we return with incorrect sym.*/
  211.   /***************************************************************************/
  212.   if( state == OP0 )                    /*                                   */
  213.   {                                     /*                                   */
  214.    state = OPN;                         /* go to the got name state.         */
  215.    continue; /* with NextSymbol */      /* go get the next token.            */
  216.   }                                     /*                                   */
  217.   break;                                /* break out of the loop, we're      */
  218.                                         /* confused.                         */
  219.  }                                      /*                                   */
  220.  /****************************************************************************/
  221.  /* come here after leaving the token parsing loop.                          */
  222.  /*                                                                          */
  223.  /* state          *sym   rc   addr   emsg                                   */
  224.  /* --------------|------|----|------|-------|------------------------------ */
  225.  /*  OPN          | yes  | 0  | x    |name   |normal name.                   */
  226.  /*  OP2          | no   | 0  | yes  |0      |normal return with address.    */
  227.  /*  OP1,OP2,OP1C | yes  | 1  | x    |vestige|expression error.              */
  228.  /*  OP1,OP2,OP1C | no   | 1  | x    |expr   |expression error.              */
  229.  /*  OPE          | x    | x  | x    |x      |expression error.              */
  230.  /*                                                                          */
  231.  /****************************************************************************/
  232.  *addr= NULL;                           /* assume null address.              */
  233.  if(*sym)                               /* if after all of this and the      */
  234.   state = OPE;                          /* expression has not been consumed  */
  235.                                         /* by the parser, then state = OPE.  */
  236.  switch( state )                        /*                                   */
  237.  {                                      /*                                   */
  238.   case OPN:                             /* found a name.                     */
  239.     strcpy(emsg,expr);                  /* stuff it in a string.             */
  240.     return(0);                          /* return success.                   */
  241.   case OP1:                             /* one operand state.             204*/
  242.    if( state == OP1 && *sym == 0 )      /* if its a simple case of flat   204*/
  243.    {                                    /* address.                       204*/
  244.      *addr = off;                       /* return sucess.                 204*/
  245.      return(0);                         /*                                204*/
  246.    }                                    /*                                204*/
  247.    goto caseop2;
  248. caseop2:
  249.  
  250.   case OP2:                             /* sucessfully parsed an address.    */
  251.    if( state == OP2 && *sym == 0 )      /*                                   */
  252.    {                                    /*                                   */
  253.     if( TestBit(seg,02) )               /* if its a GDT then it must be   204*/
  254.     {
  255.        *addr = Data_SelOff2Flat((ushort)seg,
  256.                  (ushort)off);          /* simple flat address else       607*/
  257.        if( *addr == NULL )                                              /*827*/
  258.        {                                                                /*827*/
  259.         strcpy(emsg,"Address not loaded.");                             /*827*/
  260.         return(1);                                                      /*827*/
  261.        }
  262.     }
  263.     else                                /* convert into flat address and  204*/
  264.        *addr = off;                     /* assign                         204*/
  265.                                         /*                                204*/
  266.     return(0);                          /*                                   */
  267.    }                                    /*                                   */
  268.    goto caseop0;
  269. caseop0:
  270.   case OP0:                             /* initial state.(null expr)         */
  271.   case OP1C:                            /* one operand state.                */
  272.   case OPE:                             /* one operand and a ":"             */
  273.    if( *sym )                           /* the rest are errors.              */
  274.     strcpy( emsg,sym);                  /*                                   */
  275.    else                                 /*                                   */
  276.     strcpy( emsg,expr);                 /*                                   */
  277.    strcat( emsg," is incorrect");       /*                                   */
  278.    return(1);                           /*                                   */
  279.  }                                      /*                                   */
  280.  return(0);
  281. }                                       /*                                   */
  282. /*****************************************************************************/
  283. /* SetIDBrk()                                                                */
  284. /*                                                                           */
  285. /* Description:                                                              */
  286. /*                                                                           */
  287. /*   Set an immediate or deferred breakpoints by name or address.            */
  288. /*                                                                           */
  289. /* Parameters:                                                               */
  290. /*                                                                           */
  291. /*   expr      ->   the raw expression.                                      */
  292. /*   DorI           immediate or deferred.                                   */
  293. /*   DefineType     the type of the breakpoint...see brk.h.                  */
  294. /*   ppmsg     ->-> to an error message.                                     */
  295. /*                                                                           */
  296. /* Return:                                                                   */
  297. /*                                                                           */
  298. /*   rc                                                                      */
  299. /*                                                                           */
  300. /*                                                                           */
  301. /* Assumptions:                                                              */
  302. /*                                                                           */
  303. /*****************************************************************************/
  304. extern UCHAR         IfUscores;         /* TRUE if syms may have uscore prefx*/
  305. extern UCHAR         VideoAtr;
  306. extern AFILE        *allfps;
  307. extern PROCESS_NODE *pnode;
  308.  
  309. static UCHAR  buffer[ PROMAX + 2];
  310.  
  311. APIRET SetIDBrk( UCHAR *expr, int DorI, int DefineType, char **ppmsg)
  312. {
  313.  uint     rc;
  314.  BRK     *pbrk;
  315.  ULONG    mid;
  316.  ULONG    lno;
  317.  char    *cp;
  318.  char    *cpp;
  319.  char    *cpq;
  320.  int      len;
  321.  AFILE   *fp;
  322.  BOOL     IsDotQualified;
  323.  
  324.  ULONG    addr      = NULL;
  325.  char    *pdllname  = NULL;
  326.  char    *pfuncname = NULL;
  327.  DEBFILE *pdf       = NULL;
  328.  
  329.  /****************************************************************************/
  330.  /* - First, do some syntax checking.                                        */
  331.  /****************************************************************************/
  332.  switch( DefineType )
  333.  {
  334.   case BP_FUNC_NAME:
  335.   {
  336.    /**************************************************************************/
  337.    /* - handle [dllname.]funcname.                                           */
  338.    /* - strip off any path info that may have been included.                 */
  339.    /**************************************************************************/
  340.    cpq            = strrchr(expr, '\\');
  341.    cp = (cpq)?cpq+1:expr;
  342.  
  343.    IsDotQualified = strchr(expr, '.')?TRUE:FALSE;
  344.  
  345.    if( IsDotQualified == TRUE )
  346.    {
  347.     cpp = strchr(cp, '.' );
  348.  
  349.     if( cp == cpp )
  350.     ;
  351.     else
  352.     {
  353.      len      = cpp - cp + 1;
  354.      pdllname = Talloc(len);
  355.  
  356.      strncpy(pdllname, cp, len - 1 );
  357.     }
  358.     cp = cpp + 1;
  359.    }
  360.    len = strlen(cp);
  361.    if( len == 0 )
  362.    {
  363.     /**************************************************************************/
  364.     /* - there MUST be a function name.                                       */
  365.     /**************************************************************************/
  366.     Error( ERR_BKPT_DEFN_SYNTAX, FALSE, 1, expr );
  367.     return(1);
  368.    }
  369.    pfuncname = Talloc(len + 1);
  370.    strcpy(pfuncname, cp);
  371.   }
  372.   break;
  373.  
  374.   case BP_DLL_LOAD:
  375.   {
  376.    buffer[0] = ' ';
  377.    rc = ParseNameAddr(expr, &addr, &buffer[1]);
  378.    if( rc != 0 )
  379.    {
  380.     Error( ERR_BKPT_DEFN_SYNTAX, FALSE, 1, expr );
  381.     return(1);
  382.    }
  383.    pdllname = Talloc(strlen(expr) + 1);
  384.    strcpy(pdllname, expr );
  385.   }
  386.   break;
  387.  
  388.   case BP_ADDR:
  389.   case BP_LOAD_ADDR:
  390.   {
  391.    /**************************************************************************/
  392.    /* - handle an address entry.                                             */
  393.    /**************************************************************************/
  394.    buffer[0] = ' ';
  395.    rc = ParseNameAddr(expr, &addr, &buffer[1]);
  396.    if( (rc != 0) || (addr == NULL) )
  397.    {
  398.     Error( ERR_BKPT_DEFN_SYNTAX, FALSE, 1, expr );
  399.     return(1);
  400.    }
  401.   }
  402.   break;
  403.  }
  404.  
  405.  /****************************************************************************/
  406.  /* - At this point, we have:                                                */
  407.  /*                                                                          */
  408.  /*   - a [dllname.]funcname                                                 */
  409.  /*   - or, an address                                                       */
  410.  /*                                                                          */
  411.  /****************************************************************************/
  412.  if( DorI == BP_IMMEDIATE )
  413.  {
  414.   /***************************************************************************/
  415.   /* - if we have an immediate breakpoint and the user has specified a dll,  */
  416.   /*   then we need to check to verify that the dll is loaded.               */
  417.   /***************************************************************************/
  418.   if( pdllname )
  419.   {
  420.    pdf = findpdf( pdllname );
  421.    if( pdf == NULL )
  422.    {
  423.     Error( ERR_BKPT_DEFN_DLL, FALSE, 1, pdllname );
  424.     Tfree(pdllname);
  425.     return(1);
  426.    }
  427.   }
  428.  
  429.   switch( DefineType )
  430.   {
  431.    case BP_FUNC_NAME:
  432.    {
  433.     /*************************************************************************/
  434.     /* - convert the function name to an address.                            */
  435.     /*************************************************************************/
  436.     strcpy( buffer + 1, pfuncname );
  437.  
  438.     if( pdf != NULL )
  439.     {
  440.      /************************************************************************/
  441.      /* - come here when a dll name was specified.                           */
  442.      /************************************************************************/
  443.      addr   = DBPub(buffer+1,pdf);
  444.      if( (addr == NULL) && IfUscores )
  445.      {
  446.       buffer[0] = '_';
  447.       addr= DBPub(buffer,pdf);
  448.      }
  449.      if( addr == NULL )
  450.      {
  451.       Error( ERR_BKPT_DEFN_FUNCTION, FALSE, 2, pfuncname, pdllname );
  452.       Tfree(pfuncname);
  453.       Tfree(pdllname);
  454.       return(1);
  455.      }
  456.     }
  457.     else
  458.     {
  459.      /************************************************************************/
  460.      /* - come here when a dll name was not specified.                       */
  461.      /************************************************************************/
  462.      pdf  = pnode->ExeStruct;
  463.      addr = NULL;
  464.      for(; pdf ; pdf=pdf->next)
  465.      {
  466.       addr   = DBPub(buffer+1,pdf);
  467.       if( (addr == NULL) && IfUscores )
  468.       {
  469.        buffer[0] = '_';
  470.        addr= DBPub(buffer,pdf);
  471.       }
  472.       if( addr != NULL) break;
  473.      }
  474.  
  475.      if(addr == NULL)
  476.      {
  477.       if( DoYouWantToDefer() == TRUE )
  478.        DorI = BP_DEFR;
  479.       else
  480.        return(0);
  481.      }
  482.     }
  483.    }
  484.    break;
  485.  
  486.    case BP_ADDR:
  487.    /**************************************************************************/
  488.    /* - check if the address is loaded.                                      */
  489.    /**************************************************************************/
  490.    {
  491.     pdf = FindExeOrDllWithAddr(addr);
  492.     if( pdf == NULL )
  493.     {
  494.      Error( ERR_BKPT_DEFN_ADDRESS, FALSE, 1, expr );
  495.      return(1);
  496.     }
  497.    }
  498.    break;
  499.  
  500.   }
  501.  }
  502.  
  503.  /****************************************************************************/
  504.  /* - now define the breakpoint.                                             */
  505.  /****************************************************************************/
  506.  if( DorI == BP_IMMEDIATE )
  507.  {
  508.   LNOTAB *pLnoTabEntry;
  509.   int     sfi;
  510.  
  511.   mid = DBMapInstAddr(addr, &pLnoTabEntry, pdf);
  512.   sfi = lno = 0;
  513.   if( pLnoTabEntry )
  514.   {
  515.    lno = pLnoTabEntry->lno;
  516.    sfi = pLnoTabEntry->sfi;
  517.   }
  518.   pbrk                   = DefBrk(addr, TRUE);
  519.   pbrk->mid              = mid;
  520.   pbrk->lno              = lno;
  521.   pbrk->sfi              = sfi;
  522.   pbrk->flag.DorI        = BP_IMMEDIATE;
  523.   pbrk->flag.DefineType  = DefineType;
  524.   pbrk->flag.ActionType  = BRK_SIMP;
  525.   pbrk->dllname          = pdllname;
  526.   pbrk->funcname         = pfuncname;
  527.  
  528.   /***************************************************************************/
  529.   /* - scan the views and mark this breakpoint if necessary.                 */
  530.   /***************************************************************************/
  531.   for( fp = allfps; mid && fp; fp = fp->next )
  532.     if( fp->mid == pbrk->mid )
  533.       MarkLineBRKs( fp );
  534.  }
  535.  else /* DorI == BP_DEFR */
  536.  {
  537.   /***************************************************************************/
  538.   /* - define deferred breakpoints.                                          */
  539.   /***************************************************************************/
  540.   pbrk                  = DefBrk( NULL, FALSE);
  541.   pbrk->flag.DorI       = BP_DEFR;
  542.   pbrk->flag.DefineType = DefineType;
  543.   pbrk->flag.ActionType = BRK_SIMP;
  544.  
  545.   switch( DefineType )
  546.   {
  547.    case BP_FUNC_NAME:
  548.    {
  549.     pbrk->dllname  = pdllname;
  550.     pbrk->funcname = pfuncname;
  551.    }
  552.    break;
  553.  
  554.    case BP_LOAD_ADDR:
  555.    {
  556.     /*************************************************************************/
  557.     /* - add the load address.                                               */
  558.     /*************************************************************************/
  559.     pbrk->brkat = addr;
  560.    }
  561.    break;
  562.  
  563.    case BP_DLL_LOAD:
  564.    {
  565.     /*************************************************************************/
  566.     /* - attach the dll name.                                                */
  567.     /*************************************************************************/
  568.     pbrk->dllname = pdllname;
  569.    }
  570.    break;
  571.   }
  572.  
  573.   /***************************************************************************/
  574.   /* - a little post-processing on the breakpoint definition.                */
  575.   /* - put the dll name in lower case.                                       */
  576.   /***************************************************************************/
  577.   if( pbrk && pbrk->dllname )
  578.    strlwr(pbrk->dllname);
  579.  }
  580.  return(0);
  581. }
  582.  
  583. /*****************************************************************************/
  584. /* ConvertDefBrks()                                                          */
  585. /*                                                                           */
  586. /* Description:                                                              */
  587. /*                                                                           */
  588. /*   Scan bp ring and convert deferred to immediate bps.                     */
  589. /*                                                                           */
  590. /* Parameters:                                                               */
  591. /*                                                                           */
  592. /*   pdf      input  - DEBFILE pointer.                                      */
  593. /*            Insert - flag for breakpoint insertion.                        */
  594. /*                     TRUE  - insert. Used with DLL loads.                  */
  595. /*                   - FALSE - do not insert. Used with EXE loads.           */
  596. /* Return:                                                                   */
  597. /*                                                                           */
  598. /* Assumptions:                                                              */
  599. /*                                                                           */
  600. /*  pdf is not null.                                                         */
  601. /*                                                                           */
  602. /*****************************************************************************/
  603. extern uchar        IfUscores;          /* TRUE if syms may have uscore prefx*/
  604.  
  605. APIRET ConvertDefBrks( PROCESS_NODE *pnode, DEBFILE *pdf, int Insert)
  606. {
  607.  BRK     *pbrk;
  608.  ULONG    mid;
  609.  ULONG    lno;
  610.  uint     addr;
  611.  uchar    sbuffer[256];
  612.  ULONG    junk;
  613.  char    *cp;
  614.  char    *cpp;
  615.  AFILE   *fp;
  616.  char     dllname[13];
  617.  int      len;
  618.  APIRET   ReturnType = 0;
  619.  
  620.  
  621.  pbrk = pnode->allbrks;
  622.  for(;pbrk; pbrk=pbrk->next )
  623.  {
  624.   if( pbrk->flag.DorI == BP_IMMEDIATE )
  625.    continue;
  626.  
  627.   /***************************************************************************/
  628.   /* - massage the dll name for our use.                                     */
  629.   /***************************************************************************/
  630.   cp  = strrchr( pdf->DebFilePtr->fn, '\\' );
  631.   cpp = strchr(  cp, '.');
  632.   len = cpp - cp - 1;
  633.   memset( dllname, 0, sizeof(dllname) );
  634.   strncpy( dllname, cp+1, len);
  635.  
  636.   /***************************************************************************/
  637.   /* - now handle the breakpoint.                                            */
  638.   /***************************************************************************/
  639.   switch( pbrk->flag.DefineType )
  640.   {
  641.    case BP_LOAD_ADDR:
  642.    {
  643.     DEBFILE *pdfx;
  644.  
  645.     if(pbrk->flag.Reported == 1 )
  646.     ;
  647.     else
  648.     {
  649.      pdfx = FindExeOrDllWithAddr(pbrk->brkat);
  650.      if( pdfx )
  651.      {
  652.       pbrk->flag.Reported = 1;
  653.       pbrk->mte           = pdf->mte;
  654.       ReturnType = TRAP_ADDR_LOAD;
  655.      }
  656.     }
  657.    }
  658.    break;
  659.  
  660.    case BP_DLL_LOAD:
  661.    {
  662.     if( pbrk->dllname &&
  663.         (stricmp(dllname, pbrk->dllname) == 0)
  664.       )
  665.     {
  666.      pbrk->flag.Reported    = 1;
  667.      ReturnType = TRAP_DLL_LOAD;
  668.     }
  669.    }
  670.    break;
  671.  
  672.    case BP_SRC_LNO:
  673.    {
  674.     if( pbrk->dllname == NULL )
  675.     ;
  676.     else
  677.     {
  678.      /************************************************************************/
  679.      /* - if this breakpoint is defined for this dll and the srcname         */
  680.      /*   and lno can be mapped to an address then convert the breakpoint    */
  681.      /*   and define it to esp.                                              */
  682.      /************************************************************************/
  683.      if( stricmp(dllname, pbrk->dllname) == 0 )
  684.      {
  685.       int sfi;
  686.  
  687.       mid  = MapSourceFileToMidSfi( pbrk->srcname, &sfi, pdf );
  688.  
  689.       if( (mid != 0 ) &&
  690.           ( (addr = DBMapLno(mid, pbrk->lno, sfi, &junk, pdf) ) != NULL)
  691.         )
  692.       {
  693.        pbrk->brkat            = addr;
  694.        pbrk->mid              = mid;
  695.        pbrk->sfi              = sfi;
  696.        pbrk->flag.DorI        = BP_IMMEDIATE;
  697.        pbrk->flag.WasDeferred = TRUE;
  698.        pbrk->mte              = pdf->mte;
  699.        xDefBrk( pbrk->brkat );
  700.       }
  701.      }
  702.     }
  703.    }
  704.    break;
  705.  
  706.    case BP_FUNC_NAME:
  707.    {
  708.     /*************************************************************************/
  709.     /* - if the breakpoint definition specifies a dll, then we check         */
  710.     /*   for a dll name match between the breakpoint and the pdf being       */
  711.     /*   loaded.                                                             */
  712.     /*************************************************************************/
  713.     if( pbrk->dllname &&
  714.         (stricmp(dllname, pbrk->dllname) != 0)
  715.       )
  716.      continue;
  717.  
  718.     /*************************************************************************/
  719.     /* - now check for the existence of the function name in this dll.       */
  720.     /*************************************************************************/
  721.     strcpy(sbuffer+1, pbrk->funcname);
  722.  
  723.     addr = DBPub(sbuffer+1, pdf);
  724.  
  725.     if( (addr == NULL) && IfUscores )
  726.     {
  727.      sbuffer[0] = '_';
  728.      addr= DBPub(sbuffer,pdf);
  729.     }
  730.  
  731.     /*************************************************************************/
  732.     /* - if there is no breakpoint in this dll by this function name,        */
  733.     /*   then go on to the next breakpoint.                                  */
  734.     /* - else, convert to an immediate breakpoint.                           */
  735.     /*************************************************************************/
  736.     if( addr == NULL )
  737.      continue;
  738.  
  739.     {
  740.      int     sfi;
  741.      LNOTAB *pLnoTabEntry;
  742.  
  743.      mid = DBMapInstAddr(addr, &pLnoTabEntry, pdf);
  744.      lno = sfi = 0;
  745.      if( pLnoTabEntry )
  746.      {
  747.       lno = pLnoTabEntry->lno;
  748.       sfi = pLnoTabEntry->sfi;
  749.      }
  750.  
  751.      pbrk->brkat            = addr;
  752.      pbrk->mid              = mid;
  753.      pbrk->lno              = lno;
  754.      pbrk->sfi              = sfi;
  755.      pbrk->flag.DorI        = BP_IMMEDIATE;
  756.      pbrk->flag.WasDeferred = TRUE;
  757.      pbrk->mte              = pdf->mte;
  758.     }
  759.  
  760.     /*************************************************************************/
  761.     /* - Now, we have created an immediate break for this dll. If a dll      */
  762.     /*   name was not specified, then we need to spin off another deferred   */
  763.     /*   breakpoint to catch any more dlls with this same function name.     */
  764.     /*************************************************************************/
  765.     if( pbrk->dllname == NULL )
  766.     {
  767.      BRK *p;
  768.  
  769.      p                  = DefBrk( NULL, FALSE);
  770.      p->flag.DorI       = BP_DEFR;
  771.      p->flag.DefineType = BP_FUNC_NAME;
  772.      p->flag.ActionType = BRK_SIMP;
  773.      p->funcname        = Talloc(strlen(pbrk->funcname) + 1 );
  774.  
  775.      strcpy(p->funcname, pbrk->funcname);
  776.     }
  777.  
  778.     /*************************************************************************/
  779.     /* - now that we've setup another deferred break, add the dll name to    */
  780.     /*   the breakpoint just converted.                                      */
  781.     /*************************************************************************/
  782.     pbrk->dllname = Talloc( strlen(dllname) + 1);
  783.  
  784.     strncpy( pbrk->dllname, dllname, len);
  785.     strlwr(pbrk->dllname);
  786.  
  787.     /*************************************************************************/
  788.     /* - define the breakpoint to the probe.                                 */
  789.     /*************************************************************************/
  790.     xDefBrk( pbrk->brkat );
  791.    }
  792.    break;
  793.  
  794.    case BP_RESTART:
  795.    {
  796.     /*************************************************************************/
  797.     /* - restart breakpoints get converted to address breakpoints.           */
  798.     /*************************************************************************/
  799.     if( stricmp(dllname, pbrk->dllname) == 0 )
  800.     {
  801.      /************************************************************************/
  802.      /* pbrk->brkat contains only the offset part of the breakpoint          */
  803.      /* address. We have to add the base address of the object               */
  804.      /* containing the breakpoint.                                           */
  805.      /************************************************************************/
  806.      pbrk->brkat           += GetLoadAddr(pdf->mte, pbrk->objnum);
  807.      pbrk->flag.DorI        = BP_IMMEDIATE;
  808.      pbrk->flag.DefineType  = BP_ADDR;
  809.  
  810.      xDefBrk( pbrk->brkat );
  811.     }
  812.    }
  813.    break;
  814.  
  815.    default:
  816.     break;
  817.   }
  818.  
  819.   /***************************************************************************/
  820.   /* - scan the views and mark this breakpoint if necessary.                 */
  821.   /***************************************************************************/
  822.   for( fp = allfps; mid && fp; fp = fp->next )
  823.     if( fp->mid == pbrk->mid )
  824.       MarkLineBRKs( fp );
  825.  }
  826.  return(ReturnType);
  827. }                                       /* end ConvertDefBrks().             */
  828. /*****************************************************************************/
  829. /* SaveBrks()                                                                */
  830. /*                                                                           */
  831. /* Description:                                                              */
  832. /*   Save breakpoints across restart.                                        */
  833. /*                                                                           */
  834. /* Parameters:                                                               */
  835. /*                                                                           */
  836. /*  pnode      input -> to the process node.                                 */
  837. /*                                                                           */
  838. /* Return:                                                                   */
  839. /*                                                                           */
  840. /* Assumptions:                                                              */
  841. /*                                                                           */
  842. /*  An address in a bp node will always have an associated exe/dll node.     */
  843. /*                                                                           */
  844. /*****************************************************************************/
  845. void SaveBrks( PROCESS_NODE *pnode )
  846. {
  847.  BRK     *pbrk;
  848.  BRK     *pnext;
  849.  DEBFILE *pdf;
  850.  int      len;
  851.  uint     addr;
  852.  ushort   objnum;
  853.  uint     loadaddr = 0 ;
  854.  
  855.  /****************************************************************************/
  856.  /* - get rid of file breakpoints since they will be resoted from file.      */
  857.  /****************************************************************************/
  858.  pbrk = pnode->allbrks;
  859.  for( ; pbrk; )
  860.  {
  861.   pnext = pbrk->next;
  862.   if( pbrk->flag.File == TRUE )
  863.   {
  864.    UndBrk( pbrk->brkat, TRUE );
  865.   }
  866.   pbrk = pnext;
  867.  }
  868.  
  869.  pbrk = pnode->allbrks;
  870.  for( ; pbrk; pbrk=pbrk->next )
  871.  {
  872.   /***************************************************************************/
  873.   /* - reset a load address breakpoint back to unreported.                   */
  874.   /***************************************************************************/
  875.   if( pbrk->flag.DefineType == BP_LOAD_ADDR )
  876.   {
  877.    pbrk->flag.Reported = 0;
  878.    pbrk->mte           = 0;
  879.   }
  880.  
  881.   /***************************************************************************/
  882.   /* - If the breakpoint is deferred, then leave it that way.                */
  883.   /***************************************************************************/
  884.   if( pbrk->flag.DorI == BP_DEFR )
  885.    continue;
  886.  
  887.   /***************************************************************************/
  888.   /* - If the breakpoint is a load address/dll load then reset it will       */
  889.   /*   simply retain its deferred status. Actually, you'll never get to      */
  890.   /*   this code since it was handled above.                                 */
  891.   /***************************************************************************/
  892.   else if( (pbrk->flag.DefineType == BP_DLL_LOAD) ||
  893.            (pbrk->flag.DefineType == BP_LOAD_ADDR)
  894.          )
  895.   ;
  896.  
  897.   /***************************************************************************/
  898.   /* - if the debuggee did not DosFreeModule() a dll in which a deferred     */
  899.   /*   breakpoint was hit, then there will be an immediate breakpoint        */
  900.   /*   defined. we need to set this breakpoint back to its deferred          */
  901.   /*   state.                                                                */
  902.   /***************************************************************************/
  903.   else if( pbrk->flag.WasDeferred == TRUE )
  904.   {
  905.    pbrk->flag.DorI        = BP_DEFR;
  906.    pbrk->flag.WasDeferred = FALSE;
  907.    pbrk->brkat            = 0;
  908.    pbrk->mid              = 0;
  909.    pbrk->lno              = 0;
  910.    pbrk->sfi              = 0;
  911.    pbrk->mte              = 0;
  912.   }
  913.   else
  914.   {
  915.    /**************************************************************************/
  916.    /*  - At this point we have an immediate breakpoint that we want to defer */
  917.    /*    for restart.                                                        */
  918.    /**************************************************************************/
  919.    addr = pbrk->brkat;
  920.    pdf  = FindExeOrDllWithAddr(addr);
  921.  
  922.    if( pbrk->dllname == NULL )
  923.    {
  924.     /*************************************************************************/
  925.     /* - if the dllname is not defined, then define it.                      */
  926.     /*************************************************************************/
  927.     char *cp;
  928.     char *cpp;
  929.  
  930.     cp            = strrchr( pdf->DebFilePtr->fn, '\\' );
  931.     cpp           = strchr(  cp, '.');
  932.     len           = cpp - cp - 1;
  933.     pbrk->dllname = Talloc(len + 1);
  934.  
  935.     strncpy( pbrk->dllname, cp+1, len);
  936.     strlwr(pbrk->dllname);
  937.    }
  938.  
  939.    /**************************************************************************/
  940.    /* Now, we want to convert the selector back to a segment number to be    */
  941.    /* reconverted at load time. We do this beacuse we don't know if the      */
  942.    /* segment number will be loaded into the same selector on restart.       */
  943.    /**************************************************************************/
  944.    objnum = MapAddrtoObjnum(pdf, pbrk->brkat, &loadaddr);
  945.    if (objnum != 0 )
  946.    {
  947.      pbrk->objnum           = objnum;
  948.      pbrk->brkat           -= loadaddr;
  949.      pbrk->flag.DorI        = BP_DEFR;
  950.      pbrk->flag.DefineType  = BP_RESTART;
  951.    }
  952.   }
  953.  }
  954. }
  955.  
  956. /*****************************************************************************/
  957. /* - put a message into the dialog window.                                   */
  958. /*****************************************************************************/
  959. void  DisplayBkPntChoice( DIALOGSHELL *shell, DIALOGCHOICE *ptr )
  960. {
  961.  char  *pMsgBuf;
  962.  char  *pLine;
  963.  int    i;
  964.  
  965.  pMsgBuf = GetHelpMsg(HELP_BKPTS_DEFERRED, NULL, 0 );
  966.  pLine   = strtok( pMsgBuf, "\n");
  967.  i       = 0;
  968.  do
  969.  {
  970.   {
  971.    char *cp;
  972.    char *cpend;
  973.  
  974.    cpend = pLine + strlen(pLine);
  975.  
  976.    for( cp = pLine; cp <= cpend; cp++ )
  977.    {
  978.     if( *cp == '\r' )
  979.     {
  980.      *cp = ' ';
  981.     }
  982.    }
  983.   }
  984.  
  985.   putrc( shell->row + shell->SkipLines + i, shell->col + 2, pLine );
  986.  
  987.   pLine = strtok(NULL, "\n");
  988.   i++;
  989.  }
  990.  while( pLine != NULL );
  991. }                                                                       /*701*/
  992.  
  993. /*****************************************************************************/
  994. /* - ask the user about deferring the breakpoint.                            */
  995. /*****************************************************************************/
  996. BOOL DoYouWantToDefer( void )
  997. {
  998.  int   i;
  999.  UINT  key;
  1000.  CHAR *cp;
  1001.  
  1002.  DosBeep( 1000/*Hz*/, 3/*Millisecs*/ );
  1003.  VideoAtr = vaHelp;
  1004.  
  1005.  GetScrAccess();
  1006.  
  1007.  cp = GetHelpMsg(HELP_BKPTS_DEFERRED, NULL, 0 );
  1008.  
  1009.  i  = 0;
  1010.  while( *cp++ == '\n') i++;
  1011.  
  1012.  for( i = 0; *cp ; cp++ )
  1013.   if( *cp == '\n' )
  1014.    i++;
  1015.  
  1016.  Dia_BkPnt.length = i + 5;
  1017.  
  1018.  DisplayDialog( &Dia_BkPnt, FALSE );
  1019.  key = ProcessYesNoBox( &Dia_BkPnt, &Dia_BkPnt_Choices );
  1020.  RemoveDialog( &Dia_BkPnt );
  1021.  SetScrAccess();
  1022.  
  1023.  if( (key == key_y) || (key == key_Y) || (key == ENTER) )
  1024.   return( TRUE );
  1025.  
  1026.  return(FALSE);
  1027. }
  1028.