mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 18:13:03 +00:00
Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys.
This commit is contained in:
parent
b94e2d8ca0
commit
c2c66aff7d
24198 changed files with 0 additions and 37285 deletions
129
sdk/lib/rtl/i386/debug_asm.S
Normal file
129
sdk/lib/rtl/i386/debug_asm.S
Normal 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
387
sdk/lib/rtl/i386/except.c
Normal 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 */
|
397
sdk/lib/rtl/i386/except_asm.s
Normal file
397
sdk/lib/rtl/i386/except_asm.s
Normal 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
153
sdk/lib/rtl/i386/interlck.S
Normal 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
|
33
sdk/lib/rtl/i386/res_asm.s
Normal file
33
sdk/lib/rtl/i386/res_asm.s
Normal 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
330
sdk/lib/rtl/i386/rtlmem.s
Normal 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
|
55
sdk/lib/rtl/i386/rtlswap.S
Normal file
55
sdk/lib/rtl/i386/rtlswap.S
Normal 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
80
sdk/lib/rtl/i386/thread.c
Normal 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 */
|
Loading…
Add table
Add a link
Reference in a new issue