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