home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sherlock.zip / CV32 / CVSRC.C < prev    next >
C/C++ Source or Header  |  1994-06-29  |  10KB  |  374 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    <string.h>
  12. #include    <sys\stat.h>
  13.  
  14. #define     INCL_DOSPROCESS
  15. #include    <os2.h>
  16. #include    "..\Debug.h"
  17.  
  18. #include    "..\SrcInter.h"
  19. #include    "CV.h"
  20. #include    "CV32.h"
  21.  
  22. /*
  23. ** Find the offset of a line given a file name.
  24. */
  25. ULONG _System CVFindSourceLine(DebugModule *module, int line, char *fileName)
  26. {
  27. CVModule   *cvMod   = ((CVAuxData *) module->AuxData)->moduleData;
  28. USHORT      i;
  29. LineOffsetEntry32   *lineData;
  30.  
  31.     /*
  32.     ** Find the source module.
  33.     */
  34.     for(; cvMod; cvMod=cvMod->next) {
  35.  
  36.         if(cvMod->lineData == NULL)
  37.             continue;
  38.  
  39.         /*
  40.         ** Check for the correct file name.
  41.         */
  42.         if(stricmp(cvMod->lineData->fileName, fileName) != 0)
  43.             continue;
  44.  
  45.         /*
  46.         ** Read the line/offset pairs.
  47.         */
  48.         lineData = cvMod->lineData->lineData;
  49.         for(i=0; i<cvMod->lineData->count; i++) {
  50.         if(line == (int) lineData[i].line) {
  51.                 ULONG offset;
  52.  
  53.                 offset = lineData[i].offset;
  54.  
  55.                 /*
  56.                 ** Find the adjustment for the object.
  57.                 */
  58.         debugBuffer->Value = cvMod->module->segment;
  59.         debugBuffer->MTE   = module->MTE;
  60.         if(DispatchCommand(DBG_C_NumToAddr))
  61.             return 0;
  62.         return offset + debugBuffer->Addr;
  63.             }
  64.         if(line < (int) lineData[i].line) {
  65.                 return 0;
  66.             }
  67.         }
  68.     }
  69.  
  70.     return 0;
  71. }
  72.  
  73. /*
  74. ** Find the source file associated with a given EIP for the module.
  75. */
  76. int _System CVFindSource(DebugModule *module, ULONG eipOffset,
  77.             char *funcName, char *sourceName, ULONG *lineNum)
  78. {
  79. CVModule   *cvMod   = ((CVAuxData *) module->AuxData)->moduleData;
  80. ULONG        relOffset;
  81. ULONG        baseOffset;
  82. USHORT        i;
  83. USHORT        objectNum;
  84.  
  85.     *sourceName = '\0';
  86.     *funcName = '\0';
  87.     *lineNum = 0;
  88.  
  89.     /*
  90.     ** Find out which object and relative offset the EIP is assocated with.
  91.     */
  92.     debugBuffer->Addr = eipOffset;
  93.     debugBuffer->MTE  = module->MTE;
  94.     if(DispatchCommand(DBG_C_AddrToObject))
  95.     return 0;
  96.     baseOffset = debugBuffer->Buffer;
  97.     relOffset  = eipOffset - baseOffset;
  98.  
  99.     /*
  100.     ** Find the object number associated with the address.
  101.     */
  102.     for(objectNum=1;;objectNum++) {
  103.     debugBuffer->Value = (ULONG) objectNum;
  104.     debugBuffer->MTE   = module->MTE;
  105.     if(DispatchCommand(DBG_C_NumToAddr) != DBG_N_Success)
  106.         break;
  107.     if(debugBuffer->Addr == baseOffset)
  108.         break;
  109.     }
  110.  
  111.     /*
  112.     ** Find the source module.
  113.     */
  114.     for(; cvMod; cvMod=cvMod->next) {
  115.         LineOffsetEntry32  *lineData;
  116.     USHORT     totalBytes;
  117.  
  118.     /*
  119.         ** Is this module a possiblity
  120.         */
  121.         if((cvMod->module->offset > relOffset) ||
  122.            ((cvMod->module->offset+cvMod->module->cbSeg) < relOffset))
  123.             continue;
  124.  
  125.     /*
  126.     ** Search the symbol records until we find the function we are looking for.
  127.     */
  128.     totalBytes = cvMod->symbolSize;
  129.     if(cvMod->symbols != NULL) {
  130.         unsigned char    *tmp;
  131.  
  132.         tmp = cvMod->symbols;
  133.         while(totalBytes > 0) {
  134.                 totalBytes -= tmp[0] + 1;
  135.         if(tmp[1] == 0x81 || tmp[1] == 0x8f) {
  136.             ProcedureStart32 *tp;
  137.  
  138.             tp = (ProcedureStart32 *) &tmp[2];
  139.             if((relOffset >= tp->offset) &&
  140.                (relOffset < tp->offset + tp->procLength)) {
  141.             if(tp->name[0] == '_') {
  142.                 strncpy(funcName, &tp->name[1], tp->cbName-1);
  143.                 funcName[tp->cbName-1] = '\0';
  144.             } else {
  145.                 strncpy(funcName, tp->name, tp->cbName);
  146.                 funcName[tp->cbName] = '\0';
  147.             }
  148.             break;
  149.             }
  150.         } else if(tmp[1] == 0x01 || tmp[1] == 0x0f) {
  151.             ProcedureStart *tp;
  152.  
  153.             tp = (ProcedureStart *) &tmp[2];
  154.             if((relOffset >= tp->offset) &&
  155.                (relOffset < tp->offset + tp->procLength)) {
  156.             if(tp->name[0] == '_') {
  157.                 strncpy(funcName, &tp->name[1], tp->cbName-1);
  158.                 funcName[tp->cbName-1] = '\0';
  159.             } else {
  160.                 strncpy(funcName, tp->name, tp->cbName);
  161.                 funcName[tp->cbName] = '\0';
  162.             }
  163.             break;
  164.             }
  165.         }
  166.                 tmp += tmp[0] + 1;
  167.             }
  168.  
  169.     /*
  170.     ** If there are no symbol records, then check the publics.
  171.     */
  172.     } else if(cvMod->public != NULL) {
  173.         CVPublic32 *public, *best;
  174.  
  175.         best = NULL;
  176.         for(public = cvMod->public; public; public=public->next) {
  177.         if(public->data.segment != objectNum)
  178.             continue;
  179.  
  180.         if(best == NULL)
  181.             best = public;
  182.         if((relOffset >= public->data.offset) &&
  183.            (public->data.offset < best->data.offset)) {
  184.             best = public;
  185.         }
  186.         }
  187.         strcpy(sourceName, "UNKNOWN");
  188.         if(best == NULL) {
  189.         strcpy(funcName, "UNKNOWN");
  190.         } else {
  191.         if(best->data.name[0] == '_')
  192.             strcpy(funcName, &best->data.name[1]);
  193.         else
  194.             strcpy(funcName, best->data.name);
  195.         }
  196.     }
  197.  
  198.         /*
  199.         ** Find the line for the offset.
  200.     */
  201.     if(cvMod->lineData) {
  202.         lineData = cvMod->lineData->lineData;
  203.         for(i=1; i<cvMod->lineData->count; i++) {
  204.         if(relOffset < lineData[i].offset)
  205.             break;
  206.         }
  207.         *lineNum = (ULONG) lineData[i-1].line;
  208.         strcpy(sourceName, cvMod->lineData->fileName);
  209.     } else {
  210.         sourceName[0] = 0;
  211.     }
  212.     return 1;
  213.     }
  214.     return 0;
  215. }
  216.  
  217. /*
  218. ** Find the address of a function given the name.
  219. */
  220. ULONG _System CVFindFuncAddr(DebugModule *module, char *funcName)
  221. {
  222. CVModule   *cvMod = ((CVAuxData *) module->AuxData)->moduleData;
  223. UCHAR       cbName = (unsigned char) strlen(funcName);
  224.  
  225.     /*
  226.     ** Find the source module.
  227.     */
  228.     for(;cvMod; cvMod=cvMod->next) {
  229.         USHORT  totalBytes;
  230.     unsigned char    *tmp;
  231.  
  232.     /*
  233.     ** Try the symbol records first.
  234.     */
  235.     if(cvMod->symbols != NULL) {
  236.  
  237.         tmp = cvMod->symbols;
  238.         totalBytes = cvMod->symbolSize;
  239.         while(totalBytes > 0) {
  240.  
  241.         totalBytes -= tmp[0] + 1;
  242.  
  243.         /*
  244.         ** 32 Bit procedure.
  245.                 */
  246.         if(tmp[1] == 0x81 || tmp[1] == 0x8f) {
  247.             ProcedureStart32 *tp;
  248.  
  249.             tp = (ProcedureStart32 *) &tmp[2];
  250.                     if((UCHAR) (cbName+1) == tp->cbName) {
  251.             if(strncmp(funcName, &tp->name[1], cbName-1) == 0) {
  252.                 debugBuffer->MTE = module->MTE;
  253.                 debugBuffer->Value = cvMod->module->segment;
  254.                 if(DispatchCommand(DBG_C_NumToAddr))
  255.                 return 0;
  256.                 return debugBuffer->Addr + tp->offset;
  257.             }
  258.             }
  259.             if(cbName = tp->cbName) {
  260.             if(strncmp(funcName, tp->name, cbName) == 0) {
  261.                 debugBuffer->MTE = module->MTE;
  262.                 debugBuffer->Value = cvMod->module->segment;
  263.                 if(DispatchCommand(DBG_C_NumToAddr))
  264.                 return 0;
  265.                 return debugBuffer->Addr + tp->offset;
  266.             }
  267.             }
  268.         }
  269.  
  270.         /*
  271.         ** 32 Bit code label.
  272.         */
  273.         if(tmp[1] == 0x8b) {
  274.             CodeLabel32 *cl;
  275.  
  276.             cl = (CodeLabel32 *) &tmp[2];
  277.                     if((UCHAR) (cbName+1) == cl->cbName) {
  278.             if(strncmp(funcName, &cl->name[1], cbName-1) == 0) {
  279.                 debugBuffer->MTE = module->MTE;
  280.                 debugBuffer->Value = cvMod->module->segment;
  281.                 if(DispatchCommand(DBG_C_NumToAddr))
  282.                 return 0;
  283.                 return debugBuffer->Addr + cl->offset;
  284.             }
  285.             }
  286.             if(cbName == cl->cbName) {
  287.             if(strncmp(funcName, cl->name, cbName) == 0) {
  288.                 debugBuffer->MTE = module->MTE;
  289.                 debugBuffer->Value = cvMod->module->segment;
  290.                 if(DispatchCommand(DBG_C_NumToAddr))
  291.                 return 0;
  292.                 return debugBuffer->Addr + cl->offset;
  293.             }
  294.             }
  295.         }
  296.  
  297.         /*
  298.         ** 16 Bit procedure.
  299.         */
  300.         if(tmp[1] == 0x01 || tmp[1] == 0x0f) {
  301.             ProcedureStart *tp;
  302.  
  303.             tp = (ProcedureStart *) &tmp[2];
  304.                     if((UCHAR) (cbName+1) == tp->cbName) {
  305.             if(strncmp(funcName, &tp->name[1], cbName-1) == 0) {
  306.                 debugBuffer->MTE = module->MTE;
  307.                 debugBuffer->Value = cvMod->module->segment;
  308.                 if(DispatchCommand(DBG_C_NumToAddr))
  309.                 return 0;
  310.                 return debugBuffer->Addr + tp->offset;
  311.             }
  312.             }
  313.             if(cbName = tp->cbName) {
  314.             if(strncmp(funcName, tp->name, cbName) == 0) {
  315.                 debugBuffer->MTE = module->MTE;
  316.                 debugBuffer->Value = cvMod->module->segment;
  317.                 if(DispatchCommand(DBG_C_NumToAddr))
  318.                 return 0;
  319.                 return debugBuffer->Addr + tp->offset;
  320.             }
  321.             }
  322.         }
  323.  
  324.         /*
  325.         ** 16 Bit code label.
  326.         */
  327.         if(tmp[1] == 0x0b) {
  328.             CodeLabel *cl;
  329.  
  330.             cl = (CodeLabel *) &tmp[2];
  331.                     if((UCHAR) (cbName+1) == cl->cbName) {
  332.             if(strncmp(funcName, &cl->name[1], cbName-1) == 0) {
  333.                 debugBuffer->MTE = module->MTE;
  334.                 debugBuffer->Value = cvMod->module->segment;
  335.                 if(DispatchCommand(DBG_C_NumToAddr))
  336.                 return 0;
  337.                 return debugBuffer->Addr + cl->offset;
  338.             }
  339.             }
  340.             if(cbName == cl->cbName) {
  341.             if(strncmp(funcName, cl->name, cbName) == 0) {
  342.                 debugBuffer->MTE = module->MTE;
  343.                 debugBuffer->Value = cvMod->module->segment;
  344.                 if(DispatchCommand(DBG_C_NumToAddr))
  345.                 return 0;
  346.                 return debugBuffer->Addr + cl->offset;
  347.             }
  348.             }
  349.         }
  350.         tmp += tmp[0] + 1;
  351.         }
  352.     }
  353.  
  354.     /*
  355.     ** Try the public records last.
  356.     */
  357.     if(cvMod->public != NULL) {
  358.         CVPublic32 *public;
  359.  
  360.         for(public = cvMod->public; public; public=public->next) {
  361.         if((strcmp(funcName,  public->data.name) == 0) ||
  362.            (strcmp(funcName, &public->data.name[1]) == 0)) {
  363.             debugBuffer->MTE = module->MTE;
  364.             debugBuffer->Value = public->data.segment;
  365.             if(DispatchCommand(DBG_C_NumToAddr))
  366.             return 0;
  367.             return debugBuffer->Addr + public->data.offset;
  368.         }
  369.         }
  370.     }
  371.     }
  372.     return 0;
  373. }
  374.