Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys.

This commit is contained in:
Colin Finck 2017-10-03 07:45:34 +00:00
parent b94e2d8ca0
commit c2c66aff7d
24198 changed files with 0 additions and 37285 deletions

View file

@ -0,0 +1,129 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Run-Time Library
* PURPOSE: Debug Routines
* FILE: lib/rtl/i386/debug_asm.S
* PROGRAMER: Alex Ionescu (alex@relsoft.net)
*/
#include <asm.inc>
/* FUNCTIONS ***************************************************************/
.code
PUBLIC _DbgBreakPointNoBugCheck@0
FUNC _DbgBreakPointNoBugCheck@0
FPO 0, 0, 0, 0, 0, FRAME_FPO
/* Do breakpoint */
int 3
ret
ENDFUNC
PUBLIC _DbgUserBreakPoint@0
_DbgUserBreakPoint@0:
PUBLIC _DbgBreakPoint@0
FUNC _DbgBreakPoint@0
FPO 0, 0, 0, 0, 0, FRAME_FPO
/* Do breakpoint */
int 3
ret
ENDFUNC
PUBLIC _DbgBreakPointWithStatus@4
FUNC _DbgBreakPointWithStatus@4
FPO 0, 1, 0, 0, 0, FRAME_FPO
/* Put Status in EAX */
mov eax, [esp+4]
PUBLIC _RtlpBreakWithStatusInstruction@0
GLOBAL_LABEL _RtlpBreakWithStatusInstruction@0
/*
* Do a "labeled" breakpoint -- the KD data block has a "BreakpointWithStatus" field
* pointing to this label, letting a debugger easily check that a breakpoint has occured here
* and thereby know that there is a Status for it to retrieve from EAX
*
* In other words, Status is passed as an argument directly to the debugger
*/
int 3
ret 4
ENDFUNC
PUBLIC _DebugService2@12
FUNC _DebugService2@12
FPO 0, 3, 3, 0, 1, FRAME_NONFPO
/* Set up the stack */
push ebp
CFI_ADJUST_CFA_OFFSET 4
CFI_REL_OFFSET ebp, 0
mov ebp, esp
CFI_DEF_CFA_REGISTER ebp
/* Call the interrupt */
mov eax, [ebp+16]
mov ecx, [ebp+8]
mov edx, [ebp+12]
int HEX(2D)
int 3
/* Return */
pop ebp
CFI_SAME_VALUE ebp
CFI_DEF_CFA esp, 12
ret 12
ENDFUNC
PUBLIC _DebugService@20
FUNC _DebugService@20
FPO 0, 5, 3, 0, 1, FRAME_NONFPO
/* Set up the stack */
push ebp
CFI_ADJUST_CFA_OFFSET 4
CFI_REL_OFFSET ebp, 0
mov ebp, esp
CFI_DEF_CFA_REGISTER ebp
/* Save non-volatiles */
push ebx
CFI_REL_OFFSET ebx, -4
push edi
CFI_REL_OFFSET edi, -8
/* Call the Interrupt */
mov eax, [ebp+8]
mov ecx, [ebp+12]
mov edx, [ebp+16]
mov ebx, [ebp+20]
mov edi, [ebp+24]
int HEX(2D)
int 3
/* Restore non-volatiles */
pop edi
CFI_SAME_VALUE edi
pop ebx
CFI_SAME_VALUE ebx
/* Return */
pop ebp
CFI_SAME_VALUE ebp
CFI_DEF_CFA esp, 20
ret 20
ENDFUNC
END

387
sdk/lib/rtl/i386/except.c Normal file
View file

