home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sherlock.zip / CV32 / CVSUPP.C < prev    next >
C/C++ Source or Header  |  1994-06-29  |  13KB  |  532 lines

  1. /*
  2. **  Sherlock - Copyright 1992, 1993, 1994
  3. **    Harfmann Software
  4. **    Compuserve: 73147,213
  5. **    All rights reserved
  6. */
  7. /*
  8. ** Code view interface functions to extract symbolic information
  9. ** given a state to extract information from.
  10. */
  11. #include    <stdio.h>
  12. #include    <stdlib.h>
  13. #include    <ctype.h>
  14. #include    <malloc.h>
  15. #include    <memory.h>
  16. #include    <sys\stat.h>
  17.  
  18. #define     INCL_DOSPROCESS
  19. #include    <os2.h>
  20. #include    "..\Debug.h"
  21.  
  22. #include    "..\SrcInter.h"
  23. #include    "CV.h"
  24. #include    "CV32.h"
  25.  
  26. void hexdump(unsigned char *data, int count, char *buff);
  27.  
  28. /*
  29. ** Get the value of a number leave.
  30. */
  31. int CVGetNumber(UCHAR *types, ULONG *num)
  32. {
  33.  
  34.     /*
  35.     ** Unsigned numeric leaves
  36.     */
  37.     if(types[0] < 0x80) {
  38.     *num = types[0];
  39.     return 1;
  40.     } else if(types[0] == 0x85) {
  41.     *num = types[1] + (types[2]<<8);
  42.     return 3;
  43.     } else if(types[0] == 0x86) {
  44.     *num = types[1]     + types[2]<<8 +
  45.            types[3]<<16 + types[4]<<24;
  46.     return 5;
  47.  
  48.     /*
  49.     ** Signed numeric leaves
  50.     */
  51.     } else if(types[0] == 0x88) {
  52.     *num = (ULONG) ((int) types[1]);
  53.     return 2;
  54.     } else if(types[0] == 0x89) {
  55.     *num = (ULONG) ((int) (types[1] + types[2]<<8));
  56.     return 3;
  57.     } else if(types[0] == 0x8a) {
  58.     *num = types[1]     + types[2]<<8 +
  59.            types[3]<<16 + types[4]<<24;
  60.     return 5;
  61.     }
  62.     return 0;
  63. }
  64.  
  65. /*
  66. ** Get a type index.
  67. */
  68. USHORT GetType(UCHAR *types)
  69. {
  70. USHORT *ptr;
  71.  
  72.     if(types[0] != 0x83)
  73.     return 0xffff;
  74.  
  75.     ptr = (USHORT *) &types[1];
  76.     return *ptr;
  77. }
  78.  
  79. /*
  80. ** Given a target type index, return a pointer to the start of the type string.
  81. */
  82. UCHAR *FindType(CVTypeData *cvType, USHORT targetIndex)
  83. {
  84. CVModule   *cvMod;
  85. UCHAR      *types;
  86. USHORT      currentIndex = 0x200;
  87. USHORT      i;
  88.  
  89.     cvMod    = cvType->module;
  90.     types       = cvMod->type;
  91.     if(targetIndex < 0x200)
  92.         return NULL;
  93.  
  94.     /*
  95.     ** Search for the type.
  96.     */
  97.     for(i=0; i<cvMod->typeSize;) {
  98.         if(targetIndex == currentIndex)
  99.             break;
  100.  
  101.         i += types[i+1] + types[i+2] * 256 + 3;
  102.         currentIndex++;
  103.     }
  104.     return &types[i];
  105. }
  106.  
  107. /*
  108. ** Answer the size of a base type size.
  109. */
  110. int CVGetBaseTypeSize(USHORT targetIndex)
  111. {
  112.     if(targetIndex >= 0x200)
  113.     return 4;
  114.  
  115.     switch((targetIndex & 0x01c) >> 2) {
  116.         /* Real */
  117.         case 2: switch(targetIndex & 0x03) {
  118.                     case 0: /* Single */
  119.                         return 4;
  120.                     case 1: /* Double */
  121.                         return 8;
  122.                     case 2: /* Long double */
  123.                         return 10;
  124.                     case 3: /* Reserved */
  125.                         return 4;
  126.                     } break;
  127.  
  128.         /* Complex */
  129.         case 3: switch(targetIndex & 0x03) {
  130.                     case 0: /* Single */
  131.                         return 8;
  132.                     case 1: /* Double */
  133.                         return 16;
  134.                     case 2: /* Long double */
  135.                         return 20;
  136.                     case 3: /* Reserved */
  137.                         return 4;
  138.                 } break;
  139.  
  140.         /* Currency */
  141.         case 6: switch(targetIndex & 0x03) {
  142.                     case 1:
  143.                         return 8;   /* Normal   */
  144.                     case 0: /* Reserved */
  145.                     case 2:
  146.                     case 3: return 4;
  147.                 } break;
  148.  
  149.         /* Other base c types. */
  150.         case 0:
  151.         case 1:
  152.         case 4:
  153.         case 5:
  154.         case 7: switch(targetIndex & 0x03) {
  155.                     case 0: /* Byte */
  156.                         return 1;   /* Byte     */
  157.                     case 1: /* Word */
  158.                         return 2;   /* Word     */
  159.                     case 2: /* Long     */
  160.                         return 4;
  161.                     case 3: /* Reserved */
  162.                         return 4;
  163.                 } break;
  164.     }
  165.     return 4;
  166. }
  167.  
  168. /*
  169. ** Answer the size of the structure.
  170. */
  171. int elementSize(State *state)
  172. {
  173. CVTypeData *cvType = state->typeData;
  174. UCHAR       *types;
  175. USHORT        targetIndex;
  176. ULONG        num;
  177.  
  178.  
  179.     /*
  180.     ** Get the pointer to the type string.
  181.     */
  182.     types = FindType(cvType, cvType->typeIndex);
  183.     if(types != NULL) {
  184.         /*
  185.         ** Verify that this is a structure.
  186.         */
  187.     if(types[3] == 0x79) {
  188.         /*
  189.         ** Need to skip over the length string.
  190.         */
  191.         CVGetNumber(&types[4], &num);
  192.         return num;
  193.     }
  194.  
  195.     /*
  196.     ** See if this is a pointers structure.
  197.     */
  198.     if(types[3] == 0x7a) {
  199.         return 4;
  200.     }
  201.  
  202.     /*
  203.     ** Try for an array.
  204.     */
  205.     if(types[3] == 0x78) {
  206.         int i;
  207.  
  208.         i = CVGetNumber(&types[4], &num) + 4;
  209.         targetIndex = GetType(&types[i]);
  210.         if(targetIndex < 0x200)
  211.         return CVGetBaseTypeSize(targetIndex);
  212.         types = FindType(cvType, targetIndex);
  213.         if(types[3] == 0x7a)
  214.         return 4;
  215.         if(types[3] == 0x79)
  216.         return 4;
  217.         if(types[3] == 0x78) {
  218.         i = CVGetNumber(&types[4], &num) + 4;
  219.         return CVGetBaseTypeSize(GetType(&types[i]));
  220.         }
  221.         return 4;
  222.     }
  223.  
  224.     /*
  225.     ** Dump the unknown data type.
  226.     */
  227.     {
  228. {
  229. char buff[80];
  230. hexdump(types, 16, buff);
  231. fprintf(stderr, "Unknown type encountered:\n");
  232. fprintf(stderr, "%s\n", buff);
  233. }
  234.         return 4;
  235.  
  236.     }
  237.     }
  238.  
  239.     targetIndex = cvType->typeIndex;
  240.     return CVGetBaseTypeSize(targetIndex);
  241. }
  242.  
  243. /*
  244. ** Get the data from the debuggee, format it and then put it in a buffer.
  245. */
  246. int CVGetValue(DebugModule *module, State *state)
  247. {
  248. UCHAR       *data;
  249. CVTypeData *cvType = state->typeData;
  250. USHORT        targetIndex;
  251.  
  252.  
  253.     module;
  254.  
  255.     /*
  256.     ** Get the data from the debuggee
  257.     */
  258.     data = calloc(state->elementSize + 4, 1);
  259.     debugBuffer->Len    = state->elementSize;
  260.     debugBuffer->Addr    = state->addr;
  261.     debugBuffer->Buffer = (ULONG) data;
  262.     if(DispatchCommand(DBG_C_ReadMemBuf) != DBG_N_Success) {
  263.     free(data);
  264.     return OUT_OF_CONTEXT;
  265.     }
  266.     if(state->value.typeValue == BYTE_INDEX_IN_LVAL)
  267.     *(ULONG *) data = *(ULONG *)data + state->value.val.lVal;
  268.  
  269.     /*
  270.     ** Check the type of the data.
  271.     */
  272.     targetIndex = cvType->typeIndex;
  273.     if(targetIndex > 0x0200) {
  274.     char *types;
  275.  
  276.     types = FindType(cvType, cvType->typeIndex);
  277.     if(types == NULL) {
  278.         free(data);
  279.         return INTERNAL_ERROR;
  280.     }
  281.  
  282.     /*
  283.     ** Pointers
  284.     */
  285.     if(types[3] == 0x7a) {
  286.         USHORT  typeIndex;
  287.  
  288.         state->value.typeValue = PTR_VAL;
  289.         state->value.val.lVal = *(ULONG *) data;
  290.         typeIndex = GetType(&types[5]);
  291.         state->isStruct = 0;
  292.         if(typeIndex >= 0x200) {
  293.         types = FindType(cvType, typeIndex);
  294.         if(types[3] == 0x79) {
  295.             state->isStruct = 1;
  296.             cvType->typeIndex = typeIndex;
  297.         }
  298.         }
  299.         free(data);
  300.         return SUCCESS;
  301.     }
  302.  
  303.     /*
  304.     ** Structures
  305.     */
  306.     if(types[3] == 0x79) {
  307.         state->value.typeValue = PTR_VAL;
  308.         state->value.val.lVal  = state->addr;
  309.         state->isStruct       = 1;
  310.         return SUCCESS;
  311.     }
  312.  
  313.     /*
  314.     ** Arrays
  315.     */
  316.     if(types[3] == 0x78) {
  317.         int     i;
  318.         ULONG   size;
  319.         USHORT  typeIndex;
  320.  
  321.         state->value.typeValue = PTR_VAL;
  322.         state->value.val.lVal  = state->addr;
  323.         i = CVGetNumber(&types[4], &size) + 4;
  324.         typeIndex = GetType(&types[i]);
  325.         if((typeIndex == 0x80) || (typeIndex == 0x84)) {
  326.         char   *ptr;
  327.  
  328.         size /= 8;
  329.         ptr = malloc(size+1);
  330.         ptr[size] = 0;
  331.         state->value.typeValue = STR_VAL;
  332.         state->value.val.sVal  = ptr;
  333.         debugBuffer->Len       = size;
  334.         debugBuffer->Addr      = state->addr;
  335.         debugBuffer->Buffer    = (ULONG) ptr;
  336.         if((i = DispatchCommand(DBG_C_ReadMemBuf)) == DBG_N_Success)
  337.             return SUCCESS;
  338.  
  339.         free(ptr);
  340.         state->value.typeValue = PTR_VAL;
  341.         state->value.val.lVal  = *(ULONG *) data;
  342.         return OUT_OF_CONTEXT;
  343.         }
  344.         return SUCCESS;
  345.     }
  346.  
  347. {
  348. char buff[80];
  349. hexdump(types, 16, buff);
  350. fprintf(stderr, "Unknown type in GetValue\n");
  351. fprintf(stderr, "%s\n", buff);
  352. }
  353.     free(data);
  354.     return INVALID_NAME;
  355.     }
  356.  
  357.     /*
  358.     ** For predefined types, break it down.
  359.     */
  360.     switch((targetIndex & 0x01c) >> 2) {
  361.     /* Real */
  362.     case 2: switch(targetIndex & 0x03) {
  363.             case 0: /* Single */
  364.                 state->value.val.dVal  = *(float *) data;
  365.                 state->value.typeValue = DOUBLE_VAL;
  366.                             free(data);
  367.                 return SUCCESS;
  368.             case 1: /* Double */
  369.                 state->value.val.dVal  = *(double *) data;
  370.                 state->value.typeValue = DOUBLE_VAL;
  371.                             free(data);
  372.                 return SUCCESS;
  373.             case 2: /* Long double */
  374.                 free(data);
  375.                 return INVALID_VALUE;
  376.             case 3: /* Reserved */
  377.                 free(data);
  378.                 return INTERNAL_ERROR;
  379.         } break;
  380.  
  381.     /* Complex */
  382.     case 3: free(data);
  383.         return INVALID_VALUE;
  384.  
  385.     /* Currency */
  386.     case 6: free(data);
  387.         return INVALID_VALUE;
  388.  
  389.     /* Other base c types. */
  390.     case 0: /* SIGNED   */
  391.     case 1: /* UNSIGNED */
  392.     case 4: /* BOOLEAN  */
  393.     case 5: /* ASCII    */
  394.         if((targetIndex & 0x60) == 0) {
  395.             switch(targetIndex & 0x03) {
  396.             case 0: /* Byte */
  397.                 state->value.val.lVal  = data[0];
  398.                 state->value.typeValue = CHAR_VAL;
  399.                                 free(data);
  400.                 return SUCCESS;;
  401.             case 1: /* Word */
  402.                 state->value.val.lVal  = *(short *) data;
  403.                 state->value.typeValue = LONG_VAL;
  404.                                 free(data);
  405.                 return SUCCESS;;
  406.             case 2: /* Long     */
  407.                 state->value.val.lVal  = *(long *) data;
  408.                 state->value.typeValue = LONG_VAL;
  409.                                 free(data);
  410.                 return SUCCESS;;
  411.             case 3: /* Reserved */
  412.                 free(data);
  413.                 return INTERNAL_ERROR;
  414.             }
  415.         } else {
  416.             debugBuffer->Addr    = *(ULONG *) data;
  417.             debugBuffer->Buffer = (ULONG) data;
  418.             debugBuffer->Len    = 4;
  419.             if(DispatchCommand(DBG_C_ReadMemBuf) != 0) {
  420.             free(data);
  421.             return OUT_OF_CONTEXT;
  422.             }
  423.             switch(targetIndex & 0x03) {
  424.             case 0: /* Byte */
  425.                 {
  426.                 ULONG    base, tmp;
  427.                 int    numBytes;
  428.  
  429.                 tmp = base = *(ULONG *) data;
  430.                 numBytes = 0;
  431.                 do {
  432.                     debugBuffer->Addr    = tmp;
  433.                     debugBuffer->Buffer = (ULONG) data;
  434.                     debugBuffer->Len    = 1;
  435.                     if(DispatchCommand(DBG_C_ReadMemBuf) != 0) {
  436.                     free(data);
  437.                     return OUT_OF_CONTEXT;
  438.                     }
  439.                     numBytes++;
  440.                     tmp++;
  441.                 } while(data[0] != 0);
  442.                 state->value.val.sVal  = malloc(numBytes);
  443.                 state->value.typeValue = STR_VAL;
  444.                 debugBuffer->Addr   = base;
  445.                 debugBuffer->Buffer = (ULONG) state->value.val.sVal;
  446.                 debugBuffer->Len    = numBytes;
  447.                 if(DispatchCommand(DBG_C_ReadMemBuf) != 0) {
  448.                     free(data);
  449.                     return OUT_OF_CONTEXT;
  450.                 }
  451.                 state->value.val.sVal[numBytes] = 0;
  452.                 free(data);
  453.                 return SUCCESS;
  454.                 }
  455.             case 1: /* Word */
  456.                 state->value.val.lVal  = *(short *) data;
  457.                 state->value.typeValue = LONG_VAL;
  458.                                 free(data);
  459.                 return SUCCESS;
  460.             case 2: /* Long     */
  461.                 state->value.val.lVal  = *(long *) data;
  462.                 state->value.typeValue = LONG_VAL;
  463.                                 free(data);
  464.                 return SUCCESS;
  465.             case 3: /* Reserved */
  466.                 free(data);
  467.                 return INTERNAL_ERROR;
  468.             }
  469.             return INVALID_VALUE;
  470.         } break;
  471.     }
  472.     free(data);
  473.     return INVALID_VALUE;
  474. }
  475.  
  476. /*
  477. ** Assuming the address is a pointer to a pointer, return the value
  478. ** at the pointer.
  479. */
  480. int CVGetRegisterValue(DebugModule *module, State *state)
  481. {
  482. CVTypeData *cvType = state->typeData;
  483.  
  484.     module;
  485.     if(cvType->registerNum != -1) {
  486.     if(DispatchCommand(DBG_C_ReadReg))
  487.         return INTERNAL_ERROR;
  488.     switch(cvType->registerNum) {
  489.         case 16: state->value.val.lVal = debugBuffer->EAX; return SUCCESS;
  490.         case 17: state->value.val.lVal = debugBuffer->ECX; return SUCCESS;
  491.         case 18: state->value.val.lVal = debugBuffer->EDX; return SUCCESS;
  492.         case 19: state->value.val.lVal = debugBuffer->EBX; return SUCCESS;
  493.         case 20: state->value.val.lVal = debugBuffer->ESP; return SUCCESS;
  494.         case 21: state->value.val.lVal = debugBuffer->EBP; return SUCCESS;
  495.         case 22: state->value.val.lVal = debugBuffer->ESI; return SUCCESS;
  496.         case 23: state->value.val.lVal = debugBuffer->EDI; return SUCCESS;
  497.         default: state->value.typeValue = UNKNOWN_VAL; return INVALID_NAME;
  498.     }
  499.     }
  500.     return INVALID_NAME;
  501. }
  502.  
  503. /*
  504. **  Dump a buffer of length to the buffer given.  Assume that length is
  505. **  less than 16 and that the buffer is large enough to hold the result.
  506. */
  507. void hexdump(unsigned char *data, int count, char *buff)
  508. {
  509. int i;
  510. static char digits[] = "0123456789ABCDEF";
  511.  
  512.     count = min(count, 16);
  513.     for(i=0; i<count; i++) {
  514.         if(i == 8) {
  515.             *buff++ = ' ';
  516.             *buff++ = ' ';
  517.         }
  518.         *buff++ = digits[data[i]/16];
  519.         *buff++ = digits[data[i]%16];
  520.         *buff++ = ' ';
  521.     }
  522.     *buff++ = ' ';
  523.     *buff++ = ' ';
  524.     *buff++ = ' ';
  525.  
  526.     memcpy(buff, data, 16);
  527.     for(i=0; i<count; i++)
  528.     buff[i] = isgraph(buff[i]) ? buff[i] : (char) '.';
  529.     buff[16] = '\0';
  530.     return;
  531. }
  532.