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

  1. /*****************************************************************************/
  2. /* File:                                                                     */
  3. /*                                                                           */
  4. /*   dbif.c                                                                  */
  5. /*                                                                           */
  6. /* Description:                                                              */
  7. /*                                                                           */
  8. /*   Interface functions.                                                    */
  9. /*                                                                           */
  10. /* History:                                                                  */
  11. /*                                                                           */
  12. /*   04/10/95 Updated.                                                       */
  13. /*                                                                           */
  14. /*****************************************************************************/
  15.  
  16. #include "all.h"
  17.  
  18. extern PtraceBuffer  AppPTB;
  19. extern CmdParms      cmd;
  20.  
  21. extern PROCESS_NODE *pnode;
  22.  
  23. UINT DataTid;
  24. UINT DataMid;
  25.  
  26. /*****************************************************************************/
  27. /*  DBPub                                                                    */
  28. /*                                                                           */
  29. /* Description:                                                              */
  30. /*   returns information (type id, module id, and * ) about a given public   */
  31. /*   name.                                                                   */
  32. /*                                                                           */
  33. /* Parameters:                                                               */
  34. /*   pub       pointer to a public name.                                     */
  35. /*   pdf        pointer to debug file structure.                             */
  36. /*                                                                           */
  37. /* Return:                                                                   */
  38. /*   pubaddr    public address.                                              */
  39. /*              NULL for not found.                                          */
  40. /*                                                                           */
  41. /*****************************************************************************/
  42. UINT DBPub( UCHAR *pub , DEBFILE *pdf)
  43. {
  44.  uint      pubaddr;
  45.  MODULE   *mptr;
  46.  uchar     pubname[256];
  47.  uchar     temppub[256];
  48.  uint      publen;
  49.  PUBREC32 *precptr;
  50.  PUBREC16 *precptr16;
  51.  uchar    *pubend;
  52.  int       rc;
  53.  
  54. /*****************************************************************************/
  55. /* Scan public segments looking for a public name.                           */
  56. /*                                                                           */
  57. /*  1. Scan through the modules in this pdf until we find a match.           */
  58. /*  2. Branch on 16 or 32 bit modules.                                       */
  59. /*  3. Scan through the publics for each module.                             */
  60. /*  4. Convert public names to Z strings and compare case sensitive.         */
  61. /*  5. If no compare, then compare case insensitive unless user said not     */
  62. /*     to.                                                                   */
  63. /*  6. If we find a match, then break and return pubaddr.                    */
  64. /*                                                                           */
  65. /*****************************************************************************/
  66.  
  67.  pubaddr = NULL;
  68.  for( mptr = pdf->MidAnchor; mptr != NULL; mptr = mptr->NextMod )
  69.  {
  70.   switch( mptr->DbgFormatFlags.Pubs )
  71.   {
  72.    case TYPE_PUB_32:
  73.     precptr=(PUBREC32 *)DBPubSeg(mptr->mid,&publen,pdf);
  74.     if ( precptr != NULL )
  75.     {
  76.      pubend = (uchar *)precptr + publen;
  77.      for( ; (uchar *)precptr < pubend; )
  78.      {
  79.       strncpy(pubname,(uchar *)(&precptr->Namelen) + 1,precptr->Namelen);
  80.       pubname[precptr->Namelen] = '\0';
  81.       rc = strcmp( pubname, pub );
  82.       if ( rc && !cmd.CaseSens )
  83.       {
  84.        strcpy( temppub , pub );
  85.        strlwr(temppub);
  86.        strlwr(pubname );
  87.        rc = strcmp( pubname, temppub );
  88.       }
  89.  
  90.       if ( !rc )
  91.       {
  92. /***?*/DataMid = mptr->mid;
  93. /***?*/DataTid = precptr->Typeid;
  94.        pubaddr = precptr->Offset;
  95.        return(pubaddr);
  96.       }
  97.       precptr = (PUBREC32 *)NextPubRec32(precptr);
  98.      }
  99.     }
  100.     break;
  101.  
  102.    case TYPE_PUB_16:
  103.     precptr16=(PUBREC16 *)DBPubSeg(mptr->mid,&publen,pdf);
  104.     if ( precptr16 != NULL )
  105.     {
  106.      pubend = (uchar *)precptr16 + publen;
  107.      for( ; (uchar *)precptr16 < pubend; )
  108.      {
  109.       strncpy( pubname,(uchar *)(&precptr16->Namelen)+1,precptr16->Namelen);
  110.       pubname[precptr16->Namelen] = '\0';
  111.       rc = strcmp( pubname, pub );
  112.       if ( rc && !cmd.CaseSens )
  113.       {
  114.        strcpy( temppub , pub );
  115.        strlwr(temppub);
  116.        strlwr(pubname );
  117.        rc = strcmp( pubname, temppub );
  118.       }
  119.       if ( !rc )
  120.       {
  121. /***?*/DataMid = mptr->mid;
  122. /***?*/DataTid = GetInternal0_16PtrIndex( precptr16->Typeid );
  123.        pubaddr =  precptr16->Pub16Addr.FlatAddr;
  124.        return(pubaddr);
  125.       }
  126.       precptr16 = (PUBREC16 *)NextPubRec16(precptr16);
  127.      }
  128.     }
  129.     break;
  130.   }
  131.  }
  132.  return ( pubaddr );
  133. }
  134.  
  135. /*****************************************************************************/
  136. /* DBPut                                                                     */
  137. /*                                                                           */
  138. /* Description:                                                              */
  139. /*   puts data into the user's application address space.                    */
  140. /*                                                                           */
  141. /* Parameters:                                                               */
  142. /*   address    pointer to address space in user's application.              */
  143. /*   nbytes     number of bytes to copy to the user's application.           */
  144. /*   source     pointer to buffer of data that is targeted for the app.      */
  145. /*                                                                           */
  146. /* Return:                                                                   */
  147. /*   rc         whether it worked (0) or not (1).                            */
  148. /*                                                                           */
  149. /*****************************************************************************/
  150.   uint
  151. DBPut( uint   address,
  152.        uint  nbytes,
  153.        uchar *source)
  154. {
  155.   uint  rc;
  156.   PtraceBuffer ptb;
  157.  
  158.     if( (address >> REGADDCHECKPOS) == REGISTERTYPEADDR )
  159.     {
  160.      *(uint*)( (uint)&AppPTB + (address & REGISTERADDRMASK) )
  161.                 = *(uint*)source;
  162.      return( rc=0 );
  163.     }
  164.  
  165.   memset(&ptb,0,sizeof(ptb));
  166.   ptb.Pid = DbgGetProcessID();
  167.   ptb.Cmd = DBG_C_WriteMemBuf;
  168.   ptb.Addr =  (ulong)address;
  169.   ptb.Buffer = (ulong)source;
  170.   ptb.Len = (ulong)nbytes;
  171.   rc = xDosDebug( &ptb );
  172.   if(rc || (ptb.Cmd != DBG_N_Success ))
  173.     return ( 1 );
  174.  
  175.   return ( 0 );
  176. }
  177.  
  178. /*****************************************************************************/
  179. /* DBNextMod()                                                               */
  180. /*                                                                           */
  181. /* Description:                                                              */
  182. /*   Return the next sequential mid.                                         */
  183. /*                                                                           */
  184. /* Parameters:                                                               */
  185. /*   mid        we want the mid after this one.                              */
  186. /*              for mid = 0 return fisrt mid in chain.                       */
  187. /*              for mid = non-zero return next mid in the chain.             */
  188. /*              return mid = 0 if no more mids.                              */
  189. /*   pdf        pointer to debug file structure.                             */
  190. /*                                                                           */
  191. /* Return:                                                                   */
  192. /*   pModule->mid  the next mid in the chain.                                */
  193. /*                                                                           */
  194. /* Assumptions:                                                              */
  195. /*   There exists at least one mid.                                          */
  196. /*   The mid you're looking for exists.                                      */
  197. /*                                                                           */
  198. /*****************************************************************************/
  199. UINT DBNextMod( UINT mid, DEBFILE *pdf )
  200. {
  201.  MODULE   *pModule;
  202.  
  203.  pModule = pdf->MidAnchor;
  204.  if ( mid == 0 )
  205.   return( pModule->mid );
  206.  
  207.  for( ;
  208.     pModule->mid != mid;
  209.     pModule = pModule->NextMod
  210.    ){;}
  211.  
  212.  if ( pModule->NextMod )
  213.   return( pModule->NextMod->mid );
  214.  
  215.  return( 0 );
  216. }
  217.  
  218. /*****************************************************************************/
  219. /* DBGet                                                                     */
  220. /*                                                                           */
  221. /* Description:                                                              */
  222. /*   gets data from the user's application address space.                    */
  223. /*                                                                           */
  224. /* Parameters:                                                               */
  225. /*   address    pointer to address space in user's application.              */
  226. /*   nbytes     number of bytes to copy from the user's application.         */
  227. /*   totlptr    pointer to number of bytes that were read in.                */
  228. /*                                                                           */
  229. /* Return:                                                                   */
  230. /*   p          pointer to DBGet buffer that holds the bytes read in.        */
  231. /*                                                                           */
  232. /* Assumptions:                                                              */
  233. /*                                                                           */
  234. /*   address  is a flat address.                                             */
  235. /*                                                                           */
  236. /*****************************************************************************/
  237.   uchar*
  238. DBGet( uint address, uint nbytes, uint *totlptr  )
  239. {
  240.  UCHAR *pbytes;
  241.  
  242. /*****************************************************************************/
  243. /* Fisrt check if the address is a register address, to do this we check     */
  244. /* the 8 most significant bits for the bit pattern 01000000 if it is equal   */
  245. /* then return the pointer to the appropriate register field in the app      */
  246. /* ptrace buffer. stuff in the length of size of reg in the bytes read       */
  247. /* pointer.                                                                  */
  248. /*                                                                           */
  249. /* NOTE:                                                                     */
  250. /*   The checking for register address had been changed from checking two    */
  251. /* MSB's to 8 MSB's because you can have a junk address which has the two    */
  252. /* MSB's set and you fall into trap.                                         */
  253. /*****************************************************************************/
  254.  
  255.     if( (address >> REGADDCHECKPOS) == REGISTERTYPEADDR )
  256.     {
  257.        *totlptr = sizeof(AppPTB.EAX);
  258.        return( (uchar *)(&AppPTB) + (address & REGISTERADDRMASK) );
  259.     }
  260.  
  261.  
  262.   pbytes = GetDataBytes( address, nbytes, totlptr  );
  263.  return(pbytes);
  264. }
  265.  
  266. /*****************************************************************************/
  267. /*  DBFindProcName()                                                         */
  268. /*                                                                           */
  269. /* Description:                                                              */
  270. /*   Get a pointer to the function name.                                     */
  271. /*                                                                           */
  272. /* Parameters:                                                               */
  273. /*   addr       an address within some function.                             */
  274. /*   pdf        pointer to debug file containing this address.               */
  275. /*                                                                           */
  276. /* Return:                                                                   */
  277. /*              pointer to the function name.                                */
  278. /*                                                                           */
  279. /* Assumptions:                                                              */
  280. /*                                                                           */
  281. /*  pdf contains the addr.                                                   */
  282. /*  addr != null.                                                            */
  283. /*                                                                           */
  284. /*****************************************************************************/
  285. #define ASMLEVEL 1
  286.  
  287. UCHAR *DBFindProcName( ULONG addr , DEBFILE *pdf )
  288. {
  289.   static  char  ProcNameBuffer[MAXNAMELEN];
  290.   uint     mid;
  291.   uchar    *precptr;
  292.   uchar    *saveptr;
  293.   uchar  *pubend;
  294.   uint    publen;
  295.   void   *scope;
  296.   MODULE *pModule;
  297.   uint    delta;
  298.   uint    NewDelta;
  299.   uint    PubOffset;
  300. /*****************************************************************************/
  301. /* What we're going to do is find the function name that contains an address.*/
  302. /* If we don't have symbol information for the module, then we'll use the    */
  303. /* public info and take a guess.                                             */
  304. /*                                                                           */
  305. /* compile|link switch|comment        | logic                                */
  306. /* switch |switch     |               |                                      */
  307. /*   Zi   |  CO       |               |                                      */
  308. /* _______|___________|_______________|___________________________           */
  309. /* 1.yes  |  no       | no debug info |                                      */
  310. /* 2.yes  |  yes      | use symbols   |                                      */
  311. /* 3.no   |  yes      | use publics   | best fit public name. not guaranteed.*/
  312. /* 4.no   |  no       | no debug info |                                      */
  313. /*                                                                           */
  314. /* 1. Check for cases 1 and 4. If no debug info, then can't find a name.     */
  315. /* 2. Get the mid for this address in cases 2 and 3.                         */
  316. /* 3. Get a ptr to the scope record if this falls in case 2.                 */
  317. /* 4. Return a ptr to the function name.                                     */
  318. /* 5. Or, fall through to case 3.                                            */
  319. /*                                                                           */
  320. /*****************************************************************************/
  321.  if( pdf->SrcOrAsm == ASMLEVEL )
  322.   return( NULL );
  323.  
  324.  mid=GetMid(addr,pdf);
  325.  if( mid == 0 )
  326.   return( NULL );
  327.  
  328.  scope = LocateScope(addr,mid,pdf);
  329.  if( scope != NULL )
  330.  {
  331.   pModule = GetPtrToModule( mid, pdf );
  332.   if( pModule != NULL )
  333.   {
  334.    switch( pModule->DbgFormatFlags.Syms )
  335.    {
  336.     case TYPE104_C211:
  337.     case TYPE104_C600:
  338.     case TYPE104_CL386:
  339.     case TYPE104_HL01:
  340.     case TYPE104_HL02:
  341.     case TYPE104_HL03:
  342.     case TYPE104_HL04:
  343.      return((uchar*)&(((SSProc *)scope)->NameLen) );
  344.    }
  345.   }
  346.  }
  347.  
  348. /*****************************************************************************/
  349. /* If we get here, then we have public information for the module but no     */
  350. /* symbols.                                                                  */
  351. /*                                                                           */
  352. /* 1. Get a ptr the publics for this module.                                 */
  353. /* 2. Get a ptr the module structure for the mid.                            */
  354. /* 3. Branch on 16 or 32 bit public segment.                                 */
  355. /* 4. Scan the publics updating the closest one to addr.                     */
  356. /* 5. Return a pointer to the name in the public record.                     */
  357. /*                                                                           */
  358. /*****************************************************************************/
  359.  precptr = DBPubSeg(mid, &publen, pdf);
  360.  if ( !precptr )
  361.   return( NULL );
  362.  pubend = precptr + publen;
  363.  saveptr = NULL;
  364.  delta =  0xFFFFFFFF;
  365.  NewDelta = 0;
  366.  pModule = GetPtrToModule( mid, pdf );
  367.  
  368.  switch( pModule->DbgFormatFlags.Pubs )
  369.  {
  370.   case TYPE_PUB_32:
  371.   {
  372.    PUBREC32 *pubrec32;
  373.  
  374.    for( ; precptr < pubend; )
  375.    {
  376.     PubOffset = ((PUBREC32 *)precptr)->Offset;
  377.     if( addr >= PubOffset )
  378.     {
  379.      NewDelta = addr - PubOffset;
  380.      if ( NewDelta < delta )
  381.      {
  382.       delta = NewDelta;
  383.       saveptr = precptr;
  384.      }
  385.     }
  386.     precptr = NextPubRec32(precptr);
  387.    }
  388.  
  389.    if ( !saveptr )
  390.     return( NULL);
  391.  
  392.    pubrec32 = (PUBREC32 *)saveptr;
  393.    *(ushort *)&ProcNameBuffer[0] = pubrec32->Namelen;
  394.    memcpy(&ProcNameBuffer[2], &pubrec32->Namelen+1, pubrec32->Namelen);
  395.    return( &ProcNameBuffer[0] );
  396.   }
  397.  
  398.  
  399.   case TYPE_PUB_16:
  400.   {
  401.    PUBREC16 *pubrec16;
  402.  
  403.    for( ; precptr < pubend; )
  404.    {
  405.     PubOffset = ((PUBREC16 *)precptr)->Pub16Addr.FlatAddr;
  406.     if( addr >= PubOffset )
  407.     {
  408.      NewDelta = addr - PubOffset;
  409.      if ( NewDelta < delta )
  410.      {
  411.       delta = NewDelta;
  412.       saveptr = precptr;
  413.      }
  414.     }
  415.     precptr = NextPubRec16(precptr);
  416.    }
  417.  
  418.    if ( !saveptr )
  419.     return( NULL);
  420.  
  421.    pubrec16 = (PUBREC16 *)saveptr;
  422.    *(ushort *)&ProcNameBuffer[0] = pubrec16->Namelen;
  423.    memcpy(&ProcNameBuffer[2], &pubrec16->Namelen+1, pubrec16->Namelen);
  424.    return( &ProcNameBuffer[0] );
  425.   }
  426.  }
  427.  return(NULL);
  428. }
  429. /*****************************************************************************/
  430. /* GetMid()                                                                  */
  431. /*                                                                           */
  432. /* Description:                                                              */
  433. /*   get module id for a given instruction address within a pdf.             */
  434. /*                                                                           */
  435. /* Parameters:                                                               */
  436. /*   address    instruction address for which a mid is to be returned.       */
  437. /*   pdf        pointer to debug file structure.                             */
  438. /*                                                                           */
  439. /* Return:                                                                   */
  440. /*   mid        module id for the given instruction.  0 => instruction       */
  441. /*              address was out of range of our collection of mids.          */
  442. /*                                                                           */
  443. /* Assumptions:                                                              */
  444. /*                                                                           */
  445. /*   none.                                                                   */
  446. /*                                                                           */
  447. /*****************************************************************************/
  448. UINT GetMid( ULONG addr, DEBFILE *pdf )
  449. {
  450.  MODULE  *pModule;
  451.  UINT     mid;
  452.  
  453.  /****************************************************************************/
  454.  /* scan the module ring and check for the containment of the parameter      */
  455.  /* addr. return 0 if no containment.                                        */
  456.  /****************************************************************************/
  457.  mid = 0;
  458.  for( pModule = pdf->MidAnchor; pModule != NULL; pModule = pModule->NextMod )
  459.  {
  460.   if( GetCsectWithAddr( pModule, addr ) != NULL )
  461.   {
  462.    mid = pModule->mid;
  463.    break;
  464.   }
  465.  }
  466.  return ( mid );
  467. }
  468.  
  469. /*****************************************************************************/
  470. /* GetPtrToModule()                                                          */
  471. /*                                                                           */
  472. /* Description:                                                              */
  473. /*   Get a ptr to the MODULE structure for a mid.                            */
  474. /*                                                                           */
  475. /* Parameters:                                                               */
  476. /*   mid        input - module id.                                           */
  477. /*   pdf        input - the debug file that we're to look in.                */
  478. /*                    - NULL ==> do a global search cause don't know pdf.    */
  479. /*                                                                           */
  480. /* Return:                                                                   */
  481. /*   pModule       -> to the module structure.                               */
  482. /*   NULL       didn't find it.                                              */
  483. /*                                                                           */
  484. /*****************************************************************************/
  485.  MODULE *
  486. GetPtrToModule( uint mid, DEBFILE *pdf )
  487. {
  488.  MODULE *pModule;
  489.  /****************************************************************************/
  490.  /* Jump to the inner loop if we already know the pdf we want to look in.    */
  491.  /****************************************************************************/
  492.  if( pdf != NULL )
  493.   goto PDFKNOWN;
  494.  for(pdf = pnode->ExeStruct; pdf != NULL ; pdf=pdf->next )
  495.  {
  496. PDFKNOWN:
  497.   for( pModule = pdf->MidAnchor; pModule != NULL; pModule = pModule->NextMod )      /*101*/
  498.   {
  499.    if ( pModule->mid == mid )
  500.     return(pModule);
  501.   }
  502.  }
  503.  return( NULL );
  504. }
  505. /*****************************************************************************/
  506. /* IsNearPtr16Or32()                                                         */
  507. /*                                                                           */
  508. /* Description:                                                              */
  509. /*   determine whether a near pointer is 0:16 or 0:32.                       */
  510. /*                                                                           */
  511. /* Parameters:                                                               */
  512. /*   mid        input - module id.                                           */
  513. /*   ptr        input - near pointer we're trying to resolve.                */
  514. /*   sfx        input - stack frame index for a stack variable.              */
  515. /*                                                                           */
  516. /* Return:                                                                   */
  517. /*   BIT16                                                                   */
  518. /*   BIT32                                                                   */
  519. /*   BITUNKNOWN                                                              */
  520. /*                                                                           */
  521. /* Assumptions:                                                              */
  522. /*                                                                           */
  523. /*****************************************************************************/
  524.  uchar
  525. IsNearPtr16Or32( uint mid , uint ptr , uint sfx )
  526. {
  527.  uchar   bitness;
  528.  MODULE *pModule;
  529.  /****************************************************************************/
  530.  /* We have to determine whether the pointer is 0:16 or 0:32.                */
  531.  /* This is a hole in the debug format in that a 0:16 and 0:32               */
  532.  /* should have a different type specifier. Currently, they both             */
  533.  /* have an A* format.                                                       */
  534.  /*                                                                          */
  535.  /* So, let's probe in this order:                                           */
  536.  /*  Stack   - mappable to a stack frame.                                    */
  537.  /*  Data    - mappable to a data object.                                    */
  538.  /*  Dynamic - if it doesn't map to either of the above.                     */
  539.  /*            ( use $$type format flag for the mid ).                       */
  540.  /*                                                                          */
  541.  /****************************************************************************/
  542.  if( TestBit(ptr,STACKADDRBIT) )
  543.   bitness = StackFrameMemModel( sfx );
  544.  else
  545.   bitness = GetBitness( ptr );
  546.  /****************************************************************************/
  547.  /* Must be a ptr in dynamic memory.                                         */
  548.  /****************************************************************************/
  549.  if( bitness == (uchar)BITUNKNOWN )
  550.  {
  551.   pModule = GetPtrToModule( mid , NULL );
  552.   if( pModule == NULL )
  553.    return( BITUNKNOWN );
  554.   bitness = BIT16;
  555.   if( (pModule->DbgFormatFlags.Typs == TYPE103_CL386) ||
  556.       (pModule->DbgFormatFlags.Typs == TYPE103_HL01)  ||
  557.       (pModule->DbgFormatFlags.Typs == TYPE103_HL02) )
  558.    bitness = BIT32;
  559.  }
  560.  return( bitness );
  561. }
  562.  
  563.  
  564. /*****************************************************************************/
  565. /* GetCsectWithAddr()                                                        */
  566. /*                                                                           */
  567. /* Description:                                                              */
  568. /*                                                                           */
  569. /*   get a pointer to the memory object that contains this address.          */
  570. /*                                                                           */
  571. /* Parameters:                                                               */
  572. /*                                                                           */
  573. /*   pdf        pointer to debug file with the data.                         */
  574. /*   addr       contained address.                                           */
  575. /*                                                                           */
  576. /* Return:                                                                   */
  577. /*                                                                           */
  578. /*   pCsect -> csect.                                                        */
  579. /*              NULL.                                                        */
  580. /*                                                                           */
  581. /*****************************************************************************/
  582. CSECT *GetCsectWithAddr(  MODULE *pModule, ULONG addr )
  583. {
  584.  CSECT  *pCsect;
  585.  ULONG   addrlo;
  586.  ULONG   addrhi;
  587.  
  588.  pCsect = NULL;
  589.  if( pModule )
  590.  {
  591.   pCsect = pModule->pCsects;
  592.  
  593.   for( ; pCsect != NULL; pCsect=pCsect->next )
  594.   {
  595.    addrlo = pCsect->CsectLo;
  596.    addrhi = pCsect->CsectHi;
  597.  
  598.    if( (addr >= addrlo) && (addr <= addrhi) )
  599.     break;
  600.   }
  601.  }
  602.  return( pCsect );
  603. }
  604.