@ -0,0 +1,387 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Run-Time Library
* PURPOSE: User-mode exception support for IA-32
* FILE: lib/rtl/i386/except.c
* PROGRAMERS: Alex Ionescu (alex@relsoft.net)
* Casper S. Hornstrup (chorns@users.sourceforge.net)
*/
/* INCLUDES *****************************************************************/
#include <rtl.h>
#define NDEBUG
#include <debug.h>
/* PUBLIC FUNCTIONS **********************************************************/
/*
* @implemented
*/
VOID
NTAPI
RtlGetCallersAddress(OUT PVOID *CallersAddress,
OUT PVOID *CallersCaller)
{
USHORT FrameCount;
PVOID BackTrace[2];
PULONG BackTraceHash = NULL;
/* Get the tow back trace address */
FrameCount = RtlCaptureStackBackTrace(2, 2, &BackTrace[0],BackTraceHash);
/* Only if user want it */
if (CallersAddress != NULL)
{
/* only when first frames exist */
if (FrameCount >= 1)
{
*CallersAddress = BackTrace[0];
}
else
{
*CallersAddress = NULL;
}
}
/* Only if user want it */
if (CallersCaller != NULL)
{
/* only when second frames exist */
if (FrameCount >= 2)
{
*CallersCaller = BackTrace[1];
}
else
{
*CallersCaller = NULL;
}
}
}
/*
* @implemented
*/
BOOLEAN
NTAPI
RtlDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
IN PCONTEXT Context)
{
PEXCEPTION_REGISTRATION_RECORD RegistrationFrame, NestedFrame = NULL;
DISPATCHER_CONTEXT DispatcherContext;
EXCEPTION_RECORD ExceptionRecord2;
EXCEPTION_DISPOSITION Disposition;
ULONG_PTR StackLow, StackHigh;
ULONG_PTR RegistrationFrameEnd;
/* Perform vectored exception handling for user mode */
if (RtlCallVectoredExceptionHandlers(ExceptionRecord, Context))
{
/* Exception handled, now call vectored continue handlers */
RtlCallVectoredContinueHandlers(ExceptionRecord, Context);
/* Continue execution */
return TRUE;
}
/* Get the current stack limits and registration frame */
RtlpGetStackLimits(&StackLow, &StackHigh);
RegistrationFrame = RtlpGetExceptionList();
/* Now loop every frame */
while (RegistrationFrame != EXCEPTION_CHAIN_END)
{
/* Registration chain entries are never NULL */
ASSERT(RegistrationFrame != NULL);
/* Find out where it ends */
RegistrationFrameEnd = (ULONG_PTR)RegistrationFrame +
sizeof(EXCEPTION_REGISTRATION_RECORD);
/* Make sure the registration frame is located within the stack */
if ((RegistrationFrameEnd > StackHigh) ||
((ULONG_PTR)RegistrationFrame < StackLow) ||
((ULONG_PTR)RegistrationFrame & 0x3))
{
/* Check if this happened in the DPC Stack */
if (RtlpHandleDpcStackException(RegistrationFrame,
RegistrationFrameEnd,
&StackLow,
&StackHigh))
{
/* Use DPC Stack Limits and restart */
continue;
}
/* Set invalid stack and return false */
ExceptionRecord->ExceptionFlags |= EXCEPTION_STACK_INVALID;
return FALSE;
}
/* Check if logging is enabled */
RtlpCheckLogException(ExceptionRecord,
Context,
RegistrationFrame,
sizeof(*RegistrationFrame));
/* Call the handler */
Disposition = RtlpExecuteHandlerForException(ExceptionRecord,
RegistrationFrame,
Context,
&DispatcherContext,
RegistrationFrame->Handler);
/* Check if this is a nested frame */
if (RegistrationFrame == NestedFrame)
{
/* Mask out the flag and the nested frame */
ExceptionRecord->ExceptionFlags &= ~EXCEPTION_NESTED_CALL;
NestedFrame = NULL;
}
/* Handle the dispositions */
switch (Disposition)
{
/* Continue execution */
case ExceptionContinueExecution:
/* Check if it was non-continuable */
if (ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE)
{
/* Set up the exception record */
ExceptionRecord2.ExceptionRecord = ExceptionRecord;
ExceptionRecord2.ExceptionCode =
STATUS_NONCONTINUABLE_EXCEPTION;
ExceptionRecord2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
ExceptionRecord2.NumberParameters = 0;
/* Raise the exception */
RtlRaiseException(&ExceptionRecord2);
}
else
{
/* In user mode, call any registered vectored continue handlers */
RtlCallVectoredContinueHandlers(ExceptionRecord,
Context);
/* Execution continues */
return TRUE;
}
/* Continue searching */
case ExceptionContinueSearch:
break;
/* Nested exception */
case ExceptionNestedException:
/* Turn the nested flag on */
ExceptionRecord->ExceptionFlags |= EXCEPTION_NESTED_CALL;
/* Update the current nested frame */
if (DispatcherContext.RegistrationPointer > NestedFrame)
{
/* Get the frame from the dispatcher context */
NestedFrame = DispatcherContext.RegistrationPointer;
}
break;
/* Anything else */
default:
/* Set up the exception record */
ExceptionRecord2.ExceptionRecord = ExceptionRecord;
ExceptionRecord2.ExceptionCode = STATUS_INVALID_DISPOSITION;
ExceptionRecord2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
ExceptionRecord2.NumberParameters = 0;
/* Raise the exception */
RtlRaiseException(&ExceptionRecord2);
break;
}
/* Go to the next frame */
RegistrationFrame = RegistrationFrame->Next;
}
/* Unhandled, return false */
return FALSE;
}
/*
* @implemented
*/
VOID
NTAPI
RtlUnwind(IN PVOID TargetFrame OPTIONAL,
IN PVOID TargetIp OPTIONAL,
IN PEXCEPTION_RECORD ExceptionRecord OPTIONAL,
IN PVOID ReturnValue)
{
PEXCEPTION_REGISTRATION_RECORD RegistrationFrame, OldFrame;
DISPATCHER_CONTEXT DispatcherContext;
EXCEPTION_RECORD ExceptionRecord2, ExceptionRecord3;
EXCEPTION_DISPOSITION Disposition;
ULONG_PTR StackLow, StackHigh;
ULONG_PTR RegistrationFrameEnd;
CONTEXT LocalContext;
PCONTEXT Context;
/* Get the current stack limits */
RtlpGetStackLimits(&StackLow, &StackHigh);
/* Check if we don't have an exception record */
if (!ExceptionRecord)
{
/* Overwrite the argument */
ExceptionRecord = &ExceptionRecord3;
/* Setup a local one */
ExceptionRecord3.ExceptionFlags = 0;
ExceptionRecord3.ExceptionCode = STATUS_UNWIND;
ExceptionRecord3.ExceptionRecord = NULL;
ExceptionRecord3.ExceptionAddress = _ReturnAddress();
ExceptionRecord3.NumberParameters = 0;
}
/* Check if we have a frame */
if (TargetFrame)
{
/* Set it as unwinding */
ExceptionRecord->ExceptionFlags |= EXCEPTION_UNWINDING;
}
else
{
/* Set the Exit Unwind flag as well */
ExceptionRecord->ExceptionFlags |= (EXCEPTION_UNWINDING |
EXCEPTION_EXIT_UNWIND);
}
/* Now capture the context */
Context = &LocalContext;
LocalContext.ContextFlags = CONTEXT_INTEGER |
CONTEXT_CONTROL |
CONTEXT_SEGMENTS;
RtlpCaptureContext(Context);
/* Pop the current arguments off */
Context->Esp += sizeof(TargetFrame) +
sizeof(TargetIp) +
sizeof(ExceptionRecord) +
sizeof(ReturnValue);
/* Set the new value for EAX */
Context->Eax = (ULONG)ReturnValue;
/* Get the current frame */
RegistrationFrame = RtlpGetExceptionList();
/* Now loop every frame */
while (RegistrationFrame != EXCEPTION_CHAIN_END)
{
/* Registration chain entries are never NULL */
ASSERT(RegistrationFrame != NULL);
/* If this is the target */
if (RegistrationFrame == TargetFrame) ZwContinue(Context, FALSE);
/* Check if the frame is too low */
if ((TargetFrame) &&
((ULONG_PTR)TargetFrame < (ULONG_PTR)RegistrationFrame))
{
/* Create an invalid unwind exception */
ExceptionRecord2.ExceptionCode = STATUS_INVALID_UNWIND_TARGET;
ExceptionRecord2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
ExceptionRecord2.ExceptionRecord = ExceptionRecord;
ExceptionRecord2.NumberParameters = 0;
/* Raise the exception */
RtlRaiseException(&ExceptionRecord2);
}
/* Find out where it ends */
RegistrationFrameEnd = (ULONG_PTR)RegistrationFrame +
sizeof(EXCEPTION_REGISTRATION_RECORD);
/* Make sure the registration frame is located within the stack */
if ((RegistrationFrameEnd > StackHigh) ||
((ULONG_PTR)RegistrationFrame < StackLow) ||
((ULONG_PTR)RegistrationFrame & 0x3))
{
/* Check if this happened in the DPC Stack */
if (RtlpHandleDpcStackException(RegistrationFrame,
RegistrationFrameEnd,
&StackLow,
&StackHigh))
{
/* Use DPC Stack Limits and restart */
continue;
}
/* Create an invalid stack exception */
ExceptionRecord2.ExceptionCode = STATUS_BAD_STACK;
ExceptionRecord2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
ExceptionRecord2.ExceptionRecord = ExceptionRecord;
ExceptionRecord2.NumberParameters = 0;
/* Raise the exception */
RtlRaiseException(&ExceptionRecord2);
}
else
{
/* Call the handler */
Disposition = RtlpExecuteHandlerForUnwind(ExceptionRecord,
RegistrationFrame,
Context,
&DispatcherContext,
RegistrationFrame->Handler);
switch(Disposition)
{
/* Continue searching */
case ExceptionContinueSearch:
break;
/* Collission */
case ExceptionCollidedUnwind :
/* Get the original frame */
RegistrationFrame = DispatcherContext.RegistrationPointer;
break;
/* Anything else */
default:
/* Set up the exception record */
ExceptionRecord2.ExceptionRecord = ExceptionRecord;
ExceptionRecord2.ExceptionCode = STATUS_INVALID_DISPOSITION;
ExceptionRecord2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
ExceptionRecord2.NumberParameters = 0;
/* Raise the exception */
RtlRaiseException(&ExceptionRecord2);
break;
}
/* Go to the next frame */
OldFrame = RegistrationFrame;
RegistrationFrame = RegistrationFrame->Next;
/* Remove this handler */
RtlpSetExceptionList(OldFrame);
}
}
/* Check if we reached the end */
if (TargetFrame == EXCEPTION_CHAIN_END)
{
/* Unwind completed, so we don't exit */
ZwContinue(Context, FALSE);
}
else
{
/* This is an exit_unwind or the frame wasn't present in the list */
ZwRaiseException(ExceptionRecord, Context, FALSE);
}
}
/* EOF */

