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