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