View file

@ -0,0 +1,397 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Runtime Library (RTL)
* FILE: lib/rtl/i386/except_asm.s
* PURPOSE: User-mode exception support for IA-32
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
* Stefan Ginsberg (stefan.ginsberg@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <asm.inc>
#include <ks386.inc>
EXTERN _RtlpCheckForActiveDebugger@0:PROC
EXTERN _RtlDispatchException@8:PROC
EXTERN _ZwContinue@8:PROC
EXTERN _ZwRaiseException@12:PROC
#define ExceptionContinueSearch 1
#define ExceptionNestedException 2
#define ExceptionCollidedUnwind 3
/* FUNCTIONS *****************************************************************/
.code
PUBLIC _RtlpGetExceptionList@0
_RtlpGetExceptionList@0:
/* Return the exception list */
mov eax, fs:[TEB_EXCEPTION_LIST]
ret
PUBLIC _RtlpSetExceptionList@4
_RtlpSetExceptionList@4:
/* Get the new list */
mov ecx, [esp+4]
mov ecx, [ecx]
/* Write it */
mov fs:[TEB_EXCEPTION_LIST], ecx
/* Return */
ret 4
PUBLIC _RtlCaptureContext@4
_RtlCaptureContext@4:
/* Preserve EBX and put the context in it */
push ebx
mov ebx, [esp+8]
/* Save the basic register context */
mov [ebx+CONTEXT_EAX], eax
mov [ebx+CONTEXT_ECX], ecx
mov [ebx+CONTEXT_EDX], edx
mov eax, [esp]
mov [ebx+CONTEXT_EBX], eax
mov [ebx+CONTEXT_ESI], esi
mov [ebx+CONTEXT_EDI], edi
/* Capture the other regs */
jmp CaptureRest
PUBLIC _RtlpCaptureContext@4
_RtlpCaptureContext@4:
/* Preserve EBX and put the context in it */
push ebx
mov ebx, [esp+8]
/* Clear the basic register context */
mov dword ptr [ebx+CONTEXT_EAX], 0
mov dword ptr [ebx+CONTEXT_ECX], 0
mov dword ptr [ebx+CONTEXT_EDX], 0
mov dword ptr [ebx+CONTEXT_EBX], 0
mov dword ptr [ebx+CONTEXT_ESI], 0
mov dword ptr [ebx+CONTEXT_EDI], 0
CaptureRest:
/* Capture the segment registers */
mov [ebx+CONTEXT_SEGCS], cs
mov [ebx+CONTEXT_SEGDS], ds
mov [ebx+CONTEXT_SEGES], es
mov [ebx+CONTEXT_SEGFS], fs
mov [ebx+CONTEXT_SEGGS], gs
mov [ebx+CONTEXT_SEGSS], ss
/* Capture flags */
pushfd
pop [ebx+CONTEXT_EFLAGS]
/* The return address should be in [ebp+4] */
mov eax, [ebp+4]
mov [ebx+CONTEXT_EIP], eax
/* Get EBP */
mov eax, [ebp+0]
mov [ebx+CONTEXT_EBP], eax
/* And get ESP */
lea eax, [ebp+8]
mov [ebx+CONTEXT_ESP], eax
/* Return to the caller */
pop ebx
ret 4
PUBLIC _RtlpExecuteHandlerForException@20
_RtlpExecuteHandlerForException@20:
/* Copy the routine in EDX */
mov edx, offset _RtlpExceptionProtector
/* Jump to common routine */
jmp _RtlpExecuteHandler@20
PUBLIC _RtlpExecuteHandlerForUnwind@20
_RtlpExecuteHandlerForUnwind@20:
/* Copy the routine in EDX */
mov edx, offset _RtlpUnwindProtector
_RtlpExecuteHandler@20:
/* Save non-volatile */
push ebx
push esi
push edi
/* Clear registers */
xor eax, eax
xor ebx, ebx
xor esi, esi
xor edi, edi
/* Call the 2nd-stage executer */
push [esp+32]
push [esp+32]
push [esp+32]
push [esp+32]
push [esp+32]
call _RtlpExecuteHandler2@20
/* Restore non-volatile */
pop edi
pop esi
pop ebx
ret 20
PUBLIC _RtlpExecuteHandler2@20
_RtlpExecuteHandler2@20:
/* Set up stack frame */
push ebp
mov ebp, esp
/* Save the Frame */
push [ebp+12]
/* Push handler address */
push edx
/* Push the exception list */
push [fs:TEB_EXCEPTION_LIST]
/* Link us to it */
mov [fs:TEB_EXCEPTION_LIST], esp
/* Call the handler */
push [ebp+20]
push [ebp+16]
push [ebp+12]
push [ebp+8]
mov ecx, [ebp+24]
call ecx
/* Unlink us */
mov esp, [fs:TEB_EXCEPTION_LIST]
/* Restore it */
pop [fs:TEB_EXCEPTION_LIST]
/* Undo stack frame and return */
mov esp, ebp
pop ebp
ret 20
_RtlpExceptionProtector:
/* Assume we'll continue */
mov eax, ExceptionContinueSearch
/* Put the exception record in ECX and check the Flags */
mov ecx, [esp+4]
test dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_UNWINDING + EXCEPTION_EXIT_UNWIND
jnz return
/* Save the frame in ECX and Context in EDX */
mov ecx, [esp+8]
mov edx, [esp+16]
/* Get the nested frame */
mov eax, [ecx+8]
/* Set it as the dispatcher context */
mov [edx], eax
/* Return nested exception */
mov eax, ExceptionNestedException
return:
ret 16
_RtlpUnwindProtector:
/* Assume we'll continue */
mov eax, ExceptionContinueSearch
/* Put the exception record in ECX and check the Flags */
mov ecx, [esp+4]
test dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_UNWINDING + EXCEPTION_EXIT_UNWIND
jz .return
/* Save the frame in ECX and Context in EDX */
mov ecx, [esp+8]
mov edx, [esp+16]
/* Get the nested frame */
mov eax, [ecx+8]
/* Set it as the dispatcher context */
mov [edx], eax
/* Return collided unwind */
mov eax, ExceptionCollidedUnwind
.return:
ret 16
PUBLIC _RtlRaiseException@4
_RtlRaiseException@4:
/* Set up stack frame */
push ebp
mov ebp, esp
/*
* Save the context while preserving everything but ESP and EBP.
* This is vital because the caller will be restored with this context
* in case the execution is continued, which means we must not clobber
* the non-volatiles. We preserve the volatiles too because the context
* could get passed to a debugger.
*/
lea esp, [esp-CONTEXT_FRAME_LENGTH]
push esp
call _RtlCaptureContext@4
/* Adjust ESP to account for the argument that was passed */
add dword ptr [esp+CONTEXT_ESP], 4
/* Save the exception address */
mov edx, [ebp+4]
mov eax, [ebp+8]
mov [eax+EXCEPTION_RECORD_EXCEPTION_ADDRESS], edx
/* Write the context flag */
mov dword ptr [esp+CONTEXT_FLAGS], CONTEXT_FULL
/* Check if user mode debugger is active */
call _RtlpCheckForActiveDebugger@0
test al, al
jnz DebuggerActive1
/* Dispatch the exception */
push esp
push [ebp+8]
call _RtlDispatchException@8
test al, al
jz RaiseException
/* Continue, go back to previous context */
mov ecx, esp
push 0
push ecx
call _ZwContinue@8
jmp RaiseStatus1
DebuggerActive1:
/* Raise an exception immediately */
mov ecx, esp
push 1
push ecx
push [ebp+8]
call _ZwRaiseException@12
jmp RaiseStatus1
RaiseException:
/* Raise the exception */
mov ecx, esp
push 0
push ecx
push [ebp+8]
call _ZwRaiseException@12
RaiseStatus1:
/* If we returned, raise a status */
push eax
call _RtlRaiseStatus@4
PUBLIC _RtlRaiseStatus@4
_RtlRaiseStatus@4:
/* Set up stack frame */
push ebp
mov ebp, esp
/*
* Save the context while preserving everything but ESP and EBP.
* This is vital because the caller will be restored with this context
* in case the execution is continued, which means we must not clobber
* the non-volatiles. We preserve the volatiles too because the context
* could get passed to a debugger.
*/
lea esp, [esp-CONTEXT_FRAME_LENGTH-EXCEPTION_RECORD_LENGTH]
push esp
call _RtlCaptureContext@4
/* Adjust ESP to account for the argument that was passed */
add dword ptr [esp+CONTEXT_ESP], 4
/* Set up the exception record */
lea ecx, [esp+CONTEXT_FRAME_LENGTH]
mov eax, [ebp+8]
mov dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_CODE], eax
mov dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_NONCONTINUABLE
and dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_RECORD], 0
mov eax, [ebp+4]
mov dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_ADDRESS], eax
and dword ptr [ecx+EXCEPTION_RECORD_NUMBER_PARAMETERS], 0
/* Write the context flag */
mov dword ptr [esp+CONTEXT_FLAGS], CONTEXT_FULL
/* Check if user mode debugger is active */
call _RtlpCheckForActiveDebugger@0
/* Restore ECX and jump if debugger is active */
lea ecx, [esp+CONTEXT_FRAME_LENGTH]
test al, al
jnz DebuggerActive2
/* Dispatch the exception */
push esp
push ecx
call _RtlDispatchException@8
/* Raise exception if we got here */
lea ecx, [esp+CONTEXT_FRAME_LENGTH]
mov edx, esp
push 0
push edx
push ecx
call _ZwRaiseException@12
jmp RaiseStatus2
DebuggerActive2:
/* Raise an exception immediately */
mov edx, esp
push 1
push edx
push ecx
call _ZwRaiseException@12
RaiseStatus2:
/* If we returned, raise a status */
push eax
call _RtlRaiseStatus@4
END

