lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <51630.166.70.238.45.1217831381.squirrel@webmail.wolfmountaingroup.com>
Date:	Mon, 4 Aug 2008 00:29:41 -0600 (MDT)
From:	jmerkey@...fmountaingroup.com
To:	linux-kernel@...r.kernel.org
Subject: [PATCH 2.6.27-rc1 4/25] mdb:  Merkey's Kernel Debugger 2.6.27-rc1

Netware style debugger for Linux written by Jeffrey Vernon Merkey

--- a/debug/mdb-base.c	1969-12-31 17:00:00.000000000 -0700
+++ b/debug/mdb-base.c	2008-08-03 16:15:00.000000000 -0600
@@ -0,0 +1,2432 @@
+
+/***************************************************************************
+*
+*   Copyright (c) 2008 Jeff V. Merkey  All Rights Reserved.
+*   1058 East 50 South
+*   Lindon, Utah 84042
+*   jmerkey@...fmountaingroup.com
+*
+*   This program is free software; you can redistribute it and/or modify it
+*   under the terms of the GNU General Public License as published by the
+*   Free Software Foundation, version 3.
+*
+*   This program is distributed in the hope that it will be useful, but
+*   WITHOUT ANY WARRANTY; without even the implied warranty of
+*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*   General Public License for more details.
+*
+*   You are free to modify and re-distribute this program in accordance
+*   with the terms specified in the GNU Public License.  The copyright
+*   contained in this code is required to be present in any derivative
+*   works and you are required to provide the source code for this
+*   program as part of any commercial or non-commercial distribution.
+*   You are required to respect the rights of the Copyright holders
+*   named within this code.
+*
+*   jmerkey@...fmountaingroup.com is the official maintainer of
+*   this code.  You are encouraged to report any bugs, problems, fixes,
+*   suggestions, and comments about this software.
+*
+*   AUTHOR   :  Jeff V. Merkey
+*   FILE     :  MDB-BASE.C
+*   DESCRIP  :  Merkey's NetWare Debugger
+*   DATE     :  April 8, 2008
+*
+***************************************************************************/
+
+#include "mdb.h"
+
+#ifdef CONFIG_MDB
+
+ULONG debug_deref = 0;
+ULONG full_deref_toggle = 0;
+ULONG general_toggle = TRUE;
+ULONG line_info_toggle = TRUE;
+ULONG control_toggle = 0;
+ULONG segment_toggle = TRUE;
+ULONG numeric_toggle = 0;
+ULONG reason_toggle = TRUE;
+
+ULONG enterKeyACC(ULONG key, void *stackFrame,
+  	          ACCELERATOR *accel)
+{
+    BYTE *verbBuffer = &workbuf[0][0];
+    register BYTE *verb, *pp, *vp;
+    register ULONG count;
+
+    if (key) {};
+    if (stackFrame) {};
+    if (accel) {};
+
+    if (!debugCommand[0])
+    {
+       count = 0;
+       pp = (BYTE *)lastDebugCommand;
+       vp = verb = &verbBuffer[0];
+       while (*pp && *pp == ' ' && count++ < 80)
+	  pp++;
+
+       while (*pp && *pp != ' ' && count++ < 80)
+	  *vp++ = *pp++;
+       *vp = '\0';
+
+       while (*pp && *pp == ' ' && count++ < 80)
+	  pp++;
+
+       UpcaseString(verb);
+       if (!strcmp(verb, "P") || (lastCommand == K_F8))
+	  strcpy((char *)debugCommand, "P");
+       else
+       if (!strcmp(verb, "T") || (lastCommand == K_F7))
+	  strcpy((char *)debugCommand, "T");
+       else
+       if (!strcmp(verb, "W")   || !strcmp(verb, "D")   ||
+	   !strcmp(verb, "DB")  || !strcmp(verb, "DW")  ||
+	   !strcmp(verb, "DD")  || !strcmp(verb, "DDS") ||
+	   !strcmp(verb, "DS")  || !strcmp(verb, "DL")  ||
+	   !strcmp(verb, "U")   || !strcmp(verb, "UU")  ||
+	   !strcmp(verb, "S")   || !strcmp(verb, "SS")  ||
+	   !strcmp(verb, "SSB") || !strcmp(verb, "ID"))
+       {
+	  strcpy((char *)debugCommand, verb);
+	  repeatCommand = TRUE;
+       }
+    }
+    return 0;
+
+}
+
+
+ULONG displayDebuggerHelpHelp(BYTE *commandLine, DEBUGGER_PARSER *parser)
+{
+    if (commandLine) {}
+    if (parser) {}
+
+    DBGPrint("displays general help for all commands, or help for a
specific command\n");
+    DBGPrint("HELP         <enter>  - list all commands\n");
+    DBGPrint("HELP command <enter>  - help for a specific command\n");
+
+    return TRUE;
+}
+
+ULONG displayDebuggerHelp(BYTE *commandLine,
+			 StackFrame *stackFrame, ULONG Exception,
+			 DEBUGGER_PARSER *parser)
+{
+
+    register ULONG count;
+    BYTE *verbBuffer = &workbuf[0][0];
+    register BYTE *verb, *pp, *vp;
+
+    if (stackFrame) {};
+    if (Exception) {};
+
+    commandLine = &commandLine[parser->debugCommandNameLength];
+    while (*commandLine && *commandLine == ' ') commandLine++;
+
+    count = 0;
+    pp = commandLine;
+    vp = verb = &verbBuffer[0];
+    while (*pp && *pp == ' ' && count++ < 80)
+       pp++;
+
+    while (*pp && *pp != ' ' && count++ < 80)
+       *vp++ = *pp++;
+    *vp = '\0';
+
+    while (*pp && *pp == ' ' && count++ < 80)
+       pp++;
+
+    DebuggerParserHelpRoutine(verb, commandLine);
+    return TRUE;
+
+}
+
+// BT, BTA, BTP
+
+extern int bt_stack(struct task_struct *task, struct pt_regs *regs,
+	            unsigned long *stack);
+
+ULONG backTraceHelp(BYTE *commandLine, DEBUGGER_PARSER *parser)
+{
+    if (commandLine) {}
+    if (parser) {}
+
+    DBGPrint("bt <addr>                - display stack backtrace\n");
+    DBGPrint("bta                      - display stack backtrace all
pids\n");
+    DBGPrint("btp <pid>                - display stack backtrace by pid\n");
+    return TRUE;
+}
+
+ULONG backTraceAllPID(BYTE *cmd, StackFrame *stackFrame, ULONG Exception,
+	          DEBUGGER_PARSER *parser)
+{
+    struct task_struct *p, *g;
+
+    if (cmd) {};
+    if (stackFrame) {};
+    if (Exception) {};
+    if (parser) {};
+
+    cmd = &cmd[parser->debugCommandNameLength];
+    while (*cmd && *cmd == ' ') cmd++;
+
+    do_each_thread(g, p)
+    {
+       if (p)
+       {
+          DBGPrint("Stack backtrace for pid %d\n", p->pid);
+          if (bt_stack(p, NULL, NULL))
+             return TRUE;
+       }
+    } while_each_thread(g, p);
+    return TRUE;
+}
+
+ULONG backTracePID(BYTE *cmd, StackFrame *stackFrame, ULONG Exception,
+	          DEBUGGER_PARSER *parser)
+{
+    int pid;
+    ULONG valid = 0;
+    struct task_struct *p, *g;
+
+    if (cmd) {};
+    if (stackFrame) {};
+    if (Exception) {};
+    if (parser) {};
+
+    cmd = &cmd[parser->debugCommandNameLength];
+    while (*cmd && *cmd == ' ') cmd++;
+
+    pid = EvaluateNumericExpression(stackFrame, &cmd, &valid);
+    if (valid)
+    {
+       do_each_thread(g, p)
+       {
+          if (p && (p->pid == pid))
+          {
+             DBGPrint("Stack backtrace for pid %d\n", p->pid);
+             bt_stack(p, NULL, NULL);
+             return TRUE;
+          }
+       } while_each_thread(g, p);
+       DBGPrint("No process with pid %d found\n", pid);
+    }
+    else
+       DBGPrint("invalid pid entered for backtrace\n");
+
+    return TRUE;
+
+}
+
+ULONG backTraceStack(BYTE *cmd, StackFrame *stackFrame, ULONG Exception,
+	             DEBUGGER_PARSER *parser)
+{
+    ULONG valid = 0, address;
+
+    if (cmd) {};
+    if (stackFrame) {};
+    if (Exception) {};
+    if (parser) {};
+
+    cmd = &cmd[parser->debugCommandNameLength];
+    while (*cmd && *cmd == ' ') cmd++;
+
+    address = EvaluateExpression(stackFrame, &cmd, &valid);
+    if (valid)
+    {
+       DBGPrint("Stack backtrace for address 0x%08X\n", (unsigned)address);
+       bt_stack(NULL, NULL, (unsigned long *)address);
+       return TRUE;
+    }
+    else
+    {
+       DBGPrint("Stack backtrace for address 0x%08X\n",
+                (unsigned)GetStackAddress(stackFrame));
+       bt_stack(NULL, NULL, (unsigned long *)GetStackAddress(stackFrame));
+       return TRUE;
+    }
+    return TRUE;
+}
+
+void DisplayASCIITable(void)
+{
+
+    register ULONG i;
+    union bhex
+    {
+       unsigned int i;
+       struct btemp {
+	     unsigned one : 1;
+	     unsigned two : 1;
+	     unsigned three : 1;
+	     unsigned four : 1;
+	     unsigned five : 1;
+	     unsigned six : 1;
+	     unsigned seven : 1;
+	     unsigned eight : 1;
+       } b;
+    } val;
+
+    DBGPrint("ASCII Table\n");
+    for (i=0; i < 256; i++)
+    {
+       val.i = i;
+       switch (i)
+       {
+
+	  case 0:
+	     if (DBGPrint("|  %3i  |  (0x%02X)  |  (%1i%1i%1i%1i%1i%1i%1i%1ib) 
| NULL  |", (int)i, (unsigned)i,
+		(int)val.b.eight, (int)val.b.seven, (int)val.b.six,
+                (int)val.b.five,  (int)val.b.four, (int)val.b.three,
+                (int)val.b.two, (int)val.b.one)) return;
+	     break;
+
+	  case 8:
+	     if (DBGPrint("|  %3i  |  (0x%02X)  |  (%1i%1i%1i%1i%1i%1i%1i%1ib) 
| BKSP  |", (int)i, (unsigned)i,
+		(int)val.b.eight, (int)val.b.seven, (int)val.b.six,
+                (int)val.b.five,  (int)val.b.four,  (int)val.b.three,
+                (int)val.b.two, (int)val.b.one)) return;
+	     break;
+
+	  case 9:
+	     if (DBGPrint("|  %3i  |  (0x%02X)  |  (%1i%1i%1i%1i%1i%1i%1i%1ib) 
| TAB   |", (int)i, (unsigned)i,
+		(int)val.b.eight, (int)val.b.seven, (int)val.b.six,
+                (int)val.b.five,  (int)val.b.four,  (int)val.b.three,
+                (int)val.b.two, (int)val.b.one)) return;
+	     break;
+
+	  case 10:
+	     if (DBGPrint("|  %3i  |  (0x%02X)  |  (%1i%1i%1i%1i%1i%1i%1i%1ib) 
| <CR>  |", (int)i, (unsigned)i,
+		(int)val.b.eight, (int)val.b.seven, (int)val.b.six,
+                (int)val.b.five,  (int)val.b.four,  (int)val.b.three,
+                (int)val.b.two, (int)val.b.one)) return;
+	     break;
+
+	  case 13:
+	     if (DBGPrint("|  %3i  |  (0x%02X)  |  (%1i%1i%1i%1i%1i%1i%1i%1ib) 
| <LF>  |", (int)i, (unsigned)i,
+		(int)val.b.eight, (int)val.b.seven, (int)val.b.six,
+                (int)val.b.five,  (int)val.b.four,  (int)val.b.three,
+                (int)val.b.two, (int)val.b.one)) return;
+	     break;
+
+	  case 32:
+	     if (DBGPrint("|  %3i  |  (0x%02X)  |  (%1i%1i%1i%1i%1i%1i%1i%1ib) 
| SPACE |", (int)i, (unsigned)i,
+	        (int)val.b.eight, (int)val.b.seven, (int)val.b.six,
+                (int)val.b.five,  (int)val.b.four,  (int)val.b.three,
+                (int)val.b.two, (int)val.b.one)) return;
+	     break;
+
+	  default:
+	     if (DBGPrint("|  %3i  |  (0x%02X)  |  (%1i%1i%1i%1i%1i%1i%1i%1ib) 
|  %c    |", (int)i, (unsigned)i,
+	        (int)val.b.eight, (int)val.b.seven, (int)val.b.six,
+                (int)val.b.five,  (int)val.b.four,  (int)val.b.three,
+                (int)val.b.two, (int)val.b.one, (BYTE) i)) return;
+	     break;
+
+       }
+       if (DBGPrint("\n")) return;
+    }
+
+}
+
+#if defined(CONFIG_MODULES)
+
+// LSMOD, .M
+
+ULONG listModulesHelp(BYTE *commandLine, DEBUGGER_PARSER *parser)
+{
+    if (commandLine) {}
+    if (parser) {}
+
+    DBGPrint(".M                       - list loaded modules\n");
+    DBGPrint("lsmod                    - list loaded modules\n");
+    DBGPrint("rmmod <name>             - unload module\n");
+    return TRUE;
+}
+
+ULONG listModules(BYTE *cmd, StackFrame *stackFrame, ULONG Exception,
+	          DEBUGGER_PARSER *parser)
+{
+    if (cmd) {};
+    if (stackFrame) {};
+    if (Exception) {};
+    if (parser) {};
+
+    cmd = &cmd[parser->debugCommandNameLength];
+    while (*cmd && *cmd == ' ') cmd++;
+
+    if (*cmd)
+       mdb_modules(cmd, DBGPrint);
+    else
+       mdb_modules(NULL, DBGPrint);
+    return TRUE;
+}
+
+ULONG unloadModule(BYTE *cmd, StackFrame *stackFrame, ULONG Exception,
+	           DEBUGGER_PARSER *parser)
+{
+    if (cmd) {};
+    if (stackFrame) {};
+    if (Exception) {};
+    if (parser) {};
+
+    cmd = &cmd[parser->debugCommandNameLength];
+    while (*cmd && *cmd == ' ') cmd++;
+
+    DBGPrint("Module unload unsupported in this version\n");
+    return 0;
+}
+
+#endif
+
+// REBOOT
+
+ULONG rebootSystemHelp(BYTE *commandLine, DEBUGGER_PARSER *parser)
+{
+    if (commandLine) {}
+    if (parser) {}
+
+    DBGPrint("reboot                   - reboot host system\n");
+    return TRUE;
+}
+
+
+ULONG rebootSystem(BYTE *cmd, StackFrame *stackFrame, ULONG Exception,
+	     DEBUGGER_PARSER *parser)
+{
+    extern void machine_restart(int);
+
+    if (cmd) {};
+    if (stackFrame) {};
+    if (Exception) {};
+    if (parser) {};
+
+    machine_restart(0);
+    return TRUE;
+}
+
+// SECTIONS, .S
+
+ULONG displaySectionsHelp(BYTE *commandLine, DEBUGGER_PARSER *parser)
+{
+    if (commandLine) {}
+    if (parser) {}
+
+    DBGPrint("sections                 - display kernel/module sections\n");
+    DBGPrint(".s                       - display kernel/module sections\n");
+    return TRUE;
+}
+
+ULONG displaySections(BYTE *cmd,
+		      StackFrame *stackFrame, ULONG Exception,
+		      DEBUGGER_PARSER *parser)
+{
+     if (cmd) {};
+     if (stackFrame) {};
+     if (Exception) {};
+     if (parser) {};
+
+     DBGPrint("\n");
+
+     return TRUE;
+}
+
+// PS, .P
+
+ULONG displayKernelProcessHelp(BYTE *commandLine, DEBUGGER_PARSER *parser)
+{
+    if (commandLine) {}
+    if (parser) {}
+
+    DBGPrint("ps <addr>                - display kernel processes\n");
+    DBGPrint(".p <addr>                - display kernel processes\n");
+    return TRUE;
+}
+
+ULONG displayKernelProcess(BYTE *cmd,
+		           StackFrame *stackFrame, ULONG Exception,
+		           DEBUGGER_PARSER *parser)
+{
+     struct task_struct *p, *g;
+     ULONG valid = 0;
+
+     if (cmd) {};
+     if (stackFrame) {};
+     if (Exception) {};
+     if (parser) {};
+
+     cmd = &cmd[parser->debugCommandNameLength];
+     while (*cmd && *cmd == ' ') cmd++;
+
+     if (*cmd)
+     {
+        p = (struct task_struct *)EvaluateExpression(stackFrame, &cmd,
&valid);
+        if (valid && p)
+        {
+	   DBGPrint("%-*s      Pid   Parent [*] State %-*s Command\n",
+	   	     (int)(2*sizeof(void *))+2, "Task Addr",
+		     (int)(2*sizeof(void *))+2, "Thread");
+
+	   if (DBGPrint("0x%p %8d %8d  %d    %c  0x%p %s\n",
+	       (void *)p, p->pid, p->real_parent->pid,
+	       task_curr(p),
+               (p->state == 0) ? 'R' :
+	       (p->state < 0) ? 'U' :
+	       (p->state & TASK_UNINTERRUPTIBLE) ? 'D' :
+	       (p->state & TASK_STOPPED) ? 'T' :
+	       (p->state & TASK_TRACED) ? 'C' :
+	       (p->exit_state & EXIT_ZOMBIE) ? 'Z' :
+	       (p->exit_state & EXIT_DEAD) ? 'E' :
+	       (p->state & TASK_INTERRUPTIBLE) ? 'S' : '?',
+	       (void *)(&p->thread),
+	        p->comm))
+                  return TRUE;
+            return TRUE;
+        }
+        DBGPrint("invalid task address\n");
+        return TRUE;
+     }
+     else
+     {
+	DBGPrint("%-*s      Pid   Parent [*] State %-*s Command\n",
+		(int)(2*sizeof(void *))+2, "Task Addr",
+		(int)(2*sizeof(void *))+2, "Thread");
+
+        do_each_thread(g, p)
+        {
+           if (p)
+           {
+	      if (DBGPrint("0x%p %8d %8d  %d    %c  0x%p %s\n",
+		   (void *)p, p->pid, p->real_parent->pid,
+		   task_curr(p),
+                   (p->state == 0) ? 'R' :
+		   (p->state < 0) ? 'U' :
+		   (p->state & TASK_UNINTERRUPTIBLE) ? 'D' :
+		   (p->state & TASK_STOPPED) ? 'T' :
+		   (p->state & TASK_TRACED) ? 'C' :
+		   (p->exit_state & EXIT_ZOMBIE) ? 'Z' :
+		   (p->exit_state & EXIT_DEAD) ? 'E' :
+		   (p->state & TASK_INTERRUPTIBLE) ? 'S' : '?',
+		   (void *)(&p->thread),
+		   p->comm))
+                 return TRUE;
+           }
+        } while_each_thread(g, p);
+     }
+     return TRUE;
+
+}
+
+ULONG ascTableHelp(BYTE *commandLine, DEBUGGER_PARSER *parser)
+{
+    if (commandLine) {}
+    if (parser) {}
+
+    DBGPrint("a                        - display ASCII Table\n");
+    return TRUE;
+}
+
+// A
+
+ULONG displayASCTable(BYTE *cmd,
+		     StackFrame *stackFrame, ULONG Exception,
+		     DEBUGGER_PARSER *parser)
+{
+
+     if (cmd) {};
+     if (stackFrame) {};
+     if (Exception) {};
+     if (parser) {};
+
+     DisplayASCIITable();
+     return TRUE;
+
+}
+
+typedef struct _LINE_INFO
+{
+   ULONG SourcePresent;
+   BYTE *SourceLine;
+   BYTE *ModuleName;
+   ULONG LineNumber;
+} LINE_INFO;
+
+void GetLineInfoFromValue(ULONG value, LINE_INFO *lineInfo, ULONG *exact)
+{
+    if (exact)
+       *exact = 0;
+
+    if (lineInfo)
+    {
+        lineInfo->SourcePresent = 0;
+        lineInfo->SourceLine = "";
+        lineInfo->ModuleName = "";
+        lineInfo->LineNumber = 0;
+    }
+    return;
+}
+
+ULONG disassemble(StackFrame *stackFrame, ULONG p, ULONG count, ULONG use)
+{
+    register ULONG i;
+    BYTE *symbolName;
+    BYTE *moduleName;
+    ULONG exact = 0;
+    extern ULONG line_info_toggle;
+    LINE_INFO lineInfo;
+    register int c = get_processor_id();
+
+    for (i=0; i < count; i++)
+    {
+       GetLineInfoFromValue(p, &lineInfo, &exact);
+
+       if (line_info_toggle && exact)
+       {
+	  if (lineInfo.SourcePresent && lineInfo.SourceLine)
+	  {
+	     register ULONG length = strlen(lineInfo.SourceLine);
+
+	     i = length > 80
+             ? i + 1 + (length / 80)
+             : i + 1;
+
+	     DBGPrint("%s (%s : line %d)\n",
+				 lineInfo.SourceLine, lineInfo.ModuleName,
+				 lineInfo.LineNumber);
+
+	  }
+	  else if (line_info_toggle && lineInfo.LineNumber)
+	  {
+	     i++;
+	     DBGPrint("file %s  line %d\n",
+				 lineInfo.ModuleName, lineInfo.LineNumber);
+	  }
+       }
+
+       if (i >= count && count != 1)
+	  break;
+
+       symbolName = GetSymbolFromValue(p, &symbuf[c][0], MAX_SYMBOL_LEN);
+       if (symbolName)
+       {
+	  i++;
+          moduleName = GetModuleInfoFromSymbolValue(p, &modbuf[c][0],
+                                                    MAX_SYMBOL_LEN);
+          if (moduleName)
+          {
+	     if (DBGPrint("%s|%s:\n", moduleName, symbolName)) return p;
+          }
+          else
+          {
+	     if (DBGPrint("%s:\n", symbolName)) return p;
+          }
+       }
+       if (i >= count && count != 1)
+	  break;
+
+       if (unassemble(stackFrame, p, use, &p)) return p;
+    }
+
+    return p;
+
+}
+
+ULONG dumpSearchResults(BYTE *p, ULONG count)
+{
+
+   BYTE *symbolName;
+   BYTE *moduleName;
+   register ULONG i, r, total;
+   BYTE ch;
+   register int c = get_processor_id();
+
+   if (DBGPrint("           0  1  2  3  4  5  6  7  8  9  A  B  C  D  E 
F\n"))
+      return 1;
+
+   for (r=0; r < count; r++)
+   {
+      symbolName = GetSymbolFromValue((ULONG) p, &symbuf[c][0],
MAX_SYMBOL_LEN);
+      if (symbolName)
+      {
+         moduleName = GetModuleInfoFromSymbolValue((ULONG) p, &modbuf[c][0],
+                                                   MAX_SYMBOL_LEN);
+         if (moduleName)
+         {
+	    if (DBGPrint("%s|%s:\n", moduleName, symbolName)) return 1;
+         }
+         else
+         {
+	    if (DBGPrint("%s:\n", symbolName)) return 1;
+         }
+	 if (r++ >= count && count != 1)
+	    break;
+      }
+      DBGPrint("%08X ", (unsigned) p);
+      for (total = 0, i=0; i < 16; i++, total++)
+      {
+	 DBGPrint(" %02X", (unsigned) mdb_getword((ULONG)&p[i], 1));
+      }
+      DBGPrint("  ");
+      for (i=0; i < total; i++)
+      {
+         ch = mdb_getword((ULONG)&p[i], 1);
+
+	 if (ch < 32 || ch > 126) DBGPrint(".");
+	 else DBGPrint("%c", ch);
+      }
+      if (DBGPrint("\n")) return 1;
+
+      p = (void *)((ULONG) p + (ULONG) total);
+   }
+   return 0;
+
+}
+
+BYTE *dump(BYTE *p, ULONG count)
+{
+
+   BYTE *symbolName;
+   BYTE *moduleName;
+   register ULONG i, r, total;
+   BYTE ch;
+   register int c = get_processor_id();
+
+   DBGPrint("           0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F\n");
+
+   for (r=0; r < count; r++)
+   {
+      symbolName = GetSymbolFromValue((ULONG) p, &symbuf[c][0],
MAX_SYMBOL_LEN);
+      if (symbolName)
+      {
+         moduleName = GetModuleInfoFromSymbolValue((ULONG) p, &modbuf[c][0],
+                                                   MAX_SYMBOL_LEN);
+         if (moduleName)
+	    DBGPrint("%s|%s:\n", moduleName, symbolName);
+         else
+	    DBGPrint("%s:\n", symbolName);
+	 if (r++ >= count && count != 1)
+	    break;
+      }
+      DBGPrint("%08X ", (unsigned) p);
+      for (total = 0, i=0; i < 16; i++, total++)
+      {
+	 DBGPrint(" %02X", (unsigned) mdb_getword((ULONG)&p[i], 1));
+      }
+      DBGPrint("  ");
+      for (i=0; i < total; i++)
+      {
+         ch = mdb_getword((ULONG)&p[i], 1);
+
+	 if (ch < 32 || ch > 126) DBGPrint(".");
+	 else DBGPrint("%c", ch);
+      }
+      DBGPrint("\n");
+
+      p = (void *)((ULONG) p + (ULONG) total);
+   }
+
+   return p;
+
+}
+
+ULONG dumpWordSearchResults(BYTE *p, ULONG count)
+{
+
+   register int i, r;
+   WORD *wp;
+   BYTE *symbolName;
+   BYTE *moduleName;
+   BYTE ch;
+   register int c = get_processor_id();
+
+   wp = (WORD *) p;
+   for (r=0; r < count; r++)
+   {
+      symbolName = GetSymbolFromValue((ULONG) p, &symbuf[c][0],
MAX_SYMBOL_LEN);
+      if (symbolName)
+      {
+         moduleName = GetModuleInfoFromSymbolValue((ULONG) p, &modbuf[c][0],
+                                                   MAX_SYMBOL_LEN);
+         if (moduleName)
+         {
+	    if (DBGPrint("%s|%s:\n", moduleName, symbolName)) return 1;
+         }
+         else
+         {
+	    if (DBGPrint("%s:\n", symbolName)) return 1;
+         }
+	 if (r++ >= count && count != 1)
+	    break;
+      }
+      DBGPrint("%08X ", (unsigned) p);
+      for (i=0; i < (16 / 2); i++)
+      {
+	 DBGPrint(" %04X", (unsigned) mdb_getword((ULONG)&wp[i], 2));
+      }
+      DBGPrint("  ");
+      for (i=0; i < 16; i++)
+      {
+         ch = mdb_getword((ULONG)&p[i], 1);
+
+	 if (ch < 32 || ch > 126) DBGPrint(".");
+	 else DBGPrint("%c", ch);
+      }
+      if (DBGPrint("\n")) return 1;
+
+      p = (void *)((ULONG) p + (ULONG) 16);
+      wp = (WORD *) p;
+   }
+
+   return 0;
+
+}
+
+BYTE *dumpWord(BYTE *p, ULONG count)
+{
+
+   register int i, r;
+   WORD *wp;
+   BYTE *symbolName;
+   BYTE *moduleName;
+   BYTE ch;
+   register int c = get_processor_id();
+
+   wp = (WORD *) p;
+   for (r=0; r < count; r++)
+   {
+      symbolName = GetSymbolFromValue((ULONG) p, &symbuf[c][0],
MAX_SYMBOL_LEN);
+      if (symbolName)
+      {
+         moduleName = GetModuleInfoFromSymbolValue((ULONG) p, &modbuf[c][0],
+                                                   MAX_SYMBOL_LEN);
+         if (moduleName)
+	    DBGPrint("%s|%s:\n", moduleName, symbolName);
+         else
+	    DBGPrint("%s:\n", symbolName);
+	 if (r++ >= count && count != 1)
+	    break;
+      }
+      DBGPrint("%08X ", (unsigned) p);
+      for (i=0; i < (16 / 2); i++)
+      {
+	 DBGPrint(" %04X", (unsigned) mdb_getword((ULONG)&wp[i], 2));
+      }
+      DBGPrint("  ");
+      for (i=0; i < 16; i++)
+      {
+         ch = mdb_getword((ULONG)&p[i], 1);
+
+	 if (ch < 32 || ch > 126) DBGPrint(".");
+	 else DBGPrint("%c", ch);
+      }
+      DBGPrint("\n");
+
+      p = (void *)((ULONG) p + (ULONG) 16);
+      wp = (WORD *) p;
+   }
+
+   return p;
+
+}
+
+ULONG dumpDoubleSearchResults(BYTE *p, ULONG count)
+{
+
+   register int i, r;
+   ULONG *lp;
+   BYTE *symbolName;
+   BYTE *moduleName;
+   BYTE ch;
+   register int c = get_processor_id();
+
+   lp = (ULONG *) p;
+
+   for (r=0; r < count; r++)
+   {
+      symbolName = GetSymbolFromValue((ULONG) p, &symbuf[c][0],
MAX_SYMBOL_LEN);
+      if (symbolName)
+      {
+         moduleName = GetModuleInfoFromSymbolValue((ULONG) p, &modbuf[c][0],
+                                                   MAX_SYMBOL_LEN);
+         if (moduleName)
+         {
+	    if (DBGPrint("%s|%s:\n", moduleName, symbolName)) return 1;
+         }
+         else
+         {
+	    if (DBGPrint("%s:\n", symbolName)) return 1;
+         }
+	 if (r++ >= count && count != 1)
+	    break;
+      }
+      DBGPrint("%08X ", (unsigned) p);
+      for (i=0; i < (16 / 4); i++)
+      {
+	 DBGPrint(" %08X", (unsigned) mdb_getword((ULONG)&lp[i], 4));
+      }
+      DBGPrint("  ");
+      for (i=0; i < 16; i++)
+      {
+         ch = mdb_getword((ULONG)&p[i], 1);
+
+	 if (ch < 32 || ch > 126) DBGPrint(".");
+	 else DBGPrint("%c", ch);
+      }
+      if (DBGPrint("\n")) return 1;
+
+      p = (void *)((ULONG) p + (ULONG) 16);
+      lp = (ULONG *) p;
+   }
+
+   return 0;
+
+}
+
+BYTE *dumpDouble(BYTE *p, ULONG count)
+{
+
+   register int i, r;
+   ULONG *lp;
+   BYTE *symbolName;
+   BYTE *moduleName;
+   BYTE ch;
+   register int c = get_processor_id();
+
+   lp = (ULONG *) p;
+
+   for (r=0; r < count; r++)
+   {
+      symbolName = GetSymbolFromValue((ULONG) p, &symbuf[c][0],
MAX_SYMBOL_LEN);
+      if (symbolName)
+      {
+         moduleName = GetModuleInfoFromSymbolValue((ULONG) p, &modbuf[c][0],
+                                                   MAX_SYMBOL_LEN);
+         if (moduleName)
+	    DBGPrint("%s|%s:\n", moduleName, symbolName);
+         else
+	    DBGPrint("%s:\n", symbolName);
+	 if (r++ >= count && count != 1)
+	    break;
+      }
+      DBGPrint("%08X ", (unsigned) p);
+      for (i=0; i < (16 / 4); i++)
+      {
+	 DBGPrint(" %08X", (unsigned) mdb_getword((ULONG)&lp[i], 4));
+      }
+      DBGPrint("  ");
+      for (i=0; i < 16; i++)
+      {
+         ch = mdb_getword((ULONG)&p[i], 1);
+
+	 if (ch < 32 || ch > 126) DBGPrint(".");
+	 else DBGPrint("%c", ch);
+      }
+      DBGPrint("\n");
+
+      p = (void *)((ULONG) p + (ULONG) 16);
+      lp = (ULONG *) p;
+   }
+
+   return p;
+
+}
+
+BYTE *dumpLinkedList(BYTE *p, ULONG count, ULONG offset)
+{
+
+   register int i, r;
+   ULONG *lp;
+   BYTE ch;
+
+   lp = (ULONG *) p;
+
+   DBGPrint("           0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F\n");
+   DBGPrint("Linked List -> [%08X + %X] = %08X\n", (unsigned)lp,
+            (unsigned)offset,
+            (unsigned)mdb_getword((ULONG)((ULONG)lp + (ULONG)offset), 4));
+
+   for (r=0; r < count; r++)
+   {
+      DBGPrint("%08X ", (unsigned) p);
+      for (i=0; i < 16; i++)
+      {
+	 DBGPrint(" %02X", (unsigned) mdb_getword((ULONG)&p[i], 1));
+      }
+      DBGPrint("  ");
+      for (i=0; i < 16; i++)
+      {
+         ch = mdb_getword((ULONG)&p[i], 1);
+
+	 if (ch < 32 || ch > 126) DBGPrint(".");
+	 else DBGPrint("%c", ch);
+      }
+      DBGPrint("\n");
+
+      p = (void *)((ULONG) p + (ULONG) 16);
+   }
+
+   return (BYTE *)(mdb_getword((ULONG)((ULONG)lp + (ULONG)offset), 4));
+
+}
+
+BYTE *dumpDoubleStack(StackFrame *stackFrame, BYTE *p, ULONG count)
+{
+
+   register int i, r;
+   ULONG *lp;
+   BYTE ch;
+
+   lp = (ULONG *) p;
+
+   DBGPrint("Stack = %04lX:%08X\n",
+            (unsigned long)GetStackSegment(stackFrame),
+            (unsigned)p);
+
+   for (r=0; r < count; r++)
+   {
+      DBGPrint("%04X:", (unsigned) GetStackSegment(stackFrame));
+      DBGPrint("%08X ", (unsigned) p);
+      for (i=0; i < (16 / 4); i++)
+      {
+	 DBGPrint(" %08X", (unsigned) mdb_getword((ULONG)&lp[i], 4));
+      }
+      DBGPrint("  ");
+      for (i=0; i < 16; i++)
+      {
+         ch = mdb_getword((ULONG)&p[i], 1);
+
+	 if (ch < 32 || ch > 126) DBGPrint(".");
+	 else DBGPrint("%c", ch);
+      }
+      DBGPrint("\n");
+
+      p = (void *)((ULONG) p + (ULONG) 16);
+      lp = (ULONG *) p;
+   }
+
+   return p;
+
+}
+
+BYTE *dumpStack(StackFrame *stackFrame, BYTE *p, ULONG count)
+{
+
+   register int r;
+   ULONG *lp;
+
+   lp = (ULONG *) p;
+
+   DBGPrint("Stack = %04X:%08X\n", (unsigned)GetStackSegment(stackFrame),
+            (unsigned)p);
+
+   for (r=0; r < count; r++)
+   {
+      DBGPrint("%08X ", (unsigned) p);
+      DBGPrint("%08X ", (unsigned) mdb_getword((ULONG)lp, 4));
+      if (DisplayClosestSymbol(mdb_getword((ULONG)lp, 4)))
+         DBGPrint("\n");
+
+      p = (void *)((ULONG) p + (ULONG) 4);
+      lp = (ULONG *) p;
+   }
+
+   return p;
+
+}
+
+ULONG displayToggleHelp(BYTE *commandLine, DEBUGGER_PARSER *parser)
+{
+    if (commandLine) {}
+    if (parser) {}
+
+    DBGPrint(".tc                      - toggles control registers (ON |
OFF)\n");
+    DBGPrint(".tn                      - toggles coprocessor registers
(ON | OFF)\n");
+    DBGPrint(".ts                      - toggles segment registers (ON |
OFF)\n");
+    DBGPrint(".tg                      - toggles general registers (ON |
OFF)\n");
+    DBGPrint(".tr                      - toggles display of break reason
(ON | OFF)\n");
+    DBGPrint(".td                      - toggles full dereference display
(ON | OFF)\n");
+    DBGPrint(".tl                      - toggles source line display (ON
| OFF)\n");
+    DBGPrint(".tu                      - toggles unasm debug display (ON
| OFF)\n");
+    DBGPrint(".t or .t <address>       - display task state segment
(tss)\n");
+    return TRUE;
+}
+
+// .TU
+
+ULONG ProcessTUToggle(BYTE *cmd,
+		   StackFrame *stackFrame, ULONG Exception,
+		   DEBUGGER_PARSER *parser)
+{
+
+     if (cmd) {};
+     if (stackFrame) {};
+     if (Exception) {};
+     if (parser) {};
+
+     (debug_deref)
+     ? (debug_deref = 0)
+     : (debug_deref = 1);
+     DBGPrint("toggle unasm debug display (%s)\n",
+				  debug_deref ? "ON" : "OFF");
+     return TRUE;
+}
+
+// .TD
+
+ULONG ProcessTDToggle(BYTE *cmd,
+		   StackFrame *stackFrame, ULONG Exception,
+		   DEBUGGER_PARSER *parser)
+{
+     if (cmd) {};
+     if (stackFrame) {};
+     if (Exception) {};
+     if (parser) {};
+
+     (full_deref_toggle)
+     ? (full_deref_toggle = 0)
+     : (full_deref_toggle = 1);
+     DBGPrint("toggle full dereferencing info (%s) \n",
+					    full_deref_toggle ? "ON" : "OFF");
+     return TRUE;
+}
+
+
+// .TL
+
+ULONG ProcessTLToggle(BYTE *cmd,
+		   StackFrame *stackFrame, ULONG Exception,
+		   DEBUGGER_PARSER *parser)
+{
+     if (cmd) {};
+     if (stackFrame) {};
+     if (Exception) {};
+     if (parser) {};
+
+     (line_info_toggle)
+     ? (line_info_toggle = 0)
+     : (line_info_toggle = 1);
+     DBGPrint("toggle source line info (%s) \n",
+					    line_info_toggle ? "ON" : "OFF");
+     return TRUE;
+
+}
+
+// .TG
+
+ULONG ProcessTGToggle(BYTE *cmd,
+		   StackFrame *stackFrame, ULONG Exception,
+		   DEBUGGER_PARSER *parser)
+{
+     if (cmd) {};
+     if (stackFrame) {};
+     if (Exception) {};
+     if (parser) {};
+
+     (general_toggle)
+     ? (general_toggle = 0)
+     : (general_toggle = 1);
+     DBGPrint("toggle general registers (%s) \n",
+					    general_toggle ? "ON" : "OFF");
+     return TRUE;
+
+}
+
+// .TC
+
+ULONG ProcessTCToggle(BYTE *cmd,
+		   StackFrame *stackFrame, ULONG Exception,
+		   DEBUGGER_PARSER *parser)
+{
+     if (cmd) {};
+     if (stackFrame) {};
+     if (Exception) {};
+     if (parser) {};
+
+     (control_toggle)
+     ? (control_toggle = 0)
+     : (control_toggle = 1);
+     DBGPrint("toggle control registers (%s) \n",
+					    control_toggle ? "ON" : "OFF");
+     return TRUE;
+
+}
+
+// .TN
+
+ULONG ProcessTNToggle(BYTE *cmd,
+		   StackFrame *stackFrame, ULONG Exception,
+		   DEBUGGER_PARSER *parser)
+{
+     if (cmd) {};
+     if (stackFrame) {};
+     if (Exception) {};
+     if (parser) {};
+
+     (numeric_toggle)
+     ? (numeric_toggle = 0)
+     : (numeric_toggle = 1);
+     DBGPrint("toggle coprocessor registers (%s) \n",
+					    numeric_toggle ? "ON" : "OFF");
+     return TRUE;
+
+}
+
+// .TR
+
+ULONG ProcessTRToggle(BYTE *cmd,
+		   StackFrame *stackFrame, ULONG Exception,
+		   DEBUGGER_PARSER *parser)
+{
+     if (cmd) {};
+     if (stackFrame) {};
+     if (Exception) {};
+     if (parser) {};
+
+     (reason_toggle)
+     ? (reason_toggle = 0)
+     : (reason_toggle = 1);
+     DBGPrint("toggle display break reason (%s) \n",
+					    reason_toggle ? "ON" : "OFF");
+     return TRUE;
+
+}
+
+// .TS
+
+ULONG ProcessTSToggle(BYTE *cmd,
+		   StackFrame *stackFrame, ULONG Exception,
+		   DEBUGGER_PARSER *parser)
+{
+     if (cmd) {};
+     if (stackFrame) {};
+     if (Exception) {};
+     if (parser) {};
+
+     (segment_toggle)
+     ? (segment_toggle = 0)
+     : (segment_toggle = 1);
+     DBGPrint("toggle segment registers (%s) \n",
+					    segment_toggle ? "ON" : "OFF");
+     return TRUE;
+
+}
+
+ULONG displayDebuggerVersionHelp(BYTE *commandLine, DEBUGGER_PARSER *parser)
+{
+    if (commandLine) {}
+    if (parser) {}
+
+    DBGPrint(".v                       - display version info\n");
+    return TRUE;
+}
+
+// .V
+
+ULONG DisplayDebuggerVersion(BYTE *cmd,
+		   StackFrame *stackFrame, ULONG Exception,
+		   DEBUGGER_PARSER *parser)
+{
+     extern ULONG MajorVersion;
+     extern ULONG MinorVersion;
+     extern ULONG BuildVersion;
+
+     if (cmd) {};
+     if (stackFrame) {};
+     if (Exception) {};
+     if (parser) {};
+
+     DBGPrint("Merkey's Kernel Debugger\n");
+     DBGPrint("v%02d.%02d.%02d\n",
+              (int)MajorVersion, (int)MinorVersion, (int)BuildVersion);
+     DBGPrint("Copyright (C) 2008 Jeffrey Vernon Merkey.  "
+              "All Rights Reserved.\n");
+
+     return TRUE;
+}
+
+// .Z
+
+ULONG displaySymbolsHelp(BYTE *commandLine, DEBUGGER_PARSER *parser)
+{
+    if (commandLine) {}
+    if (parser) {}
+
+    DBGPrint(".z <name>                  - display symbol info\n");
+    return TRUE;
+}
+
+ULONG displaySymbols(BYTE *cmd,
+		    StackFrame *stackFrame, ULONG Exception,
+		    DEBUGGER_PARSER *parser)
+{
+     extern void DumpOSSymbolTableMatch(BYTE *);
+
+     if (cmd) {};
+     if (stackFrame) {};
+     if (Exception) {};
+     if (parser) {};
+
+     cmd = &cmd[parser->debugCommandNameLength];
+     while (*cmd && *cmd == ' ') cmd++;
+
+     if (*cmd)
+	DumpOSSymbolTableMatch(cmd);
+     else
+	DumpOSSymbolTableMatch(NULL);
+
+     return TRUE;
+}
+
+// LCPU
+
+ULONG listProcessors(BYTE *cmd,
+		    StackFrame *stackFrame, ULONG Exception,
+		    DEBUGGER_PARSER *parser)
+{
+     register int i;
+
+     if (cmd) {};
+     if (stackFrame) {};
+     if (Exception) {};
+     if (parser) {};
+
+     cmd = &cmd[parser->debugCommandNameLength];
+     while (*cmd && *cmd == ' ') cmd++;
+
+     DBGPrint("Current Processor: %d\n", smp_processor_id());
+     DBGPrint("Active Processors: \n");
+     for (i=0; i < MAX_PROCESSORS; i++)
+     {
+        if (cpu_online(i))
+	   DBGPrint("   Processor %d\n", i);
+     }
+     return TRUE;
+
+}
+
+ULONG clearScreenHelp(BYTE *commandLine, DEBUGGER_PARSER *parser)
+{
+    if (commandLine) {}
+    if (parser) {}
+
+    DBGPrint("cls                      - clear the screen\n");
+    return TRUE;
+}
+
+// CLS
+
+ULONG clearDebuggerScreen(BYTE *cmd,
+			 StackFrame *stackFrame, ULONG Exception,
+			 DEBUGGER_PARSER *parser)
+{
+     extern void ClearScreen(void);
+
+     if (cmd) {};
+     if (stackFrame) {};
+     if (Exception) {};
+     if (parser) {};
+
+     ClearScreen();
+     return TRUE;
+
+}
+
+ULONG SearchMemoryHelp(BYTE *commandLine, DEBUGGER_PARSER *parser)
+{
+    if (commandLine) {}
+    if (parser) {}
+
+    DBGPrint("sb                       - search for bytes at address\n");
+    DBGPrint("sw                       - search for words at address\n");
+    DBGPrint("sd                       - search for dwords at address\n");
+    return TRUE;
+}
+
+// S
+
+// use local storage and reduce stack space use.  these functions are always
+// called single threaded from the console
+
+BYTE s_changeBuffer[16];
+BYTE b_searchBuffer[16];
+BYTE b_copyBuffer[16];
+WORD w_searchBuffer[16];
+WORD w_copyBuffer[16];
+ULONG d_searchBuffer[16];
+ULONG d_copyBuffer[16];
+
+ULONG SearchMemory(BYTE *cmd,
+	       StackFrame *stackFrame, ULONG Exception,
+	       DEBUGGER_PARSER *parser)
+{
+     BYTE *changeBuffer = s_changeBuffer;
+     BYTE *searchBuffer = b_searchBuffer;
+     BYTE *copyBuffer = b_copyBuffer;
+     ULONG maxlen = sizeof(searchBuffer);
+     register BYTE *changeB;
+     BYTE *pB;
+     register ULONG address, r, value, count, len, i;
+     ULONG valid, EndingAddress = (ULONG)high_memory;
+     register int key;
+     extern int mdb_getkey(void);
+
+     if (cmd) {};
+     if (stackFrame) {};
+     if (Exception) {};
+     if (parser) {};
+
+     cmd = &cmd[parser->debugCommandNameLength];
+     while (*cmd && *cmd == ' ') cmd++;
+
+     memset((ULONG *)searchBuffer, 0, sizeof(searchBuffer));
+     count = 0;
+     changeB = (BYTE *) searchBuffer;
+     changeBuffer[0] = '\0';
+     DBGPrint("enter bytes to search for, '.' to end input\n");
+     while ((changeBuffer[0] != '.') && (count < maxlen))
+     {
+	for (r=0; r < 8; r++)
+	{
+	   DBGPrint("0x");
+
+	   ScreenInputFromKeyboard(&changeBuffer[0], 0, 4);
+
+	   if ((changeBuffer[0] == '.') || (changeBuffer[1] == '.'))
+	      break;
+
+	   pB = (BYTE *) &changeBuffer[0];
+	   len = strlen(pB);
+
+	   for (i=0; i < len; i++)
+	      DBGPrint("\b");
+
+	   value = EvaluateExpression(0, &pB, &valid);
+	   if (valid)
+	      *changeB = (BYTE) value;
+	   DBGPrint("%02X ", (BYTE) *changeB);
+
+	   changeB++;
+	   if (count++ > maxlen)
+	      break;
+	}
+	if (DBGPrint("\n")) return TRUE;
+     }
+
+     if (count)
+     {
+	DBGPrint("enter start address for search:  ");
+	ScreenInputFromKeyboard(&changeBuffer[0], 0, 16);
+	pB = (BYTE *) &changeBuffer[0];
+	address = EvaluateExpression(0, &pB, &valid);
+	if (valid)
+	{
+	   register ULONG temp;
+
+	   DBGPrint("start address = [%08X]\n", (unsigned)address);
+	   DBGPrint("enter ending address for search:  ");
+
+	   ScreenInputFromKeyboard(&changeBuffer[0], 0, 16);
+	   pB = (BYTE *) &changeBuffer[0];
+	   temp = EvaluateExpression(0, &pB, &valid);
+	   if (valid)
+	      EndingAddress = temp;
+
+	   DBGPrint("\nsearching memory from 0x%08X to 0x%08X\n",
+                    (unsigned)address, (unsigned)EndingAddress);
+	   while (address < EndingAddress)
+	   {
+              read_memory((void *)address, copyBuffer, count);
+	      if (!memcmp(searchBuffer, copyBuffer, count))
+	      {
+		 if (DBGPrint("match at address [%08X]\n",
+                     (unsigned)address)) return TRUE;
+		 if (dumpSearchResults((BYTE *)address, 4)) return TRUE;
+		 if (DBGPrint("searching\n")) return TRUE;
+	      }
+	      address++;
+	      if (!(address % 0x100000))
+	      {
+		  if (DBGPrint("searching memory at address 0x%08X ..."
+                        " Q or q to abort - any key to proceed\n",
+                                (unsigned)address)) return TRUE;
+                  key = mdb_getkey();
+                  if (((char)key == 'Q') || ((char)key == 'q'))
+                     break;
+	      }
+	   }
+	   if (DBGPrint("search completed.\n")) return TRUE;
+	   return TRUE;
+	}
+	if (DBGPrint("invalid start address\n")) return TRUE;
+	return TRUE;
+     }
+     if (DBGPrint("no search pattern\n")) return TRUE;
+     return TRUE;
+
+}
+
+// SB
+
+ULONG SearchMemoryB(BYTE *cmd,
+	       StackFrame *stackFrame, ULONG Exception,
+	       DEBUGGER_PARSER *parser)
+{
+     BYTE *changeBuffer = s_changeBuffer;
+     BYTE *searchBuffer = b_searchBuffer;
+     BYTE *copyBuffer = b_copyBuffer;
+     ULONG maxlen = sizeof(searchBuffer);
+     register BYTE *changeB;
+     BYTE *pB;
+     register ULONG address, r, value, count, len, i;
+     ULONG valid, EndingAddress = (ULONG)high_memory;
+     register int key;
+     extern int mdb_getkey(void);
+
+     if (cmd) {};
+     if (stackFrame) {};
+     if (Exception) {};
+     if (parser) {};
+
+     cmd = &cmd[parser->debugCommandNameLength];
+     while (*cmd && *cmd == ' ') cmd++;
+
+     memset((ULONG *)searchBuffer, 0, sizeof(searchBuffer));
+     count = 0;
+     changeB = (BYTE *) searchBuffer;
+     changeBuffer[0] = '\0';
+     DBGPrint("enter bytes to search for, '.' to end input\n");
+     while (changeBuffer[0] != '.' && count < maxlen)
+     {
+	for (r=0; r < 8; r++)
+	{
+	   DBGPrint("0x");
+
+	   ScreenInputFromKeyboard(&changeBuffer[0], 0, 4);
+
+	   if ((changeBuffer[0] == '.') || (changeBuffer[1] == '.'))
+	      break;
+
+	   pB = (BYTE *) &changeBuffer[0];
+	   len = strlen(pB);
+	   for (i=0; i < len; i++)
+	      DBGPrint("\b");
+
+	   value = EvaluateExpression(0, &pB, &valid);
+	   if (valid)
+	      *changeB = (BYTE) value;
+	   DBGPrint("%02X ", (BYTE) *changeB);
+
+	   changeB++;
+	   if (count++ > maxlen)
+	      break;
+	}
+	if (DBGPrint("\n")) return TRUE;
+     }
+
+     if (count)
+     {
+	DBGPrint("enter start address for search:  ");
+	ScreenInputFromKeyboard(&changeBuffer[0], 0, 16);
+	pB = (BYTE *) &changeBuffer[0];
+	address = EvaluateExpression(0, &pB, &valid);
+	if (valid)
+	{
+	   register ULONG temp;
+
+	   DBGPrint("start address = [%08X]\n", (unsigned)address);
+
+	   DBGPrint("enter ending address for search:  ");
+	   ScreenInputFromKeyboard(&changeBuffer[0], 0, 16);
+	   pB = (BYTE *) &changeBuffer[0];
+	   temp = EvaluateExpression(0, &pB, &valid);
+	   if (valid)
+	      EndingAddress = temp;
+
+	   DBGPrint("\nsearching memory from 0x%08X to 0x%08X\n",
+                    (unsigned)address, (unsigned)EndingAddress);
+	   while (address < EndingAddress)
+	   {
+              read_memory((void *)address, copyBuffer, count);
+	      if (!memcmp(searchBuffer, copyBuffer, count))
+	      {
+		 if (DBGPrint("match at address [%08X]\n",
+                     (unsigned)address)) return TRUE;
+		 if (dumpSearchResults((BYTE *)address, 4)) return TRUE;
+		 if (DBGPrint("searching\n")) return TRUE;
+	      }
+	      address++;
+	      if (!(address % 0x100000))
+	      {
+		 if (DBGPrint("searching memory at address 0x%08X ..."
+                        " Q or q to abort - any key to proceed\n",
+                              (unsigned)address)) return TRUE;
+                 key = mdb_getkey();
+                 if (((char)key == 'Q') || ((char)key == 'q'))
+                    break;
+	      }
+	   }
+	   if (DBGPrint("search completed.\n")) return TRUE;
+	   return TRUE;
+	}
+	if (DBGPrint("invalid start address\n")) return TRUE;
+	return TRUE;
+     }
+     if (DBGPrint("no search pattern\n")) return TRUE;
+     return TRUE;
+}
+
+// SW
+
+ULONG SearchMemoryW(BYTE *cmd,
+	       StackFrame *stackFrame, ULONG Exception,
+	       DEBUGGER_PARSER *parser)
+{
+     BYTE *changeBuffer = s_changeBuffer;
+     WORD *searchBuffer = w_searchBuffer;
+     WORD *copyBuffer = w_copyBuffer;
+     ULONG maxlen = sizeof(searchBuffer) / sizeof(WORD);
+     register WORD *changeW;
+     BYTE *pB;
+     register ULONG address, r, value, count, len, i;
+     ULONG valid, EndingAddress = (ULONG)high_memory;
+     register int key;
+     extern int mdb_getkey(void);
+
+     if (cmd) {};
+     if (stackFrame) {};
+     if (Exception) {};
+     if (parser) {};
+
+     cmd = &cmd[parser->debugCommandNameLength];
+     while (*cmd && *cmd == ' ') cmd++;
+
+     memset((ULONG *)searchBuffer, 0, sizeof(searchBuffer));
+     count = 0;
+     changeW = (WORD *) searchBuffer;
+     changeBuffer[0] = '\0';
+     DBGPrint("enter words to search for, '.' to end input\n");
+     while (changeBuffer[0] != '.' && count < maxlen)
+     {
+	for (r=0; r < 4; r++)
+	{
+	   DBGPrint("0x");
+
+	   ScreenInputFromKeyboard(&changeBuffer[0], 0, 6);
+
+	   if ((changeBuffer[0] == '.') || (changeBuffer[1] == '.') ||
+	       (changeBuffer[2] == '.') || (changeBuffer[3] == '.'))
+	      break;
+
+	   pB = (BYTE *) &changeBuffer[0];
+	   len = strlen(pB);
+	   for (i=0; i < len; i++)
+	      DBGPrint("\b");
+
+	   value = EvaluateExpression(0, &pB, &valid);
+	   if (valid)
+	      *changeW = value;
+	   DBGPrint("%04X ", *changeW);
+
+	   changeW++;
+	   if (count++ > maxlen)
+	      break;
+	}
+	if (DBGPrint("\n")) return TRUE;
+     }
+
+     if (count)
+     {
+	DBGPrint("enter start address for search:  ");
+	ScreenInputFromKeyboard(&changeBuffer[0], 0, 16);
+	pB = (BYTE *) &changeBuffer[0];
+	address = EvaluateExpression(0, &pB, &valid);
+	if (valid)
+	{
+	   register ULONG temp;
+
+	   DBGPrint("start address = [%08X]\n", (unsigned)address);
+
+	   DBGPrint("enter ending address for search:  ");
+	   ScreenInputFromKeyboard(&changeBuffer[0], 0, 16);
+	   pB = (BYTE *) &changeBuffer[0];
+	   temp = EvaluateExpression(0, &pB, &valid);
+	   if (valid)
+	      EndingAddress = temp;
+
+	   DBGPrint("searching memory from 0x%08X to 0x%08X\n",
+                    (unsigned)address, (unsigned)EndingAddress);
+	   while (address < EndingAddress)
+	   {
+              read_memory((void *)address, copyBuffer, count *
sizeof(WORD));
+	      if (!memcmp(searchBuffer, copyBuffer, count * sizeof(WORD)))
+	      {
+		 if (DBGPrint("match at address [%08X]\n",
+                     (unsigned)address)) return TRUE;
+		 if (dumpWordSearchResults((BYTE *)address, 4))
+                     return TRUE;
+		 if (DBGPrint("searching\n")) return TRUE;;
+	      }
+	      address++;
+	      if (!(address % 0x100000))
+	      {
+		 if (DBGPrint("searching memory at address 0x%08X ..."
+                        " Q or q to abort - any key to proceed\n",
+                              (unsigned)address)) return TRUE;
+                  key = mdb_getkey();
+                  if (((char)key == 'Q') || ((char)key == 'q'))
+                     break;
+	      }
+	   }
+	   if (DBGPrint("search completed.\n")) return TRUE;
+	   return TRUE;
+	}
+	if (DBGPrint("invalid start address\n")) return TRUE;
+	return TRUE;
+     }
+     if (DBGPrint("no search pattern\n")) return TRUE;
+     return TRUE;
+}
+
+// SD
+
+ULONG SearchMemoryD(BYTE *cmd,
+	       StackFrame *stackFrame, ULONG Exception,
+	       DEBUGGER_PARSER *parser)
+{
+     register BYTE *changeBuffer = s_changeBuffer;
+     register ULONG *searchBuffer = d_searchBuffer;
+     register ULONG *copyBuffer = d_copyBuffer;
+     register ULONG maxlen = sizeof(searchBuffer) / sizeof(ULONG);
+     register ULONG *changeD;
+     BYTE *pB;
+     register ULONG address, r, value, count, len, i;
+     ULONG valid, EndingAddress = (ULONG)high_memory;
+     register int key;
+     extern int mdb_getkey(void);
+
+     if (cmd) {};
+     if (stackFrame) {};
+     if (Exception) {};
+     if (parser) {};
+
+     cmd = &cmd[parser->debugCommandNameLength];
+     while (*cmd && *cmd == ' ') cmd++;
+
+     memset((ULONG *)searchBuffer, 0, sizeof(searchBuffer));
+     count = 0;
+     changeD = (ULONG *) searchBuffer;
+     changeBuffer[0] = '\0';
+     DBGPrint("enter dwords to search for, '.' to end input\n");
+     while (changeBuffer[0] != '.' && count < maxlen)
+     {
+	for (r=0; r < 2; r++)
+	{
+	   DBGPrint("0x");
+
+	   ScreenInputFromKeyboard(&changeBuffer[0], 0, 8);
+
+	   if ((changeBuffer[0] == '.') || (changeBuffer[1] == '.') ||
+	       (changeBuffer[2] == '.') || (changeBuffer[3] == '.') ||
+	       (changeBuffer[4] == '.') || (changeBuffer[5] == '.') ||
+	       (changeBuffer[6] == '.') || (changeBuffer[7] == '.'))
+	      break;
+
+	   pB = (BYTE *) &changeBuffer[0];
+	   len = strlen(pB);
+	   for (i=0; i < len; i++)
+	      DBGPrint("\b");
+
+	   value = EvaluateExpression(0, &pB, &valid);
+	   if (valid)
+	      *changeD = value;
+	   DBGPrint("%08X ", (unsigned)*changeD);
+
+	   changeD++;
+	   if (count++ > maxlen)
+	      break;
+	}
+	if (DBGPrint("\n")) return TRUE;
+     }
+
+     if (count)
+     {
+	DBGPrint("enter start address for search:  ");
+	ScreenInputFromKeyboard(&changeBuffer[0], 0, 16);
+	pB = (BYTE *) &changeBuffer[0];
+	address = EvaluateExpression(0, &pB, &valid);
+	if (valid)
+	{
+	   register ULONG temp;
+
+	   DBGPrint("start address = [%08X]\n", (unsigned)address);
+
+	   DBGPrint("enter ending address for search:  ");
+	   ScreenInputFromKeyboard(&changeBuffer[0], 0, 16);
+	   pB = (BYTE *) &changeBuffer[0];
+	   temp = EvaluateExpression(0, &pB, &valid);
+	   if (valid)
+	      EndingAddress = temp;
+
+	   DBGPrint("searching memory from 0x%08X to 0x%08X\n",
+                    (unsigned)address, (unsigned)EndingAddress);
+	   while (address < EndingAddress)
+	   {
+              read_memory((void *)address, copyBuffer, count *
sizeof(ULONG));
+	      if (!memcmp(searchBuffer, copyBuffer, count * sizeof(ULONG)))
+	      {
+		 if (DBGPrint("match at address [%08X]\n",
+                     (unsigned)address)) return TRUE;
+		 if (dumpDoubleSearchResults((BYTE *)address, 4))
+                     return TRUE;
+		 if (DBGPrint("searching\n")) return TRUE;
+	      }
+	      address++;
+	      if (!(address % 0x100000))
+	      {
+		 if (DBGPrint("searching memory at address 0x%08X ..."
+                        " Q or q to abort - any key to proceed\n",
+                              (unsigned)address)) return TRUE;
+                  key = mdb_getkey();
+                  if (((char)key == 'Q') || ((char)key == 'q'))
+                     break;
+	      }
+	   }
+	   if (DBGPrint("search completed.\n")) return TRUE;
+	   return TRUE;
+	}
+	if (DBGPrint("invalid start address\n")) return TRUE;
+	return TRUE;
+     }
+     if (DBGPrint("no search pattern\n")) return TRUE;
+     return TRUE;
+}
+
+
+ULONG changeMemoryHelp(BYTE *commandLine, DEBUGGER_PARSER *parser)
+{
+    if (commandLine) {}
+    if (parser) {}
+
+    DBGPrint("c   <address>            - change bytes at address\n");
+    DBGPrint("cb  <address>            - change bytes at address\n");
+    DBGPrint("cw  <address>            - change words at address\n");
+    DBGPrint("cd  <address>            - change dwords at address\n");
+    return TRUE;
+}
+
+// CW
+
+ULONG changeWordValue(BYTE *cmd,
+	       StackFrame *stackFrame, ULONG Exception,
+	       DEBUGGER_PARSER *parser)
+{
+     register BYTE *changeBuffer = &workbuf[0][0];
+     register WORD *changeW, oldW;
+     BYTE *pB;
+     register ULONG address, r, value, len, i;
+     ULONG valid;
+
+     if (cmd) {};
+     if (stackFrame) {};
+     if (Exception) {};
+     if (parser) {};
+
+     cmd = &cmd[parser->debugCommandNameLength];
+     while (*cmd && *cmd == ' ') cmd++;
+
+     address = EvaluateExpression(stackFrame, &cmd, &valid);
+     if (valid)
+     {
+	changeW = (WORD *) address;
+	changeBuffer[0] = '\0';
+	DBGPrint("enter new value, <enter> to skip, or '.' to exit\n");
+	while (changeBuffer[0] != '.')
+	{
+	   DBGPrint("[%08X] ", (unsigned)changeW);
+	   for (r=0; r < 4; r++)
+	   {
+	      oldW = (WORD) mdb_getword((ULONG)changeW, 2);
+	      DBGPrint("(%04X)=", (unsigned) oldW);
+
+              ScreenInputFromKeyboard(&changeBuffer[0], 0, 6);
+
+	      if ((changeBuffer[0] == '.') || (changeBuffer[1] == '.') ||
+		  (changeBuffer[2] == '.') || (changeBuffer[3] == '.'))
+		 break;
+	      pB = (BYTE *) &changeBuffer[0];
+	      len = strlen(pB);
+
+	      for (i=0; i < len; i++)
+		 DBGPrint("\b");
+
+	      value = EvaluateExpression(0, &pB, &valid);
+	      if (valid)
+		 mdb_putword((ULONG)changeW, value, 2);
+	      DBGPrint("%04X ", (unsigned) mdb_getword((ULONG)changeW, 2));
+	      changeW++;
+	   }
+	   if (DBGPrint("\n")) return TRUE;
+	}
+	return TRUE;
+     }
+     DBGPrint("invalid change (word) address\n");
+     return TRUE;
+}
+
+// CD
+
+ULONG changeDoubleValue(BYTE *cmd,
+	       StackFrame *stackFrame, ULONG Exception,
+	       DEBUGGER_PARSER *parser)
+{
+     register BYTE *changeBuffer = &workbuf[0][0];
+     register ULONG *changeD, oldD;
+     register ULONG address, r, value, len, i;
+     BYTE *pB;
+     ULONG valid;
+
+     if (cmd) {};
+     if (stackFrame) {};
+     if (Exception) {};
+     if (parser) {};
+
+     cmd = &cmd[parser->debugCommandNameLength];
+     while (*cmd && *cmd == ' ') cmd++;
+
+     address = EvaluateExpression(stackFrame, &cmd, &valid);
+     if (valid)
+     {
+	changeD = (ULONG *) address;
+	changeBuffer[0] = '\0';
+	DBGPrint("enter new value, <enter> to skip, or '.' to exit\n");
+	while (changeBuffer[0] != '.')
+	{
+	   DBGPrint("[%08X] ", (unsigned)changeD);
+	   for (r=0; r < 2; r++)
+	   {
+	      oldD = (ULONG) mdb_getword((ULONG)changeD, 4);
+	      DBGPrint("(%08X)=", (unsigned) oldD);
+
+	      ScreenInputFromKeyboard(&changeBuffer[0], 0, 8);
+
+	      if ((changeBuffer[0] == '.') || (changeBuffer[1] == '.') ||
+		  (changeBuffer[2] == '.') || (changeBuffer[3] == '.') ||
+		  (changeBuffer[4] == '.') || (changeBuffer[5] == '.') ||
+		  (changeBuffer[6] == '.') || (changeBuffer[7] == '.'))
+		 break;
+
+	      pB = (BYTE *) &changeBuffer[0];
+	      len = strlen(pB);
+
+	      for (i=0; i < len; i++)
+		 DBGPrint("\b");
+
+	      value = EvaluateExpression(0, &pB, &valid);
+	      if (valid)
+		 mdb_putword((ULONG)changeD, value, 4);
+	      DBGPrint("%08X ", (unsigned)mdb_getword((ULONG)changeD, 4));
+	      changeD++;
+	   }
+	   if (DBGPrint("\n")) return TRUE;
+	}
+	return TRUE;
+     }
+     DBGPrint("invalid change (dword) address\n");
+     return TRUE;
+}
+
+// CB
+
+ULONG changeByteValue(BYTE *cmd,
+	       StackFrame *stackFrame, ULONG Exception,
+	       DEBUGGER_PARSER *parser)
+{
+     BYTE *changeBuffer = &workbuf[0][0];
+     register BYTE *changeB, oldB;
+     BYTE *pB;
+     register ULONG address, r, value, len, i;
+     ULONG valid;
+
+     if (cmd) {};
+     if (stackFrame) {};
+     if (Exception) {};
+     if (parser) {};
+
+     cmd = &cmd[parser->debugCommandNameLength];
+     while (*cmd && *cmd == ' ') cmd++;
+
+     address = EvaluateExpression(stackFrame, &cmd, &valid);
+     if (valid)
+     {
+	changeB = (BYTE *) address;
+	changeBuffer[0] = '\0';
+	DBGPrint("enter new value, <enter> to skip, or '.' to exit\n");
+	while (changeBuffer[0] != '.')
+	{
+	   DBGPrint("[%08X] ", (unsigned)changeB);
+	   for (r=0; r < 8; r++)
+	   {
+	      oldB = (BYTE) mdb_getword((ULONG)changeB, 1);
+	      DBGPrint("(%02X)=", (unsigned) oldB);
+
+	      ScreenInputFromKeyboard(&changeBuffer[0], 0, 4);
+
+	      if ((changeBuffer[0] == '.') || (changeBuffer[1] == '.'))
+		 break;
+
+	      pB = (BYTE *) &changeBuffer[0];
+	      len = strlen(pB);
+	      for (i=0; i < len; i++)
+		 DBGPrint("\b");
+
+	      value = EvaluateExpression(0, &pB, &valid);
+	      if (valid)
+		 mdb_putword((ULONG)changeB, value, 1);
+	      DBGPrint("%02X ", (BYTE) mdb_getword((ULONG)changeB, 1));
+	      changeB++;
+	   }
+	   if (DBGPrint("\n")) return TRUE;
+	}
+	return TRUE;
+     }
+     DBGPrint("invalid change (byte) address\n");
+     return TRUE;
+}
+
+// C
+
+ULONG changeDefaultValue(BYTE *cmd,
+			StackFrame *stackFrame, ULONG Exception,
+			DEBUGGER_PARSER *parser)
+{
+     BYTE *changeBuffer = &workbuf[0][0];
+     register BYTE *changeB, oldB;
+     BYTE *pB;
+     register ULONG address, r, value, len, i;
+     ULONG valid;
+
+     if (cmd) {};
+     if (stackFrame) {};
+     if (Exception) {};
+     if (parser) {};
+
+     cmd = &cmd[parser->debugCommandNameLength];
+     while (*cmd && *cmd == ' ') cmd++;
+
+     address = EvaluateExpression(stackFrame, &cmd, &valid);
+     if (valid)
+     {
+	changeB = (BYTE *) address;
+	changeBuffer[0] = '\0';
+	DBGPrint("enter new value, <enter> to skip, or '.' to exit\n");
+	while (changeBuffer[0] != '.')
+	{
+	   DBGPrint("[%08X] ", (unsigned)changeB);
+	   for (r=0; r < 8; r++)
+	   {
+	      oldB = (BYTE) mdb_getword((ULONG)changeB, 1);
+	      DBGPrint("(%02X)=", (BYTE) oldB);
+
+	      ScreenInputFromKeyboard(&changeBuffer[0], 0, 4);
+
+	      if ((changeBuffer[0] == '.') || (changeBuffer[1] == '.'))
+		 break;
+
+	      pB = (BYTE *) &changeBuffer[0];
+	      len = strlen(pB);
+
+	      for (i=0; i < len; i++)
+		 DBGPrint("\b");
+
+	      value = EvaluateExpression(0, &pB, &valid);
+	      if (valid)
+		 mdb_putword((ULONG)changeB, value, 1);
+	      DBGPrint("%02X ", (BYTE) mdb_getword((ULONG)changeB, 1));
+	      changeB++;
+	   }
+	   if (DBGPrint("\n")) return TRUE;
+	}
+	return TRUE;
+     }
+     DBGPrint("invalid change (byte) address\n");
+     return TRUE;
+
+}
+
+ULONG displayCloseHelp(BYTE *commandLine, DEBUGGER_PARSER *parser)
+{
+    if (commandLine) {}
+    if (parser) {}
+
+    DBGPrint("?   <address>            - display closest symbols to
<address>\n");
+    return TRUE;
+
+}
+
+// ?
+
+ULONG displayCloseSymbols(BYTE *cmd,
+			 StackFrame *stackFrame, ULONG Exception,
+			 DEBUGGER_PARSER *parser)
+{
+     register ULONG oldD;
+     ULONG valid;
+
+     if (cmd) {};
+     if (stackFrame) {};
+     if (Exception) {};
+     if (parser) {};
+
+     cmd = &cmd[parser->debugCommandNameLength];
+     while (*cmd && *cmd == ' ') cmd++;
+
+     oldD = EvaluateExpression(stackFrame, &cmd, &valid);
+     if (!valid)
+	oldD = GetIP(stackFrame);
+     DisplayClosestSymbol(oldD);
+     return TRUE;
+
+}
+
+ULONG debuggerWalkStack(BYTE *cmd,
+		       StackFrame *stackFrame, ULONG Exception,
+		       DEBUGGER_PARSER *parser)
+{
+     ULONG valid;
+
+     if (cmd) {};
+     if (stackFrame) {};
+     if (Exception) {};
+     if (parser) {};
+
+     cmd = &cmd[parser->debugCommandNameLength];
+     while (*cmd && *cmd == ' ') cmd++;
+
+     if (repeatCommand)
+     {
+	lastDumpAddress = dumpStack(stackFrame,
+                          (BYTE *)lastDumpAddress, lastDisplayLength);
+	return TRUE;
+     }
+     lastDumpAddress = (BYTE *) EvaluateExpression(stackFrame, &cmd,
&valid);
+     if (!valid)
+	lastDumpAddress = (BYTE *) GetStackAddress(stackFrame);
+     displayLength = EvaluateExpression(stackFrame, &cmd, &valid);
+     if (!displayLength || displayLength > 20)
+	displayLength = 20;
+     lastDumpAddress = dumpStack(stackFrame, (BYTE *)lastDumpAddress,
displayLength);
+     return TRUE;
+
+}
+
+ULONG displayDumpHelp(BYTE *commandLine, DEBUGGER_PARSER *parser)
+{
+    if (commandLine) {}
+    if (parser) {}
+
+    DBGPrint("d   <address> <#lines>   - dump memory as bytes\n");
+    DBGPrint("dw  <address> <#lines>   - dump memory as words\n");
+    DBGPrint("dd  <address> <#lines>   - dump memory as double words\n");
+    DBGPrint("dl  <address> <#lines>   - dump linked list\n");
+    DBGPrint("ds  <address> <#lines>   - dump stack\n");
+    DBGPrint("dds <address> <#lines>   - dump stack double word\n");
+    DBGPrint("w   <address>            - display symbols on the stack\n");
+
+    return TRUE;
+}
+
+// DL
+
+ULONG debuggerDumpLinkedList(BYTE *cmd,
+			    StackFrame *stackFrame, ULONG Exception,
+			    DEBUGGER_PARSER *parser)
+{
+     ULONG valid;
+     extern volatile BYTE *lastLinkAddress;
+
+     if (cmd) {};
+     if (stackFrame) {};
+     if (Exception) {};
+     if (parser) {};
+
+     cmd = &cmd[parser->debugCommandNameLength];
+     while (*cmd && *cmd == ' ') cmd++;
+
+     if (repeatCommand)
+     {
+	lastLinkAddress = dumpLinkedList((BYTE *)lastLinkAddress,
lastDisplayLength, 0);
+	return TRUE;
+     }
+
+     lastLinkAddress = (BYTE *) EvaluateNumericExpression(stackFrame, &cmd,
+                                                          &valid);
+     if (!valid)
+	lastLinkAddress = (BYTE *) GetStackAddress(stackFrame);
+
+     displayLength = EvaluateNumericExpression(stackFrame, &cmd, &valid);
+     if (!displayLength || displayLength > 20)
+	displayLength = 20;
+
+     lastLinkAddress = dumpLinkedList((BYTE *)lastLinkAddress,
displayLength, 0);
+
+     return TRUE;
+
+}
+
+// DW
+
+ULONG debuggerDumpWord(BYTE *cmd,
+		      StackFrame *stackFrame, ULONG Exception,
+		      DEBUGGER_PARSER *parser)
+{
+     ULONG valid;
+
+     if (cmd) {};
+     if (stackFrame) {};
+     if (Exception) {};
+     if (parser) {};
+
+     cmd = &cmd[parser->debugCommandNameLength];
+     while (*cmd && *cmd == ' ') cmd++;
+
+     if (repeatCommand)
+     {
+	lastDumpAddress = dumpWord((BYTE *)lastDumpAddress, lastDisplayLength);
+	return TRUE;
+     }
+     lastDumpAddress = (BYTE *) EvaluateExpression(stackFrame, &cmd,
&valid);
+     if (!valid)
+	lastDumpAddress = (BYTE *) GetStackAddress(stackFrame);
+     displayLength = EvaluateExpression(stackFrame, &cmd, &valid);
+     if (!displayLength || displayLength > 20)
+	displayLength = 20;
+     lastDumpAddress = dumpWord((BYTE *)lastDumpAddress, displayLength);
+     return TRUE;
+}
+
+// DS
+
+ULONG debuggerDumpStack(BYTE *cmd,
+		       StackFrame *stackFrame, ULONG Exception,
+		       DEBUGGER_PARSER *parser)
+{
+     ULONG valid;
+
+     if (cmd) {};
+     if (stackFrame) {};
+     if (Exception) {};
+     if (parser) {};
+
+     cmd = &cmd[parser->debugCommandNameLength];
+     while (*cmd && *cmd == ' ') cmd++;
+
+     if (repeatCommand)
+     {
+	lastDumpAddress = dumpStack(stackFrame, (BYTE *)lastDumpAddress,
lastDisplayLength);
+	return TRUE;
+     }
+     lastDumpAddress = (BYTE *) EvaluateExpression(stackFrame, &cmd,
&valid);
+     if (!valid)
+	lastDumpAddress = (BYTE *) GetStackAddress(stackFrame);
+     displayLength = EvaluateExpression(stackFrame, &cmd, &valid);
+     if (!displayLength || displayLength > 20)
+	displayLength = 20;
+     lastDumpAddress = dumpStack(stackFrame, (BYTE *)lastDumpAddress,
displayLength);
+     return TRUE;
+
+}
+
+// DDS
+
+ULONG debuggerDumpDoubleStack(BYTE *cmd,
+			     StackFrame *stackFrame, ULONG Exception,
+			     DEBUGGER_PARSER *parser)
+{
+     ULONG valid;
+
+     if (cmd) {};
+     if (stackFrame) {};
+     if (Exception) {};
+     if (parser) {};
+
+     cmd = &cmd[parser->debugCommandNameLength];
+     while (*cmd && *cmd == ' ') cmd++;
+
+     if (repeatCommand)
+     {
+	lastDumpAddress = dumpDoubleStack(stackFrame, (BYTE *)lastDumpAddress,
+						    lastDisplayLength);
+	return TRUE;
+     }
+     lastDumpAddress = (BYTE *) EvaluateExpression(stackFrame, &cmd,
&valid);
+     if (!valid)
+	lastDumpAddress = (BYTE *) GetStackAddress(stackFrame);
+     displayLength = EvaluateExpression(stackFrame, &cmd, &valid);
+     if (!displayLength || displayLength > 20)
+	displayLength = 20;
+     lastDumpAddress = dumpDoubleStack(stackFrame, (BYTE *)lastDumpAddress,
+						    displayLength);
+     return TRUE;
+
+}
+
+// DD
+
+ULONG debuggerDumpDouble(BYTE *cmd,
+			StackFrame *stackFrame, ULONG Exception,
+			DEBUGGER_PARSER *parser)
+{
+     ULONG valid;
+
+     if (cmd) {};
+     if (stackFrame) {};
+     if (Exception) {};
+     if (parser) {};
+
+     cmd = &cmd[parser->debugCommandNameLength];
+     while (*cmd && *cmd == ' ') cmd++;
+
+     if (repeatCommand)
+     {
+	lastDumpAddress = dumpDouble((BYTE *)lastDumpAddress, lastDisplayLength);
+	return TRUE;
+     }
+     lastDumpAddress = (BYTE *) EvaluateExpression(stackFrame, &cmd,
&valid);
+     if (!valid)
+	lastDumpAddress = (BYTE *) GetStackAddress(stackFrame);
+     displayLength = EvaluateExpression(stackFrame, &cmd, &valid);
+     if (!displayLength || displayLength > 20)
+	displayLength = 20;
+     lastDumpAddress = dumpDouble((BYTE *)lastDumpAddress, displayLength);
+     return TRUE;
+
+}
+
+// D
+
+ULONG debuggerDumpByte(BYTE *cmd,
+		      StackFrame *stackFrame, ULONG Exception,
+		      DEBUGGER_PARSER *parser)
+{
+     ULONG valid;
+
+     if (cmd) {};
+     if (stackFrame) {};
+     if (Exception) {};
+     if (parser) {};
+
+     cmd = &cmd[parser->debugCommandNameLength];
+     while (*cmd && *cmd == ' ') cmd++;
+
+     if (repeatCommand)
+     {
+	lastDumpAddress = dump((BYTE *)lastDumpAddress, lastDisplayLength);
+	return TRUE;
+     }
+     lastDumpAddress = (BYTE *) EvaluateExpression(stackFrame, &cmd,
&valid);
+     if (!valid)
+	lastDumpAddress = (BYTE *) GetStackAddress(stackFrame);
+     displayLength = EvaluateExpression(stackFrame, &cmd, &valid);
+     if (!displayLength || displayLength > 20)
+	displayLength = 20;
+     lastDumpAddress = dump((BYTE *)lastDumpAddress, displayLength);
+     return TRUE;
+
+}
+
+ULONG displayDisassembleHelp(BYTE *commandLine, DEBUGGER_PARSER *parser)
+{
+    if (commandLine) {}
+    if (parser) {}
+
+    DBGPrint("id  <address> <#lines>   - unassemble code (32-bit)\n");
+    DBGPrint("u   <address> <#lines>   - unassemble code (32-bit)\n");
+    DBGPrint("uu  <address> <#lines>   - unassemble code (16-bit)\n");
+    return TRUE;
+}
+
+// UU
+
+ULONG processDisassemble16(BYTE *cmd,
+			  StackFrame *stackFrame, ULONG Exception,
+			  DEBUGGER_PARSER *parser)
+{
+     ULONG valid;
+
+     if (cmd) {};
+     if (stackFrame) {};
+     if (Exception) {};
+     if (parser) {};
+
+     cmd = &cmd[parser->debugCommandNameLength];
+     while (*cmd && *cmd == ' ') cmd++;
+
+     if (repeatCommand)
+     {
+	lastUnasmAddress = disassemble(stackFrame, (ULONG)lastUnasmAddress,
+						    lastDisplayLength, 0);
+	return TRUE;
+     }
+     lastUnasmAddress = EvaluateExpression(stackFrame, &cmd, &valid);
+     if (!valid)
+     {
+        if (!*cmd)
+	   lastUnasmAddress = GetIP(stackFrame);
+        else
+        {
+           DBGPrint("invalid address for unassemble\n");
+           return TRUE;
+        }
+     }
+     displayLength = EvaluateExpression(stackFrame, &cmd, &valid);
+     if (!displayLength || displayLength > 20)
+		     displayLength = 20;
+     lastUnasmAddress = disassemble(stackFrame, (ULONG)lastUnasmAddress,
+						 displayLength, 0);
+     return TRUE;
+}
+
+// U
+
+ULONG processDisassemble32(BYTE *cmd,
+			  StackFrame *stackFrame, ULONG Exception,
+			  DEBUGGER_PARSER *parser)
+{
+     ULONG valid;
+
+     if (cmd) {};
+     if (stackFrame) {};
+     if (Exception) {};
+     if (parser) {};
+
+     cmd = &cmd[parser->debugCommandNameLength];
+     while (*cmd && *cmd == ' ') cmd++;
+
+     if (repeatCommand)
+     {
+	lastUnasmAddress = disassemble(stackFrame, (ULONG)lastUnasmAddress,
+				       lastDisplayLength, 1);
+	return TRUE;
+     }
+     lastUnasmAddress = EvaluateExpression(stackFrame, &cmd, &valid);
+     if (!valid)
+     {
+        if (!*cmd)
+	   lastUnasmAddress = GetIP(stackFrame);
+        else
+        {
+           DBGPrint("invalid address for unassemble\n");
+           return TRUE;
+        }
+     }
+     displayLength = EvaluateExpression(stackFrame, &cmd, &valid);
+     if (!displayLength || displayLength > 20)
+	displayLength = 20;
+     lastUnasmAddress = disassemble(stackFrame, (ULONG)lastUnasmAddress,
+						 displayLength, 1);
+     return TRUE;
+
+}
+
+#endif


By making a contribution to this project, I certify that
the contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file.

Jeffrey Vernon Merkey



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