[ros-diffs] [tkreuzer] 44970: [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)

tkreuzer at svn.reactos.org tkreuzer at svn.reactos.org
Wed Jan 6 01:39:07 CET 2010


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?rev=44970&view=auto
==============================================================================
--- 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 at 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?rev=44970&view=auto
==============================================================================
--- 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 at 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=44970&view=auto
==============================================================================
--- 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 at 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=44970&view=auto
==============================================================================
--- 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=44970&view=auto
==============================================================================
--- 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 at 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=44970&view=auto
==============================================================================
--- 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 at 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/RtlGetCallersAddress.html
+ */
+#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=44970&r1=44969&r2=44970&view=diff
==============================================================================
--- 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=44970&r1=44969&r2=44970&view=diff
==============================================================================
--- 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&r1=44969&r2=44970&view=diff
==============================================================================
--- 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&r1=44969&r2=44970&view=diff
==============================================================================
--- 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=44970&r1=44969&r2=44970&view=diff
==============================================================================
--- 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=44970&r1=44969&r2=44970&view=diff
==============================================================================
--- 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";




More information about the Ros-diffs mailing list