153
sdk/lib/rtl/i386/interlck.S Normal file
View file

@ -0,0 +1,153 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/rtl/i386/interlck.S
* PURPOSE: Rtl Interlocked Functions for x86
* PROGRAMMERS: Timo Kreuzer
*/
#include <asm.inc>
/* FUNCTIONS ****************************************************************/
.code
/* PSLIST_ENTRY
* NTAPI
* RtlInterlockedPopEntrySList(
* IN PSLIST_HEADER ListHead);
*/
PUBLIC _ExpInterlockedPopEntrySListResume@0
PUBLIC _ExpInterlockedPopEntrySListEnd@0
PUBLIC _ExpInterlockedPopEntrySListFault@0
PUBLIC _RtlInterlockedPopEntrySList@4
_RtlInterlockedPopEntrySList@4:
/* Save registers */
push ebx
push ebp
/* Load ListHead into ebp */
mov ebp, [esp + 12]
_ExpInterlockedPopEntrySListResume@0:
/* Load ListHead->Next into eax */
mov eax, [ebp]
/* Load ListHead->Depth and ListHead->Sequence into edx */
mov edx, [ebp + 4]
/* Check if ListHead->Next is NULL */
or eax, eax
jz _ExpInterlockedPopEntrySList2
/* Copy Depth and Sequence number and adjust Depth */
lea ecx, [edx - 1]
_ExpInterlockedPopEntrySListFault@0:
/* Get next pointer */
mov ebx, [eax]
_ExpInterlockedPopEntrySListEnd@0:
/* If [ebp] equals edx:eax, exchange it with ecx:ebx */
LOCK cmpxchg8b qword ptr [ebp]
/* If not equal, retry with edx:eax, being the content of [ebp] now */
jnz _ExpInterlockedPopEntrySListResume@0
/* Restore registers and return */
_ExpInterlockedPopEntrySList2:
pop ebp
pop ebx
ret 4
/* PSLIST_ENTRY
* NTAPI
* RtlInterlockedPushEntrySList(
* IN PSLIST_HEADER ListHead,
* IN PSLIST_ENTRY ListEntry);
*/
PUBLIC _RtlInterlockedPushEntrySList@8
_RtlInterlockedPushEntrySList@8:
/* Save registers */
push ebx
push ebp
/* Load ListHead into ebp */
mov ebp, [esp + 12]
/* Load ListEntry into ebx */
mov ebx, [esp + 16]
/* Load ListHead->Next into eax */
mov eax, [ebp]
/* Load ListHead->Depth and ListHead->Sequence into edx */
mov edx, [ebp + 4]
_RtlpInterlockedPushEntrySListResume:
/* Set ListEntry->Next to ListHead->Next */
mov [ebx], eax
/* Copy ListHead->Depth and ListHead->Sequence and adjust them */
lea ecx, [edx + HEX(10001)]
/* If [ebp] equals edx:eax, exchange it with ecx:ebx */
LOCK cmpxchg8b qword ptr [ebp]
/* If not equal, retry with edx:eax, being the content of [ebp] now */
jnz _RtlpInterlockedPushEntrySListResume
/* Restore registers and return */
pop ebp
pop ebx
ret 8
/* PSLIST_ENTRY
* NTAPI
* RtlInterlockedFlushSList(
* IN PSINGLE_LIST_ENTRY ListHead);
*/
PUBLIC _RtlInterlockedFlushSList@4
_RtlInterlockedFlushSList@4:
/* Save registers */
push ebx
push ebp
/* Clear ebx */
xor ebx, ebx
/* Load ListHead into ebp */
mov ebp, [esp + 12]
/* Load ListHead->Next into eax */
mov eax, [ebp]
/* Load ListHead->Depth and ListHead->Sequence into edx */
mov edx, [ebp + 4]
_RtlpInterlockedFlushSListResume:
/* Check if ListHead->Next is NULL */
or eax, eax
jz _RtlpInterlockedFlushSListEnd
/* Copy Depth and Sequence number to ecx */
mov ecx, edx
/* Clear Depth in cx */
xor cx, cx
/* If [ebp] equals edx:eax, exchange it with ecx:ebx */
LOCK cmpxchg8b qword ptr [ebp]
/* If not equal, retry with edx:eax, being the content of [ebp] now */
jnz _RtlpInterlockedFlushSListResume
/* Restore registers and return */
_RtlpInterlockedFlushSListEnd:
pop ebp
pop ebx
ret 4
END

