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

  1. /*****************************************************************************/
  2. /* File:                                             IBM INTERNAL USE ONLY   */
  3. /*   symbols.c                                                               */
  4. /*                                                                           */
  5. /* Description:                                                              */
  6. /*  Handling of symbols segment generated by the compiler and fixed up by    */
  7. /*  the linker.                                                              */
  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  100   Philip    port to 32 bit.                              */
  16. /*... 02/08/91  101   Joe       port to 32 bit.                              */
  17. /*... 02/08/91  102   Pratima   port to 32 bit.                              */
  18. /*... 02/08/91  103   Dave      port to 32 bit.                              */
  19. /*... 02/08/91  104                                                          */
  20. /*... 02/08/91  105   Christina port to 32 bit.                              */
  21. /*... 02/08/91  106   Srinivas  port to 32 bit.                              */
  22. /*... 02/08/91  107   Dave      port to 32 bit.                              */
  23. /*... 02/08/91  108   Dave      port to 32 bit.                              */
  24. /*... 02/08/91  109                                                          */
  25. /*... 02/08/91  110   Srinivas  port to 32 bit.                              */
  26. /*... 02/08/91  111   Christina port to 32 bit.                              */
  27. /*... 02/08/91  112   Joe       port to 32 bit.                              */
  28. /*... 02/08/91  113                                                          */
  29. /*... 02/08/91  114                                                          */
  30. /*... 02/08/91  115   Srinivas  port to 32 bit.                              */
  31. /*... 02/08/91  116   Joe       port to 32 bit.                              */
  32. /*                                                                           */
  33. /*...Release 1.00 (Pre-release 1)                                            */
  34. /*...                                                                        */
  35. /*... 07/09/91  205   srinivas  Hooking up of register variables.            */
  36. /*... 07/19/91  218   srinivas  global variables not being shown properly.   */
  37. /*... 09/11/91  237   Srinivas  Proper initialization of debug format flags. */
  38. /*... 09/25/91  240   Srinivas  recursive PLX based variables.               */
  39. /*... 09/25/91  241   Srinivas  hanging PLX based variables.                 */
  40. /*...                                                                        */
  41. /*...Release 1.00 (Pre-release 107 11/13/91)                                 */
  42. /*...                                                                        */
  43. /*... 11/21/91  403   Srinivas  case sensitivity with structure member names.*/
  44. /*...                                                                        */
  45. /*...Release 1.00 (Pre-release 1.08 10/10/91)                                */
  46. /*...                                                                        */
  47. /*... 02/07/92  512   Srinivas  Handle Toronto "C" userdefs.                 */
  48. /*...                           ( 512 Backed out by change 813).             */
  49. /*... 02/12/92  521   Srinivas  Port to C-Set/2.                             */
  50. /*...                                                                        */
  51. /*...Release 1.00 (03/03/92)                                                 */
  52. /*...                                                                        */
  53. /*... 03/16/92  605   Srinivas  HLL Reg Symbol record not being mapped.      */
  54. /*... 03/18/92  606   Srinivas  Handle multiple segment numbers in lno table */
  55. /*...                           due to alloc_text pragma.                    */
  56. /*... 01/26/93  809   Selwyn    HLL Level 2 support.                         */
  57. /*... 03/03/93  813   Joe       Revised types handling for HL03.             */
  58. /*...                                                                        */
  59. /**Includes*******************************************************************/
  60.  
  61. #include "all.h"                        /* SD86 include files                */
  62.  
  63. /**Externs********************************************************************/
  64.  
  65. extern SCOPE        ExprScope;          /* Set by ParseExpr and findlvar.    */
  66. extern uint         ExprTid;            /* Set by ParseExpr and findlvar     */
  67.                                         /*                   and findsvar.   */
  68. extern PtraceBuffer AppPTB;             /* Application Ptrace buffer.        */
  69. extern CmdParms     cmd;                /* start command parms.              */
  70.  
  71. SSProc      *Qproc;                     /* Set by Qsymbol() to the SSProc    */
  72.                                         /* record containing the symbol.     */
  73.  
  74. /*************************************************************************101*/
  75. /* CopyProcName()                                                         101*/
  76. /*                                                                        101*/
  77. /* Description:                                                           101*/
  78. /*   copys the procedure name from a scope record into a buffer.          101*/
  79. /*                                                                        101*/
  80. /* Parameters:                                                            101*/
  81. /*   scope       input  - ptr to scope record.                            101*/
  82. /*   buf         output - buffer destination of the name.                 101*/
  83. /*   buflen      output - length of the buffer we're stuffing into.       101*/
  84. /*                                                                        101*/
  85. /* Return:                                                                101*/
  86. /*   buf         -> to the buffer.                                        101*/
  87. /*                                                                        101*/
  88. /* Assumptions:                                                           101*/
  89. /*                                                                        101*/
  90. /*   scope -> a valid scope record.                                       101*/
  91. /*                                                                        101*/
  92. /*************************************************************************101*/
  93.  uchar *                                                                /*101*/
  94. CopyProcName( void *scope, uchar *buf, uint buflen )                    /*101*/
  95. {                                                                       /*101*/
  96.  uint    n;                                                             /*101*/
  97.  uchar  *PtrToProcName;                                                 /*101*/
  98.                                                                         /*101*/
  99.  /****************************************************************************/
  100.  /* - get a ptr to the name field of the SSProc record.                   101*/
  101.  /* - get the length of the name and put it in the buffer.                101*/
  102.  /* - truncate the name if needed.                                        101*/
  103.  /****************************************************************************/
  104.  n = 0;                                                                 /*101*/
  105.  if (scope != NULL)                                                     /*107*/
  106.  {                                                                      /*107*/
  107.   BOOL IsMangled;
  108.   char buffer[1024];
  109.  
  110.   memset(buffer, 0, sizeof(buffer));
  111.  
  112.   PtrToProcName = &(((SSProc *)scope )->Name[0]);
  113.   IsMangled     = FALSE;
  114.   IsMangled     = unmangle( buffer, PtrToProcName );
  115.  
  116.   if( IsMangled == FALSE )
  117.   {
  118.    n = ((SSProc *)scope)->NameLen;
  119.    if( n > buflen-1 )
  120.     n = buflen;
  121.    memcpy(buf, PtrToProcName, n );
  122.   }
  123.   else
  124.   {
  125.    n =  strlen(buffer);
  126.    if( n > buflen-1 )
  127.     n = buflen;
  128.    memcpy(buf, buffer, n);
  129.   }
  130.  }
  131.  buf[n] = 0;
  132.  return( buf );
  133. }
  134.  
  135. uint
  136. findsvar(uint mid,varstr vsym )
  137. {
  138.  
  139. DEBFILE *pdf;
  140. uchar *p, *pend;                        /* was register.                  112*/
  141. uint   nested=0;
  142. ULONG len;
  143. int    rc;                              /* string compare return code        */
  144. uchar *pname;                           /*                                   */
  145.  
  146. pdf = DBFindPdf( mid );
  147. if( !pdf )
  148.   goto error;
  149.  
  150. if( (p = (uchar*) DBSymSeg(mid, &len , pdf)) && len )
  151. {
  152.   for( pend = p + len; p < pend; p = (uchar *) NextSSrec(p) )
  153.   {
  154.     switch( ((SSRec *)p)->RecType )                                     /*809*/
  155.     {
  156.       case SSPROC:                                                      /*809*/
  157.       case SSBEGIN:                                                     /*809*/
  158.         nested += 1;  break;
  159.  
  160.       case SSEND:                                                       /*809*/
  161.         nested -= 1;  break;
  162.  
  163.       case SSVAR:                       /* static variable case           809*/
  164.       {
  165.         len = *(USHORT *)vsym;          /* length of name in vsym         809*/
  166.         pname = ((SSVar *)p)->Name;     /* -> to name in SSvar16 record   809*/
  167.  
  168.         if( !nested && len == ((SSVar *)p)->NameLen )
  169.                                         /* the name lengths match then       */
  170.         {                               /* if between "{}" and               */
  171.           rc = strncmp(pname,  vsym+2 , len); /* compare character names  809*/
  172.                                               /* as is                       */
  173.           if (rc && !cmd.CaseSens )           /* mismatch & !case sensitive? */
  174.             rc = memicmp(pname, vsym+2 ,len); /* now compare again.   809 403*/
  175.                                               /* with case insenstivty.   403*/
  176.           if( rc == 0 )                 /* did they match?                   */
  177.           {
  178.             ExprTid = ((SSVar *)p)->TypeIndex;                          /*809*/
  179.                                         /* set expression type id            */
  180.             return( (uint)(((SSVar *)p)->Offset) );                     /*809*/
  181.           }                             /* end of not case sensitive         */
  182.         }
  183.         break;                          /* end of between "{}"               */
  184.       }
  185.     }   }   }
  186. error:
  187.     return( NULL );
  188. }
  189.  
  190.   uint
  191. findlvar( uint mid, uchar *vsym, uint lno, int sfi, BOOL *pthis )
  192. {
  193.  ushort    kind=0;
  194.  int       target;
  195.  SSRec    *p;
  196.  Trec     *tp;                          /* -> type rec in $$type info.       */
  197.     target = NULL;                      /*                                116*/
  198.     p = Qsymbol(mid, lno, sfi, vsym);
  199.     if( p == NULL )
  200.     {
  201.      char this[6];
  202.  
  203.      this[0] = 4;
  204.      this[1] = 0;
  205.      this[2] = 't';
  206.      this[3] = 'h';
  207.      this[4] = 'i';
  208.      this[5] = 's';
  209.      p       = Qsymbol( mid, lno, sfi, this );
  210.      if(p)
  211.       *pthis  = TRUE;
  212.     }
  213.     if(p)                                                               /*521*/
  214.     {
  215.         switch( p->RecType )
  216.         {
  217.           case SSDEF:                                                   /*809*/
  218.           {
  219.             target = ( (SSDef *)p )->FrameOffset;                       /*809*/
  220.             if( target >= 0 )
  221.               SetBit(target,STACKADDRBIT);
  222.             kind = ( (SSDef *)p )->TypeIndex;                           /*809*/
  223.             break;
  224.           }
  225.  
  226.           case SSVAR:                                                   /*809*/
  227.             target = ((SSVar *)p) ->Offset;                             /*809*/
  228.             kind = ((SSVar *)p) ->TypeIndex;                            /*809*/
  229.             break;
  230.  
  231.  
  232.           case SSREG:                                                   /*809*/
  233.             switch( ((SSReg *)p) ->RegNum )
  234.             {                                                           /*809*/
  235.               case SSREGBX16:                                           /*605*/
  236.               case SSREGBX32:                                           /*605*/
  237.                 target = (uint)(&AppPTB.EBX) - (uint)(&AppPTB);         /*205*/
  238.                 break;                                                  /*205*/
  239.               case SSREGSI16:                                           /*605*/
  240.               case SSREGSI32:                                           /*605*/
  241.                 target = (uint)(&AppPTB.ESI) - (uint)(&AppPTB);         /*205*/
  242.                 break;                                                  /*205*/
  243.               case SSREGDI16:                                           /*605*/
  244.               case SSREGDI32:                                           /*605*/
  245.                 target = (uint)(&AppPTB.EDI) - (uint)(&AppPTB);         /*205*/
  246.                 break;                                                  /*205*/
  247.             }                                                           /*205*/
  248.             SetBit(target,REGADDRBIT);                                  /*205*/
  249.             kind = ((SSReg *)p) ->TypeIndex;                            /*809*/
  250.             break;                                                      /*205*/
  251.  
  252.           case SSUSERDEF:                                               /*809*/
  253. /**********************F******************************************************/
  254. /* This case was added to support PL/X based variables. If we get here,      */
  255. /* a typedef record has been found in the symbols area within the context    */
  256. /* an SSProc block. In the example consider the Typedef TABLE.               */
  257. /*                                                                           */
  258. /*$$symbols dump:                                                            */
  259. /*       105   Proc      5F36    0790   06DE       0000   06DE  LECSORT      */
  260. /*       105   TypeDef           0562                           SORT@        */
  261. /*       105   Defn      0006    0193                           @PA00079     */
  262. /*       105   TypeDef           0564                           COMMUNAL     */
  263. /*       105   TypeDef           0601                           GAB          */
  264. /*       105   TypeDef           0662                           LSEG         */
  265. /*       105   TypeDef           0711                           NAMEENTRY    */
  266. /*       105   TypeDef           0746                           PUBLIC       */
  267. /*       105   Defn      FFFA    0129                           RC           */
  268. /*       105   TypeDef           0788                           TABLE        */
  269. /*       105   End                                                           */
  270. /*       105   Static 0005:85EE  0193                           WORK1@       */
  271. /*       105   Static 0005:85F2  0193                           TAB@         */
  272. /*       105   Static 0005:85F6  0130                           CNT          */
  273. /*       105   Static 0005:85FA  0130                           START        */
  274. /*       105   Static 0005:85FE  0130                           LAST         */
  275. /*       105   Static 0005:8602  0130                           UPP          */
  276. /*       105   Static 0005:8606  0130                           DOWN         */
  277. /*       105   Static 0005:860A  0193                           HOLD@        */
  278. /*       105   Static 0005:860E  0129                           NUMINCHAIN   */
  279. /*       105   Static 0005:8610  0516                           TYPESRT      */
  280. /*       105   Static 0005:8612  0517                           MODLST       */
  281. /*       105   Static 0005:862C  0521                           SORTFLAGS    */
  282. /*       105   Static 0005:862E  0526                           COMMON       */
  283. /*                                                                           */
  284. /*$$types dump:                                                              */
  285. /*       788) Ptr      : Far Type:789 Name:TAB@                              */
  286. /*       789) Array    : Bytes:4 Type:INT   *                                */
  287. /*                                                                           */
  288. /*Here's what we do:                                                         */
  289. /*                                                                           */
  290. /*   1. Get the typeno associated with the typedef record. In this           */
  291. /*      example "TABLE" has a Typedef = 788.                                 */
  292. /*   2. Get a pointer to this type record in the $$types area.               */
  293. /*   3. If the type record (788) is not a Ptr, then we assume that the       */
  294. /*      variable was declared as "based" but no basing pointer was           */
  295. /*      specified. In this case, we cannot get a pointer to the storage      */
  296. /*      that we want to type so we return a NULL target.                     */
  297. /*   4. if it is a T_PTR then:                                               */
  298. /*      - resolve the typeno. In this case 789.                              */
  299. /*        This establishes the type to associate with the based variable.    */
  300. /*      - Now we have to get a pointer to the storage to be typed. We get    */
  301. /*        this from the name field of the Ptr record. In this case "TAB@".   */
  302. /*      - find the basing pointer location. This is the location of          */
  303. /*        "TAB@".                                                            */
  304. /*      - The basing pointer location will contain the pointer that          */
  305. /*        locates the storage, so we dereference it.                         */
  306. /*   5. establish ExprTid and ExprScope.                                     */
  307. /*   6. return the target or NULL.                                           */
  308. /*                                                                           */
  309. /*****************************************************************************/
  310. {                                       /*                                   */
  311.  uchar   *pname;                        /* a ptr to the name.                */
  312.  uchar    pubname[256];                 /* DBPub() requires Z string.        */
  313.  uint    ptr;                           /* a pointer holder.                 */
  314.  SSProc  *Qprocsave;                    /* Set by Qsymbol() to the SSProc    */
  315.  DEBFILE *pdf;                          /* debug file node.                  */
  316.  BOOL     junk;
  317.                                         /*                                   */
  318.  kind = ((TD_USERDEF*)p)->TypeIndex;    /* establish type of based var    813*/
  319.  tp = QbasetypeRec(mid, kind);          /* get a ptr to its type rec.        */
  320.  if( tp &&                              /* if it exists and it's a pointer   */
  321.      (tp->RecType == T_PTR )            /* then we continue, else we retur813*/
  322.    )                                    /* a NULL target.                    */
  323.  {                                      /*                                   */
  324.   kind = ((TD_POINTER*)tp)->TypeIndex;                                  /*813*/
  325.                                         /*                                   */
  326.   if (kind < 512)                       /* if the type is primitive then  241*/
  327.     break;                              /* its a hanging based variable   241*/
  328.                                         /* then we can't do any thing     241*/
  329.   pname = (uchar*)&(((TD_POINTER*)tp)->NameLen);                        /*813*/
  330. /*****************************************************************************/
  331. /* At this point, we have a based variable and we know the name of the       */
  332. /* basing pointer. The basing pointer can be anywhere, so we will do a       */
  333. /* general search for this guy. We will have to make a recursive call        */
  334. /* to findlvar() ( !!eeks ) so we will have to save/restore Qproc,which      */
  335. /* is the scope of the based variable, since it gets set by findlvar().      */
  336. /* We look for the basing pointer in the following order:                    */
  337. /*                                                                           */
  338. /*  1. local variable or statics/externs declared in scope.                  */
  339. /*  2. static variables.                                                     */
  340. /*  3. public variables.                                                     */
  341. /*                                                                           */
  342. /* Dereference the pointer if we find it.                                    */
  343. /*****************************************************************************/
  344.   Qprocsave = Qproc;                    /* save the -> to scoping rec        */
  345.   ptr = findlvar(mid, pname, lno, sfi, &junk);
  346.   if( ptr == NULL )
  347.   {
  348.    ptr = findsvar(mid,pname);
  349.    if( ptr == NULL )
  350.    {
  351.     pdf=DBFindPdf(mid);
  352.     if( pdf != NULL )
  353.     {
  354.      USHORT NameLen = *(USHORT *)pname;
  355.  
  356.      strncpy( pubname, pname+2, NameLen );
  357.      pubname[NameLen] = '\0';
  358.      ptr = DBPub(pubname,pdf);
  359.     }
  360.    }
  361.   }
  362.  
  363.   if(ptr != NULL)                       /* if we found the symbol, then      */
  364.    target = DerefPointer(ptr,mid);      /* dereference the pointer.       240*/
  365.  
  366.   Qproc = Qprocsave;                    /* restore the scope of based var.   */
  367.  }                                      /*                                   */
  368.  break;                                 /* typedef handling is done.         */
  369. }                                       /* end of blocking for SSTYPEDEF.    */
  370.                                         /*                                   */
  371. /*****************************************************************************/
  372.  
  373.         }                               /* end of switch->rectype            */
  374.     }
  375.     if( target != NULL ) {              /*                                218*/
  376.         ExprTid = kind;                                                 /*813*/
  377.         ExprScope = Qproc;
  378.     }
  379.     return( target );
  380. }
  381. /*****************************************************************************/
  382. /* FindScope()                                                               */
  383. /*                                                                           */
  384. /* Description:                                                              */
  385. /*  Returns a pointer to the SSProc record for the addr argument. As a side  */
  386. /*  effect the mid and lno are put into the locations specified by the caller*/
  387. /*  if symbol information is found for this addr.                            */
  388. /*                                                                           */
  389. /* Parameters:                                                               */
  390. /*   addr       address to be scoped.                                        */
  391. /*   midlnoptr  where the caller wants the mid/lno stuffed.               107*/
  392. /*                                                                           */
  393. /* Return:                                                                   */
  394. /*             pointer to SSProc.                                            */
  395. /*   NULL      if no symbol info for this addr                               */
  396. /*                                                                           */
  397. /* Assumptions:                                                              */
  398. /*                                                                           */
  399. /*                                                                           */
  400. /*****************************************************************************/
  401.  void *
  402. FindScope( uint addr, uint *midlnoptr )                                 /*107*/
  403. {
  404.  ULONG mid = 0;
  405.  ULONG lno = 0;
  406.  DEBFILE *pdf;                          /* debug file pointer                */
  407.  
  408.  *midlnoptr='\0';                       /* initialize the mid value       107*/
  409.  *(midlnoptr+1)='\0';                   /* initialize the lno value       107*/
  410.  pdf=FindExeOrDllWithAddr( addr);       /* find debug file for addr.      101*/
  411.  if(pdf == NULL)                        /* if we can't find the debug file101*/
  412.   return(NULL);                         /* then return all null values.      */
  413.                                         /*                                   */
  414.  {
  415.   LNOTAB *pLnoTabEntry;
  416.  
  417.   mid = DBMapInstAddr(addr, &pLnoTabEntry, pdf);
  418.   if(pLnoTabEntry)
  419.    lno = pLnoTabEntry->lno;
  420.  }
  421.  
  422.  if(mid)                                /* find mid and lno for this addr    */
  423.   {
  424.    *midlnoptr=mid;                      /* mid where caller wants it      107*/
  425.    *(midlnoptr+1)=lno;                  /* lno where caller wants it      107*/
  426.    return( LocateScope(addr,mid,pdf) ); /* return pointer to SSProc record   */
  427.   }
  428.  return( NULL);                         /* if no symbols info for this addr  */
  429. }                                       /* then return a null pointer        */
  430.  
  431. /*****************************************************************************/
  432. /* LocateScope()                                                             */
  433. /*                                                                           */
  434. /* Description:                                                              */
  435. /*  This function finds the SSProc record in the symbols area associated     */
  436. /*  with the argument address and mid.                                       */
  437. /*                                                                           */
  438. /* Parameters:                                                               */
  439. /*   addr     the address that we want scoped                                */
  440. /*   mid      module containing this address                                 */
  441. /*                                                                           */
  442. /* Return:                                                                   */
  443. /*   p        pointer to the SSProc record                                   */
  444. /*                                                                           */
  445. /*                                                                           */
  446. /*                                                                           */
  447. /*****************************************************************************/
  448.  void *
  449. LocateScope( uint addr, uint mid , DEBFILE *pdf)
  450. {
  451.  uchar  *p;                             /* pointer to an SSProc record       */
  452.  uchar  *pend;                          /* pointer to end of symbols area    */
  453.  ULONG   len = 0;                       /* the size of the symbols area      */
  454.  MODULE  *mptr;                         /* -> to module for mid parameter.101*/
  455.  ULONG   ProcStartAddr;                 /* start of procedure in module.  101*/
  456.  ULONG   ProcEndAddr;                   /* end of procedure in module.    101*/
  457.                                         /* looking at proper symbols recs 606*/
  458.                                         /* for a given segment            606*/
  459.  ULONG  SegFlatAddr = 0;
  460.  USHORT SegNum;
  461. /*
  462.   DBSYMSEG returns a pointer and length for the local symbols associated with
  463.   the mid argument.
  464. */
  465.  
  466.  p = ( uchar * )DBSymSeg(mid,&len,pdf);
  467.  if( p == NULL ||  len == 0 )
  468.   return( NULL );
  469.  
  470.  mptr = GetPtrToModule( mid ,pdf );
  471.  
  472.  switch( mptr->DbgFormatFlags.Syms )
  473.  {
  474.   case TYPE104_C211:
  475.   case TYPE104_C600:
  476.    /**************************************************************************/
  477.    /*                                                                        */
  478.    /* C211 symbol records do not have an SSCHGDEF record. So we need         */
  479.    /* to initialize SegFlatAddr based on the single csect record that        */
  480.    /* the linker generates.                                                  */
  481.    /*                                                                        */
  482.    /**************************************************************************/
  483.    if(mptr->pCsects)
  484.     SegFlatAddr = mptr->pCsects->SegFlatAddr;
  485.    goto caseTYPE104_C600;
  486.  
  487. caseTYPE104_C600:
  488.   case TYPE104_HL01:
  489.   case TYPE104_HL02:
  490.   case TYPE104_HL03:
  491.   case TYPE104_HL04:
  492.   case TYPE104_CL386:
  493.    for( pend = p + len; p < pend; p = (uchar *)NextSSrec(p) )
  494.    {
  495.  
  496.     if( ((SSRec *)p)->RecType == SSCHGDEF)
  497.     {
  498.      SegNum      = ((SSChgDef *)p)->SegNum;
  499.      SegFlatAddr = GetLoadAddr( pdf->mte, SegNum );
  500.     }
  501.  
  502.     if( ((SSRec *)p)->RecType == SSPROC )
  503.     {
  504.      ProcStartAddr = SegFlatAddr + ((SSProc *)p)->ProcOffset;
  505.      ProcEndAddr = ProcStartAddr + ( (SSProc *)p )->ProcLen;
  506.      if ( addr >= ProcStartAddr && addr < ProcEndAddr )
  507.       return( p );
  508.     }
  509.    }
  510.    break;
  511.  }
  512.  return(NULL);
  513. }                                       /* end of LocateScope function       */
  514.  
  515. /*****************************************************************************/
  516. /* Qsymbol()                                                                 */
  517. /*                                                                           */
  518. /* Description:                                                              */
  519. /*  This function finds a pointer to the SSdef , SSvar, or SSreg record      */
  520. /*  in the symbols area for a given (mid,lno) context.                       */
  521. /*                                                                           */
  522. /* Parameters:                                                               */
  523. /*   mid      module id containing the lno.                                  */
  524. /*   lno      the context of the symbol.                                     */
  525. /*   vsym     a pointer to the symbol name. First byte is name length.       */
  526. /*                                                                           */
  527. /* Return:                                                                   */
  528. /*   Qrec     a pointer to the SSdef, SSvar, or SSreg record in symbol area. */
  529. /*                                                                           */
  530. /*                                                                           */
  531. /*                                                                           */
  532. /*****************************************************************************/
  533.  
  534. SSRec *Qsymbol( uint mid, uint lno, int sfi, uchar *vsym )
  535. {
  536.  ushort   nest;                         /* depth of left braces "{"          */
  537.  ushort   exclude;                      /* excludes certain recs inside "{}" */
  538.  int      disp;                         /* offset from proc or scope begin   */
  539.  uchar   *p;                            /* pointer to a symbol record        */
  540.  uchar   *pend;                         /* pointer to end of symbol area     */
  541.  uchar   *Qrec;                         /* pointer to the sym rec we want    */
  542.  ULONG    len;                          /* the span of lno                   */
  543.  uint     addr;                         /* address of lno                 101*/
  544.  uint     type;                         /* symbol record type                */
  545.  DEBFILE *pdf;                          /* -> debug file                     */
  546.  MODULE  *mptr;                         /* -> to module for mid parameter.101*/
  547.  uint     ProcStartAddr;                /* start of procedure in module.  101*/
  548.  uint     ProcEndAddr;                  /* end of procedure in module.    101*/
  549.  uint     BlockStartAddr;               /* start of {} block.             101*/
  550.  SSRec   *PtrToNextSymRec;              /* look ahead pointer to next sym.112*/
  551.  uchar    SkipNextBeginRec;             /* skip begin following proc.     112*/
  552.                                         /* looking at proper symbols recs 606*/
  553.                                         /* for a given segment            606*/
  554.  ULONG  SegFlatAddr;
  555.  USHORT SegNum;
  556.  
  557.  pdf=DBFindPdf(mid);                    /* find a debug file for this mid    */
  558.  addr=DBMapLno(mid, lno, sfi, &len, pdf );
  559.  if( addr == NULL )                     /* if not an executable let's try    */
  560.   addr=DBMapNonExLine(mid, lno, sfi, pdf); /* to map it to a non executable. */
  561.                                         /*                                   */
  562.  p = (UCHAR*) DBSymSeg(mid, &len, pdf);
  563.  if( (mid  == 0 )     ||
  564.      (addr == NULL ) ||
  565.      (p == NULL )    ||
  566.      (len == 0   )
  567.    )
  568.   return( NULL );
  569.  
  570. /*****************************************************************************/
  571. /* The first thing we want to do is get to the procedure record that scopes  */
  572. /* this symbol. So we get a pointer to the SSProc record that contains this  */
  573. /* offset. Note that this code assumes we will always find a proc.           */
  574. /*****************************************************************************/
  575.  
  576.  mptr = GetPtrToModule( mid ,pdf );
  577.  Qproc = NULL;
  578.  pend = NULL;                           /* initialise pend to null        218*/
  579.  switch( mptr->DbgFormatFlags.Syms )
  580.  {
  581.   case TYPE104_C211:                                                /*809 237*/
  582.   case TYPE104_C600:                                                /*809 237*/
  583.    /**************************************************************************/
  584.    /*                                                                        */
  585.    /* C211 symbol records do not have an SSCHGDEF record. So we need         */
  586.    /* to initialize SegFlatAddr based on the single csect record that        */
  587.    /* the linker generates.                                                  */
  588.    /*                                                                        */
  589.    /**************************************************************************/
  590.    if(mptr->pCsects)
  591.     SegFlatAddr = mptr->pCsects->SegFlatAddr;
  592.  
  593.    for( pend = p + len; p < pend; p = (uchar *) NextSSrec(p) )
  594.    {
  595.  
  596.     if( ((SSRec *)p)->RecType == SSCHGDEF)
  597.     {
  598.      SegNum      = ((SSChgDef *)p)->SegNum;
  599.      SegFlatAddr = GetLoadAddr( pdf->mte, SegNum );
  600.     }
  601.     if( ((SSRec *)p)->RecType == SSPROC)                                /*809*/
  602.     {
  603.      ProcStartAddr = SegFlatAddr + ((SSProc *)p)->ProcOffset;
  604.      ProcEndAddr = ProcStartAddr + ( (SSProc *)p )->ProcLen;
  605.      if ( addr >= ProcStartAddr && addr < ProcEndAddr )
  606.         break;
  607.     }
  608.    }
  609.    break;
  610.  
  611.   case TYPE104_HL01:                                                /*809 237*/
  612.   case TYPE104_HL02:                                                /*809 237*/
  613.   case TYPE104_HL03:                                                /*809 237*/
  614.   case TYPE104_HL04:
  615.   case TYPE104_CL386:                                               /*809 237*/
  616.    for( pend = p + len; p < pend; p = (uchar *)NextSSrec(p) )
  617.    {
  618.     ULONG  SegFlatAddr;
  619.     USHORT SegNum;
  620.  
  621.     if( ((SSRec *)p)->RecType == SSCHGDEF)
  622.     {
  623.      SegNum      = ((SSChgDef *)p)->SegNum;
  624.      SegFlatAddr = GetLoadAddr( pdf->mte, SegNum );
  625.     }
  626.     if( ((SSRec *)p)->RecType == SSPROC )                               /*809*/
  627.     {
  628.      ProcStartAddr = SegFlatAddr + ((SSProc *)p)->ProcOffset;
  629.      ProcEndAddr = ProcStartAddr + ( (SSProc *)p )->ProcLen;            /*809*/
  630.      if ( addr >= ProcStartAddr && addr < ProcEndAddr )
  631.       break;
  632.     }
  633.    }
  634.    break;
  635.  
  636.  }
  637.  Qproc = (SSProc *) p;                  /* save a pointer to the proc rec.   */
  638. /*****************************************************************************/
  639. /* At this point, p locates the SSProc record that scopes this symbol.       */
  640. /*                                                                           */
  641. /* The following "for" loop reads and processes symbol records.  The primary */
  642. /* controls are "nest" and "exclude".  The "nest" counter counts the level of*/
  643. /* nesting of {} blocks.  When nest = 0, we've finished scanning the proc.   */
  644. /* The "exclude" counter counts the level of {} blocks excluded from the     */
  645. /* search.  A block is excluded if its scope does not include the "off"      */
  646. /* variable.                                                                 */
  647. /*                                                                           */
  648. /*        in scope:       out of scope:                                      */
  649. /*                                                                           */
  650. /*                     off-->                                                */
  651. /*              {           {           {                                    */
  652. /*                                                                           */
  653. /*        off--->                                                            */
  654. /*                                                                           */
  655. /*              }           }           }                                    */
  656. /*                                off--->                                    */
  657. /*                                                                           */
  658. /* Logic Overview:                                                           */
  659. /*                                                                           */
  660. /* For the range of symbol records in this proc:                             */
  661. /*  Switch on symbol record type:                                            */
  662. /*   Begin:                                                                  */
  663. /*     nest += 1:                                                            */
  664. /*     if "off" out of scope of {}, exclude += 1:                            */
  665. /*                                                                           */
  666. /*   End:                                                                    */
  667. /*     nest -= 1;                                                            */
  668. /*     if exclude > 0, then exclude -= 1:                                    */
  669. /*                                                                           */
  670. /*   Variable:                                                               */
  671. /*     if !exclude, then look for the symbol in this {}:                     */
  672. /*     scan to end of {} and continue looking for shadows.                   */
  673. /*                                                                           */
  674. /* done when nest == 0                                                       */
  675. /*                                                                           */
  676. /* All "{}" blocks must be searched to resolve possible shadowed variables.  */
  677. /* Blocks "{}" that are beyond "off" are obviously out of scope.             */
  678. /*                                                                           */
  679. /*                                                                           */
  680. /*****************************************************************************/
  681.  Qrec = NULL;                           /*                                112*/
  682.  SkipNextBeginRec = FALSE;              /*                                112*/
  683.  for( nest = 0,                         /* scan symbol records.           218*/
  684.       exclude = 0;                      /*                                112*/
  685.       p < pend ;                        /*                                218*/
  686.       p = (uchar *) NextSSrec(p)        /* bump to next symbol record.    112*/
  687.     )                                   /*                                112*/
  688.  {                                      /*                                112*/
  689.                                         /*                                112*/
  690.   type =((SSRec *)p)->RecType;          /* define symbol record type. 809 112*/
  691.   switch( type )                        /*                                112*/
  692.   {                                     /*                                112*/
  693.    /**************************************************************************/
  694.    /* We compute a displacement and a length to be used for determining   112*/
  695.    /* exclusion of scoping blocks. If we have a begin record immediately  112*/
  696.    /* following a proc, then we use the disp and len of the containing    112*/
  697.    /* procedure instead of computing values from the begin record.        112*/
  698.    /*                                                                     112*/
  699.    /**************************************************************************/
  700.    case SSPROC:                                                         /*112*/
  701.     PtrToNextSymRec = NextSSrec(p);                                     /*112*/
  702.     if ( PtrToNextSymRec->RecType == SSBEGIN )                          /*112*/
  703.      SkipNextBeginRec = TRUE;                                           /*112*/
  704.     {
  705.      CSECT *pCsect;
  706.      ULONG  SegFlatAddr;
  707.  
  708.      pCsect      = GetCsectWithAddr( mptr,  addr );
  709.      SegFlatAddr = pCsect->SegFlatAddr;
  710.     BlockStartAddr = SegFlatAddr + ((SSProc *)p)->ProcOffset;
  711.     }
  712.     disp = addr - BlockStartAddr;                                       /*112*/
  713.     len  = ((SSProc *)p)->ProcLen;                                 /*809  112*/
  714.     goto EXCLUDE;                                                       /*112*/
  715.                                                                         /*112*/
  716.    case SSBEGIN:                                                        /*112*/
  717.     if( SkipNextBeginRec == TRUE )                                      /*112*/
  718.     {                                                                   /*112*/
  719.      SkipNextBeginRec = FALSE;                                          /*112*/
  720.      goto EXCLUDE;                                                      /*112*/
  721.     }                                                                   /*112*/
  722.     else                                                                /*112*/
  723.     {                                                                   /*112*/
  724.      CSECT *pCsect;
  725.      ULONG  SegFlatAddr;
  726.  
  727.      pCsect      = GetCsectWithAddr( mptr,  addr );
  728.      SegFlatAddr = pCsect->SegFlatAddr;
  729.      BlockStartAddr = SegFlatAddr + ((SSBegin *)p)->BlockOffset;
  730.      disp = addr - BlockStartAddr;                                      /*112*/
  731.      len  = ((SSBegin *)p)->BlockLen;                                   /*112*/
  732.      goto EXCLUDE;                                                      /*112*/
  733.     }                                                                   /*112*/
  734.  
  735. EXCLUDE:
  736.  
  737.     if( exclude ||                      /* if current records are out of     */
  738.         (disp < 0) ||                   /* scope or we are starting a {}     */
  739.         disp >= (int)len                /* that is out of scope, then bump   */
  740.       )                                 /* the exclude flag.                 */
  741.      exclude += 1;                      /*                                   */
  742.     nest += 1;                          /* bump the nesting level.           */
  743.     break;                              /*                                   */
  744.                                         /*                                   */
  745.    case SSEND:                          /*                                101*/
  746.                                         /* end scope record "}".             */
  747.     if( exclude )                       /*                                   */
  748.      exclude -= 1;                      /* if out of scope back up a level.  */
  749.     nest -= 1;                          /* back up a level of nesting.       */
  750.     break;                              /*                                   */
  751.                                         /*                                   */
  752.    default:                             /* all records between "{}".         */
  753.     if(  exclude == 0 )                 /* if out of scope, don't consider.  */
  754.     {                                   /*                                   */
  755.      uchar *q;                          /*                                   */
  756.      p = findsym(p,&Qrec,vsym);         /* look for symbol within "{}".      */
  757.      if( Qrec!=NULL )                   /* if we find it in this "{}",then   */
  758.       for(;;)                           /* scan to the next "{" or "}" and   */
  759.       {                                 /* continue looking for shadows.     */
  760.        q = (uchar *) NextSSrec(p);      /*                                   */
  761.        if( *(q+1)==SSBEGIN ||           /*                                101*/
  762.            *(q+1)==SSEND )              /*                                101*/
  763.         break;                          /*                                   */
  764.        p = q;                           /*                                   */
  765.       }                                 /*                                   */
  766.     }                                   /*                                   */
  767.     break;                              /*                                   */
  768.   }                                     /* end switch of symbol record type  */
  769.   if ( nest <= 0 )                      /* if out of "{}" then break out  218*/
  770.       break;                            /* of for loop                    218*/
  771.  }                                      /* end scan records in procedure     */
  772.  return( (SSRec *) Qrec );              /* return ptr to symbol rec in    809*/
  773. }                                       /* $$symbols area.                   */
  774.  
  775. /*****************************************************************************/
  776. /* findsym()                                                                 */
  777. /*                                                                           */
  778. /* Description:                                                              */
  779. /*                                                                           */
  780. /*   Find a variable in the $$symbol segment.                                */
  781. /*                                                                           */
  782. /* Parameters:                                                               */
  783. /*                                                                           */
  784. /*   p          input  - -> the initial symbol record.                       */
  785. /*   Qrec       output - -> where to put the pointer to the found symbol rec.*/
  786. /*                          NULL if no find.                                 */
  787. /*   vsym       input  - -> to the symbol name.                              */
  788. /*                                                                           */
  789. /* Return:                                                                   */
  790. /*                                                                           */
  791. /*   p          pointer to record or last record before a Begin/End record.  */
  792. /*                                                                           */
  793. /* Assumptions:                                                              */
  794. /*                                                                           */
  795. /*   p DOES NOT point to an SSBEGIN or SSEND record on input.                */
  796. /*                                                                           */
  797. /*****************************************************************************/
  798. #define SSDEFHEADERSIZE      9
  799. #define SSREGHEADERSIZE      6
  800. #define SSUSERDEFHEADERSIZE  5
  801. #define SSVARHEADERSIZE      12
  802.  
  803. uchar *findsym( uchar *p, uchar **Qrec, uchar *vsym )
  804. {                                       /*                                   */
  805.  uint     len1;                         /* length of a symbol record.        */
  806.  uint     len2;                         /* length of a symbol record.        */
  807.  uchar   *q= NULL;                      /* a holder for the symbol rec ptr521*/
  808.  uint     type;                         /* the type of the symbol record.    */
  809.  uchar   *cp;                           /* char ptr into symbol record.      */
  810.  int      rc;                           /* compare return code.              */
  811.  uchar   *cpsym;                        /* char ptr into vsym.               */
  812.  
  813. /*****************************************************************************/
  814. /* We will scan the symbol segment until we find a match or we run into a    */
  815. /* begin/end record. We return a pointer to the record containing the match  */
  816. /* or to the last record before we encountered a begin/end record.           */
  817. /*                                                                           */
  818. /*****************************************************************************/
  819.  for( ;; )
  820.  {
  821.   cp = p;
  822.   type = *(cp+2);                                                       /*809*/
  823.   switch( type )
  824.   {
  825.    case SSDEF:
  826.     cp += SSDEFHEADERSIZE;                                              /*809*/
  827.     break;
  828.  
  829.    case SSREG:
  830.     cp += SSREGHEADERSIZE;                                              /*809*/
  831.     break;
  832.  
  833.    case SSUSERDEF:
  834.     cp += SSUSERDEFHEADERSIZE;                                          /*809*/
  835.     break;
  836.  
  837.    case SSVAR:
  838.     cp += SSVARHEADERSIZE;                                              /*809*/
  839.     break;
  840.  
  841.    case SSBEGIN:
  842.    case SSEND:
  843.     return(q);
  844.   }
  845. /*****************************************************************************/
  846. /* At this point, we have a ptr to the name in a symbol record. We start to  */
  847. /* compare. If lengths do not match, then no need to proceed.                */
  848. /*                                                                           */
  849. /*****************************************************************************/
  850.   len1   = *(ushort*)cp;                /* get name length in symbol rec.    */
  851.   cp += 2;                                                              /*809*/
  852.   cpsym = vsym;                         /* set pointer to len byte in vsym.  */
  853.   len2 = *(USHORT*)cpsym;               /* if lenghts match, then proceed.813*/
  854.   cpsym += 2;                           /*                                813*/
  855.   if( len1 == len2 )                    /* if lenghts match, then proceed.813*/
  856.   {                                     /*                                   */
  857.    if ( cmd.CaseSens == TRUE )          /* perform case sensitive or         */
  858.     rc = strncmp(cpsym,cp,len1);        /* insensitive compare.              */
  859.    else                                 /*                                   */
  860.     rc = strnicmp(cpsym,cp,len1);       /*                                   */
  861.    if( rc == 0 )                        /* if we found a match, give the     */
  862.    {                                    /* pointer to the caller and         */
  863.     *Qrec = p;                          /* return.                           */
  864.     return(p);                          /*                                   */
  865.    }                                    /*                                   */
  866.   }                                     /*                                   */
  867.   q = p;                                /* hold ptr to symbol rec. may need. */
  868.   p = (uchar *) NextSSrec(p);           /* bump to next symbol record.       */
  869.  }                                      /*                                   */
  870. }                                       /*                                   */
  871.