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