View file

@ -0,0 +1,33 @@
/*
* COPYRIGHT: GNU GPL - See COPYING in the top level directory
* PROJECT: ReactOS Run-Time Library
* PURPOSE:
* FILE: lib/rtl/i386/res_asm.s
* PROGRAMER:
*/
#include <asm.inc>
#include <ks386.inc>
EXTERN _LdrpAccessResource@16:PROC
/*
* On x86, Shrinker, an executable compressor, depends on the
* "call access_resource" instruction being there.
*/
.code
PUBLIC _LdrAccessResource@16
_LdrAccessResource@16:
push ebp
mov ebp, esp
sub esp, 4
push [ebp + 24]
push [ebp + 20]
push [ebp + 16]
push [ebp + 12]
push [ebp + 8]
call _LdrpAccessResource@16
leave
ret 16
END

330
sdk/lib/rtl/i386/rtlmem.s Normal file
View file

@ -0,0 +1,330 @@
/*
* COPYRIGHT: GNU GPL - See COPYING in the top level directory
* PROJECT: ReactOS Run-Time Library
* PURPOSE: Memory functions
* FILE: lib/rtl/i386/rtlmem.s
* PROGRAMER: Alex Ionescu (alex.ionescu@reactos.org)
*/
#include <asm.inc>
/* GLOBALS *******************************************************************/
PUBLIC _RtlCompareMemory@12
PUBLIC _RtlCompareMemoryUlong@12
PUBLIC _RtlFillMemory@12
PUBLIC _RtlFillMemoryUlong@12
PUBLIC _RtlMoveMemory@12
PUBLIC _RtlZeroMemory@8
/* FUNCTIONS *****************************************************************/
.code
_RtlCompareMemory@12:
/* Save volatiles */
push esi
push edi
/* Clear direction flag and load pointers and size in ULONGs */
cld
mov esi, [esp+12]
mov edi, [esp+16]
mov ecx, [esp+20]
shr ecx, 2
jz NoUlongs
/* Compare the ULONGs */
repe cmpsd
jnz NotEqual
NoUlongs:
/* Compare what's left */
mov ecx, [esp+20]
and ecx, 3
jz NoneLeft
repe cmpsb
jnz NotEqual2
NoneLeft:
/* We're done, return full count */
mov eax, [esp+20]
pop edi
pop esi
ret 12
NotEqual:
/* Compare the last ULONG */
sub esi, 4
sub edi, 4
mov ecx, 5
repe cmpsb
NotEqual2:
/* Remember how many matched */
dec esi
sub esi, [esp+12]
/* Return count */
mov eax, esi
pop edi
pop esi
ret 12
_RtlCompareMemoryUlong@12:
/* Get pointers and size in ULONGs */
push edi
mov edi, [esp+8]
mov ecx, [esp+12]
mov eax, [esp+16]
shr ecx, 2
/* Do the compare and check result */
repe scasd
jz Done
sub edi, 4
/* Return count */
Done:
sub edi, [esp+8]
mov eax, edi
pop edi
ret 12
_RtlFillMemory@12:
/* Get pointers and size */
push edi
mov edi, [esp+8]
mov ecx, [esp+12]
/* Get pattern */
mov al, [esp+16]
mov ah, al
shl eax, 16
mov al, [esp+16]
mov ah, al
/* Clear direction flag and set ULONG size and UCHAR remainder */
cld
mov edx, ecx
and edx, 3
shr ecx, 2
/* Do the fill */
rep stosd
or ecx, edx
jnz ByteFill
/* Return */
pop edi
ret 12
ByteFill:
/* Fill what's left */
rep stosb
pop edi
ret 12
_RtlFillMemoryUlong@12:
/* Get pointer, size and pattern */
push edi
mov edi, [esp+8]
mov ecx, [esp+12]
mov eax, [esp+16]
shr ecx, 2
/* Do the fill and return */
rep stosd
pop edi
ret 12
_RtlFillMemoryUlonglong@16:
/* Save volatiles */
push edi
push esi
/* Get pointer, size and pattern */
mov ecx, [esp+16]
mov esi, [esp+12]
mov eax, [esp+20]
shr ecx, 2
sub ecx, 2
/* Save the first part */
mov [esi], eax
/* Read second part */
mov eax, [esp+24]
lea edi, [esi+8]
mov [esi+4], eax
/* Do the fill and return */
rep movsd
pop esi
pop edi
ret 16
_RtlZeroMemory@8:
/* Get pointers and size */
push edi
mov edi, [esp+8]
mov ecx, [esp+12]
/* Get pattern */
xor eax, eax
/* Clear direction flag and set ULONG size and UCHAR remainder */
cld
mov edx, ecx
and edx, 3
shr ecx, 2
/* Do the fill */
rep stosd
or ecx, edx
jnz ByteZero
/* Return */
pop edi
ret 8
ByteZero:
/* Fill what's left */
rep stosb
pop edi
ret 8
_RtlMoveMemory@12:
push ebp
mov ebp, esp
/* Save non-volatiles */
push esi
push edi
/* Get pointers and size */
mov edi, [ebp + 8]
mov esi, [ebp + 12]
mov ecx, [ebp + 16]
/* Use downward copy if source < dest and overlapping */
cmp edi, esi
jbe .CopyUp
mov eax, ecx
add eax, esi
cmp edi, eax
jb .CopyDown
.CopyUp:
cld
/* Check for small moves */
cmp ecx, 16
jb .CopyUpBytes
/* Check if its already aligned */
mov edx, ecx
test edi, 3
je .CopyUpDwords
/* Make the destination dword aligned */
mov ecx, edi
and ecx, 3
sub ecx, 5
not ecx
sub edx, ecx
rep movsb
mov ecx, edx
.CopyUpDwords:
shr ecx, 2
rep movsd
mov ecx, edx
and ecx, 3
.CopyUpBytes:
test ecx, ecx
je .CopyUpEnd
rep movsb
.CopyUpEnd:
mov eax, [ebp + 8]
pop edi
pop esi
pop ebp
ret 12
.CopyDown:
std
/* Go to the end of the region */
add edi, ecx
add esi, ecx
/* Check for small moves */
cmp ecx, 16
jb .CopyDownSmall
/* Check if its already aligned */
mov edx, ecx
test edi, 3
je .CopyDownAligned
/* Make the destination dword aligned */
mov ecx, edi
and ecx, 3
sub edx, ecx
dec esi
dec edi
rep movsb
mov ecx, edx
sub esi, 3
sub edi, 3
.CopyDownDwords:
shr ecx, 2
rep movsd
mov ecx, edx
and ecx, 3
je .CopyDownEnd
add esi, 3
add edi, 3
.CopyDownBytes:
rep movsb
.CopyDownEnd:
cld
mov eax, [ebp + 8]
pop edi
pop esi
pop ebp
ret 12
.CopyDownAligned:
sub edi, 4
sub esi, 4
jmp .CopyDownDwords
.CopyDownSmall:
test ecx, ecx
je .CopyDownEnd
dec esi
dec edi
jmp .CopyDownBytes
END

