Author: tkreuzer
Date: Wed Jan 6 01:39:07 2010
New Revision: 44970
URL:
http://svn.reactos.org/svn/reactos?rev=44970&view=rev
Log:
[RTL]
Merge from amd64 branch
35738,37004,37308,37324,37330,37331,37332,37370,37419,37424,37425,37428,37473,37492,37844,37911,37987,40604,41006,43686,43951,43953,43980,43993,44001,44289,44295,44296,44428,44966,44967,44968
- Implement amd64 specific RTL functions: RtlLookupFunctionTable, RtlLookupFunctionEntry,
RtlCaptureContext, RtlVirtualUnwind, RtlWalkFrameChain, RtlGetCallersAddress,
RtlRaiseException (Timo Kreuzer)
- Implement amd64 asm functions: RtlCompareMemory, DebugService,
RtlInterlockedPopEntrySList, RtlInterlockedPushEntrySList and RtlInterlockedFlushSList
(Timo Kreuzer)
- Don't use double in rtl's sprintf / swprintf, use double_t union instead.
(Stefan Ginsberg)
Added:
trunk/reactos/lib/rtl/amd64/ (with props)
trunk/reactos/lib/rtl/amd64/debug_asm.S (with props)
trunk/reactos/lib/rtl/amd64/except_asm.S (with props)
trunk/reactos/lib/rtl/amd64/rtlmem.S (with props)
trunk/reactos/lib/rtl/amd64/slist.S (with props)
trunk/reactos/lib/rtl/amd64/stubs.c (with props)
trunk/reactos/lib/rtl/amd64/unwind.c (with props)
Modified:
trunk/reactos/lib/rtl/exception.c
trunk/reactos/lib/rtl/rtl.rbuild
trunk/reactos/lib/rtl/rtlp.h
trunk/reactos/lib/rtl/slist.c
trunk/reactos/lib/rtl/sprintf.c
trunk/reactos/lib/rtl/swprintf.c
Propchange: trunk/reactos/lib/rtl/amd64/
------------------------------------------------------------------------------
--- bugtraq:logregex (added)
+++ bugtraq:logregex Wed Jan 6 01:39:07 2010
@@ -1,0 +1,2 @@
+([Ii]ssue|[Bb]ug)s? #?(\d+)(,? ?#?(\d+))*(,? ?(and |or )?#?(\d+))?
+(\d+)
Propchange: trunk/reactos/lib/rtl/amd64/
------------------------------------------------------------------------------
bugtraq:message = See issue #%BUGID% for more details.
Propchange: trunk/reactos/lib/rtl/amd64/
------------------------------------------------------------------------------
bugtraq:url =
http://www.reactos.org/bugzilla/show_bug.cgi?id=%BUGID%
Propchange: trunk/reactos/lib/rtl/amd64/
------------------------------------------------------------------------------
tsvn:logminsize = 10
Added: trunk/reactos/lib/rtl/amd64/debug_asm.S
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/amd64/debug_asm.S?…
==============================================================================
--- trunk/reactos/lib/rtl/amd64/debug_asm.S (added)
+++ trunk/reactos/lib/rtl/amd64/debug_asm.S [iso-8859-1] Wed Jan 6 01:39:07 2010
@@ -1,0 +1,79 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Run-Time Library
+ * PURPOSE: Debug Routines
+ * FILE: lib/rtl/i386/debug.S
+ * PROGRAMER: Alex Ionescu (alex(a)relsoft.net)
+ */
+
+.intel_syntax noprefix
+
+/* GLOBALS ****************************************************************/
+
+.globl _DbgBreakPoint
+.globl _DbgBreakPointWithStatus
+.globl _DbgUserBreakPoint
+.globl _DebugService
+.globl _DebugService2
+.globl _DbgBreakPointNoBugCheck
+.globl _RtlpBreakWithStatusInstruction
+
+/* FUNCTIONS ***************************************************************/
+
+.func DbgBreakPointNoBugCheck
+_DbgBreakPointNoBugCheck:
+ int 3
+ ret
+.endfunc
+
+.func DbgBreakPoint
+_DbgBreakPoint:
+_DbgUserBreakPoint:
+ int 3
+ ret
+.endfunc
+
+.func DbgBreakPointWithStatus
+_DbgBreakPointWithStatus:
+ mov eax, ecx
+
+_RtlpBreakWithStatusInstruction:
+ int 3
+ ret
+.endfunc
+
+.func DebugService2
+_DebugService2:
+ ret
+ /* Call the interrupt */
+// mov eax, [rbp+8]
+// int 0x2D
+// int 3
+
+.endfunc
+
+/******************************************************************************
+ * NTSTATUS NTAPI DebugService(
+ * IN ULONG Service, // <rcx> = [rsp + 8]
+ * IN PVOID Buffer, // <rdx> = [rsp + 16]
+ * IN ULONG Length, // <r8> = [rsp + 24]
+ * IN PVOID Argument1, // <r9> = [rsp + 32]
+ * IN PVOID Argument2); // [rsp + 40]
+ */
+.func DebugService
+_DebugService:
+
+ /* Prepare registers for interrupt */
+ mov eax, ecx // Service
+ mov rcx, rdx // Buffer
+ mov edx, r8d // Length
+ mov r8, r9 // Argument1
+ mov r9, [rsp + 40] // Argument2
+
+ /* Call the Interrupt */
+ int 0x2D
+ int 3
+
+ /* Return */
+ ret
+.endfunc
Propchange: trunk/reactos/lib/rtl/amd64/debug_asm.S
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/lib/rtl/amd64/except_asm.S
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/amd64/except_asm.S…
==============================================================================
--- trunk/reactos/lib/rtl/amd64/except_asm.S (added)
+++ trunk/reactos/lib/rtl/amd64/except_asm.S [iso-8859-1] Wed Jan 6 01:39:07 2010
@@ -1,0 +1,100 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Runtime Library (RTL)
+ * FILE: lib/rtl/amd64/except_asm.S
+ * PURPOSE: Exception support for AMD64
+ * PROGRAMMERS: Timo Kreuzer (timo.kreuzer(a)reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <ndk/asm.h>
+.intel_syntax noprefix
+
+/* FUNCTIONS *****************************************************************/
+
+/*
+ * VOID NTAPI
+ * RtlCaptureContext(
+ * PCONTEXT ContextRecord); <rcx>
+ */
+.func RtlCaptureContext
+.global _RtlCaptureContext
+_RtlCaptureContext:
+ .cfi_startproc
+
+ /* Push rflags */
+ pushfq
+ .cfi_adjust_cfa_offset 8
+
+ /* Save the basic register context */
+ mov [rcx + CONTEXT_Rax], rax
+ mov [rcx + CONTEXT_Rcx], rcx
+ mov [rcx + CONTEXT_Rdx], rdx
+
+ /* Load rflags into rax */
+ mov rax, [rsp]
+
+ mov [rcx + CONTEXT_Rbx], rbx
+ mov [rcx + CONTEXT_Rsi], rsi
+ mov [rcx + CONTEXT_Rdi], rdi
+
+ /* Store rflags */
+ mov [rcx + CONTEXT_EFlags], rax
+
+ mov [rcx + CONTEXT_Rbp], rbp
+ mov [rcx + CONTEXT_R8], r8
+ mov [rcx + CONTEXT_R9], r9
+
+ /* Load former stack pointer in rax */
+ lea rax, [rsp + 0x10]
+
+ mov [rcx + CONTEXT_R10], r10
+ mov [rcx + CONTEXT_R11], r11
+ mov [rcx + CONTEXT_R12], r12
+
+ /* Store stack pointer */
+ mov [rcx + CONTEXT_Rsp], rax
+
+ mov [rcx + CONTEXT_R13], r13
+ mov [rcx + CONTEXT_R14], r14
+ mov [rcx + CONTEXT_R15], r15
+
+ /* Load return address in rax */
+ mov rax, [rsp + 8]
+
+ /* Safe segment selectors */
+ mov [rcx + CONTEXT_SegCs], cs
+ mov [rcx + CONTEXT_SegDs], ds
+ mov [rcx + CONTEXT_SegEs], es
+ mov [rcx + CONTEXT_SegFs], fs
+ mov [rcx + CONTEXT_SegGs], gs
+ mov [rcx + CONTEXT_SegSs], ss
+
+ /* Store return address */
+ mov [rcx + CONTEXT_Rip], rax
+
+ /* Safe xmm registers */
+ movdqa [rcx + CONTEXT_Xmm0], xmm0
+ movdqa [rcx + CONTEXT_Xmm1], xmm1
+ movdqa [rcx + CONTEXT_Xmm2], xmm2
+ movdqa [rcx + CONTEXT_Xmm3], xmm3
+ movdqa [rcx + CONTEXT_Xmm4], xmm4
+ movdqa [rcx + CONTEXT_Xmm5], xmm5
+ movdqa [rcx + CONTEXT_Xmm6], xmm6
+ movdqa [rcx + CONTEXT_Xmm7], xmm7
+ movdqa [rcx + CONTEXT_Xmm8], xmm8
+ movdqa [rcx + CONTEXT_Xmm9], xmm9
+ movdqa [rcx + CONTEXT_Xmm10], xmm10
+ movdqa [rcx + CONTEXT_Xmm11], xmm11
+ movdqa [rcx + CONTEXT_Xmm12], xmm12
+ movdqa [rcx + CONTEXT_Xmm13], xmm13
+ movdqa [rcx + CONTEXT_Xmm14], xmm14
+ movdqa [rcx + CONTEXT_Xmm15], xmm15
+
+ /* Cleanup stack and return */
+ add rsp, 8
+ ret
+ .cfi_endproc
+.endfunc
+
Propchange: trunk/reactos/lib/rtl/amd64/except_asm.S
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/lib/rtl/amd64/rtlmem.S
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/amd64/rtlmem.S?rev…
==============================================================================
--- trunk/reactos/lib/rtl/amd64/rtlmem.S (added)
+++ trunk/reactos/lib/rtl/amd64/rtlmem.S [iso-8859-1] Wed Jan 6 01:39:07 2010
@@ -1,0 +1,78 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Run-Time Library
+ * PURPOSE: Memory functions for amd64
+ * FILE: lib/rtl/i386/rtlswap.S
+ * PROGRAMER: Timo Kreuzer (timo.kreuzer(a)reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <ndk/amd64/asmmacro.S>
+
+/* FUNCTIONS *****************************************************************/
+.intel_syntax noprefix
+
+/* SIZE_T
+ * RtlCompareMemory(
+ * IN CONST VOID *Source1, <rcx>
+ * IN CONST VOID *Source2, <rdx>
+ * IN SIZE_T Length <r8>
+ * );
+ */
+.proc RtlCompareMemory
+
+ /* Save registers */
+ push rsi
+ .pushreg rsi
+ push rdi
+ .pushreg rdi
+
+ /* Setup registers for compare */
+ mov rsi, rcx
+ mov rdi, rdx
+
+ /* Clear direction flag */
+ cli
+
+ /* Get number of qwords */
+ mov rcx, r8
+ shr rcx, 3
+ jz 2f
+
+ /* Compare qwords */
+ repe cmpsq
+ jnz 4f
+
+2: /* Compare rest */
+ mov rcx, r8
+ and rcx, 7
+ jz 3f
+
+ repe cmpsb
+ jnz 5f
+
+3: /* All equal */
+ /* Return the full count */
+ mov rax, rcx
+ jmp 6f
+
+4: /* Not equal after comparing qwords */
+ /* Compare the last qword */
+ sub rsi, 8
+ sub rdi, 8
+ mov rcx, 8
+ repe cmpsb
+
+5: /* Not equal after comparing bytes */
+ /* Return difference */
+ sub rdi, rdx
+ dec rdi
+ mov rax, rdi
+
+6: /* Cleanup and return */
+ pop rdi
+ pop rsi
+ ret
+.endproc
+
Propchange: trunk/reactos/lib/rtl/amd64/rtlmem.S
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/lib/rtl/amd64/slist.S
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/amd64/slist.S?rev=…
==============================================================================
--- trunk/reactos/lib/rtl/amd64/slist.S (added)
+++ trunk/reactos/lib/rtl/amd64/slist.S [iso-8859-1] Wed Jan 6 01:39:07 2010
@@ -1,0 +1,343 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS system libraries
+ * FILE: lib/rtl/amd64/interlck.S
+ * PURPOSE: Rtl Interlocked Functions for amd64
+ * PROGRAMMERS: Timo Kreuzer
+ */
+
+#include <ndk/asm.h>
+#include <ndk/amd64/asmmacro.S>
+.intel_syntax noprefix
+
+#define SLIST8A_DEPTH_MASK 0x000000000000FFFF
+#define SLIST8A_DEPTH_INC 0x0000000000000001
+#define SLIST8A_SEQUENCE_MASK 0x0000000001FF0000
+#define SLIST8A_SEQUENCE_INC 0x0000000000010000
+#define SLIST8A_NEXTENTRY_MASK 0xFFFFFFFFFE000000
+#define SLIST8A_NEXTENTRY_SHIFT 21
+#define SLIST8B_HEADERTYPE_MASK 0x0000000000000001
+#define SLIST8B_INIT_MASK 0x0000000000000002
+#define SLIST8B_REGION_MASK 0xE000000000000000
+#define SLIST8_POINTER_MASK 0x000007FFFFFFFFF0
+
+#define SLIST16A_DEPTH_MASK 0x000000000000FFFF
+#define SLIST16A_DEPTH_INC 0x0000000000000001
+#define SLIST16A_SEQUENCE_MASK 0xFFFFFFFFFFFF0000
+#define SLIST16A_SEQUENCE_INC 0x0000000000010000
+#define SLIST16B_HEADERTYPE_MASK 0x0000000000000001
+#define SLIST16B_INIT_MASK 0x0000000000000002
+#define SLIST16B_NEXTENTY_MASK 0xFFFFFFFFFFFFFFF0
+
+
+/* FUNCTIONS ****************************************************************/
+
+.global _ExpInterlockedPopEntrySList
+.global _ExpInterlockedPopEntrySListResume
+.global _ExpInterlockedPopEntrySListFault
+.global _ExpInterlockedPopEntrySListEnd
+.global _ExpInterlockedPopEntrySListResume16
+.global _ExpInterlockedPopEntrySListFault16
+.global _ExpInterlockedPopEntrySListEnd16
+.global _ExpInterlockedPushEntrySList
+.global _ExpInterlockedFlushSList
+
+/* PSLIST_ENTRY
+ * NTAPI
+ * RtlInterlockedPopEntrySList(
+ * IN PSLIST_HEADER ListHead);
+ */
+.proc RtlInterlockedPopEntrySList
+_ExpInterlockedPopEntrySList:
+
+ /* Load ListHead->Region into rdx */
+ mov rdx, [rcx + 8]
+
+ /* Load ListHead->Alignment into rax */
+ mov rax, [rcx]
+
+ /* Check what kind of header this is */
+ test rdx, SLIST8B_HEADERTYPE_MASK
+ jnz _RtlInterlockedPopEntrySList16
+
+ /* We have an 8 byte header */
+
+_ExpInterlockedPopEntrySListResume:
+
+ /* Check if ListHead->NextEntry is NULL */
+ mov r9, rax
+ and r9, SLIST8A_NEXTENTRY_MASK
+ jz _RtlInterlockedPopEntrySListEmpty
+
+ /* Copy Depth and Sequence number and adjust Depth */
+ lea r8, [rax - SLIST8A_DEPTH_INC]
+ and r8, SLIST8A_SEQUENCE_MASK | SLIST8A_DEPTH_MASK
+
+ /* Create a pointer template from rcx in rdx */
+ mov rdx, ~SLIST8_POINTER_MASK
+ and rdx, rcx
+
+ /* Shift the NextEntry pointer */
+ shr r9, SLIST8A_NEXTENTRY_SHIFT
+
+ /* Combine to new pointer in rdx */
+ or rdx, r9
+
+_ExpInterlockedPopEntrySListFault:
+
+ /* Load the next NextEntry pointer to r9 */
+ mov r9, [rdx]
+
+ /* Shift bits in place */
+ shl r9, SLIST8A_NEXTENTRY_SHIFT
+
+ /* Combine into r8 */
+ or r8, r9
+
+_ExpInterlockedPopEntrySListEnd:
+
+ /* If [rcx] equals rax, exchange it with r8 */
+ lock cmpxchg [rcx], r8
+
+ /* If not equal, retry with rax, being the content of [rcx] now */
+ jnz _ExpInterlockedPopEntrySListResume
+
+ /* Shift the pointer bits in place */
+ and rax, SLIST8A_NEXTENTRY_MASK
+ shr rax, SLIST8A_NEXTENTRY_SHIFT
+
+ /* Use rcx as pointer template */
+ mov rdx, ~SLIST8_POINTER_MASK
+ and rdx, rcx
+
+ /* Combine result and return */
+ or rax, rdx
+ ret
+
+_RtlInterlockedPopEntrySListEmpty:
+ xor rax, rax
+ ret
+
+_RtlInterlockedPopEntrySList16:
+ /* This is a 16 byte header */
+
+ /* Save rbx */
+ push rbx
+
+ /* Copy rcx to r8, as we need rcx for the exchange */
+ mov r8, rcx
+
+_ExpInterlockedPopEntrySListResume16:
+
+ /* Check if ListHead->NextEntry is NULL */
+ mov r9, rdx
+ and r9, SLIST16B_NEXTENTY_MASK
+ jz _RtlInterlockedPopEntrySListEmpty16
+
+_ExpInterlockedPopEntrySListFault16:
+
+ /* Get next pointer */
+ mov rcx, [r9]
+
+ /* Set ListHead->HeaderType = 1 and ListHead->Init = 1 */
+ or rcx, 0x3
+
+ /* Copy Depth and Sequence number and adjust Depth */
+ lea rbx, [rax - SLIST16A_DEPTH_INC]
+
+_ExpInterlockedPopEntrySListEnd16:
+
+ /* If [r8] equals rdx:rax, exchange it with rcx:rbx */
+ lock cmpxchg16b [r8]
+
+ /* If not equal, retry with rdx:rax, being the content of [r8] now */
+ jnz _ExpInterlockedPopEntrySListResume16
+
+ /* Copy the old NextEntry pointer to rax */
+ mov rax, rdx
+ and rax, SLIST16B_NEXTENTY_MASK
+
+ /* Return */
+ pop rbx
+ ret
+
+_RtlInterlockedPopEntrySListEmpty16:
+ xor rax, rax
+ pop rbx
+ ret
+
+.endproc
+
+
+/* PSLIST_ENTRY
+ * NTAPI
+ * RtlInterlockedPushEntrySList(
+ * IN PSLIST_HEADER ListHead,
+ * IN PSLIST_ENTRY ListEntry);
+ */
+.proc RtlInterlockedPushEntrySList
+_ExpInterlockedPushEntrySList:
+
+ /* Load ListHead->Alignment into rax */
+ mov rax, [rcx]
+
+ /* Load ListHead->Region into rdx */
+ mov r9, [rcx + 8]
+
+ /* Check what kind of header this is */
+ test r9, SLIST8B_HEADERTYPE_MASK
+ jnz _RtlInterlockedPushEntrySList16
+
+ /* We have an 8 byte header */
+
+_RtlInterlockedPushEntrySListLoop:
+
+ /* Get ListHead->NextEntry */
+ mov r8, rax
+ and r8, SLIST8A_NEXTENTRY_MASK
+ jz _RtlInterlockedPushEntrySListEmpty
+
+ /* Shift the NextEntry pointer */
+ shr r8, SLIST8A_NEXTENTRY_SHIFT
+
+ /* Create a pointer template from rcx in rdx */
+ mov r9, ~SLIST8_POINTER_MASK
+ and r9, rcx
+
+ /* Combine to new pointer and save as ListEntry->NextEntry */
+ or r8, r9
+
+_RtlInterlockedPushEntrySListEmpty:
+ /* Store the NextEntry pointer in the new ListEntry */
+ mov [rdx], r8
+
+ /* Shift and mask the new ListEntry pointer */
+ mov r8, rdx
+ shl r8, SLIST8A_NEXTENTRY_SHIFT
+ and r8, SLIST8A_NEXTENTRY_MASK
+
+ /* Copy and adjust depth and sequence number */
+ lea r9, [rax + SLIST8A_DEPTH_INC + SLIST8A_SEQUENCE_INC]
+ and r9, SLIST8A_SEQUENCE_MASK | SLIST8A_DEPTH_MASK
+
+ /* Combine to exchange value in r8 */
+ or r8, r9
+
+ /* Save the NextEntry in r9 */
+ mov r9, [rdx]
+
+ /* If [rcx] equals rax, exchange it with r8 */
+ lock cmpxchg [rcx], r8
+
+ /* If not equal, retry with rax, being the content of [rcx] now */
+ jnz _RtlInterlockedPushEntrySListLoop
+
+ /* Return the old NextEntry pointer */
+ mov rax, r9
+ ret
+
+_RtlInterlockedPushEntrySList16:
+ /* This is a 16 byte header */
+
+ /* Save rbx */
+ push rbx
+
+ /* Copy rcx/rdx to r8/r9, as we need rcx/rdx for the exchange */
+ mov r8, rcx
+ mov r9, rdx
+
+ /* Set ListHead->HeaderType = 1 and ListHead->Init = 1 */
+ mov rcx, rdx
+ or rcx, 0x3
+
+ mov rdx, [r8 + 8]
+
+_RtlInterlockedPushEntrySListLoop16:
+
+ /* Move ListHead->NextEntry to rbx */
+ mov rbx, rdx
+ and rbx, SLIST16B_NEXTENTY_MASK
+
+ /* Store next pointer in ListEntry->NextEntry */
+ mov [r9], rbx
+
+ /* Copy Depth and Sequence number and adjust Depth */
+ lea rbx, [rax + SLIST16A_DEPTH_INC + SLIST16A_SEQUENCE_INC]
+
+ /* If [r8] equals rdx:rax, exchange it with rcx:rbx */
+ lock cmpxchg16b [r8]
+
+ /* If not equal, retry with rdx:rax, being the content of [r8] now */
+ jnz _RtlInterlockedPushEntrySListLoop16
+
+ /* Copy the old NextEntry pointer to rax */
+ mov rax, rdx
+ and rax, SLIST16B_NEXTENTY_MASK
+
+ /* Return */
+ pop rbx
+ ret
+
+.endproc
+
+/* PSLIST_ENTRY
+ * NTAPI
+ * RtlInterlockedFlushSList(
+ * IN PSINGLE_LIST_ENTRY ListHead);
+ */
+.proc RtlInterlockedFlushSList
+_ExpInterlockedFlushSList:
+
+ /* Load ListHead->Region into rdx */
+ mov rax, [rcx + 8]
+
+ /* Check what kind of header this is */
+ test rax, SLIST8B_HEADERTYPE_MASK
+ jnz _RtlInterlockedFlushSList16
+
+ /* We have an 8 byte header */
+
+_RtlInterlockedFlushSListLoop:
+
+ /* Zero ListHead->Alignment */
+ xor r8, r8
+
+ /* If [rcx] equals rax, exchange it with r8 */
+ lock cmpxchg [rcx], r8
+
+ /* If not equal, retry with rax, being the content of [rcx] now */
+ jnz _RtlInterlockedFlushSListLoop
+
+ /* Use rcx as pointer template */
+ mov rdx, ~SLIST8_POINTER_MASK
+ or rdx, rcx
+
+ /* Combine result and return */
+ or rax, rdx
+ ret
+
+_RtlInterlockedFlushSList16:
+ /* We have a 16 byte header */
+ push rbx
+
+ mov rdx, [rcx + 8]
+ xor rbx, rbx
+ mov rcx, 0x3
+
+_RtlInterlockedFlushSListLoop16:
+
+ /* If [r8] equals rdx:rax, exchange it with rcx:rbx */
+ lock cmpxchg16b [r8]
+
+ /* If not equal, retry with rdx:rax, being the content of [r8] now */
+ jnz _RtlInterlockedFlushSListLoop16
+
+ /* Copy the old NextEntry pointer to rax */
+ mov rax, rdx
+ and rax, SLIST16B_NEXTENTY_MASK
+
+ /* Return */
+ pop rbx
+ ret
+
+.endproc
Propchange: trunk/reactos/lib/rtl/amd64/slist.S
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/lib/rtl/amd64/stubs.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/amd64/stubs.c?rev=…
==============================================================================
--- trunk/reactos/lib/rtl/amd64/stubs.c (added)
+++ trunk/reactos/lib/rtl/amd64/stubs.c [iso-8859-1] Wed Jan 6 01:39:07 2010
@@ -1,0 +1,53 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Run-Time Library
+ * PURPOSE: AMD64 stubs
+ * FILE: lib/rtl/amd64/stubs.c
+ * PROGRAMMERS: Stefan Ginsberg (stefan.ginsberg(a)reactos.org)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <rtl.h>
+#define NDEBUG
+#include <debug.h>
+
+/* PUBLIC FUNCTIONS **********************************************************/
+
+/*
+ * @unimplemented
+ */
+VOID
+NTAPI
+RtlInitializeContext(IN HANDLE ProcessHandle,
+ OUT PCONTEXT ThreadContext,
+ IN PVOID ThreadStartParam OPTIONAL,
+ IN PTHREAD_START_ROUTINE ThreadStartAddress,
+ IN PINITIAL_TEB InitialTeb)
+{
+ UNIMPLEMENTED;
+ return;
+}
+
+/*
+ * @unimplemented
+ */
+PVOID
+NTAPI
+RtlpGetExceptionAddress(VOID)
+{
+ UNIMPLEMENTED;
+ return NULL;
+}
+
+/*
+ * @unimplemented
+ */
+BOOLEAN
+NTAPI
+RtlDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
+ IN PCONTEXT Context)
+{
+ UNIMPLEMENTED;
+ return FALSE;
+}
Propchange: trunk/reactos/lib/rtl/amd64/stubs.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/lib/rtl/amd64/unwind.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/amd64/unwind.c?rev…
==============================================================================
--- trunk/reactos/lib/rtl/amd64/unwind.c (added)
+++ trunk/reactos/lib/rtl/amd64/unwind.c [iso-8859-1] Wed Jan 6 01:39:07 2010
@@ -1,0 +1,684 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS system libraries
+ * PURPOSE: Unwinding related functions
+ * PROGRAMMER: Timo Kreuzer (timo.kreuzer(a)reactos.org)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <rtl.h>
+
+#define NDEBUG
+#include <debug.h>
+
+#define UNWIND_HISTORY_TABLE_NONE 0
+#define UNWIND_HISTORY_TABLE_GLOBAL 1
+#define UNWIND_HISTORY_TABLE_LOCAL 2
+
+#define UWOP_PUSH_NONVOL 0
+#define UWOP_ALLOC_LARGE 1
+#define UWOP_ALLOC_SMALL 2
+#define UWOP_SET_FPREG 3
+#define UWOP_SAVE_NONVOL 4
+#define UWOP_SAVE_NONVOL_FAR 5
+#define UWOP_SAVE_XMM 6
+#define UWOP_SAVE_XMM_FAR 7
+#define UWOP_SAVE_XMM128 8
+#define UWOP_SAVE_XMM128_FAR 9
+#define UWOP_PUSH_MACHFRAME 10
+
+#define UNW_FLAG_NHANDLER 0
+#define UNW_FLAG_EHANDLER 1
+#define UNW_FLAG_UHANDLER 2
+#define UNW_FLAG_CHAININFO 4
+
+typedef unsigned char UBYTE;
+
+typedef union _UNWIND_CODE
+{
+ struct
+ {
+ UBYTE CodeOffset;
+ UBYTE UnwindOp:4;
+ UBYTE OpInfo:4;
+ };
+ USHORT FrameOffset;
+} UNWIND_CODE, *PUNWIND_CODE;
+
+typedef struct _UNWIND_INFO
+{
+ UBYTE Version:3;
+ UBYTE Flags:5;
+ UBYTE SizeOfProlog;
+ UBYTE CountOfCodes;
+ UBYTE FrameRegister:4;
+ UBYTE FrameOffset:4;
+ UNWIND_CODE UnwindCode[1];
+/* union {
+ OPTIONAL ULONG ExceptionHandler;
+ OPTIONAL ULONG FunctionEntry;
+ };
+ OPTIONAL ULONG ExceptionData[];
+*/
+} UNWIND_INFO, *PUNWIND_INFO;
+
+/* FUNCTIONS *****************************************************************/
+
+/*! RtlLookupFunctionTable
+ * \brief Locates the table of RUNTIME_FUNCTION entries for a code address.
+ * \param ControlPc
+ * Address of the code, for which the table should be searched.
+ * \param ImageBase
+ * Pointer to a DWORD64 that receives the base address of the
+ * corresponding executable image.
+ * \param Length
+ * Pointer to an ULONG that receives the number of table entries
+ * present in the table.
+ */
+PRUNTIME_FUNCTION
+NTAPI
+RtlLookupFunctionTable(
+ IN DWORD64 ControlPc,
+ OUT PDWORD64 ImageBase,
+ OUT PULONG Length)
+{
+ PVOID Table;
+ ULONG Size;
+
+ /* Find corresponding file header from code address */
+ if (!RtlPcToFileHeader((PVOID)ControlPc, (PVOID*)ImageBase))
+ {
+ /* Nothing found */
+ return NULL;
+ }
+
+ /* Locate the exception directory */
+ Table = RtlImageDirectoryEntryToData((PVOID)*ImageBase,
+ TRUE,
+ IMAGE_DIRECTORY_ENTRY_EXCEPTION,
+ &Size);
+
+ /* Return the number of entries */
+ *Length = Size / sizeof(RUNTIME_FUNCTION);
+
+ /* Return the address of the table */
+ return Table;
+}
+
+/*! RtlLookupFunctionEntry
+ * \brief Locates the RUNTIME_FUNCTION entry corresponding to a code address.
+ * \ref
http://msdn.microsoft.com/en-us/library/ms680597(VS.85).aspx
+ * \todo Implement HistoryTable
+ */
+PRUNTIME_FUNCTION
+NTAPI
+RtlLookupFunctionEntry(
+ IN DWORD64 ControlPc,
+ OUT PDWORD64 ImageBase,
+ OUT PUNWIND_HISTORY_TABLE HistoryTable)
+{
+ PRUNTIME_FUNCTION FunctionTable, FunctionEntry;
+ ULONG TableLength;
+ ULONG IndexLo, IndexHi, IndexMid;
+
+ /* Find the corresponding table */
+ FunctionTable = RtlLookupFunctionTable(ControlPc, ImageBase, &TableLength);
+
+ /* Fail, if no table is found */
+ if (!FunctionTable)
+ {
+ return NULL;
+ }
+
+ /* Use relative virtual address */
+ ControlPc -= *ImageBase;
+
+ /* Do a binary search */
+ IndexLo = 0;
+ IndexHi = TableLength;
+ while (IndexHi > IndexLo)
+ {
+ IndexMid = (IndexLo + IndexHi) / 2;
+ FunctionEntry = &FunctionTable[IndexMid];
+
+ if (ControlPc < FunctionEntry->BeginAddress)
+ {
+ /* Continue search in lower half */
+ IndexHi = IndexMid;
+ }
+ else if (ControlPc >= FunctionEntry->EndAddress)
+ {
+ /* Continue search in upper half */
+ IndexLo = IndexMid + 1;
+ }
+ else
+ {
+ /* ControlPc is within limits, return entry */
+ return FunctionEntry;
+ }
+ }
+
+ /* Nothing found, return NULL */
+ return NULL;
+}
+
+BOOLEAN
+NTAPI
+RtlAddFunctionTable(
+ IN PRUNTIME_FUNCTION FunctionTable,
+ IN DWORD EntryCount,
+ IN DWORD64 BaseAddress)
+{
+ UNIMPLEMENTED;
+ return FALSE;
+}
+
+BOOLEAN
+NTAPI
+RtlDeleteFunctionTable(
+ IN PRUNTIME_FUNCTION FunctionTable)
+{
+ UNIMPLEMENTED;
+ return FALSE;
+}
+
+BOOLEAN
+NTAPI
+RtlInstallFunctionTableCallback(
+ IN DWORD64 TableIdentifier,
+ IN DWORD64 BaseAddress,
+ IN DWORD Length,
+ IN PGET_RUNTIME_FUNCTION_CALLBACK Callback,
+ IN PVOID Context,
+ IN PCWSTR OutOfProcessCallbackDll)
+{
+ UNIMPLEMENTED;
+ return FALSE;
+}
+
+void
+FORCEINLINE
+SetReg(PCONTEXT Context, BYTE Reg, DWORD64 Value)
+{
+ ((DWORD64*)(&Context->Rax))[Reg] = Value;
+}
+
+DWORD64
+FORCEINLINE
+GetReg(PCONTEXT Context, BYTE Reg)
+{
+ return ((DWORD64*)(&Context->Rax))[Reg];
+}
+
+void
+FORCEINLINE
+PopReg(PCONTEXT Context, BYTE Reg)
+{
+ DWORD64 Value = *(DWORD64*)Context->Rsp;
+ Context->Rsp += 8;
+ SetReg(Context, Reg, Value);
+}
+
+/*! RtlpTryToUnwindEpilog
+ * \brief Helper function that tries to unwind epilog instructions.
+ * \return TRUE if we have been in an epilog and it could be unwound.
+ * FALSE if the instructions were not allowed for an epilog.
+ * \ref
+ *
http://msdn.microsoft.com/en-us/library/8ydc79k6(VS.80).aspx
+ *
http://msdn.microsoft.com/en-us/library/tawsa7cb.aspx
+ * \todo
+ * - Test and compare with Windows behaviour
+ */
+BOOLEAN
+static
+inline
+RtlpTryToUnwindEpilog(
+ PCONTEXT Context,
+ ULONG64 ImageBase,
+ PRUNTIME_FUNCTION FunctionEntry)
+{
+ CONTEXT LocalContext;
+ BYTE *InstrPtr;
+ DWORD Instr;
+ BYTE Reg, Mod;
+ ULONG64 EndAddress;
+
+ /* Make a local copy of the context */
+ LocalContext = *Context;
+
+ InstrPtr = (BYTE*)LocalContext.Rip;
+
+ /* Check if first instruction of epilog is "add rsp, x" */
+ Instr = *(DWORD*)InstrPtr;
+ if ( (Instr & 0x00fffdff) == 0x00c48148 )
+ {
+ if ( (Instr & 0x0000ff00) == 0x8300 )
+ {
+ /* This is "add rsp, 0x??" */
+ LocalContext.Rsp += Instr >> 24;
+ InstrPtr += 4;
+ }
+ else
+ {
+ /* This is "add rsp, 0x???????? */
+ LocalContext.Rsp += *(DWORD*)(InstrPtr + 3);
+ InstrPtr += 7;
+ }
+ }
+ /* Check if first instruction of epilog is "lea rsp, ..." */
+ else if ( (Instr & 0x38fffe) == 0x208d48 )
+ {
+ /* Get the register */
+ Reg = ((Instr << 8) | (Instr >> 16)) & 0x7;
+
+ LocalContext.Rsp = GetReg(&LocalContext, Reg);
+
+ /* Get adressing mode */
+ Mod = (Instr >> 22) & 0x3;
+ if (Mod == 0)
+ {
+ /* No displacement */
+ InstrPtr += 3;
+ }
+ else if (Mod == 1)
+ {
+ /* 1 byte displacement */
+ LocalContext.Rsp += Instr >> 24;
+ InstrPtr += 4;
+ }
+ else if (Mod == 2)
+ {
+ /* 4 bytes displacement */
+ LocalContext.Rsp += *(DWORD*)(InstrPtr + 3);
+ InstrPtr += 7;
+ }
+ }
+
+ /* Loop the following instructions */
+ EndAddress = FunctionEntry->EndAddress + ImageBase;
+ while((DWORD64)InstrPtr < EndAddress)
+ {
+ Instr = *(DWORD*)InstrPtr;
+
+ /* Check for a simple pop */
+ if ( (Instr & 0xf8) == 0x58 )
+ {
+ /* Opcode pops a basic register from stack */
+ Reg = Instr & 0x7;
+ PopReg(&LocalContext, Reg);
+ InstrPtr++;
+ continue;
+ }
+
+ /* Check for REX + pop */
+ if ( (Instr & 0xf8fb) == 0x5841 )
+ {
+ /* Opcode is pop r8 .. r15 */
+ Reg = (Instr & 0x7) + 8;
+ PopReg(&LocalContext, Reg);
+ InstrPtr += 2;
+ continue;
+ }
+
+ /* Check for retn / retf */
+ if ( (Instr & 0xf7) == 0xc3 )
+ {
+ /* We are finished */
+ break;
+ }
+
+ /* Opcode not allowed for Epilog */
+ return FALSE;
+ }
+
+ /* Unwind is finished, pop new Rip from Stack */
+ LocalContext.Rip = *(DWORD64*)LocalContext.Rsp;
+ LocalContext.Rsp += sizeof(DWORD64);
+
+ *Context = LocalContext;
+ return TRUE;
+}
+
+
+PEXCEPTION_ROUTINE
+NTAPI
+RtlVirtualUnwind(
+ IN ULONG HandlerType,
+ IN ULONG64 ImageBase,
+ IN ULONG64 ControlPc,
+ IN PRUNTIME_FUNCTION FunctionEntry,
+ IN OUT PCONTEXT Context,
+ OUT PVOID *HandlerData,
+ OUT PULONG64 EstablisherFrame,
+ IN OUT PKNONVOLATILE_CONTEXT_POINTERS ContextPointers)
+{
+ PUNWIND_INFO UnwindInfo;
+ ULONG CodeOffset;
+ ULONG i;
+ UNWIND_CODE UnwindCode;
+ BYTE Reg;
+
+ /* Use relative virtual address */
+ ControlPc -= ImageBase;
+
+ /* Sanity checks */
+ if ( (ControlPc < FunctionEntry->BeginAddress) ||
+ (ControlPc >= FunctionEntry->EndAddress) )
+ {
+ return NULL;
+ }
+
+ /* Get a pointer to the unwind info */
+ UnwindInfo = RVA(ImageBase, FunctionEntry->UnwindData);
+
+ /* Calculate relative offset to function start */
+ CodeOffset = ControlPc - FunctionEntry->BeginAddress;
+
+ /* Check if we are in the function epilog and try to finish it */
+ if (CodeOffset > UnwindInfo->SizeOfProlog)
+ {
+ if (RtlpTryToUnwindEpilog(Context, ImageBase, FunctionEntry))
+ {
+ /* There's no exception routine */
+ return NULL;
+ }
+ }
+
+ /* Skip all Ops with an offset greater than the current Offset */
+ i = 0;
+ while (i < UnwindInfo->CountOfCodes &&
+ CodeOffset < UnwindInfo->UnwindCode[i].CodeOffset)
+ {
+ UnwindCode = UnwindInfo->UnwindCode[i];
+ switch (UnwindCode.UnwindOp)
+ {
+ case UWOP_SAVE_NONVOL:
+ case UWOP_SAVE_XMM:
+ case UWOP_SAVE_XMM128:
+ i += 2;
+ break;
+
+ case UWOP_SAVE_NONVOL_FAR:
+ case UWOP_SAVE_XMM_FAR:
+ case UWOP_SAVE_XMM128_FAR:
+ i += 3;
+ break;
+
+ case UWOP_ALLOC_LARGE:
+ i += UnwindCode.OpInfo ? 3 : 2;
+ break;
+
+ default:
+ i++;
+ }
+ }
+
+ /* Process the left Ops */
+ while (i < UnwindInfo->CountOfCodes)
+ {
+ UnwindCode = UnwindInfo->UnwindCode[i];
+ switch (UnwindCode.UnwindOp)
+ {
+ case UWOP_PUSH_NONVOL:
+ Reg = UnwindCode.OpInfo;
+ SetReg(Context, Reg, *(DWORD64*)Context->Rsp);
+ Context->Rsp += sizeof(DWORD64);
+ i++;
+ break;
+
+ case UWOP_ALLOC_LARGE:
+ if (UnwindCode.OpInfo)
+ {
+ ULONG Offset = *(ULONG*)(&UnwindInfo->UnwindCode[i+1]);
+ Context->Rsp += Offset;
+ i += 3;
+ }
+ else
+ {
+ USHORT Offset = UnwindInfo->UnwindCode[i+1].FrameOffset;
+ Context->Rsp += Offset * 8;
+ i += 2;
+ }
+ break;
+
+ case UWOP_ALLOC_SMALL:
+ Context->Rsp += (UnwindCode.OpInfo + 1) * 8;
+ i++;
+ break;
+
+ case UWOP_SET_FPREG:
+ i++;
+ break;
+
+ case UWOP_SAVE_NONVOL:
+ i += 2;
+ break;
+
+ case UWOP_SAVE_NONVOL_FAR:
+ i += 3;
+ break;
+
+ case UWOP_SAVE_XMM:
+ i += 2;
+ break;
+
+ case UWOP_SAVE_XMM_FAR:
+ i += 3;
+ break;
+
+ case UWOP_SAVE_XMM128:
+ i += 2;
+ break;
+
+ case UWOP_SAVE_XMM128_FAR:
+ i += 3;
+ break;
+
+ case UWOP_PUSH_MACHFRAME:
+ i += 1;
+ break;
+ }
+ }
+
+ /* Unwind is finished, pop new Rip from Stack */
+ Context->Rip = *(DWORD64*)Context->Rsp;
+ Context->Rsp += sizeof(DWORD64);
+
+ return 0;
+}
+
+VOID
+NTAPI
+RtlUnwindEx(
+ IN ULONG64 TargetFrame,
+ IN ULONG64 TargetIp,
+ IN PEXCEPTION_RECORD ExceptionRecord,
+ IN PVOID ReturnValue,
+ OUT PCONTEXT OriginalContext,
+ IN PUNWIND_HISTORY_TABLE HistoryTable)
+{
+ UNIMPLEMENTED;
+ return;
+}
+
+VOID
+NTAPI
+RtlUnwind(
+ IN PVOID TargetFrame,
+ IN PVOID TargetIp,
+ IN PEXCEPTION_RECORD ExceptionRecord,
+ IN PVOID ReturnValue)
+{
+ UNIMPLEMENTED;
+ return;
+}
+
+ULONG
+NTAPI
+RtlWalkFrameChain(OUT PVOID *Callers,
+ IN ULONG Count,
+ IN ULONG Flags)
+{
+ CONTEXT Context;
+ ULONG64 ControlPc, ImageBase, EstablisherFrame;
+ ULONG64 StackLow, StackHigh;
+ PVOID HandlerData;
+ INT i;
+ PRUNTIME_FUNCTION FunctionEntry;
+
+ DPRINT("Enter RtlWalkFrameChain\n");
+
+ /* Capture the current Context */
+ RtlCaptureContext(&Context);
+ ControlPc = Context.Rip;
+
+ /* Get the stack limits */
+ RtlpGetStackLimits(&StackLow, &StackHigh);
+
+ /* Check if we want the user-mode stack frame */
+ if (Flags == 1)
+ {
+ }
+
+ /* Loop the frames */
+ for (i = 0; i < Count; i++)
+ {
+ /* Lookup the FunctionEntry for the current ControlPc */
+ FunctionEntry = RtlLookupFunctionEntry(ControlPc, &ImageBase, NULL);
+
+ /* Is this a leaf function? */
+ if (!FunctionEntry)
+ {
+ Context.Rip = *(DWORD64*)Context.Rsp;
+ Context.Rsp += sizeof(DWORD64);
+ DPRINT("leaf funtion, new Rip = %p, new Rsp = %p\n",
(PVOID)Context.Rip, (PVOID)Context.Rsp);
+ }
+ else
+ {
+ RtlVirtualUnwind(0,
+ ImageBase,
+ ControlPc,
+ FunctionEntry,
+ &Context,
+ &HandlerData,
+ &EstablisherFrame,
+ NULL);
+ DPRINT("normal funtion, new Rip = %p, new Rsp = %p\n",
(PVOID)Context.Rip, (PVOID)Context.Rsp);
+ }
+
+ /* Check if new Rip is valid */
+ if (!Context.Rip)
+ {
+ break;
+ }
+
+ /* Check, if we have left our stack */
+ if ((Context.Rsp < StackLow) || (Context.Rsp > StackHigh))
+ {
+ break;
+ }
+
+ /* Save this frame and continue with new Rip */
+ ControlPc = Context.Rip;
+ Callers[i] = (PVOID)ControlPc;
+ }
+
+ DPRINT("RtlWalkFrameChain returns %ld\n", i);
+ return i;
+}
+
+/*! RtlGetCallersAddress
+ * \ref
http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/Debug…
+ */
+#undef RtlGetCallersAddress
+VOID
+NTAPI
+RtlGetCallersAddress(
+ OUT PVOID *CallersAddress,
+ OUT PVOID *CallersCaller )
+{
+ PVOID Callers[4];
+ ULONG Number;
+
+ /* Get callers:
+ * RtlWalkFrameChain -> RtlGetCallersAddress -> x -> y */
+ Number = RtlWalkFrameChain(Callers, 4, 0);
+
+ if (CallersAddress)
+ {
+ *CallersAddress = (Number >= 3) ? Callers[2] : NULL;
+ }
+ if (CallersCaller)
+ {
+ *CallersCaller = (Number == 4) ? Callers[3] : NULL;
+ }
+
+ return;
+}
+
+// FIXME: move to different file
+VOID
+NTAPI
+RtlRaiseException(IN PEXCEPTION_RECORD ExceptionRecord)
+{
+ CONTEXT Context;
+ NTSTATUS Status = STATUS_INVALID_DISPOSITION;
+ ULONG64 ImageBase;
+ PRUNTIME_FUNCTION FunctionEntry;
+ PVOID HandlerData;
+ ULONG64 EstablisherFrame;
+
+ /* Capture the context */
+ RtlCaptureContext(&Context);
+
+ /* Get the function entry for this function */
+ FunctionEntry = RtlLookupFunctionEntry(Context.Rip,
+ &ImageBase,
+ NULL);
+
+ /* Check if we found it */
+ if (FunctionEntry)
+ {
+ /* Unwind to the caller of this function */
+ RtlVirtualUnwind(UNW_FLAG_NHANDLER,
+ ImageBase,
+ Context.Rip,
+ FunctionEntry,
+ &Context,
+ &HandlerData,
+ &EstablisherFrame,
+ NULL);
+
+ /* Save the exception address */
+ ExceptionRecord->ExceptionAddress = (PVOID)Context.Rip;
+
+ /* Write the context flag */
+ Context.ContextFlags = CONTEXT_FULL;
+
+ /* Check if user mode debugger is active */
+ if (RtlpCheckForActiveDebugger())
+ {
+ /* Raise an exception immediately */
+ Status = ZwRaiseException(ExceptionRecord, &Context, TRUE);
+ }
+ else
+ {
+ /* Dispatch the exception and check if we should continue */
+ if (!RtlDispatchException(ExceptionRecord, &Context))
+ {
+ /* Raise the exception */
+ Status = ZwRaiseException(ExceptionRecord, &Context, FALSE);
+ }
+ else
+ {
+ /* Continue, go back to previous context */
+ Status = ZwContinue(&Context, FALSE);
+ }
+ }
+ }
+
+ /* If we returned, raise a status */
+ RtlRaiseStatus(Status);
+}
+
Propchange: trunk/reactos/lib/rtl/amd64/unwind.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/lib/rtl/exception.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/exception.c?rev=44…
==============================================================================
--- trunk/reactos/lib/rtl/exception.c [iso-8859-1] (original)
+++ trunk/reactos/lib/rtl/exception.c [iso-8859-1] Wed Jan 6 01:39:07 2010
@@ -17,7 +17,7 @@
/* FUNCTIONS ***************************************************************/
-#if !defined(_M_IX86)
+#if !defined(_M_IX86) && !defined(_M_AMD64)
/*
* @implemented
@@ -62,6 +62,10 @@
/* If we returned, raise a status */
RtlRaiseStatus(Status);
}
+
+#endif
+
+#if !defined(_M_IX86)
#ifdef _MSC_VER
#pragma warning(push)
Modified: trunk/reactos/lib/rtl/rtl.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/rtl.rbuild?rev=449…
==============================================================================
--- trunk/reactos/lib/rtl/rtl.rbuild [iso-8859-1] (original)
+++ trunk/reactos/lib/rtl/rtl.rbuild [iso-8859-1] Wed Jan 6 01:39:07 2010
@@ -31,6 +31,17 @@
<if property="ARCH" value="arm">
<directory name="arm">
<file>debug_asm.S</file>
+ </directory>
+ <file>mem.c</file>
+ <file>memgen.c</file>
+ </if>
+ <if property="ARCH" value="amd64">
+ <directory name="amd64">
+ <file>debug_asm.S</file>
+ <file>except_asm.S</file>
+ <file>slist.S</file>
+ <file>unwind.c</file>
+ <file>stubs.c</file>
</directory>
<file>mem.c</file>
<file>memgen.c</file>
Modified: trunk/reactos/lib/rtl/rtlp.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/rtlp.h?rev=44970&a…
==============================================================================
--- trunk/reactos/lib/rtl/rtlp.h [iso-8859-1] (original)
+++ trunk/reactos/lib/rtl/rtlp.h [iso-8859-1] Wed Jan 6 01:39:07 2010
@@ -32,10 +32,12 @@
#define ROUND_UP(n, align) \
ROUND_DOWN(((ULONG)n) + (align) - 1, (align))
+#define RVA(m, b) ((PVOID)((ULONG_PTR)(b) + (ULONG_PTR)(m)))
+
VOID
NTAPI
-RtlpGetStackLimits(PULONG_PTR StackBase,
- PULONG_PTR StackLimit);
+RtlpGetStackLimits(PULONG_PTR LowLimit,
+ PULONG_PTR HighLimit);
PEXCEPTION_REGISTRATION_RECORD
NTAPI
Modified: trunk/reactos/lib/rtl/slist.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/slist.c?rev=44970&…
==============================================================================
--- trunk/reactos/lib/rtl/slist.c [iso-8859-1] (original)
+++ trunk/reactos/lib/rtl/slist.c [iso-8859-1] Wed Jan 6 01:39:07 2010
@@ -20,7 +20,10 @@
RtlInitializeSListHead(IN PSLIST_HEADER ListHead)
{
#ifdef _WIN64
- UNIMPLEMENTED;
+ ListHead->Alignment = 0;
+ ListHead->Region = 0;
+ ListHead->Header8.Init = 1;
+ // ListHead->Header8.HeaderType = 1; // FIXME: depending on cmpxchg16b support?
#else
ListHead->Alignment = 0;
#endif
@@ -31,8 +34,25 @@
RtlFirstEntrySList(IN const SLIST_HEADER *ListHead)
{
#ifdef _WIN64
- UNIMPLEMENTED;
- return NULL;
+ if (ListHead->Header8.HeaderType)
+ {
+ return (PVOID)(ListHead->Region & ~0xF);
+ }
+ else
+ {
+ union {
+ PVOID P;
+ struct {
+ ULONG64 Reserved:4;
+ ULONG64 NextEntry:39;
+ ULONG64 Reserved2:21;
+ } Bits;
+ } Pointer;
+
+ Pointer.P = (PVOID)ListHead;
+ Pointer.Bits.NextEntry = ListHead->Header8.NextEntry;
+ return Pointer.P;
+ }
#else
return ListHead->Next.Next;
#endif
@@ -43,8 +63,8 @@
RtlQueryDepthSList(IN PSLIST_HEADER ListHead)
{
#ifdef _WIN64
- UNIMPLEMENTED;
- return 0;
+ return ListHead->Header8.HeaderType ?
+ ListHead->Header16.Sequence : ListHead->Header8.Sequence;
#else
return ListHead->Depth;
#endif
Modified: trunk/reactos/lib/rtl/sprintf.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/sprintf.c?rev=4497…
==============================================================================
--- trunk/reactos/lib/rtl/sprintf.c [iso-8859-1] (original)
+++ trunk/reactos/lib/rtl/sprintf.c [iso-8859-1] Wed Jan 6 01:39:07 2010
@@ -27,40 +27,33 @@
#define SPECIAL 32 /* 0x */
#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
#define REMOVEHEX 256 /* use 256 as remve 0x frim BASE 16 */
-typedef struct {
- unsigned int mantissal:32;
- unsigned int mantissah:20;
- unsigned int exponent:11;
- unsigned int sign:1;
+typedef union {
+ struct {
+ unsigned int mantissal:32;
+ unsigned int mantissah:20;
+ unsigned int exponent:11;
+ unsigned int sign:1;
+ };
+ long long AsLongLong;
} double_t;
+
+/* We depend on this being true */
+C_ASSERT(sizeof(double_t) == sizeof(double));
static
__inline
int
-_isinf(double __x)
-{
- union
- {
- double* __x;
- double_t* x;
- } x;
-
- x.__x = &__x;
- return ( x.x->exponent == 0x7ff && ( x.x->mantissah == 0 &&
x.x->mantissal == 0 ));
+_isinf(double_t x)
+{
+ return ( x.exponent == 0x7ff && ( x.mantissah == 0 && x.mantissal == 0
));
}
static
__inline
int
-_isnan(double __x)
-{
- union
- {
- double* __x;
- double_t* x;
- } x;
- x.__x = &__x;
- return ( x.x->exponent == 0x7ff && ( x.x->mantissah != 0 ||
x.x->mantissal != 0 ));
+_isnan(double_t x)
+{
+ return ( x.exponent == 0x7ff && ( x.mantissah != 0 || x.mantissal != 0 ));
}
@@ -180,14 +173,13 @@
}
static char *
-numberf(char * buf, char * end, double num, int base, int size, int precision, int type)
+numberf(char * buf, char * end, double_t num, int base, int size, int precision, int
type)
{
char c,sign,tmp[66];
const char *digits;
const char *small_digits = "0123456789abcdefghijklmnopqrstuvwxyz";
const char *large_digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int i;
- long long x;
/* FIXME
the float version of number is direcly copy of number
@@ -201,9 +193,9 @@
c = (type & ZEROPAD) ? '0' : ' ';
sign = 0;
if (type & SIGN) {
- if (num < 0) {
+ if (num.sign) {
sign = '-';
- num = -num;
+ num.sign = 0;
size--;
} else if (type & PLUS) {
sign = '+';
@@ -220,15 +212,11 @@
size--;
}
i = 0;
- if (num == 0)
+ if (num.AsLongLong == 0)
tmp[i++] = '0';
- else while (num != 0)
+ else while (num.AsLongLong != 0)
{
- x = num;
- tmp[i++] = digits[do_div(&x,base)];
-#ifndef _M_ARM // Missing __floatdidf in CeGCC 0.55 -- GCC 4.4
- num=x;
-#endif
+ tmp[i++] = digits[do_div(&num.AsLongLong,base)];
}
if (i > precision)
precision = i;
@@ -389,7 +377,7 @@
{
int len;
unsigned long long num;
- double _double;
+ double_t _double;
int base;
char *str, *end;
@@ -600,7 +588,7 @@
case 'f':
case 'g':
case 'G':
- _double = (double)va_arg(args, double);
+ _double = va_arg(args, double_t);
if ( _isnan(_double) ) {
s = "Nan";
len = 3;
@@ -631,7 +619,7 @@
} else {
if ( precision == -1 )
precision = 6;
- str = numberf(str, end, (int)_double, base, field_width, precision,
flags);
+ str = numberf(str, end, _double, base, field_width, precision, flags);
}
continue;
Modified: trunk/reactos/lib/rtl/swprintf.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/swprintf.c?rev=449…
==============================================================================
--- trunk/reactos/lib/rtl/swprintf.c [iso-8859-1] (original)
+++ trunk/reactos/lib/rtl/swprintf.c [iso-8859-1] Wed Jan 6 01:39:07 2010
@@ -27,40 +27,33 @@
#define SPECIAL 32 /* 0x */
#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
#define REMOVEHEX 256 /* use 256 as remve 0x frim BASE 16 */
-typedef struct {
- unsigned int mantissal:32;
- unsigned int mantissah:20;
- unsigned int exponent:11;
- unsigned int sign:1;
+typedef union {
+ struct {
+ unsigned int mantissal:32;
+ unsigned int mantissah:20;
+ unsigned int exponent:11;
+ unsigned int sign:1;
+ };
+ long long AsLongLong;
} double_t;
+
+/* We depend on this being true */
+C_ASSERT(sizeof(double_t) == sizeof(double));
static
__inline
int
-_isinf(double __x)
-{
- union
- {
- double* __x;
- double_t* x;
- } x;
-
- x.__x = &__x;
- return ( x.x->exponent == 0x7ff && ( x.x->mantissah == 0 &&
x.x->mantissal == 0 ));
+_isinf(double_t x)
+{
+ return ( x.exponent == 0x7ff && ( x.mantissah == 0 && x.mantissal == 0
));
}
static
__inline
int
-_isnan(double __x)
-{
- union
- {
- double* __x;
- double_t* x;
- } x;
- x.__x = &__x;
- return ( x.x->exponent == 0x7ff && ( x.x->mantissah != 0 ||
x.x->mantissal != 0 ));
+_isnan(double_t x)
+{
+ return ( x.exponent == 0x7ff && ( x.mantissah != 0 || x.mantissal != 0 ));
}
@@ -179,14 +172,13 @@
}
static wchar_t *
-numberf(wchar_t * buf, wchar_t * end, double num, int base, int size, int precision, int
type)
+numberf(wchar_t * buf, wchar_t * end, double_t num, int base, int size, int precision,
int type)
{
wchar_t c, sign, tmp[66];
const wchar_t *digits;
const wchar_t *small_digits = L"0123456789abcdefghijklmnopqrstuvwxyz";
const wchar_t *large_digits = L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int i;
- long long x;
/* FIXME
the float version of number is direcly copy of number
@@ -201,9 +193,9 @@
c = (type & ZEROPAD) ? L'0' : L' ';
sign = 0;
if (type & SIGN) {
- if (num < 0) {
+ if (num.sign) {
sign = L'-';
- num = -num;
+ num.sign = 0;
size--;
} else if (type & PLUS) {
sign = L'+';
@@ -220,15 +212,11 @@
size--;
}
i = 0;
- if (num == 0)
+ if (num.AsLongLong == 0)
tmp[i++] = L'0';
- else while (num != 0)
- {
- x = num;
- tmp[i++] = digits[do_div(&x,base)];
-#ifndef _M_ARM // Missing __floatdidf in CeGCC 0.55 -- GCC 4.4
- num = x;
-#endif
+ else while (num.AsLongLong != 0)
+ {
+ tmp[i++] = digits[do_div(&num.AsLongLong,base)];
}
if (i > precision)
precision = i;
@@ -394,7 +382,7 @@
const char *s;
const wchar_t *sw;
const wchar_t *ss;
- double _double;
+ double_t _double;
int flags; /* flags to number() */
@@ -597,7 +585,7 @@
case 'f':
case 'g':
case 'G':
- _double = (double)va_arg(args, double);
+ _double = va_arg(args, double_t);
if ( _isnan(_double) ) {
ss = L"Nan";