home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sherlock.zip / HLL / HLL.C next >
C/C++ Source or Header  |  1994-06-29  |  10KB  |  362 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    <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    "HLL.h"
  23.  
  24. /*
  25. ** Global variables.
  26. */
  27. static int (* _System Dispatch)(int command);
  28. DebugBuffer *debugBuffer;
  29.  
  30. /*
  31. ** Answer the linkage priority.
  32. ** Return 1 for insert in front of list - (first crack at linking)
  33. ** Return 0 for add to end of list.    - (last crack at linking)
  34. */
  35. int _System linkPriority(void)
  36. {
  37.     return 1;
  38. }
  39.  
  40. /*
  41. ** Answer whether the module named is a HLL module.
  42. ** If so, set the function pointers and return true.
  43. */
  44. int _System isKnownModule(DebugModule *module,
  45.                int (* _System DispatchCommand)(int command),
  46.                DebugBuffer *buffer)
  47. {
  48. HLLAuxData *auxData;
  49. HLLModule  *lastModule = NULL;
  50. FILE       *mod;
  51. USHORT      i;
  52. ULONG        sectionBaseOffset;
  53. SubSectionDictionary *sectionDictionary;
  54.  
  55. struct stat          statBuff;
  56. SubSectionDictHeader  dictHeader;
  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(HLLAuxData), 1);
  82.     auxData = (HLLAuxData *) module->AuxData;
  83.     fread(&auxData->tag[0], 8, 1, mod);
  84.  
  85.     /*
  86.     ** Make sure that we have HLL information.
  87.     */
  88.     if(strncmp(auxData->tag, "NB04", 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 HLL information.
  102.     */
  103.     if(strncmp(auxData->tag, "NB04", 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(&dictHeader, sizeof(dictHeader), 1, mod);
  113.     sectionDictionary = (SubSectionDictionary *) malloc(dictHeader.numEntries * sizeof(SubSectionDictionary));
  114.     fread(sectionDictionary, sizeof(SubSectionDictionary), dictHeader.numEntries, mod);
  115.  
  116.     /*
  117.     ** Read each section into a module.
  118.     */
  119.     for(i=0; i<dictHeader.numEntries; 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 = (HLLModule *) calloc(sizeof(HLLModule), 1);
  133.             auxData->moduleData = lastModule;
  134.                 } else {
  135.             lastModule->next = (HLLModule *) calloc(sizeof(HLLModule), 1);
  136.                     lastModule = lastModule->next;
  137.                 }
  138.         lastModule->module = (ModulesDataEntry *) 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.         PublicsDataEntry   *entry;
  151.         static HLLPublic   *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(PublicsDataEntry);
  169.             if(lastModule->public == NULL) {
  170.             next = lastModule->public = (HLLPublic *)
  171.                 malloc(sizeof(HLLPublic) + entry->cbName + 1);
  172.                     } else {
  173.             next->next = (HLLPublic *)
  174.                 malloc(sizeof(HLLPublic) + 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(PublicsDataEntry) - 1;
  182.             entry = (PublicsDataEntry *) ptr;
  183.             totalBytes += numBytes;
  184.                 }
  185.                 free(base);
  186.                 break;
  187.             }
  188.  
  189.             /*
  190.             ** Is this a types record.
  191.             */
  192.             case sstTypes: {
  193.         lastModule->type = (char *) malloc(sectionSize);
  194.                 lastModule->typeSize = sectionSize;
  195.         fread(lastModule->type, sectionSize, 1, mod);
  196.         break;
  197.             }
  198.  
  199.             /*
  200.             ** Is this a symbol record.
  201.             */
  202.         case sstSymbols: {
  203.         lastModule->symbols = (char *) malloc(sectionSize);
  204.                 lastModule->symbolSize = sectionSize;
  205.         fread(lastModule->symbols, sectionSize, 1, mod);
  206.         break;
  207.             }
  208.  
  209.         /*
  210.             ** Is this a libraries record.
  211.             */
  212.             case sstLibraries: {
  213.                 char    *allNames;
  214.                 int     numNames;
  215.                 USHORT  index;
  216.  
  217.         /*
  218.                 ** Load the names into a scratch area.
  219.                 */
  220.         allNames = (char *) malloc(sectionSize+1);
  221.                 fread(allNames, sectionSize, 1, mod);
  222.  
  223.                 /*
  224.                 ** Find out how many name there are.
  225.                 */
  226.                 index = 0;
  227.                 numNames = 0;
  228.                 while(index < sectionSize) {
  229.                     index += allNames[index] + 1;
  230.                     numNames++;
  231.                 }
  232.         auxData->libraries = (char **) malloc(numNames * sizeof(char *));
  233.  
  234.                 /*
  235.                 ** Copy the names into their 'permanent' location.
  236.                 */
  237.                 index = 0;
  238.                 numNames = 0;
  239.                 while(index < sectionSize) {
  240.             auxData->libraries[numNames] = (char *) malloc(allNames[index] + 1);
  241.                     strncpy(auxData->libraries[numNames], &allNames[index+1],
  242.                             allNames[index]);
  243.                     auxData->libraries[numNames][allNames[index]] = '\0';
  244.                     index += allNames[index] + 1;
  245.                     numNames++;
  246.                 }
  247.                 break;
  248.             }
  249.  
  250.         /*
  251.         ** New Line line offset information data.
  252.             */
  253.         case sstNewLineData: {
  254.         HLLLineData    *data;
  255.         _Packed struct _tag_FirstEntry {
  256.             USHORT    dummy;
  257.             UCHAR    entryType;
  258.             UCHAR    res;
  259.             USHORT    numEntries;
  260.             USHORT    segmentNum;
  261.         } record;
  262.         USHORT        count;
  263.         ULONG        fnTableSize;
  264.         int        i;
  265.  
  266.         /*
  267.         ** Read the header.
  268.         */
  269.         fread(&record, sizeof(record), 1, mod);
  270.  
  271.         /*
  272.         ** If this is version 3 (or later) of the debug
  273.         ** spec, skip the file name table size after the
  274.         ** header record.
  275.         */
  276.         if(lastModule->module->version >= 0x300) {
  277.             fread(&fnTableSize, sizeof(ULONG), 1, mod);
  278.         }
  279.  
  280.         /*
  281.         ** Read the entry data
  282.         */
  283.         data = (HLLLineData *) malloc(sizeof(HLLLineData));
  284.         data->entryType = record.entryType;
  285.         data->numEntries = record.numEntries;
  286.         switch (record.entryType) {
  287.             case 0: count = record.numEntries * 8;
  288.                 break;
  289.             case 1: count = record.numEntries * 12;
  290.                 break;
  291.             case 2: count = record.numEntries * 16;
  292.                 break;
  293.             default:    fprintf(stderr, "Bad line entry type\n");
  294.                 exit(1);
  295.         }
  296.         data->entryData.srcLines = (SrcLine *) malloc(count);
  297.         fread(data->entryData.srcLines, count, 1, mod);
  298.  
  299.         /*
  300.         ** Read the path data.
  301.         */
  302.         data->segmentNum = record.segmentNum;
  303.         data->pathEntries = (union _tag_PathEntries*) malloc(count);
  304.         fread(&data->startRecNum,  sizeof(ULONG), 1, mod);
  305.         fread(&data->numPrimaries, sizeof(ULONG), 1, mod);
  306.         fread(&data->numSrcFiles,  sizeof(ULONG), 1, mod);
  307.         data = (HLLLineData *) realloc(data, sizeof(HLLLineData) +
  308.                      sizeof(char *) * data->numSrcFiles);
  309.         for(i=0; i<data->numSrcFiles; i++) {
  310.             UCHAR   numChars;
  311.  
  312.             fread(&numChars, 1, 1, mod);
  313.             data->fileNames[i] = (char *) malloc(numChars+1);
  314.             fread(data->fileNames[i], numChars, 1, mod);
  315.             data->fileNames[i][numChars] = '\0';
  316.         }
  317.         lastModule->newLineData = data;
  318.         break;
  319.         }
  320.  
  321.         /*
  322.         ** Default case - display unknown module.
  323.         */
  324.         default: {
  325. fprintf(stderr, "Type: Unknown: %04x\n", sectionDictionary[i].sectionType);
  326.         break;
  327.         }
  328.     }
  329.     }
  330.     fclose(mod);
  331.     if(auxData->tag[0] != 'N' ||
  332.        auxData->tag[1] != 'B') {
  333.         free(auxData);
  334.         module->AuxData = NULL;
  335.         return 0;
  336.     }
  337.  
  338.     /*
  339.     ** Set up the links to access the data.
  340.     */
  341.     module->FindSource       = HLLFindSource;
  342.     module->FindSourceLine = HLLFindSourceLine;
  343.     module->FindFuncAddr   = HLLFindFuncAddr;
  344.  
  345.     module->GetName       = HLLGetName;
  346.     module->GetArray       = HLLGetArray;
  347.     module->GetNumMembers  = HLLGetNumMembers;
  348.     module->GetMemberIndex = HLLGetMemberIndex;
  349.  
  350.     return 1;
  351. }
  352.  
  353. /*
  354. ** Define the stub for connecting to the system.
  355. */
  356. int DispatchCommand(int command)
  357. {
  358.     if(Dispatch)
  359.     return Dispatch(command);
  360.     return DBG_N_Error;
  361. }
  362.