View file

@ -0,0 +1,55 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Run-Time Library
* PURPOSE: Byte swap functions
* FILE: lib/rtl/i386/rtlswap.S
* PROGRAMER: Alex Ionescu (alex.ionescu@reactos.org)
* Timo Kreuzer (timo.kreuzer@reactos.org)
*/
#include <asm.inc>
PUBLIC @RtlUshortByteSwap@4
PUBLIC @RtlUlongByteSwap@4
PUBLIC @RtlUlonglongByteSwap@8
/* FUNCTIONS ***************************************************************/
.code
FUNC @RtlUshortByteSwap@4
FPO 0, 0, 0, 0, 0, FRAME_FPO
/* Swap high and low bits */
mov ah, cl
mov al, ch
ret
ENDFUNC
FUNC @RtlUlongByteSwap@4
FPO 0, 0, 0, 0, 0, FRAME_FPO
/* Swap high and low bits */
mov eax, ecx
bswap eax
ret
ENDFUNC
FUNC @RtlUlonglongByteSwap@8
FPO 0, 2, 0, 0, 0, FRAME_FPO
/* Get 64-bit integer */
mov eax, [esp+8]
mov edx, [esp+4]
/* Swap it */
bswap edx
bswap eax
/* Return it (NOTE: this might look wrong, since fastcall functions
should clean up the stack, even if the first parameter is an ULONGLONG,
and therefore put on tthe stack instead of in ecx and edx,
but thats exactly how the function behaves on Windows! */
ret
ENDFUNC
END

