home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sherlock.zip / NODEBUG.C < prev    next >
C/C++ Source or Header  |  1994-06-29  |  6KB  |  253 lines

  1. /*
  2. **  Sherlock - Copyright 1992, 1993, 1994
  3. **    Harfmann Software
  4. **    Compuserve: 73147,213
  5. **    All rights reserved
  6. */
  7. /*
  8. ** For all the DLL's without debugging information, get the
  9. ** export list and find the addresses associated with them.
  10. */
  11. #include    <stdio.h>
  12. #include    <string.h>
  13. #include    <malloc.h>
  14. #include    <sys\stat.h>
  15.  
  16. #define     INCL_DOSMODULEMGR
  17. #define     INCL_DOSPROCESS
  18. #include    <os2.h>
  19. #include    "debug.h"
  20.  
  21. #include    "newexe.h"
  22. typedef unsigned long DWORD;
  23. typedef unsigned short WORD;
  24. #include    "exe386.h"
  25.  
  26. #include    "Debugger.h"
  27. #include    "SrcInter.h"
  28. #include    "Source.h"
  29.  
  30. typedef struct _DefAuxData {
  31.     struct _DefAuxData *next;
  32.     char               *name;
  33.     ULONG               addr;
  34. } DefAuxData;
  35.  
  36. /*
  37. ** Find a function based on the function with the next lower address.
  38. */
  39. static int _System DefFindSource(DebugModule *module, ULONG eipOffset,
  40.             char *funcName, char *sourceName, ULONG *lineNum)
  41. {
  42. DefAuxData  *top, *bottom, *mod;
  43.  
  44.     top = bottom = module->AuxData;
  45.     for(mod=module->AuxData; mod; mod=mod->next) {
  46.  
  47.         /*
  48.         ** Close in from the bottom.
  49.         */
  50.         if((mod->addr >= bottom->addr) &&
  51.            (mod->addr <= eipOffset)) {
  52.         bottom = mod;
  53.         }
  54.  
  55.         /*
  56.         ** Close in from the top.
  57.         */
  58.         if((mod->addr <= top->addr) &&
  59.            (mod->addr >= eipOffset)) {
  60.             top = mod;
  61.         }
  62.     }
  63.     if(bottom)
  64.     strcpy(funcName, bottom->name);
  65.     else
  66.     strcpy(funcName, "UNKNOWN");
  67.     if(top)
  68.     strcpy(sourceName, top->name);
  69.     else
  70.     strcpy(sourceName, "UNKNOWN");
  71.     *lineNum    = 0;
  72.     return 0;
  73. }
  74.  
  75. /*
  76. ** Find the address of a function.
  77. */
  78. static ULONG _System DefFindFuncAddr(DebugModule *module, char *funcName)
  79. {
  80. DefAuxData *mod;
  81.  
  82.     for(mod = module->AuxData; mod; mod=mod->next) {
  83.         if(stricmp(funcName, mod->name) == 0) {
  84.             return mod->addr;
  85.         }
  86.     }
  87.     return 0;
  88. }
  89.  
  90. /*
  91. ** Free all of the collected information.
  92. */
  93. static void _System DefFreeModule(DebugModule *module)
  94. {
  95. DefAuxData *mod, *next;
  96.  
  97.     for(mod=module->AuxData; mod;) {
  98.         free(mod->name);
  99.         next = mod->next;
  100.         free(mod);
  101.         mod = next;
  102.     }
  103.     module->AuxData = NULL;
  104. }
  105.  
  106. /*
  107. ** Connect to a module without debugging information.
  108. */
  109. int DefConnectModule(DebugModule *module)
  110. {
  111. FILE           *mod;
  112. DefAuxData     *data, *prior;
  113. ULONG           size;
  114. unsigned char   cbName;
  115. struct exe_hdr  dosHdr;
  116. HMODULE         modHandle;
  117. char        buff[CCHMAXPATH];
  118. struct stat    statBuff;
  119. union   {
  120.     struct new_exe  os21x;
  121.     struct e32_exe  os22x;
  122. } header;
  123.  
  124.     /*
  125.     ** Open the file.
  126.     */
  127.     if((mod = fopen(module->name, "rb")) == NULL) {
  128.     fprintf(logFile, "Unable to open module %s.\n", module->name);
  129.     return 0;
  130.     }
  131.     fstat(fileno(mod), &statBuff);
  132.     module->fileSize   = statBuff.st_size;
  133.     module->fTimestamp = statBuff.st_atime;
  134.  
  135.     /*
  136.     ** Get the DOS exe header.
  137.     */
  138.     fread(&dosHdr, sizeof(struct exe_hdr), 1, mod);
  139.     fseek(mod, dosHdr.e_lfanew, SEEK_SET);
  140.  
  141.     /*
  142.     ** Read the os2 header.
  143.     */
  144.     fread(&header, sizeof(header), 1, mod);
  145.     if(header.os21x.ne_magic == NEMAGIC) {
  146.         fseek(mod, dosHdr.e_lfanew + header.os21x.ne_rsrctab, SEEK_SET);
  147.     } else {
  148.         fseek(mod, dosHdr.e_lfanew + header.os22x.e32_restab, SEEK_SET);
  149.     }
  150.  
  151.     /*
  152.     ** Read the Resident names table.
  153.     **
  154.     ** Skip over the module name.
  155.     */
  156.     fread(&cbName, 1, 1, mod);
  157.     fseek(mod, cbName + 2, SEEK_CUR);
  158.  
  159.     /*
  160.     ** Read the names.
  161.     */
  162.     fread(&cbName, 1, 1, mod);
  163.     module->AuxData = (void *) malloc(sizeof(DefAuxData));
  164.     data = (DefAuxData *) module->AuxData;
  165.     data->name = NULL;
  166.     prior = data;
  167.     while(cbName != 0) {
  168.         USHORT  dummy;
  169.  
  170.     data->name = (void *) malloc(cbName + 1);
  171.         fread(data->name, cbName, 1, mod);
  172.         data->name[cbName] = '\0';
  173.  
  174.         fread(&dummy, 2, 1, mod);
  175.         fread(&cbName, 1, 1, mod);
  176.     data->next = (DefAuxData *) malloc(sizeof(DefAuxData));
  177.         prior = data;
  178.         data = data->next;
  179.     }
  180.  
  181.     /*
  182.     ** Seek to the Non-Resident names table.
  183.     */
  184.     if(header.os21x.ne_magic == NEMAGIC) {
  185.         fseek(mod, header.os21x.ne_nrestab, SEEK_SET);
  186.         size = header.os21x.ne_cbnrestab;
  187.     } else {
  188.         fseek(mod, header.os22x.e32_nrestab, SEEK_SET);
  189.         size = header.os22x.e32_cbnrestab;
  190.     }
  191.  
  192.     /*
  193.     ** Make sure that there is a non-resident table to read.
  194.     */
  195.     if(size != 0) {
  196.  
  197.         /*
  198.         ** Read the comment.
  199.         */
  200.         fread(&cbName, 1, 1, mod);
  201.         size -= cbName + 3;
  202.         fseek(mod, cbName + 2, SEEK_CUR);
  203.  
  204.         /*
  205.         ** Read the names.
  206.         */
  207.         fread(&cbName, 1, 1, mod);
  208.         while((size != 0) && (cbName != 0)) {
  209.             USHORT  dummy;
  210.  
  211.             size -= cbName + 3;
  212.         data->name = (char *) malloc(cbName + 1);
  213.             fread(data->name, cbName, 1, mod);
  214.             data->name[cbName] = '\0';
  215.  
  216.             fread(&dummy, 2, 1, mod);
  217.             fread(&cbName, 1, 1, mod);
  218.         data->next = (DefAuxData *) malloc(sizeof(DefAuxData));
  219.             prior = data;
  220.             data = data->next;
  221.         }
  222.     }
  223.     prior->next = NULL;
  224.     if(prior == data) {
  225.         module->AuxData = NULL;
  226.     }
  227.     free(data);
  228.     fclose(mod);
  229.  
  230.     /*
  231.     ** Find the export addresses of the functions.
  232.     */
  233.     DosLoadModule(buff, sizeof(buff), module->name, &modHandle);
  234.     for(data = module->AuxData; data; data=data->next) {
  235.     if(DosQueryProcAddr(modHandle, 0, data->name, (PFN *) &data->addr) != 0) {
  236. #if 0
  237.         fprintf(logFile, "Unable to find address for %s:%s\n",
  238.             module->name, data->name);
  239. #endif
  240.             data->addr = 0;
  241.         }
  242.     }
  243.     DosFreeModule(modHandle);
  244.  
  245.     /*
  246.     ** Finally, connect the display routines.
  247.     */
  248.     module->FreeModule   = DefFreeModule;
  249.     module->FindSource   = DefFindSource;
  250.     module->FindFuncAddr = DefFindFuncAddr;
  251.     return 1;
  252. }
  253.