home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sherlock.zip / CV32 / CVDATA.C < prev    next >
C/C++ Source or Header  |  1994-06-29  |  13KB  |  503 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    <string.h>
  13. #include    <malloc.h>
  14. #include    <sys\stat.h>
  15.  
  16. #define     INCL_DOSPROCESS
  17. #include    <os2.h>
  18. #include    "..\Debug.h"
  19.  
  20. #include    "..\SrcInter.h"
  21. #include    "CV.h"
  22. #include    "CV32.h"
  23.  
  24. /*
  25. ** Get the member of a structure.
  26. */
  27. int CVGetMember(DebugModule *module, State *state, State *state2)
  28. {
  29. CVTypeData *cvType = cvType = state->typeData;
  30. UCHAR       *types;
  31. UCHAR       *tList;
  32. UCHAR       *nList;
  33. ULONG        nameLen;
  34. ULONG        index;
  35. ULONG        i;
  36. ULONG        num, numFields;
  37.  
  38.     module;
  39.  
  40.     /*
  41.     ** Make sure we have an address in state.
  42.     */
  43.     if(state->value.typeValue != PTR_VAL)
  44.     return INVALID_VALUE;
  45.  
  46.     /*
  47.     ** Make sure we have a name in state2.
  48.     */
  49.     if(state2->value.typeValue != NAME_VAL)
  50.     return INVALID_NAME;
  51.  
  52.     /*
  53.     ** Get the type data for the structure.
  54.     */
  55.     types = FindType(cvType, cvType->typeIndex);
  56.     if(types == NULL)
  57.     return INTERNAL_ERROR;
  58.     if(types[3] != 0x79)
  59.     return INTERNAL_ERROR;
  60.  
  61.     /*
  62.     ** Need to skip over the length string.
  63.     */
  64.     i  = CVGetNumber(&types[4], &num) + 4;
  65.     i += CVGetNumber(&types[i], &numFields);
  66.  
  67.     /*
  68.     ** Get the type list for the name.
  69.     */
  70.     tList = FindType(cvType, GetType(&types[i  ]));
  71.     nList = FindType(cvType, GetType(&types[i+3]));
  72.     if((nList == NULL) || (tList == NULL)) {
  73.     return INTERNAL_ERROR;
  74.     }
  75.     if((nList[3] != 0x7f) || (tList[3] != 0x7f)) {
  76.     return INTERNAL_ERROR;
  77.     }
  78.  
  79.     /*
  80.     ** Find the name in the name list.
  81.     */
  82.     nameLen = strlen(state2->value.val.sVal);
  83.     for(i=4, index=0; index<numFields; index++) {
  84.     if(nameLen == nList[i+1])
  85.         if(strncmp(&nList[i+2], state2->value.val.sVal, nameLen) == 0)
  86.         break;
  87.     i += nList[i+1] + 2;
  88.     i += CVGetNumber(&nList[i], &num);
  89.     }
  90.     if(nameLen != nList[i+1])
  91.     return INVALID_NAME;
  92.     if(strncmp(&nList[i+2], state2->value.val.sVal, nameLen) != 0)
  93.     return INVALID_NAME;
  94.  
  95.     /*
  96.     ** Find the actual offset of the value and then put it
  97.     ** into the address field of the state.
  98.     */
  99.     i += nList[i+1] + 2;
  100.     i += CVGetNumber(&nList[i], &num);
  101.     state->addr = state->value.val.lVal + num;
  102.  
  103.     /*
  104.     ** Find the type information.
  105.     */
  106.     cvType->registerNum = -1;
  107.     cvType->typeIndex = GetType(&tList[index * 3 + 4]);
  108.     return CVGetValue(module, state);
  109. }
  110.  
  111. /*
  112. ** Find the offset of a variable given  the name.  Find Globals,
  113. ** then statics then locals.
  114. */
  115. int CVGetName(DebugModule *module, State *state, State *state2)
  116. {
  117. CVModule   *cvMod   = ((CVAuxData *) module->AuxData)->moduleData;
  118. USHORT        cbName  = (USHORT) strlen(state->value.val.sVal);
  119. ULONG       eip     = state->baseEIP;
  120.  
  121.     /*
  122.     ** If state2 is non-null, then it must be a member of a structure.
  123.     */
  124.     if(state2 != NULL)
  125.     return CVGetMember(module, state, state2);
  126.  
  127.     /*
  128.     ** Make sure we have a name in state.
  129.     */
  130.     if(state->value.typeValue != NAME_VAL)
  131.     return INVALID_NAME;
  132.  
  133.     /*
  134.     ** Find out which object and relative offset the EIP is assocated with.
  135.     */
  136.     debugBuffer->Addr = eip;
  137.     debugBuffer->MTE  = module->MTE;
  138.     if(DispatchCommand(DBG_C_AddrToObject))
  139.     return INTERNAL_ERROR;
  140.     eip -= debugBuffer->Buffer;
  141.  
  142.     /*
  143.     ** Find the source module.
  144.     */
  145.     for(; cvMod; cvMod=cvMod->next) {
  146.  
  147.         /*
  148.         ** See if this is the correct module to look in for locals and
  149.         ** file statics.
  150.         */
  151.         if(cvMod->module != NULL) {
  152.             if((eip >= cvMod->module->offset) &&
  153.                (eip <  cvMod->module->offset + cvMod->module->cbSeg))
  154.                break;
  155.         }
  156.     }
  157.     if(cvMod == NULL)
  158.     return INVALID_NAME;
  159.  
  160.     /*
  161.     ** Try the local symbols first.
  162.     */
  163.     if(cvMod->symbols != NULL) {
  164.         unsigned char  *tmp = cvMod->symbols;
  165.         unsigned short  totalBytes;
  166.  
  167.         totalBytes = cvMod->symbolSize;
  168.         while(totalBytes > 0) {
  169.             totalBytes -= tmp[0] + 1;
  170.  
  171.             /*
  172.             ** BP-Relative symbol.
  173.             */
  174.             if(tmp[1] == 0x84) {
  175.                 BPRelativeSymbol32 *base;
  176.  
  177.                 /*
  178.                 ** Read the record and null terminate the string.
  179.                 */
  180.                 base = (BPRelativeSymbol32 *) &tmp[2];
  181.  
  182.                 /*
  183.                 ** Is the length correct?
  184.                 */
  185.                 if(cbName == base->cbName) {
  186.  
  187.                     /*
  188.                     ** Is the name correct.
  189.                     */
  190.             if(strncmp(state->value.val.sVal, base->name, cbName) == 0) {
  191.             CVTypeData *td;
  192.  
  193.                         /*
  194.                         ** Set the state/type information.
  195.             */
  196.             td = (CVTypeData *) malloc(sizeof(CVTypeData));
  197.             state->typeData     = td;
  198.             state->typeDataSize = sizeof(CVTypeData);
  199.             td->module        = cvMod;
  200.             td->registerNum     = -1;
  201.             td->typeIndex        = base->type;
  202.             state->elementSize  = elementSize(state);
  203.             state->addr = state->baseEBP + base->offset;
  204.             return CVGetValue(module, state);
  205.                     }
  206.                 }
  207.             }
  208.  
  209.             /*
  210.             ** Local symbol.
  211.             */
  212.             if(tmp[1] == 0x85) {
  213.                 LocalSymbol32 *base;
  214.  
  215.                 /*
  216.                 ** Read the record and null terminate the string.
  217.                 */
  218.                 base = (LocalSymbol32 *) &tmp[2];
  219.  
  220.                 /*
  221.                 ** Is the length correct?
  222.                 */
  223.                 if(cbName == base->cbName) {
  224.  
  225.                     /*
  226.                     ** Is the name correct.
  227.                     */
  228.             if(strncmp(state->value.val.sVal, base->name, cbName) == 0) {
  229.             CVTypeData *td;
  230.  
  231.             td = (CVTypeData *)malloc(sizeof(CVTypeData));
  232.             state->typeData     = td;
  233.             state->typeDataSize = sizeof(CVTypeData);
  234.             td->module        = cvMod;
  235.             td->typeIndex        = base->type;
  236.             td->registerNum     = -1;
  237.             state->elementSize  = elementSize(state);
  238.  
  239.                         /*
  240.                         ** Get the base of the object.
  241.                         */
  242.             debugBuffer->Value = base->segment;
  243.             debugBuffer->MTE = module->MTE;
  244.             if(DispatchCommand(DBG_C_NumToAddr))
  245.                 return INTERNAL_ERROR;
  246.             state->addr = debugBuffer->Addr + base->offset;
  247.             state->value.val.lVal  = 0;
  248.             state->value.typeValue = UNKNOWN_VAL;
  249.             return CVGetValue(module, state);
  250.                     }
  251.                 }
  252.             }
  253.  
  254.             /*
  255.             ** Register variable.
  256.             */
  257.             if((tmp[1] == 0x8d) || (tmp[1] == 0x0d)) {
  258.                 RegisterSymbol *base;
  259.  
  260.                 base = (RegisterSymbol *) &tmp[2];
  261.  
  262.                 /*
  263.                 ** Is the length correct?
  264.                 */
  265.                 if(cbName == base->cbName) {
  266.                     /*
  267.                     ** Is this the correct variable?
  268.                     */
  269.             if(strncmp(state->value.val.sVal, base->name, cbName) == 0) {
  270.             CVTypeData *td;
  271.  
  272.             td = (CVTypeData *)malloc(sizeof(CVTypeData));
  273.             state->typeData     = td;
  274.             state->typeDataSize = sizeof(CVTypeData);
  275.             td->module        = cvMod;
  276.             td->typeIndex        = base->type;
  277.             td->registerNum     = base->registerNum;
  278.             state->elementSize  = elementSize(state);
  279.             state->addr = 0;
  280.             if(base->type < 0x200) {
  281.                 if((base->type & 0x60) == 0) {
  282.                 switch((base->type & 0x1c) >> 2) {
  283.                     case 0:
  284.                     case 1:
  285.                     case 4: state->value.typeValue = LONG_VAL; break;
  286.                     case 2: state->value.typeValue = DOUBLE_VAL; break;
  287.                     case 3: state->value.typeValue = CHAR_VAL; break;
  288.                     case 5: state->value.typeValue = CHAR_VAL; break;
  289.                     case 6: state->value.typeValue = UNKNOWN_VAL; break;
  290.                     case 7: state->value.typeValue = UNKNOWN_VAL; break;
  291.                 }
  292.                 } else {
  293.                 state->value.typeValue = PTR_VAL;
  294.                 }
  295.             } else {
  296.                 state->value.typeValue = PTR_VAL;
  297.             }
  298.             return CVGetRegisterValue(module, state);
  299.                     }
  300.                 }
  301.             }
  302.             tmp += tmp[0] + 1;
  303.         }
  304.     }
  305.  
  306.     /*
  307.     ** We did not find a local variable, try a public variable.
  308.     */
  309.     cvMod = ((CVAuxData *) module->AuxData)->moduleData;
  310.     for(; cvMod; cvMod=cvMod->next) {
  311.  
  312.         if(cvMod->public != NULL) {
  313.             CVPublic32  *cvPub = cvMod->public;
  314.  
  315.             for(;cvPub; cvPub=cvPub->next) {
  316.                 /*
  317.                 ** Is this the correct variable?
  318.         */
  319.         if(strncmp(state->value.val.sVal, cvPub->data.name, cbName) == 0) {
  320.             CVTypeData *td;
  321.  
  322.             td = (CVTypeData *)malloc(sizeof(CVTypeData));
  323.             state->typeData    = td;
  324.             state->typeDataSize = sizeof(CVTypeData);
  325.             td->module        = cvMod;
  326.             td->typeIndex    = cvPub->data.type;
  327.             td->registerNum    = -1;
  328.             state->elementSize    = elementSize(state);
  329.  
  330.                     /*
  331.                     ** Get the base of the object.
  332.                     */
  333.             debugBuffer->Value = cvPub->data.segment;
  334.             debugBuffer->MTE = module->MTE;
  335.             if(DispatchCommand(DBG_C_NumToAddr))
  336.             return INTERNAL_ERROR;
  337.             state->addr = debugBuffer->Addr + cvPub->data.offset;
  338.             state->value.val.lVal  = 0;
  339.             state->value.typeValue = UNKNOWN_VAL;
  340.             return CVGetValue(module, state);
  341.                 }
  342.             }
  343.         }
  344.     }
  345.     return INVALID_NAME;
  346. }
  347.  
  348. /*
  349. ** Find the number of members in a structure.
  350. */
  351. int CVGetNumMembers(DebugModule *module, State *state)
  352. {
  353. CVTypeData *cvType = state->typeData;
  354. UCHAR      *types;
  355. int        i;
  356. ULONG        num;
  357.  
  358.     module; /* Reference to keep from getting a warning! */
  359.  
  360.     /*
  361.     ** Get a pointer to the type string.
  362.     */
  363.     types = FindType(cvType, cvType->typeIndex);
  364.     if(types == NULL)
  365.         return 0;
  366.  
  367.     /*
  368.     ** We are now pointing at the type string for the structure,
  369.     ** now, return the number of elements in the structure.
  370.     */
  371.     if(types[3] == 0x79) {
  372.     /*
  373.     ** Need to skip over the length string.
  374.     */
  375.     i  = CVGetNumber(&types[4], &num) + 4;
  376.     i += CVGetNumber(&types[i], &num);
  377.     return num;
  378.     }
  379.     return 0;
  380. }
  381.  
  382. /*
  383. ** Get the value at the element specified in state2.
  384. */
  385. int CVGetArray(DebugModule *module, State *state, State *state2)
  386. {
  387. CVTypeData *cvType = state->typeData;
  388. int        offset;
  389. UCHAR       *types;
  390.  
  391.     module;
  392.  
  393.     /*
  394.     ** Verify the offset parameter.
  395.     */
  396.     if(state2->value.typeValue != LONG_VAL)
  397.     return INVALID_VALUE;
  398.     offset = state2->value.val.lVal;
  399.  
  400.     /*
  401.     ** Verify the address parameter.
  402.     */
  403.     if(state->value.typeValue != PTR_VAL)
  404.     return INVALID_VALUE;
  405.  
  406.     /*
  407.     ** Check the type of the data.
  408.     */
  409.     if(cvType->typeIndex < 0x200) {
  410.     if((cvType->typeIndex & 0x60) == 0)
  411.         return INVALID_VALUE;
  412.  
  413.     state->value.val.lVal  = offset * state->elementSize;
  414.     state->value.typeValue = BYTE_INDEX_IN_LVAL;
  415.     return CVGetValue(module, state);
  416.     }
  417.  
  418.     /*
  419.     ** Complex data type.
  420.     */
  421.     types = FindType(cvType, cvType->typeIndex);
  422.     if(types == NULL)
  423.     return INTERNAL_ERROR;
  424.  
  425.     /*
  426.     ** Pointers.
  427.     */
  428.     if(types[3] == 0x7A) {
  429.     cvType->typeIndex = GetType(&types[5]);
  430.     cvType->registerNum    = 0;
  431.     state->value.val.lVal  = offset * state->elementSize;
  432.     state->value.typeValue = BYTE_INDEX_IN_LVAL;
  433.     return CVGetValue(module, state);
  434.     }
  435. {
  436. char buff[80];
  437. hexdump(types, 16, buff);
  438. fprintf(stderr, "Unknown type in GetArray\n");
  439. fprintf(stderr, "%s\n", buff);
  440. }
  441.     return INVALID_VALUE;
  442. }
  443.  
  444. /*
  445. ** Get the name of the index'th structure name.
  446. */
  447. int CVGetMemberIndex(DebugModule *module,
  448.     State *state, int memberIndex, char *name)
  449. {
  450. CVTypeData *cvType = state->typeData;
  451. UCHAR       *types, *nList;
  452. int        i;
  453. ULONG        num;
  454.  
  455.     module;
  456.     /*
  457.     ** Get a pointer to the type string.
  458.     */
  459.     types = FindType(cvType, cvType->typeIndex);
  460.     if(types == NULL) {
  461.     *name = '\0';
  462.     return INTERNAL_ERROR;
  463.     }
  464.  
  465.     /*
  466.     ** Verify that this is a structure.
  467.     */
  468.     if(types[3] != 0x79) {
  469.     *name = '\0';
  470.     return INVALID_NAME;
  471.     }
  472.  
  473.     /*
  474.     ** Need to skip over the length string.
  475.     */
  476.     i  = CVGetNumber(&types[4], &num) + 4;
  477.     i += CVGetNumber(&types[i], &num);
  478.     if((num <= memberIndex) || (memberIndex < 0))
  479.     return INVALID_INDEX;
  480.  
  481.     /*
  482.     ** Get the index of the name/offset data.
  483.     */
  484.     nList = FindType(cvType, GetType(&types[i+3]));
  485.     if(nList == NULL) {
  486.     return INTERNAL_ERROR;
  487.     }
  488.     if(nList[3] != 0x7f) {
  489.     return INTERNAL_ERROR;
  490.     }
  491.  
  492.     /*
  493.     ** Find the name in the name list.
  494.     */
  495.     for(i=4; memberIndex; memberIndex--) {
  496.     i += nList[i+1] + 2;
  497.     i += CVGetNumber(&nList[i], &num);
  498.     }
  499.     strncpy(name, &nList[i+2], nList[i+1]);
  500.     name[nList[i+1]] = 0;
  501.     return SUCCESS;
  502. }
  503.