reactos/reactos/dll/ntdll/rtl/libsupp.c

489 lines
11 KiB
C
Raw Normal View History

/*
* COPYRIGHT: See COPYING in the top level directory
Major refactoring of the exception handling code + misc fixes: - Fix/add prototypes for RtlCaptureContext, RtlDispatchException and RtlUnwind - Fix EXCEPTION_REGISTRATION_RECORD structure and PEXCEPTION_ROUTINE - Add w32api excpt.h (based on mingw) with PSDK compatibility fixes - Fix seriously broken User-Mode Ldr thunk and APC Callback prototypes - Fix KiUserExceptionDispatcher - Remove useless NTDLL entrypoint - Implement NTDLL Ki* callbacks in ASM - Implement RtlCaptureContext - Fix RtlRaiseException to handle cases when a user-mode debugger is present - Fix RtlRaiseStatus as above, plus set the exception address and capture context - Little cleanup of RTL headers - Implement RtlpGetStackLimits, RtlpGetExceptionList, RtlpSetExceptionList, RtlpGetExceptionAddress in ASM - Fix RtlDispatchException, add cases for exceptions in the DPC stack and validate the validity of the exception frames. Add support for exception logging by the global flag. Use TRAP_FRAME/EXCPETION_FRAME instead of Context. - Fix RtlUnwind logic, support cases where it's called with custom arguments instead of NULL. - Reimplement RtlpCaptureContext to work properly, convert exception handler calling functions to INTEL syntax and fix some bugs (like checking for the right unwind flag, clearing volatile register values, etc. Also use some optimizations to increase speed. - Modify some kernel functions (like KeContextToTrapFrame, KiDispatchException, KiInitializeUserApc, etc.) to support a PKEXCEPTION_FRAME for future PPC compatibility. - Reimplement RtlCaptureUnicodeString/FreeUnicodeString as inlined probe macros and optimize them. - Export ExRaiseStatus/Exception as Rtl* - Reimplement NtContinue to have more platform-independent code, and to protect and validate user-mode context and parameters with SEH. - Implement KiRaiseException, add SEH to all user-mode parameters and when copying data to the user-mode stack. - Fix KiInitializeUserApc to use KeTrapFrameToContext, to save the debug registers, not to deliver APCs during v86 mode, and to protect user-mode stack operations in SEH and probing. Also make it generate the proper stack for the user-mode callback. - Implement KiUnexpectedInterrupt and KiCoprocessorError - Reimplement NtRaiseException in ASM to take advantage of optimizations due to the trap frame being in the stack when called through System call interface. - Fix Ntcontinue to respect AlertThread paramter - Fix some functiosn to return with KiServiceExit2 instead of KiServiceExit when required/needed - Fix KiDispatchException's logic, fix hacks when calling KeUserExceptionDispatcher, use correct context flags,... - Make NTDLL Ki* callbacks have SEH to protect them and return to kernel-mode with notification of any exceptions (the kernel-mode code to handle this isn't written yet though) svn path=/trunk/; revision=17811
2005-09-11 22:32:20 +00:00
* PROJECT: ReactOS NT User-Mode DLL
* FILE: lib/ntdll/rtl/libsup.c
Major refactoring of the exception handling code + misc fixes: - Fix/add prototypes for RtlCaptureContext, RtlDispatchException and RtlUnwind - Fix EXCEPTION_REGISTRATION_RECORD structure and PEXCEPTION_ROUTINE - Add w32api excpt.h (based on mingw) with PSDK compatibility fixes - Fix seriously broken User-Mode Ldr thunk and APC Callback prototypes - Fix KiUserExceptionDispatcher - Remove useless NTDLL entrypoint - Implement NTDLL Ki* callbacks in ASM - Implement RtlCaptureContext - Fix RtlRaiseException to handle cases when a user-mode debugger is present - Fix RtlRaiseStatus as above, plus set the exception address and capture context - Little cleanup of RTL headers - Implement RtlpGetStackLimits, RtlpGetExceptionList, RtlpSetExceptionList, RtlpGetExceptionAddress in ASM - Fix RtlDispatchException, add cases for exceptions in the DPC stack and validate the validity of the exception frames. Add support for exception logging by the global flag. Use TRAP_FRAME/EXCPETION_FRAME instead of Context. - Fix RtlUnwind logic, support cases where it's called with custom arguments instead of NULL. - Reimplement RtlpCaptureContext to work properly, convert exception handler calling functions to INTEL syntax and fix some bugs (like checking for the right unwind flag, clearing volatile register values, etc. Also use some optimizations to increase speed. - Modify some kernel functions (like KeContextToTrapFrame, KiDispatchException, KiInitializeUserApc, etc.) to support a PKEXCEPTION_FRAME for future PPC compatibility. - Reimplement RtlCaptureUnicodeString/FreeUnicodeString as inlined probe macros and optimize them. - Export ExRaiseStatus/Exception as Rtl* - Reimplement NtContinue to have more platform-independent code, and to protect and validate user-mode context and parameters with SEH. - Implement KiRaiseException, add SEH to all user-mode parameters and when copying data to the user-mode stack. - Fix KiInitializeUserApc to use KeTrapFrameToContext, to save the debug registers, not to deliver APCs during v86 mode, and to protect user-mode stack operations in SEH and probing. Also make it generate the proper stack for the user-mode callback. - Implement KiUnexpectedInterrupt and KiCoprocessorError - Reimplement NtRaiseException in ASM to take advantage of optimizations due to the trap frame being in the stack when called through System call interface. - Fix Ntcontinue to respect AlertThread paramter - Fix some functiosn to return with KiServiceExit2 instead of KiServiceExit when required/needed - Fix KiDispatchException's logic, fix hacks when calling KeUserExceptionDispatcher, use correct context flags,... - Make NTDLL Ki* callbacks have SEH to protect them and return to kernel-mode with notification of any exceptions (the kernel-mode code to handle this isn't written yet though) svn path=/trunk/; revision=17811
2005-09-11 22:32:20 +00:00
* PURPOSE: RTL Support Routines
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
* Gunnar Dalsnes
*/
/* INCLUDES *****************************************************************/
#include <ntdll.h>
#define NDEBUG
#include <debug.h>
SIZE_T RtlpAllocDeallocQueryBufferSize = PAGE_SIZE;
PTEB LdrpTopLevelDllBeingLoadedTeb = NULL;
/* FUNCTIONS ***************************************************************/
#ifndef _M_AMD64
// FIXME: Why "Not implemented"???
/*
* @implemented
*/
ULONG
NTAPI
RtlWalkFrameChain(OUT PVOID *Callers,
IN ULONG Count,
IN ULONG Flags)
{
/* Not implemented for user-mode */
return 0;
}
#endif
Major refactoring of the exception handling code + misc fixes: - Fix/add prototypes for RtlCaptureContext, RtlDispatchException and RtlUnwind - Fix EXCEPTION_REGISTRATION_RECORD structure and PEXCEPTION_ROUTINE - Add w32api excpt.h (based on mingw) with PSDK compatibility fixes - Fix seriously broken User-Mode Ldr thunk and APC Callback prototypes - Fix KiUserExceptionDispatcher - Remove useless NTDLL entrypoint - Implement NTDLL Ki* callbacks in ASM - Implement RtlCaptureContext - Fix RtlRaiseException to handle cases when a user-mode debugger is present - Fix RtlRaiseStatus as above, plus set the exception address and capture context - Little cleanup of RTL headers - Implement RtlpGetStackLimits, RtlpGetExceptionList, RtlpSetExceptionList, RtlpGetExceptionAddress in ASM - Fix RtlDispatchException, add cases for exceptions in the DPC stack and validate the validity of the exception frames. Add support for exception logging by the global flag. Use TRAP_FRAME/EXCPETION_FRAME instead of Context. - Fix RtlUnwind logic, support cases where it's called with custom arguments instead of NULL. - Reimplement RtlpCaptureContext to work properly, convert exception handler calling functions to INTEL syntax and fix some bugs (like checking for the right unwind flag, clearing volatile register values, etc. Also use some optimizations to increase speed. - Modify some kernel functions (like KeContextToTrapFrame, KiDispatchException, KiInitializeUserApc, etc.) to support a PKEXCEPTION_FRAME for future PPC compatibility. - Reimplement RtlCaptureUnicodeString/FreeUnicodeString as inlined probe macros and optimize them. - Export ExRaiseStatus/Exception as Rtl* - Reimplement NtContinue to have more platform-independent code, and to protect and validate user-mode context and parameters with SEH. - Implement KiRaiseException, add SEH to all user-mode parameters and when copying data to the user-mode stack. - Fix KiInitializeUserApc to use KeTrapFrameToContext, to save the debug registers, not to deliver APCs during v86 mode, and to protect user-mode stack operations in SEH and probing. Also make it generate the proper stack for the user-mode callback. - Implement KiUnexpectedInterrupt and KiCoprocessorError - Reimplement NtRaiseException in ASM to take advantage of optimizations due to the trap frame being in the stack when called through System call interface. - Fix Ntcontinue to respect AlertThread paramter - Fix some functiosn to return with KiServiceExit2 instead of KiServiceExit when required/needed - Fix KiDispatchException's logic, fix hacks when calling KeUserExceptionDispatcher, use correct context flags,... - Make NTDLL Ki* callbacks have SEH to protect them and return to kernel-mode with notification of any exceptions (the kernel-mode code to handle this isn't written yet though) svn path=/trunk/; revision=17811
2005-09-11 22:32:20 +00:00
BOOLEAN
NTAPI
- Replace RtlpGetExceptionAddress by the _ReturnAddress intrinsic and add it to ARM intrin.h as it was missing. - Simplify RtlpCheckForActiveDebugger: Remove the BOOLEAN parameter as we would always pass it FALSE. Always return FALSE false from kernel mode for simplicity. - Fix a critical flaw in our exception support: RtlRaiseException and RtlRaiseStatus were implemented in C on x86. This lead to unpredictable register corruption because the compiler could not know that it had to preserve non-volatile registers before calling RtlCaptureContext as the saved context is later used to restore the caller in case the exception is handled and execution is continued. This made the functions unsafe to return from as any non-volatile register could be corrupted. Implement them in assembly for x86 to safely capture the context using only EBP and ESP. The C versions of those routines are still used and shared for the other architectures we support -- needs to be determined if this is safe and correct for those architectures. - The ntdll exception Wine exposed this issue, and all tests now pass. The remaining failures on the build server are caused by missing or incomplete debug register support in KVM/QEMU. Run the test in another VM or on real hardware and all the tests will pass. - Implement Debug Prompt (DbgPrompt) support for KD and KDBG. The KDBG implementation reads the prompt from keyboard or serial depending on the mode so that sysreg and rosdbg can support it too. - Properly implement RtlAssert using DbgPrompt to prompt for the action to take instead of always doing a breakpoint. The new implementation is disabled until sysreg can support this. Also move RtlAssert to its own file as it has nothing to do with the error routines (nor does it belong in exception.c). - Note that DbgPrompt was already used in PspCatchCriticalBreak, and this would have resulted in a silent hang as BREAKPOINT_PROMPT wasn't handled at all by KDBG. - Implement KiRaiseAssertion (10 lines of code with the trap macros) and thus support NT_ASSERT. Add partial support for it to KDBG to print out a warning and the address of the failure, but don't do anything else. Also add NT_ASSERT to the DDK headers so that we can use it, but don't use it yet as the ARM method of performing this has not been decided nor implemented. - KiTrap3 doesn't set STATUS_SUCCESS but BREAKPOINT_BREAK. They have the same numerical value but very different meaning -- BREAKPOINT_BREAK means that the exception is a software breakpoint and not a debug service call. Fix some comments to document that this is what is checked for. - Fix inverted and broken logic in KdpReport. It would never pass second chance exceptions to the debugger, didn't respect the stop-on-exception flag properly and would always fail to handle some special exceptions in both first and second chance instead of just failing to handle it in first chance. Clean up, reformat and document what is going on. - The DebugPrint and DebugPrompt support routines only perform a 2D interrupt on x86; use more portable comments. - Add Alex to the programmer section of x86's kdsup.c -- he wrote KdpGetStateChange, KdpSetContextState and the code that was previously in KdpRead/WriteControlSpace. - Add my name to the parts of KD where I have made significant work on getting KD/WinDbg support up and running. - KD debugging is now quite functional and stable. Some bugs and stubs remain to be flushed out, but overall KD is now much better and easier to use than KDBG. svn path=/trunk/; revision=43705
2009-10-23 22:51:39 +00:00
RtlpCheckForActiveDebugger(VOID)
Major refactoring of the exception handling code + misc fixes: - Fix/add prototypes for RtlCaptureContext, RtlDispatchException and RtlUnwind - Fix EXCEPTION_REGISTRATION_RECORD structure and PEXCEPTION_ROUTINE - Add w32api excpt.h (based on mingw) with PSDK compatibility fixes - Fix seriously broken User-Mode Ldr thunk and APC Callback prototypes - Fix KiUserExceptionDispatcher - Remove useless NTDLL entrypoint - Implement NTDLL Ki* callbacks in ASM - Implement RtlCaptureContext - Fix RtlRaiseException to handle cases when a user-mode debugger is present - Fix RtlRaiseStatus as above, plus set the exception address and capture context - Little cleanup of RTL headers - Implement RtlpGetStackLimits, RtlpGetExceptionList, RtlpSetExceptionList, RtlpGetExceptionAddress in ASM - Fix RtlDispatchException, add cases for exceptions in the DPC stack and validate the validity of the exception frames. Add support for exception logging by the global flag. Use TRAP_FRAME/EXCPETION_FRAME instead of Context. - Fix RtlUnwind logic, support cases where it's called with custom arguments instead of NULL. - Reimplement RtlpCaptureContext to work properly, convert exception handler calling functions to INTEL syntax and fix some bugs (like checking for the right unwind flag, clearing volatile register values, etc. Also use some optimizations to increase speed. - Modify some kernel functions (like KeContextToTrapFrame, KiDispatchException, KiInitializeUserApc, etc.) to support a PKEXCEPTION_FRAME for future PPC compatibility. - Reimplement RtlCaptureUnicodeString/FreeUnicodeString as inlined probe macros and optimize them. - Export ExRaiseStatus/Exception as Rtl* - Reimplement NtContinue to have more platform-independent code, and to protect and validate user-mode context and parameters with SEH. - Implement KiRaiseException, add SEH to all user-mode parameters and when copying data to the user-mode stack. - Fix KiInitializeUserApc to use KeTrapFrameToContext, to save the debug registers, not to deliver APCs during v86 mode, and to protect user-mode stack operations in SEH and probing. Also make it generate the proper stack for the user-mode callback. - Implement KiUnexpectedInterrupt and KiCoprocessorError - Reimplement NtRaiseException in ASM to take advantage of optimizations due to the trap frame being in the stack when called through System call interface. - Fix Ntcontinue to respect AlertThread paramter - Fix some functiosn to return with KiServiceExit2 instead of KiServiceExit when required/needed - Fix KiDispatchException's logic, fix hacks when calling KeUserExceptionDispatcher, use correct context flags,... - Make NTDLL Ki* callbacks have SEH to protect them and return to kernel-mode with notification of any exceptions (the kernel-mode code to handle this isn't written yet though) svn path=/trunk/; revision=17811
2005-09-11 22:32:20 +00:00
{
- Replace RtlpGetExceptionAddress by the _ReturnAddress intrinsic and add it to ARM intrin.h as it was missing. - Simplify RtlpCheckForActiveDebugger: Remove the BOOLEAN parameter as we would always pass it FALSE. Always return FALSE false from kernel mode for simplicity. - Fix a critical flaw in our exception support: RtlRaiseException and RtlRaiseStatus were implemented in C on x86. This lead to unpredictable register corruption because the compiler could not know that it had to preserve non-volatile registers before calling RtlCaptureContext as the saved context is later used to restore the caller in case the exception is handled and execution is continued. This made the functions unsafe to return from as any non-volatile register could be corrupted. Implement them in assembly for x86 to safely capture the context using only EBP and ESP. The C versions of those routines are still used and shared for the other architectures we support -- needs to be determined if this is safe and correct for those architectures. - The ntdll exception Wine exposed this issue, and all tests now pass. The remaining failures on the build server are caused by missing or incomplete debug register support in KVM/QEMU. Run the test in another VM or on real hardware and all the tests will pass. - Implement Debug Prompt (DbgPrompt) support for KD and KDBG. The KDBG implementation reads the prompt from keyboard or serial depending on the mode so that sysreg and rosdbg can support it too. - Properly implement RtlAssert using DbgPrompt to prompt for the action to take instead of always doing a breakpoint. The new implementation is disabled until sysreg can support this. Also move RtlAssert to its own file as it has nothing to do with the error routines (nor does it belong in exception.c). - Note that DbgPrompt was already used in PspCatchCriticalBreak, and this would have resulted in a silent hang as BREAKPOINT_PROMPT wasn't handled at all by KDBG. - Implement KiRaiseAssertion (10 lines of code with the trap macros) and thus support NT_ASSERT. Add partial support for it to KDBG to print out a warning and the address of the failure, but don't do anything else. Also add NT_ASSERT to the DDK headers so that we can use it, but don't use it yet as the ARM method of performing this has not been decided nor implemented. - KiTrap3 doesn't set STATUS_SUCCESS but BREAKPOINT_BREAK. They have the same numerical value but very different meaning -- BREAKPOINT_BREAK means that the exception is a software breakpoint and not a debug service call. Fix some comments to document that this is what is checked for. - Fix inverted and broken logic in KdpReport. It would never pass second chance exceptions to the debugger, didn't respect the stop-on-exception flag properly and would always fail to handle some special exceptions in both first and second chance instead of just failing to handle it in first chance. Clean up, reformat and document what is going on. - The DebugPrint and DebugPrompt support routines only perform a 2D interrupt on x86; use more portable comments. - Add Alex to the programmer section of x86's kdsup.c -- he wrote KdpGetStateChange, KdpSetContextState and the code that was previously in KdpRead/WriteControlSpace. - Add my name to the parts of KD where I have made significant work on getting KD/WinDbg support up and running. - KD debugging is now quite functional and stable. Some bugs and stubs remain to be flushed out, but overall KD is now much better and easier to use than KDBG. svn path=/trunk/; revision=43705
2009-10-23 22:51:39 +00:00
/* Return the flag in the PEB */
return NtCurrentPeb()->BeingDebugged;
Major refactoring of the exception handling code + misc fixes: - Fix/add prototypes for RtlCaptureContext, RtlDispatchException and RtlUnwind - Fix EXCEPTION_REGISTRATION_RECORD structure and PEXCEPTION_ROUTINE - Add w32api excpt.h (based on mingw) with PSDK compatibility fixes - Fix seriously broken User-Mode Ldr thunk and APC Callback prototypes - Fix KiUserExceptionDispatcher - Remove useless NTDLL entrypoint - Implement NTDLL Ki* callbacks in ASM - Implement RtlCaptureContext - Fix RtlRaiseException to handle cases when a user-mode debugger is present - Fix RtlRaiseStatus as above, plus set the exception address and capture context - Little cleanup of RTL headers - Implement RtlpGetStackLimits, RtlpGetExceptionList, RtlpSetExceptionList, RtlpGetExceptionAddress in ASM - Fix RtlDispatchException, add cases for exceptions in the DPC stack and validate the validity of the exception frames. Add support for exception logging by the global flag. Use TRAP_FRAME/EXCPETION_FRAME instead of Context. - Fix RtlUnwind logic, support cases where it's called with custom arguments instead of NULL. - Reimplement RtlpCaptureContext to work properly, convert exception handler calling functions to INTEL syntax and fix some bugs (like checking for the right unwind flag, clearing volatile register values, etc. Also use some optimizations to increase speed. - Modify some kernel functions (like KeContextToTrapFrame, KiDispatchException, KiInitializeUserApc, etc.) to support a PKEXCEPTION_FRAME for future PPC compatibility. - Reimplement RtlCaptureUnicodeString/FreeUnicodeString as inlined probe macros and optimize them. - Export ExRaiseStatus/Exception as Rtl* - Reimplement NtContinue to have more platform-independent code, and to protect and validate user-mode context and parameters with SEH. - Implement KiRaiseException, add SEH to all user-mode parameters and when copying data to the user-mode stack. - Fix KiInitializeUserApc to use KeTrapFrameToContext, to save the debug registers, not to deliver APCs during v86 mode, and to protect user-mode stack operations in SEH and probing. Also make it generate the proper stack for the user-mode callback. - Implement KiUnexpectedInterrupt and KiCoprocessorError - Reimplement NtRaiseException in ASM to take advantage of optimizations due to the trap frame being in the stack when called through System call interface. - Fix Ntcontinue to respect AlertThread paramter - Fix some functiosn to return with KiServiceExit2 instead of KiServiceExit when required/needed - Fix KiDispatchException's logic, fix hacks when calling KeUserExceptionDispatcher, use correct context flags,... - Make NTDLL Ki* callbacks have SEH to protect them and return to kernel-mode with notification of any exceptions (the kernel-mode code to handle this isn't written yet though) svn path=/trunk/; revision=17811
2005-09-11 22:32:20 +00:00
}
BOOLEAN
NTAPI
- Fix support for /CRASHDEBUG and /NODEBUG; we didn't respect those settings properly and would initialize KD at boot even if they were set. - Re-enable the breakpoint in vDbgPrintExWithPrefixInternal() as this works properly now. Without this breakpoint some break-in requests got lost if the break-in occurred when handling a debug print (happened a lot at boot). - Implement Command String support for DbgCommandString() -- we now handle every debug service call. - Implement NtSetDebugFilterState() and NtQueryDebugFilterState() for KD, meaning we now support debug filters properly. - Implement KdRefreshDebuggerNotPresent(), KdChangeOption() and KdPowerTransition(). Stub KdSystemDebugControl() to return error status instead of hanging the system. - Stub the rest of the KD API to print a warning and return a failure packet instead of hanging. - Set and respect KdpContextSent when getting and setting the thread context -- WinDbg doesn't seem to rely on this, but better safe than sorry. - Support MP when getting and setting the thread context too -- if the context is operation is for another processor than the current, just get it through the KiProcessorBlock array. - Initialize the MajorVersion in the KD version block more properly -- the high byte is the major identifier (0 for NT). Add the required DBGKD_MAJOR_TYPES enumeration to wdbgexts.h. - Simplify setting and clearing the InDbgPrint flag in the TEB to minimize the impact on kernel execution; use 2 dedicated routines instead of a generic one. - KdpSymbol doesn't return anything, so don't return an ignore status from KdpReportLoadSymbolsStateChange. - Expose the KdpDefaultRetries and Kd_WIN2000_Mask variables to the registry and add them to KDBG too (unused there). - No reason to implement KdpSysGetVersion per architecture; move it back to the generic code. - Add some ARM offsets to the debugger data block that (N/A on other architectures). - Fix the default size of the DbgPrint log buffer for free builds to save some space. It should be 4 KB for a free build and 32 KB for a checked build. - Move KeDisableInterrupts to cpu.c as it fits here more than in the IRQ support code in irqobj.c. - Use KeDisableInterrupts in KeFreezeExecution instead of checking the x86 EFLAG directly. svn path=/trunk/; revision=43912
2009-11-02 17:45:51 +00:00
RtlpSetInDbgPrint(VOID)
{
- Fix support for /CRASHDEBUG and /NODEBUG; we didn't respect those settings properly and would initialize KD at boot even if they were set. - Re-enable the breakpoint in vDbgPrintExWithPrefixInternal() as this works properly now. Without this breakpoint some break-in requests got lost if the break-in occurred when handling a debug print (happened a lot at boot). - Implement Command String support for DbgCommandString() -- we now handle every debug service call. - Implement NtSetDebugFilterState() and NtQueryDebugFilterState() for KD, meaning we now support debug filters properly. - Implement KdRefreshDebuggerNotPresent(), KdChangeOption() and KdPowerTransition(). Stub KdSystemDebugControl() to return error status instead of hanging the system. - Stub the rest of the KD API to print a warning and return a failure packet instead of hanging. - Set and respect KdpContextSent when getting and setting the thread context -- WinDbg doesn't seem to rely on this, but better safe than sorry. - Support MP when getting and setting the thread context too -- if the context is operation is for another processor than the current, just get it through the KiProcessorBlock array. - Initialize the MajorVersion in the KD version block more properly -- the high byte is the major identifier (0 for NT). Add the required DBGKD_MAJOR_TYPES enumeration to wdbgexts.h. - Simplify setting and clearing the InDbgPrint flag in the TEB to minimize the impact on kernel execution; use 2 dedicated routines instead of a generic one. - KdpSymbol doesn't return anything, so don't return an ignore status from KdpReportLoadSymbolsStateChange. - Expose the KdpDefaultRetries and Kd_WIN2000_Mask variables to the registry and add them to KDBG too (unused there). - No reason to implement KdpSysGetVersion per architecture; move it back to the generic code. - Add some ARM offsets to the debugger data block that (N/A on other architectures). - Fix the default size of the DbgPrint log buffer for free builds to save some space. It should be 4 KB for a free build and 32 KB for a checked build. - Move KeDisableInterrupts to cpu.c as it fits here more than in the IRQ support code in irqobj.c. - Use KeDisableInterrupts in KeFreezeExecution instead of checking the x86 EFLAG directly. svn path=/trunk/; revision=43912
2009-11-02 17:45:51 +00:00
/* Check if it's already set and return TRUE if so */
if (NtCurrentTeb()->InDbgPrint) return TRUE;
/* Set it and return */
NtCurrentTeb()->InDbgPrint = TRUE;
return FALSE;
}
- Fix support for /CRASHDEBUG and /NODEBUG; we didn't respect those settings properly and would initialize KD at boot even if they were set. - Re-enable the breakpoint in vDbgPrintExWithPrefixInternal() as this works properly now. Without this breakpoint some break-in requests got lost if the break-in occurred when handling a debug print (happened a lot at boot). - Implement Command String support for DbgCommandString() -- we now handle every debug service call. - Implement NtSetDebugFilterState() and NtQueryDebugFilterState() for KD, meaning we now support debug filters properly. - Implement KdRefreshDebuggerNotPresent(), KdChangeOption() and KdPowerTransition(). Stub KdSystemDebugControl() to return error status instead of hanging the system. - Stub the rest of the KD API to print a warning and return a failure packet instead of hanging. - Set and respect KdpContextSent when getting and setting the thread context -- WinDbg doesn't seem to rely on this, but better safe than sorry. - Support MP when getting and setting the thread context too -- if the context is operation is for another processor than the current, just get it through the KiProcessorBlock array. - Initialize the MajorVersion in the KD version block more properly -- the high byte is the major identifier (0 for NT). Add the required DBGKD_MAJOR_TYPES enumeration to wdbgexts.h. - Simplify setting and clearing the InDbgPrint flag in the TEB to minimize the impact on kernel execution; use 2 dedicated routines instead of a generic one. - KdpSymbol doesn't return anything, so don't return an ignore status from KdpReportLoadSymbolsStateChange. - Expose the KdpDefaultRetries and Kd_WIN2000_Mask variables to the registry and add them to KDBG too (unused there). - No reason to implement KdpSysGetVersion per architecture; move it back to the generic code. - Add some ARM offsets to the debugger data block that (N/A on other architectures). - Fix the default size of the DbgPrint log buffer for free builds to save some space. It should be 4 KB for a free build and 32 KB for a checked build. - Move KeDisableInterrupts to cpu.c as it fits here more than in the IRQ support code in irqobj.c. - Use KeDisableInterrupts in KeFreezeExecution instead of checking the x86 EFLAG directly. svn path=/trunk/; revision=43912
2009-11-02 17:45:51 +00:00
VOID
NTAPI
RtlpClearInDbgPrint(VOID)
{
/* Clear the flag */
NtCurrentTeb()->InDbgPrint = FALSE;
}
KPROCESSOR_MODE
NTAPI
RtlpGetMode()
{
return UserMode;
}
/*
* @implemented
*/
PPEB
NTAPI
RtlGetCurrentPeb(VOID)
{
return NtCurrentPeb();
}
/*
* @implemented
*/
VOID NTAPI
RtlAcquirePebLock(VOID)
{
PPEB Peb = NtCurrentPeb ();
RtlEnterCriticalSection(Peb->FastPebLock);
}
/*
* @implemented
*/
VOID NTAPI
RtlReleasePebLock(VOID)
{
PPEB Peb = NtCurrentPeb ();
RtlLeaveCriticalSection(Peb->FastPebLock);
}
/*
* @implemented
*/
ULONG
NTAPI
RtlGetNtGlobalFlags(VOID)
{
Major refactoring of the exception handling code + misc fixes: - Fix/add prototypes for RtlCaptureContext, RtlDispatchException and RtlUnwind - Fix EXCEPTION_REGISTRATION_RECORD structure and PEXCEPTION_ROUTINE - Add w32api excpt.h (based on mingw) with PSDK compatibility fixes - Fix seriously broken User-Mode Ldr thunk and APC Callback prototypes - Fix KiUserExceptionDispatcher - Remove useless NTDLL entrypoint - Implement NTDLL Ki* callbacks in ASM - Implement RtlCaptureContext - Fix RtlRaiseException to handle cases when a user-mode debugger is present - Fix RtlRaiseStatus as above, plus set the exception address and capture context - Little cleanup of RTL headers - Implement RtlpGetStackLimits, RtlpGetExceptionList, RtlpSetExceptionList, RtlpGetExceptionAddress in ASM - Fix RtlDispatchException, add cases for exceptions in the DPC stack and validate the validity of the exception frames. Add support for exception logging by the global flag. Use TRAP_FRAME/EXCPETION_FRAME instead of Context. - Fix RtlUnwind logic, support cases where it's called with custom arguments instead of NULL. - Reimplement RtlpCaptureContext to work properly, convert exception handler calling functions to INTEL syntax and fix some bugs (like checking for the right unwind flag, clearing volatile register values, etc. Also use some optimizations to increase speed. - Modify some kernel functions (like KeContextToTrapFrame, KiDispatchException, KiInitializeUserApc, etc.) to support a PKEXCEPTION_FRAME for future PPC compatibility. - Reimplement RtlCaptureUnicodeString/FreeUnicodeString as inlined probe macros and optimize them. - Export ExRaiseStatus/Exception as Rtl* - Reimplement NtContinue to have more platform-independent code, and to protect and validate user-mode context and parameters with SEH. - Implement KiRaiseException, add SEH to all user-mode parameters and when copying data to the user-mode stack. - Fix KiInitializeUserApc to use KeTrapFrameToContext, to save the debug registers, not to deliver APCs during v86 mode, and to protect user-mode stack operations in SEH and probing. Also make it generate the proper stack for the user-mode callback. - Implement KiUnexpectedInterrupt and KiCoprocessorError - Reimplement NtRaiseException in ASM to take advantage of optimizations due to the trap frame being in the stack when called through System call interface. - Fix Ntcontinue to respect AlertThread paramter - Fix some functiosn to return with KiServiceExit2 instead of KiServiceExit when required/needed - Fix KiDispatchException's logic, fix hacks when calling KeUserExceptionDispatcher, use correct context flags,... - Make NTDLL Ki* callbacks have SEH to protect them and return to kernel-mode with notification of any exceptions (the kernel-mode code to handle this isn't written yet though) svn path=/trunk/; revision=17811
2005-09-11 22:32:20 +00:00
PPEB pPeb = NtCurrentPeb();
return pPeb->NtGlobalFlag;
}
NTSTATUS
NTAPI
RtlDeleteHeapLock(
PHEAP_LOCK Lock)
{
return RtlDeleteCriticalSection(&Lock->CriticalSection);
}
NTSTATUS
NTAPI
RtlEnterHeapLock(
PHEAP_LOCK Lock)
{
return RtlEnterCriticalSection(&Lock->CriticalSection);
}
NTSTATUS
NTAPI
RtlInitializeHeapLock(
PHEAP_LOCK Lock)
{
return RtlInitializeCriticalSection(&Lock->CriticalSection);
}
NTSTATUS
NTAPI
RtlLeaveHeapLock(
PHEAP_LOCK Lock)
{
return RtlLeaveCriticalSection(&Lock->CriticalSection);
}
PVOID
NTAPI
RtlpAllocateMemory(UINT Bytes,
ULONG Tag)
{
UNREFERENCED_PARAMETER(Tag);
return RtlAllocateHeap(RtlGetProcessHeap(),
0,
Bytes);
}
VOID
NTAPI
RtlpFreeMemory(PVOID Mem,
ULONG Tag)
{
UNREFERENCED_PARAMETER(Tag);
RtlFreeHeap(RtlGetProcessHeap(),
0,
Mem);
}
#if DBG
VOID FASTCALL
CHECK_PAGED_CODE_RTL(char *file, int line)
{
/* meaningless in user mode */
}
#endif
Major refactoring of the exception handling code + misc fixes: - Fix/add prototypes for RtlCaptureContext, RtlDispatchException and RtlUnwind - Fix EXCEPTION_REGISTRATION_RECORD structure and PEXCEPTION_ROUTINE - Add w32api excpt.h (based on mingw) with PSDK compatibility fixes - Fix seriously broken User-Mode Ldr thunk and APC Callback prototypes - Fix KiUserExceptionDispatcher - Remove useless NTDLL entrypoint - Implement NTDLL Ki* callbacks in ASM - Implement RtlCaptureContext - Fix RtlRaiseException to handle cases when a user-mode debugger is present - Fix RtlRaiseStatus as above, plus set the exception address and capture context - Little cleanup of RTL headers - Implement RtlpGetStackLimits, RtlpGetExceptionList, RtlpSetExceptionList, RtlpGetExceptionAddress in ASM - Fix RtlDispatchException, add cases for exceptions in the DPC stack and validate the validity of the exception frames. Add support for exception logging by the global flag. Use TRAP_FRAME/EXCPETION_FRAME instead of Context. - Fix RtlUnwind logic, support cases where it's called with custom arguments instead of NULL. - Reimplement RtlpCaptureContext to work properly, convert exception handler calling functions to INTEL syntax and fix some bugs (like checking for the right unwind flag, clearing volatile register values, etc. Also use some optimizations to increase speed. - Modify some kernel functions (like KeContextToTrapFrame, KiDispatchException, KiInitializeUserApc, etc.) to support a PKEXCEPTION_FRAME for future PPC compatibility. - Reimplement RtlCaptureUnicodeString/FreeUnicodeString as inlined probe macros and optimize them. - Export ExRaiseStatus/Exception as Rtl* - Reimplement NtContinue to have more platform-independent code, and to protect and validate user-mode context and parameters with SEH. - Implement KiRaiseException, add SEH to all user-mode parameters and when copying data to the user-mode stack. - Fix KiInitializeUserApc to use KeTrapFrameToContext, to save the debug registers, not to deliver APCs during v86 mode, and to protect user-mode stack operations in SEH and probing. Also make it generate the proper stack for the user-mode callback. - Implement KiUnexpectedInterrupt and KiCoprocessorError - Reimplement NtRaiseException in ASM to take advantage of optimizations due to the trap frame being in the stack when called through System call interface. - Fix Ntcontinue to respect AlertThread paramter - Fix some functiosn to return with KiServiceExit2 instead of KiServiceExit when required/needed - Fix KiDispatchException's logic, fix hacks when calling KeUserExceptionDispatcher, use correct context flags,... - Make NTDLL Ki* callbacks have SEH to protect them and return to kernel-mode with notification of any exceptions (the kernel-mode code to handle this isn't written yet though) svn path=/trunk/; revision=17811
2005-09-11 22:32:20 +00:00
BOOLEAN
NTAPI
RtlpHandleDpcStackException(IN PEXCEPTION_REGISTRATION_RECORD RegistrationFrame,
IN ULONG_PTR RegistrationFrameEnd,
IN OUT PULONG_PTR StackLow,
IN OUT PULONG_PTR StackHigh)
{
/* There's no such thing as a DPC stack in user-mode */
return FALSE;
}
VOID
NTAPI
RtlpCheckLogException(IN PEXCEPTION_RECORD ExceptionRecord,
IN PCONTEXT ContextRecord,
IN PVOID ContextData,
IN ULONG Size)
{
/* Exception logging is not done in user-mode */
}
BOOLEAN
NTAPI
RtlpCaptureStackLimits(IN ULONG_PTR Ebp,
IN ULONG_PTR *StackBegin,
IN ULONG_PTR *StackEnd)
{
/* FIXME: Verify */
*StackBegin = (ULONG_PTR)NtCurrentTeb()->NtTib.StackLimit;
*StackEnd = (ULONG_PTR)NtCurrentTeb()->NtTib.StackBase;
return TRUE;
}
#ifdef _AMD64_
VOID
NTAPI
RtlpGetStackLimits(
OUT PULONG_PTR LowLimit,
OUT PULONG_PTR HighLimit)
{
*LowLimit = (ULONG_PTR)NtCurrentTeb()->NtTib.StackLimit;
*HighLimit = (ULONG_PTR)NtCurrentTeb()->NtTib.StackBase;
return;
}
#endif
BOOLEAN
NTAPI
RtlIsThreadWithinLoaderCallout(VOID)
{
return LdrpTopLevelDllBeingLoadedTeb == NtCurrentTeb();
}
/* RTL Atom Tables ************************************************************/
typedef struct _RTL_ATOM_HANDLE
{
RTL_HANDLE_TABLE_ENTRY Handle;
PRTL_ATOM_TABLE_ENTRY AtomEntry;
} RTL_ATOM_HANDLE, *PRTL_ATOM_HANDLE;
NTSTATUS
RtlpInitAtomTableLock(PRTL_ATOM_TABLE AtomTable)
{
RtlInitializeCriticalSection(&AtomTable->CriticalSection);
return STATUS_SUCCESS;
}
VOID
RtlpDestroyAtomTableLock(PRTL_ATOM_TABLE AtomTable)
{
RtlDeleteCriticalSection(&AtomTable->CriticalSection);
}
BOOLEAN
RtlpLockAtomTable(PRTL_ATOM_TABLE AtomTable)
{
RtlEnterCriticalSection(&AtomTable->CriticalSection);
return TRUE;
}
VOID
RtlpUnlockAtomTable(PRTL_ATOM_TABLE AtomTable)
{
RtlLeaveCriticalSection(&AtomTable->CriticalSection);
}
/* handle functions */
BOOLEAN
RtlpCreateAtomHandleTable(PRTL_ATOM_TABLE AtomTable)
{
RtlInitializeHandleTable(0xCFFF,
sizeof(RTL_ATOM_HANDLE),
&AtomTable->RtlHandleTable);
return TRUE;
}
VOID
RtlpDestroyAtomHandleTable(PRTL_ATOM_TABLE AtomTable)
{
RtlDestroyHandleTable(&AtomTable->RtlHandleTable);
}
PRTL_ATOM_TABLE
RtlpAllocAtomTable(ULONG Size)
{
return (PRTL_ATOM_TABLE)RtlAllocateHeap(RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
Size);
}
VOID
RtlpFreeAtomTable(PRTL_ATOM_TABLE AtomTable)
{
RtlFreeHeap(RtlGetProcessHeap(),
0,
AtomTable);
}
PRTL_ATOM_TABLE_ENTRY
RtlpAllocAtomTableEntry(ULONG Size)
{
return (PRTL_ATOM_TABLE_ENTRY)RtlAllocateHeap(RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
Size);
}
VOID
RtlpFreeAtomTableEntry(PRTL_ATOM_TABLE_ENTRY Entry)
{
RtlFreeHeap(RtlGetProcessHeap(),
0,
Entry);
}
VOID
RtlpFreeAtomHandle(PRTL_ATOM_TABLE AtomTable, PRTL_ATOM_TABLE_ENTRY Entry)
{
PRTL_HANDLE_TABLE_ENTRY RtlHandleEntry;
if (RtlIsValidIndexHandle(&AtomTable->RtlHandleTable,
(ULONG)Entry->HandleIndex,
&RtlHandleEntry))
{
RtlFreeHandle(&AtomTable->RtlHandleTable,
RtlHandleEntry);
}
}
BOOLEAN
RtlpCreateAtomHandle(PRTL_ATOM_TABLE AtomTable, PRTL_ATOM_TABLE_ENTRY Entry)
{
ULONG HandleIndex;
PRTL_HANDLE_TABLE_ENTRY RtlHandle;
RtlHandle = RtlAllocateHandle(&AtomTable->RtlHandleTable,
&HandleIndex);
if (RtlHandle != NULL)
{
PRTL_ATOM_HANDLE AtomHandle = (PRTL_ATOM_HANDLE)RtlHandle;
/* FIXME - Handle Indexes >= 0xC000 ?! */
if (HandleIndex < 0xC000)
{
Entry->HandleIndex = (USHORT)HandleIndex;
Entry->Atom = 0xC000 + (USHORT)HandleIndex;
AtomHandle->AtomEntry = Entry;
AtomHandle->Handle.Flags = RTL_HANDLE_VALID;
return TRUE;
}
else
{
/* set the valid flag, otherwise RtlFreeHandle will fail! */
AtomHandle->Handle.Flags = RTL_HANDLE_VALID;
RtlFreeHandle(&AtomTable->RtlHandleTable,
RtlHandle);
}
}
return FALSE;
}
PRTL_ATOM_TABLE_ENTRY
RtlpGetAtomEntry(PRTL_ATOM_TABLE AtomTable, ULONG Index)
{
PRTL_HANDLE_TABLE_ENTRY RtlHandle;
if (RtlIsValidIndexHandle(&AtomTable->RtlHandleTable,
Index,
&RtlHandle))
{
PRTL_ATOM_HANDLE AtomHandle = (PRTL_ATOM_HANDLE)RtlHandle;
return AtomHandle->AtomEntry;
}
return NULL;
}
/*
* Ldr Resource support code
*/
IMAGE_RESOURCE_DIRECTORY *find_entry_by_name( IMAGE_RESOURCE_DIRECTORY *dir,
LPCWSTR name, void *root,
int want_dir );
IMAGE_RESOURCE_DIRECTORY *find_entry_by_id( IMAGE_RESOURCE_DIRECTORY *dir,
WORD id, void *root, int want_dir );
IMAGE_RESOURCE_DIRECTORY *find_first_entry( IMAGE_RESOURCE_DIRECTORY *dir,
void *root, int want_dir );
int push_language( USHORT *list, ULONG pos, WORD lang );
/**********************************************************************
* find_entry
*
* Find a resource entry
*/
NTSTATUS find_entry( PVOID BaseAddress, LDR_RESOURCE_INFO *info,
ULONG level, void **ret, int want_dir )
{
ULONG size;
void *root;
IMAGE_RESOURCE_DIRECTORY *resdirptr;
USHORT list[9]; /* list of languages to try */
int i, pos = 0;
LCID user_lcid, system_lcid;
root = RtlImageDirectoryEntryToData( BaseAddress, TRUE, IMAGE_DIRECTORY_ENTRY_RESOURCE, &size );
if (!root) return STATUS_RESOURCE_DATA_NOT_FOUND;
resdirptr = root;
if (!level--) goto done;
if (!(*ret = find_entry_by_name( resdirptr, (LPCWSTR)info->Type, root, want_dir || level )))
return STATUS_RESOURCE_TYPE_NOT_FOUND;
if (!level--) return STATUS_SUCCESS;
resdirptr = *ret;
if (!(*ret = find_entry_by_name( resdirptr, (LPCWSTR)info->Name, root, want_dir || level )))
return STATUS_RESOURCE_NAME_NOT_FOUND;
if (!level--) return STATUS_SUCCESS;
if (level) return STATUS_INVALID_PARAMETER; /* level > 3 */
/* 1. specified language */
pos = push_language( list, pos, info->Language );
/* 2. specified language with neutral sublanguage */
pos = push_language( list, pos, MAKELANGID( PRIMARYLANGID(info->Language), SUBLANG_NEUTRAL ) );
/* 3. neutral language with neutral sublanguage */
pos = push_language( list, pos, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ) );
/* if no explicitly specified language, try some defaults */
if (PRIMARYLANGID(info->Language) == LANG_NEUTRAL)
{
/* user defaults, unless SYS_DEFAULT sublanguage specified */
if (SUBLANGID(info->Language) != SUBLANG_SYS_DEFAULT)
{
/* 4. current thread locale language */
pos = push_language( list, pos, LANGIDFROMLCID(NtCurrentTeb()->CurrentLocale) );
if (NT_SUCCESS(NtQueryDefaultLocale(TRUE, &user_lcid)))
{
/* 5. user locale language */
pos = push_language( list, pos, LANGIDFROMLCID(user_lcid) );
/* 6. user locale language with neutral sublanguage */
pos = push_language( list, pos, MAKELANGID( PRIMARYLANGID(user_lcid), SUBLANG_NEUTRAL ) );
}
}
/* now system defaults */
if (NT_SUCCESS(NtQueryDefaultLocale(FALSE, &system_lcid)))
{
/* 7. system locale language */
pos = push_language( list, pos, LANGIDFROMLCID( system_lcid ) );
/* 8. system locale language with neutral sublanguage */
pos = push_language( list, pos, MAKELANGID( PRIMARYLANGID(system_lcid), SUBLANG_NEUTRAL ) );
}
/* 9. English */
pos = push_language( list, pos, MAKELANGID( LANG_ENGLISH, SUBLANG_DEFAULT ) );
}
resdirptr = *ret;
for (i = 0; i < pos; i++)
if ((*ret = find_entry_by_id( resdirptr, list[i], root, want_dir ))) return STATUS_SUCCESS;
/* if no explicitly specified language, return the first entry */
if (PRIMARYLANGID(info->Language) == LANG_NEUTRAL)
{
if ((*ret = find_first_entry( resdirptr, root, want_dir ))) return STATUS_SUCCESS;
}
return STATUS_RESOURCE_LANG_NOT_FOUND;
done:
*ret = resdirptr;
return STATUS_SUCCESS;
}