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