80
sdk/lib/rtl/i386/thread.c Normal file
View file

@ -0,0 +1,80 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* PURPOSE: Rtl user thread functions
* FILE: lib/rtl/i386/thread.c
* PROGRAMERS:
* Alex Ionescu (alex@relsoft.net)
* Eric Kohl
* KJK::Hyperion
*/
/* INCLUDES *****************************************************************/
#include <rtl.h>
#include "i386/ketypes.h"
#define NDEBUG
#include <debug.h>
/* PRIVATE FUNCTIONS *******************************************************/
/*
* @implemented
*/
VOID
NTAPI
RtlInitializeContext(IN HANDLE ProcessHandle,
OUT PCONTEXT ThreadContext,
IN PVOID ThreadStartParam OPTIONAL,
IN PTHREAD_START_ROUTINE ThreadStartAddress,
IN PINITIAL_TEB InitialTeb)
{
DPRINT("RtlInitializeContext: (hProcess: %p, ThreadContext: %p, Teb: %p\n",
ProcessHandle, ThreadContext, InitialTeb);
/*
* Set the Initial Registers
* This is based on NT's default values -- crazy apps might expect this...
*/
ThreadContext->Ebp = 0;
ThreadContext->Eax = 0;
ThreadContext->Ebx = 1;
ThreadContext->Ecx = 2;
ThreadContext->Edx = 3;
ThreadContext->Esi = 4;
ThreadContext->Edi = 5;
/* Set the Selectors */
ThreadContext->SegGs = 0;
ThreadContext->SegFs = KGDT_R3_TEB;
ThreadContext->SegEs = KGDT_R3_DATA;
ThreadContext->SegDs = KGDT_R3_DATA;
ThreadContext->SegSs = KGDT_R3_DATA;
ThreadContext->SegCs = KGDT_R3_CODE;
/* Enable Interrupts */
ThreadContext->EFlags = EFLAGS_INTERRUPT_MASK;
/* Settings passed */
ThreadContext->Eip = (ULONG)ThreadStartAddress;
ThreadContext->Esp = (ULONG)InitialTeb;
/* Only the basic Context is initialized */
ThreadContext->ContextFlags = CONTEXT_CONTROL |
CONTEXT_INTEGER |
CONTEXT_SEGMENTS;
/* Set up ESP to the right value */
ThreadContext->Esp -= sizeof(PVOID);
ZwWriteVirtualMemory(ProcessHandle,
(PVOID)ThreadContext->Esp,
(PVOID)&ThreadStartParam,
sizeof(PVOID),
NULL);
/* Push it down one more notch for RETEIP */
ThreadContext->Esp -= sizeof(PVOID);
}
/* EOF */