From 38758dfce718454dda39995fb69e6fc2bc6de38e Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sat, 10 Jan 2004 21:06:38 +0000 Subject: [PATCH] Added kjs system to the kernel. svn path=/trunk/; revision=7556 --- reactos/ntoskrnl/Makefile | 15 ++- reactos/ntoskrnl/dbg/kdb.c | 254 +++++++++++++++++++++++++++++++++++-- reactos/ntoskrnl/dbg/kdb.h | 7 + 3 files changed, 262 insertions(+), 14 deletions(-) diff --git a/reactos/ntoskrnl/Makefile b/reactos/ntoskrnl/Makefile index eba8349635a..4280dd5b564 100644 --- a/reactos/ntoskrnl/Makefile +++ b/reactos/ntoskrnl/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.111 2003/12/23 05:07:26 arty Exp $ +# $Id: Makefile,v 1.112 2004/01/10 21:06:37 arty Exp $ # # ReactOS Operating System # @@ -27,7 +27,13 @@ endif ifeq ($(KDBG), 1) OBJECTS_KDBG := dbg/kdb.o dbg/kdb_serial.o dbg/kdb_keyboard.o dbg/rdebug.o \ - dbg/i386/kdb_help.o dbg/kdb_stabs.o dbg/profile.o + dbg/i386/kdb_help.o dbg/kdb_stabs.o dbg/profile.o \ + ../dk/w32/lib/kjs.a +CFLAGS += -I../lib/kjs/include +preall: all + +../dk/w32/lib/kjs.a: + $(MAKE) -C ../lib/kjs else OBJECTS_KDBG := endif @@ -51,6 +57,9 @@ CFLAGS += -D_DISABLE_TIDENTS # include $(PATH_TO_TOP)/rules.mak +# +# Javascript extension for kdb +# TARGETNAME := ntoskrnl @@ -517,7 +526,7 @@ OBJECTS := \ $(OBJECTS_RESOURCE) -$(TARGETNAME).nostrip.exe: $(TARGETNAME).o $(IE_DATA) $(SDK_PATH_LIB)/string.a $(SDK_PATH_LIB)/rosrtl.a +$(TARGETNAME).nostrip.exe: $(TARGETNAME).o $(IE_DATA) $(SDK_PATH_LIB)/string.a $(SDK_PATH_LIB)/rosrtl.a $(CC) \ -Wl,-T,ntoskrnl.lnk \ -nostartfiles \ diff --git a/reactos/ntoskrnl/dbg/kdb.c b/reactos/ntoskrnl/dbg/kdb.c index 09c308945c1..a0b3329fd4a 100644 --- a/reactos/ntoskrnl/dbg/kdb.c +++ b/reactos/ntoskrnl/dbg/kdb.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: kdb.c,v 1.14 2003/12/25 14:06:15 chorns Exp $ +/* $Id: kdb.c,v 1.15 2004/01/10 21:06:38 arty Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/dbg/kdb.c @@ -35,6 +35,7 @@ #include #include #include "kdb.h" +#include "kjs.h" #define NDEBUG #include @@ -63,6 +64,8 @@ DbgAddrCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf); ULONG DbgXCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf); ULONG +DbgScriptCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf); +ULONG DbgThreadListCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf); ULONG DbgProcessListCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf); @@ -95,10 +98,13 @@ struct {"sfiles", "sfiles", "Show files that print debug prints", DbgShowFilesCommand}, {"efile", "efile ", "Enable debug prints from file", DbgEnableFileCommand}, {"dfile", "dfile ", "Disable debug prints from file", DbgDisableFileCommand}, + {"js", "js", "Script mode", DbgScriptCommand}, {"help", "help", "Display help screen", DbgProcessHelpCommand}, {NULL, NULL, NULL} }; +volatile DWORD x_dr0 = 0, x_dr1 = 0, x_dr2 = 0, x_dr3 = 0, x_dr7 = 0; + /* FUNCTIONS *****************************************************************/ /* @@ -191,6 +197,7 @@ VOID KdbGetCommand(PCH Buffer) { CHAR Key; + PCH Orig = Buffer; for (;;) { @@ -205,11 +212,22 @@ KdbGetCommand(PCH Buffer) *Buffer = 0; return; } + else if (Key == '\x8') + { + if (Buffer > Orig) + { + Buffer--; + *Buffer = 0; + DbgPrint("%c %c", 8, 8); + } + } + else + { + DbgPrint("%c", Key); - DbgPrint("%c", Key); - - *Buffer = Key; - Buffer++; + *Buffer = Key; + Buffer++; + } } } @@ -286,11 +304,7 @@ DbgPrintBackTrace(PULONG Frame, ULONG StackBase, ULONG StackLimit) while (Frame != NULL && (ULONG)Frame >= StackLimit && (ULONG)Frame < StackBase) { -#if 0 - DbgPrint("%.8x ", Frame[1]); -#else KdbPrintAddress((PVOID)Frame[1]); -#endif Frame = (PULONG)Frame[0]; i++; } @@ -341,6 +355,215 @@ DbgXCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME tf) return(1); } +static int KjsReadRegValue( void *context, + JSNode *result, + JSNode *args ) { + PCHAR cp; + PVOID *context_list = context; + PKJS kjs = (PKJS)context_list[0]; + JSVirtualMachine *vm = kjs->vm; + NTSTATUS Status; + RTL_QUERY_REGISTRY_TABLE QueryTable[2] = { { 0 } }; + UNICODE_STRING NameString; + UNICODE_STRING PathString; + UNICODE_STRING DefaultString; + UNICODE_STRING ValueResult; + ANSI_STRING AnsiResult; + + if (args->u.vinteger != 2 || + args[1].type != JS_STRING || args[2].type != JS_STRING) { + return JS_PROPERTY_FOUND; + } + + RtlInitUnicodeString(&PathString,NULL); + RtlInitUnicodeString(&NameString,NULL); + + cp = js_string_to_c_string (vm, &args[1]); + RtlCreateUnicodeStringFromAsciiz(&PathString,cp); + js_free(cp); + cp = js_string_to_c_string (vm, &args[2]); + RtlCreateUnicodeStringFromAsciiz(&NameString,cp); + js_free(cp); + + RtlInitUnicodeString(&ValueResult,NULL); + RtlInitUnicodeString(&DefaultString,L""); + RtlInitAnsiString(&AnsiResult,NULL); + + QueryTable->EntryContext = 0; + QueryTable->Flags = + RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT; + QueryTable->Name = NameString.Buffer; + QueryTable->DefaultType = REG_SZ; + QueryTable->DefaultData = &DefaultString; + QueryTable->EntryContext = &ValueResult; + Status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE, + PathString.Buffer, + QueryTable, + NULL, + NULL ); + + RtlFreeUnicodeString(&NameString); + RtlFreeUnicodeString(&PathString); + + if (NT_SUCCESS(Status)) { + RtlInitAnsiString(&AnsiResult,NULL); + RtlUnicodeStringToAnsiString(&AnsiResult, + &ValueResult, + TRUE); + js_vm_make_string (vm, result, AnsiResult.Buffer, + strlen(AnsiResult.Buffer)); + RtlFreeAnsiString(&AnsiResult); + } else { + result->type = JS_INTEGER; + result->u.vinteger = Status; + } + + return JS_PROPERTY_FOUND; +} + +static int KjsGetRegister( void *context, + JSNode *result, + JSNode *args ) { + PVOID *context_list = context; + if( args->u.vinteger == 1 && args->type == JS_INTEGER ) { + DWORD Result = ((DWORD *)context_list[1])[args[1].u.vinteger]; + result->type = JS_INTEGER; + result->u.vinteger = Result; + } + + return JS_PROPERTY_FOUND; +} + +static int KjsGetNthModule( void *context, + JSNode *result, + JSNode *args ) { + PVOID *context_list = context; + PKJS kjs = (PKJS)context_list[0]; + JSVirtualMachine *vm = kjs->vm; + PLIST_ENTRY current_entry; + MODULE_TEXT_SECTION *current; + extern LIST_ENTRY ModuleTextListHead; + int n = 0; + + if (args->u.vinteger != 1 || args[1].type != JS_INTEGER) { + return JS_PROPERTY_FOUND; + } + + current_entry = ModuleTextListHead.Flink; + + while (current_entry != &ModuleTextListHead && + current_entry != NULL && + n <= args[1].u.vinteger) { + current = CONTAINING_RECORD(current_entry, MODULE_TEXT_SECTION, + ListEntry); + current_entry = current_entry->Flink; + n++; + } + + if (current_entry && current) { + ANSI_STRING NameStringNarrow; + UNICODE_STRING NameUnicodeString; + + RtlInitUnicodeString( &NameUnicodeString, current->Name ); + RtlUnicodeStringToAnsiString( &NameStringNarrow, + &NameUnicodeString, + TRUE ); + + js_vm_make_array (vm, result, 2); + + js_vm_make_string (vm, + &result->u.varray->data[0], + NameStringNarrow.Buffer, + NameStringNarrow.Length); + + RtlFreeAnsiString(&NameStringNarrow); + + result->u.varray->data[1].type = JS_INTEGER; + result->u.varray->data[1].u.vinteger = (DWORD)current->Base; + result->type = JS_ARRAY; + return JS_PROPERTY_FOUND; + } + result->type = JS_UNDEFINED; + return JS_PROPERTY_FOUND; +} + +static BOOL FindJSEndMark( PCHAR Buffer ) { + int i; + + for( i = 0; Buffer[i] && Buffer[i+1]; i++ ) { + if( Buffer[i] == ';' && Buffer[i+1] == ';' ) return TRUE; + } + return FALSE; +} + +ULONG +DbgScriptCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME tf) +{ + PCHAR Buffer; + PCHAR BufferStart; + static void *interp = 0; + void *script_cmd_context[2]; + + if( !interp ) interp = kjs_create_interp(NULL); + if( !interp ) return 1; + + BufferStart = Buffer = ExAllocatePool( NonPagedPool, 4096 ); + if( !Buffer ) return 1; + + script_cmd_context[0] = interp; + script_cmd_context[1] = &tf; + + kjs_system_register( interp, "regs", script_cmd_context, + KjsGetRegister ); + kjs_system_register( interp, "regread", script_cmd_context, + KjsReadRegValue ); + kjs_system_register( interp, "getmodule", script_cmd_context, + KjsGetNthModule ); + + kjs_eval( interp, + "eval(" + "System.regread(" + "'\\\\Registry\\\\Machine\\\\System\\\\" + "CurrentControlSet\\\\Control\\\\Kdb'," + "'kjsinit'));" ); + + DbgPrint("\nKernel Debugger Script Interface (JavaScript :-)\n"); + DbgPrint("Terminate input with ;; and end scripting with .\n"); + do + { + if( Buffer != BufferStart ) + DbgPrint("..... "); + else + DbgPrint("kjs:> "); + KdbGetCommand( BufferStart ); + if( BufferStart[0] == '.' ) { + if( BufferStart != Buffer ) { + DbgPrint("Input Aborted.\n"); + BufferStart = Buffer; + } else { + /* Single dot input -> exit */ + break; + } + } else { + if( FindJSEndMark( Buffer ) ) { + kjs_eval( interp, Buffer ); + BufferStart = Buffer; + DbgPrint("\n"); + } else { + BufferStart = BufferStart + strlen(BufferStart); + } + } + } while (TRUE); + + ExFreePool( Buffer ); + + kjs_system_unregister( interp, script_cmd_context, KjsGetRegister ); + kjs_system_unregister( interp, script_cmd_context, KjsReadRegValue ); + kjs_system_unregister( interp, script_cmd_context, KjsGetNthModule ); + + return(1); +} + ULONG DbgBackTraceCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf) { @@ -477,7 +700,7 @@ DbgCRegsCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf) ULONG DbgDRegsCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf) { - DbgPrint("DR0 %.8x DR1 %.8x DR2 %.8x DR3 %.8x DR6 %.8x DR7 %.8x\n", + DbgPrint("Trap : DR0 %.8x DR1 %.8x DR2 %.8x DR3 %.8x DR6 %.8x DR7 %.8x\n", Tf->Dr0, Tf->Dr1, Tf->Dr2, Tf->Dr3, Tf->Dr6, Tf->Dr7); return(1); } @@ -683,6 +906,16 @@ DbgDisableFileCommand(ULONG Argc, PCH Argv[], PKTRAP_FRAME Tf) return(1); } +VOID +KdbCreateThreadHook(PCONTEXT Context) +{ + Context->Dr0 = x_dr0; + Context->Dr1 = x_dr1; + Context->Dr2 = x_dr2; + Context->Dr3 = x_dr3; + Context->Dr7 = x_dr7; +} + ULONG KdbDoCommand(PCH CommandLine, PKTRAP_FRAME Tf) { @@ -730,7 +963,6 @@ KdbMainLoop(PKTRAP_FRAME Tf) DbgPrint("\nkdb:> "); KdbGetCommand(Command); - s = KdbDoCommand(Command, Tf); } while (s != 0); } diff --git a/reactos/ntoskrnl/dbg/kdb.h b/reactos/ntoskrnl/dbg/kdb.h index f75711822e1..99baf72fab8 100644 --- a/reactos/ntoskrnl/dbg/kdb.h +++ b/reactos/ntoskrnl/dbg/kdb.h @@ -32,3 +32,10 @@ VOID KdbEnableProfiling(); VOID KdbProfileInterrupt(ULONG_PTR Eip); + +struct KDB_BPINFO { + DWORD Addr; + DWORD Type; + DWORD Size; + DWORD Enabled; +};