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

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