home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sherlock.zip / CV32 / CV32.C < prev    next >
C/C++ Source or Header  |  1994-06-29  |  11KB  |  365 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    <stdio.h>
  12. #include    <string.h>
  13. #include    <malloc.h>
  14. #include    <memory.h>
  15. #include    <sys\stat.h>
  16.  
  17. #define     INCL_DOSPROCESS
  18. #include    <os2.h>
  19. #include    "..\Debug.h"
  20.  
  21. #include    "..\SrcInter.h"
  22. #include    "CV.h"
  23. #include    "CV32.h"
  24.  
  25. /*
  26. ** Global variables.
  27. */
  28. static int (* _System Dispatch)(int command);
  29. DebugBuffer *debugBuffer;
  30.  
  31. /*
  32. ** Answer the linkage priority.
  33. ** Return 1 for insert in front of list - (first crack at linking)
  34. ** Return 0 for add to end of list.    - (last crack at linking)
  35. */
  36. int _System linkPriority(void)
  37. {
  38.     return 1;
  39. }
  40.  
  41. /*
  42. ** Answer whether the module named is a code view module.
  43. ** If so, set the function pointers and return true.
  44. */
  45. int _System isKnownModule(DebugModule *module,
  46.          int (* _System DispatchCommand)(int command),
  47.          DebugBuffer *buffer)
  48. {
  49. CVAuxData  *auxData;
  50. CVModule   *lastModule = NULL;
  51. FILE       *mod;
  52. USHORT      i;
  53. USHORT      numSections;
  54. ULONG       sectionBaseOffset;
  55. struct stat statBuff;
  56. SubSectionDictionary *sectionDictionary;
  57.  
  58.     debugBuffer = buffer;
  59.     Dispatch = DispatchCommand;
  60.  
  61.     /*
  62.     ** If this is a 16 bit module, handle it elsewhere.
  63.     */
  64.     if((module->typeFlags & 0x4000) == 0)
  65.         return 0;
  66.  
  67.     /*
  68.     ** Open the file.
  69.     */
  70.     if((mod = fopen(module->name, "rb")) == NULL) {
  71.     return 0;
  72.     }
  73.     fstat(fileno(mod), &statBuff);
  74.     module->fileSize   = statBuff.st_size;
  75.     module->fTimestamp = statBuff.st_atime;
  76.  
  77.     /*
  78.     ** Find the end header and verify the signature.
  79.     */
  80.     fseek(mod, -8, SEEK_END);
  81.     module->AuxData = (void *) calloc(sizeof(CVAuxData), 1);
  82.     auxData = (CVAuxData *) module->AuxData;
  83.     fread(&auxData->tag[0], 8, 1, mod);
  84.  
  85.     /*
  86.     ** Make sure that we have Codeview information.
  87.     */
  88.     if(strncmp(auxData->tag, "NB00", 4) != 0) {
  89.         fclose(mod);
  90.         return 0;
  91.     }
  92.  
  93.     /*
  94.     ** Go to where the start of the header is located.
  95.     */
  96.     fseek(mod, -auxData->dirOffset, SEEK_END);
  97.     sectionBaseOffset = ftell(mod);
  98.     fread(&auxData->tag[0], 8, 1, mod);
  99.  
  100.     /*
  101.     ** Double check that we have Codeview information.
  102.     */
  103.     if(strncmp(auxData->tag, "NB00", 4) != 0) {
  104.         fclose(mod);
  105.         return 0;
  106.     }
  107.  
  108.     /*
  109.     ** Find the section dictionary and read it in.
  110.     */
  111.     fseek(mod, sectionBaseOffset + auxData->dirOffset, SEEK_SET);
  112.     fread(&numSections, sizeof(USHORT), 1, mod);
  113.     sectionDictionary = (SubSectionDictionary *) malloc(numSections * sizeof(SubSectionDictionary));
  114.     fread(sectionDictionary, sizeof(SubSectionDictionary), numSections, mod);
  115.  
  116.     /*
  117.     ** Read each section into a module.
  118.     */
  119.     for(i=0; i<numSections; i++) {
  120.         USHORT sectionSize;
  121.  
  122.         sectionSize = sectionDictionary[i].sectionSize;
  123.         fseek(mod, sectionBaseOffset +
  124.                    sectionDictionary[i].offsetStart, SEEK_SET);
  125.  
  126.         switch(sectionDictionary[i].sectionType) {
  127.             /*
  128.             ** Is this a modules record
  129.             */
  130.             case sstModules: {
  131.                 if(auxData->moduleData == NULL) {
  132.             lastModule = (CVModule *) calloc(sizeof(CVModule), 1);
  133.             auxData->moduleData = lastModule;
  134.                 } else {
  135.             lastModule->next = (CVModule *) calloc(sizeof(CVModule), 1);
  136.                     lastModule = lastModule->next;
  137.                 }
  138.         lastModule->module = (ModulesDataEntry32 *) malloc(sectionSize+1);
  139.                 fread(lastModule->module, sectionSize, 1, mod);
  140.                 lastModule->module->name[lastModule->module->cbName] = '\0';
  141.                 break;
  142.             }
  143.  
  144.             /*
  145.             ** Is this a publics record.
  146.             */
  147.             case sstPublic: {
  148.                 USHORT              totalBytes;
  149.                 void               *base;
  150.                 PublicsDataEntry32 *entry;
  151.                 CVPublic32         *next;
  152.                 char               *ptr;
  153.  
  154.                 /*
  155.                 ** Read the block into memory.
  156.                 */
  157.         base = (void *) malloc(sectionSize+1);
  158.                 fread(base, sectionSize, 1, mod);
  159.  
  160.                 /*
  161.                 ** Now, change it into a linked list.
  162.                 */
  163.                 entry = base;
  164.                 totalBytes = 0;
  165.                 while(totalBytes < sectionSize) {
  166.                     USHORT  numBytes;
  167.  
  168.                     numBytes = (USHORT) entry->cbName + (USHORT) sizeof(PublicsDataEntry32);
  169.                     if(lastModule->public == NULL) {
  170.             next = lastModule->public = (CVPublic32 *)
  171.                             malloc(sizeof(CVPublic32) + entry->cbName + 1);
  172.                     } else {
  173.             next->next = (CVPublic32 *)
  174.                             malloc(sizeof(CVPublic32) + entry->cbName + 1);
  175.                         next = next->next;
  176.                     }
  177.                     next->next = NULL;
  178.             memcpy(&next->data, entry, numBytes);
  179.             next->data.name[entry->cbName] = '\0';
  180.             ptr = (char *) entry;
  181.             ptr += entry->cbName + sizeof(PublicsDataEntry32) - 1;
  182.                     entry = (PublicsDataEntry32 *) ptr;
  183.                     totalBytes += numBytes;
  184.                 }
  185.  
  186.                 free(base);
  187.                 break;
  188.             }
  189.  
  190.             /*
  191.             ** Is this a types record.
  192.             */
  193.             case sstTypes: {
  194.         lastModule->type = (char *) malloc(sectionSize);
  195.                 lastModule->typeSize = sectionSize;
  196.                 fread(lastModule->type, sectionSize, 1, mod);
  197.                 break;
  198.             }
  199.  
  200.             /*
  201.             ** Is this a symbol record.
  202.             */
  203.             case sstSymbols: {
  204.         lastModule->symbols = (char *) malloc(sectionSize);
  205.                 lastModule->symbolSize = sectionSize;
  206.                 fread(lastModule->symbols, sectionSize, 1, mod);
  207.                 break;
  208.             }
  209.  
  210.             /*
  211.             ** Is this a Source line number record.
  212.             */
  213.             case sstSrcLines: {
  214.                 char *name;
  215.                 USHORT count;
  216.                 char   cbName;
  217.                 LineOffsetEntry32 *lineData;
  218.  
  219.                 /*
  220.                 ** Allocate the memory used.
  221.                 */
  222.         lastModule->lineData = (CVLineData *) malloc(sizeof(CVLineData));
  223.  
  224.                 /*
  225.                 ** Read in the name.
  226.                 */
  227.                 fread(&cbName, 1, 1, mod);
  228.         name = (char *) malloc(cbName + 1);
  229.                 fread(name, cbName, 1, mod);
  230.                 name[cbName] = '\0';
  231.                 lastModule->lineData->fileName = name;
  232.  
  233.                 /*
  234.                 ** Read in the line data.
  235.                 */
  236.                 lastModule->lineData->segment = 0;
  237.                 fread(&count, 2, 1, mod);
  238.                 lastModule->lineData->count = count;
  239.         lineData = (LineOffsetEntry32 *) malloc(sizeof(LineOffsetEntry32) * count);
  240.                 lastModule->lineData->lineData = lineData;
  241.                 fread(lineData, sizeof(LineOffsetEntry32) * count, 1, mod);
  242.                 break;
  243.             }
  244.  
  245.             /*
  246.             ** Is this a libraries record.
  247.             */
  248.             case sstLibraries: {
  249.                 char    *allNames;
  250.                 int     numNames;
  251.                 USHORT  index;
  252.  
  253.                 /*
  254.                 ** Load the names into a scratch area.
  255.                 */
  256.         allNames = (char *) malloc(sectionSize+1);
  257.                 fread(allNames, sectionSize, 1, mod);
  258.  
  259.                 /*
  260.                 ** Find out how many name there are.
  261.                 */
  262.                 index = 0;
  263.                 numNames = 0;
  264.                 while(index < sectionSize) {
  265.                     index += allNames[index] + 1;
  266.                     numNames++;
  267.                 }
  268.         auxData->libraries = (char **) malloc(numNames * sizeof(char *));
  269.  
  270.                 /*
  271.                 ** Copy the names into their 'permanent' location.
  272.                 */
  273.                 index = 0;
  274.                 numNames = 0;
  275.                 while(index < sectionSize) {
  276.             auxData->libraries[numNames] = (char *) malloc(allNames[index] + 1);
  277.                     strncpy(auxData->libraries[numNames], &allNames[index+1],
  278.                             allNames[index]);
  279.                     auxData->libraries[numNames][allNames[index]] = '\0';
  280.                     index += allNames[index] + 1;
  281.                     numNames++;
  282.                 }
  283.                 break;
  284.             }
  285.  
  286.             /*
  287.             ** Compacted type record.
  288.             */
  289.             case sstCompacted: {
  290.         auxData->compactedData = (char *) malloc(sectionSize+1);
  291.                 fread(auxData->compactedData, sectionSize, 1, mod);
  292.                 auxData->compactedSize = sectionSize;
  293.                 break;
  294.             }
  295.  
  296.             /*
  297.             ** Is this a Source line number record with segment.
  298.             */
  299.             case sstSrcLnSeg: {
  300.                 char *name;
  301.                 LineOffsetEntry32 *lineData;
  302.                 USHORT count;
  303.                 USHORT segment;
  304.                 char   cbName;
  305.  
  306.                 /*
  307.                 ** Allocate the memory used.
  308.                 */
  309.         lastModule->lineData = (CVLineData *) malloc(sizeof(CVLineData));
  310.  
  311.                 /*
  312.                 ** Read in the name.
  313.                 */
  314.                 fread(&cbName, 1, 1, mod);
  315.         name = (char *) malloc(cbName + 1);
  316.                 fread(name, cbName, 1, mod);
  317.                 name[cbName] = '\0';
  318.                 lastModule->lineData->fileName = name;
  319.  
  320.                 /*
  321.                 ** Read in the line data.
  322.                 */
  323.                 fread(&segment, 2, 1, mod);
  324.                 lastModule->lineData->segment = segment;
  325.                 fread(&count, 2, 1, mod);
  326.                 lastModule->lineData->count = count;
  327.         lineData = (LineOffsetEntry32 *) malloc(sizeof(LineOffsetEntry32) * count);
  328.                 lastModule->lineData->lineData = lineData;
  329.                 fread(lineData, sizeof(LineOffsetEntry32), count, mod);
  330.                 break;
  331.             }
  332.         }
  333.     }
  334.     fclose(mod);
  335.     if(auxData->tag[0] != 'N' ||
  336.        auxData->tag[1] != 'B') {
  337.         free(auxData);
  338.         module->AuxData = NULL;
  339.         return 0;
  340.     }
  341.  
  342.     /*
  343.     ** Set up the links to access the data.
  344.     */
  345.     module->FindSource     = CVFindSource;
  346.     module->FindSourceLine = CVFindSourceLine;
  347.     module->FindFuncAddr   = CVFindFuncAddr;
  348.  
  349.     module->GetName       = CVGetName;
  350.     module->GetArray       = CVGetArray;
  351.     module->GetNumMembers  = CVGetNumMembers;
  352.     module->GetMemberIndex = CVGetMemberIndex;
  353.     return 1;
  354. }
  355.  
  356. /*
  357. ** Define the stub for connecting to the system.
  358. */
  359. int DispatchCommand(int command)
  360. {
  361.     if(Dispatch)
  362.     return Dispatch(command);
  363.     return DBG_N_Error;
  364. }
  365.