home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sherlock.zip / HEXDUMP.C < prev    next >
C/C++ Source or Header  |  1994-10-07  |  7KB  |  267 lines

  1. /*
  2. **  Sherlock - Copyright 1992, 1993, 1994
  3. **    Harfmann Software
  4. **    Compuserve: 73147,213
  5. **    All rights reserved
  6. */
  7. #include    <stdio.h>
  8. #include    <stdlib.h>
  9. #include    <ctype.h>
  10. #include    <memory.h>
  11. #include    <math.h>
  12. #include    <time.h>
  13. #include    <sys\stat.h>
  14.  
  15. #define     INCL_DOSSESMGR
  16. #define     INCL_DOSPROCESS
  17. #include    <os2.h>
  18. #include    "debug.h"
  19.  
  20. #include    "Debugger.h"
  21. #include    "SrcInter.h"
  22. #include    "Source.h"
  23.  
  24.  
  25. /*
  26. ** Convert a string to an address.  Do any necessary linearization.
  27. */
  28. ULONG StrToAddr(char *str, int type)
  29. {
  30. ULONG val;
  31. char *end;
  32.  
  33.     val = strtoul(str, &end, 16);
  34.     if((val & 0xffff0000) != 0)
  35.     return val;
  36.     DispatchCommand(DBG_C_ReadReg);
  37.     switch(type) {
  38.     case TOADDR_CODE:   return Linearize(val, debugBuffer.CS);
  39.     case TOADDR_DATA:   return Linearize(val, debugBuffer.DS);
  40.     case TOADDR_STACK:  return Linearize(val, debugBuffer.SS);
  41.     }
  42.     return 0;
  43. }
  44.  
  45. /*
  46. ** Linearize an offset/segment.  This linearization will
  47. ** check whether the segment is 16/32 bit.  If 32 bit,
  48. ** just return offset.    If 16 bit, convert to linear.
  49. */
  50. ULONG Linearize(ULONG offset, USHORT segment)
  51. {
  52.     if((offset & 0xffff0000) != 0)
  53.     return offset;
  54.  
  55.     debugBuffer.Value = segment;
  56.     debugBuffer.Index = offset;
  57.     DispatchCommand(DBG_C_SelToLin);
  58.     return debugBuffer.Addr;
  59. }
  60.  
  61. /*
  62. **  Dump a buffer of length to the buffer given.  Assume that length is
  63. **  less than 16 and that the buffer is large enough to hold the result.
  64. */
  65. void hexdump(unsigned char *data, int count, char *buff)
  66. {
  67. static char digits[] = "0123456789ABCDEF";
  68. int i;
  69.  
  70.     count = min(count, 16);
  71.     for(i=0; i<count; i++) {
  72.         if(i == 8) {
  73.             *buff++ = ' ';
  74.             *buff++ = ' ';
  75.         }
  76.         *buff++ = digits[data[i]/16];
  77.         *buff++ = digits[data[i]%16];
  78.         *buff++ = ' ';
  79.     }
  80.     *buff++ = ' ';
  81.     *buff++ = ' ';
  82.     *buff++ = ' ';
  83.  
  84.     memcpy(buff, data, 16);
  85.     for(i=0; i<count; i++)
  86.     buff[i] = isgraph(buff[i]) ? buff[i] : (char) '.';
  87.     buff[16] = '\0';
  88.     return;
  89. }
  90.  
  91. /*
  92. ** Dump the stack frame.
  93. */
  94. void DumpStack(int threadID)
  95. {
  96. ULONG    lineNum;
  97. struct {
  98.     ULONG   ebp;
  99.     ULONG   eip;
  100. } info;
  101. DebugModule *module;
  102. ULONG    oldTid;
  103. ULONG    objectNum;
  104. ULONG    baseOffset;
  105. USHORT    lastCS;
  106. char    funcName[MAX_FUNCNAME];
  107. char    sourceName[CCHMAXPATH];
  108.  
  109.     /*
  110.     ** Find the base and then extract out the EIP.  Follow the chain
  111.     ** until EBP == 0
  112.     */
  113.     oldTid = debugBuffer.Tid;
  114.     debugBuffer.Tid = threadID;
  115.     DispatchCommand(DBG_C_ReadReg);
  116.     lastCS   = debugBuffer.CS;
  117.     info.ebp = Linearize(debugBuffer.EBP, debugBuffer.SS);
  118.     info.eip = Linearize(debugBuffer.EIP, debugBuffer.CS);
  119.     while(1) {
  120.     /*
  121.     ** End of chain.
  122.     */
  123.     if((info.ebp == 0) || (info.eip == 0)) {
  124.         debugBuffer.Tid = oldTid;
  125.         return;
  126.     }
  127.  
  128.     /*
  129.     ** Find the module.
  130.     */
  131.     debugBuffer.Addr = info.eip;
  132.     DispatchCommand(DBG_C_AddrToObject);
  133.         module = FindModule(debugBuffer.MTE, NULL);
  134.     if(module == NULL) {
  135.         fprintf(logFile, "MODULE NOT FOUND!\n");
  136.         debugBuffer.Tid = oldTid;
  137.         return;
  138.     }
  139.  
  140.     /*
  141.     ** Dump EBP:EIP of the current stack frame.
  142.     */
  143.     baseOffset = debugBuffer.Buffer;
  144.     fprintf(logFile, "EBP:\t%08x\tEIP:\t%08x\n", info.ebp, info.eip);
  145.     fprintf(logFile, "  Base:\t%08x\tRel:\t%08x\tLen:\t%08x\n",
  146.         baseOffset, info.eip - baseOffset, debugBuffer.Len);
  147.  
  148.     /*
  149.     ** Find the object number associated with the address.
  150.     */
  151.     for(objectNum=1;;objectNum++) {
  152.         debugBuffer.Value = (ULONG) objectNum;
  153.         debugBuffer.MTE   = module->MTE;
  154.         if(DispatchCommand(DBG_C_NumToAddr) != DBG_N_Success)
  155.         break;
  156.         if(debugBuffer.Addr == baseOffset)
  157.         break;
  158.     }
  159.     fprintf(logFile, "  Object: %08x\n", objectNum);
  160.  
  161.         /*
  162.     ** Dump the values.
  163.     */
  164.     FindSource(module, info.eip,
  165.            funcName, sourceName, &lineNum);
  166.     if(lineNum != 0)
  167.         fprintf(logFile, "  Module:   %s\n"
  168.                 "  Size:     %u\n"
  169.                 "  Timestamp:%s\n"
  170.                 "  Function: %s\n"
  171.                 "  Source:   %s\n"
  172.                 "  Line:     %d\n\n",
  173.             module->name, module->fileSize, ctime(&module->fTimestamp),
  174.             funcName, sourceName, lineNum);
  175.     else
  176.         fprintf(logFile, "  Module:   %s\n"
  177.                 "  Size:     %u\n"
  178.                 "  Timestamp:%s\n"
  179.                 "  Lo Function: %s\n"
  180.                 "  Hi Function: %s\n\n",
  181.             module->name, module->fileSize, ctime(&module->fTimestamp),
  182.             funcName, sourceName);
  183.  
  184. #ifdef SHERLOCK
  185.         {
  186.             DebugModule *module;
  187.             char *mod;
  188.  
  189.         debugBuffer.Addr = info.eip;
  190.         DispatchCommand(DBG_C_AddrToObject);
  191.         if((debugBuffer.Cmd == DBG_N_Success) &&
  192.            (debugBuffer.Value & 0x10000000)) {
  193.                 module = FindModule(debugBuffer.MTE, NULL);
  194.                 if(module == NULL)
  195.                     mod = "UNKNOWN";
  196.                 else
  197.                     mod = module->name;
  198.         FindSource(module, info.eip,
  199.             funcName, sourceName, &lineNum);
  200.         fprintf(logFile, "EIP: %08x, DLL: %s Func: %s\n",
  201.             info.eip, mod, funcName);
  202.         DisplaySource(module, sourceName, lineNum);
  203.         fprintf(logFile, "\n\n");
  204.         }
  205.     }
  206. #endif
  207.  
  208.     /*
  209.     ** Get prior EBP, EIP
  210.     */
  211.     if(module->typeFlags & FAPPTYP_32BIT) {
  212.             debugBuffer.Addr = info.ebp;
  213.             debugBuffer.Len  = 8;
  214.             debugBuffer.Buffer = (ULONG) &info.ebp;
  215.             info.ebp = info.eip = 0;
  216.         DispatchCommand(DBG_C_ReadMemBuf);
  217.     } else {
  218.         USHORT  codePtr[2];
  219.  
  220.         /* Get the new code pointer. */
  221.         debugBuffer.Addr = info.ebp+2;
  222.         debugBuffer.Len  = 4;
  223.         debugBuffer.Buffer = (ULONG) &codePtr;
  224.         info.eip = 0;
  225.         DispatchCommand(DBG_C_ReadMemBuf);
  226.  
  227.         /* Now, get the new base pointer. */
  228.         debugBuffer.Addr = info.ebp;
  229.         debugBuffer.Len  = 2;
  230.             debugBuffer.Buffer = (ULONG) &info.ebp;
  231.         info.ebp = 0;
  232.         DispatchCommand(DBG_C_ReadMemBuf);
  233.         info.ebp = Linearize(info.ebp, debugBuffer.SS);
  234.  
  235.         /*
  236.         ** Now for real hocus pocus.  Try to find out
  237.         ** if the pointer is a near or far call!
  238.         **
  239.         ** First, check for NULL pointer, Must be end of chain.
  240.         */
  241.         if((codePtr[0] == 0) && (codePtr[1] == 0)) {
  242.         info.eip = 0;
  243.         } else {
  244.         USHORT tmp;
  245.  
  246.         /*
  247.         ** If supposidly ring 0 or ring 1 caller, then
  248.         ** that cannot be correct, must be a near call.
  249.         */
  250.         tmp = codePtr[1] & 0x03;
  251.         if((tmp == 0) || (tmp == 1)) {
  252.             info.eip = Linearize(codePtr[0], lastCS);
  253.         } else {
  254.  
  255.             /*
  256.             ** Assume that it is a far pointer.
  257.             */
  258.             lastCS = codePtr[1];
  259.             info.eip = Linearize(codePtr[0], lastCS);
  260.         }
  261.         }
  262.     }
  263.     }
  264.     debugBuffer.Tid = oldTid;
  265.     return;
  266. }
  267.